Browse Source

add info hash v2 support

main
ghost 1 year ago
parent
commit
6d0b42a88b
  1. 2
      composer.json
  2. BIN
      database/yggtracker.mwb
  3. 4
      example/environment/sphinx.conf
  4. 10
      src/crontab/scrape.php
  5. 109
      src/library/database.php
  6. 228
      src/public/action.php
  7. 142
      src/public/edit.php

2
composer.json

@ -4,7 +4,7 @@
"type": "library", "type": "library",
"require": { "require": {
"php": "^8.1", "php": "^8.1",
"yggverse/parser": ">=0.2.0", "yggverse/parser": ">=0.3.0",
"jdenticon/jdenticon": "^1.0" "jdenticon/jdenticon": "^1.0"
}, },
"license": "MIT", "license": "MIT",

BIN
database/yggtracker.mwb

Binary file not shown.

4
example/environment/sphinx.conf

@ -19,6 +19,10 @@ source magnet : yggtracker
`magnet`.`metaDescription`, \ `magnet`.`metaDescription`, \
`magnet`.`description`, \ `magnet`.`description`, \
`magnet`.`dn`, \ `magnet`.`dn`, \
(SELECT GROUP_CONCAT(DISTINCT `infoHash`.`value`) \
FROM `infoHash` \
JOIN `magnetToInfoHash` ON (`magnetToInfoHash`.`magnetId` = `magnet`.`magnetId`) \
WHERE `infoHash`.`infoHashId` = `magnetToInfoHash`.`infoHashId`) AS `infoHash`, \
(SELECT GROUP_CONCAT(DISTINCT `keywordTopic`.`value`) \ (SELECT GROUP_CONCAT(DISTINCT `keywordTopic`.`value`) \
FROM `keywordTopic` \ FROM `keywordTopic` \
JOIN `magnetToKeywordTopic` ON (`magnetToKeywordTopic`.`magnetId` = `magnet`.`magnetId`) \ JOIN `magnetToKeywordTopic` ON (`magnetToKeywordTopic`.`magnetId` = `magnet`.`magnetId`) \

10
src/crontab/scrape.php

@ -57,6 +57,12 @@ try {
foreach ($db->getMagnetToAddressTrackerScrapeQueue(CRAWLER_SCRAPE_QUEUE_LIMIT) as $queue) foreach ($db->getMagnetToAddressTrackerScrapeQueue(CRAWLER_SCRAPE_QUEUE_LIMIT) as $queue)
{ {
$hash = [];
foreach ($db->findMagnetToInfoHashByMagnetId($queue->magnetId) as $result)
{
$hash[] = $db->getInfoHash($result->infoHashId)->value;
}
if ($addressTracker = $db->getAddressTracker($queue->addressTrackerId)) if ($addressTracker = $db->getAddressTracker($queue->addressTrackerId))
{ {
// Build url // Build url
@ -72,9 +78,7 @@ try {
$host->value, $host->value,
$uri->value); $uri->value);
$hash = str_replace('urn:btih:', false, $db->getMagnet($queue->magnetId)->xt); if ($scrape = $scraper->scrape($hash, [$url], null, 1))
if ($scrape = $scraper->scrape([$hash], [$url], null, 1))
{ {
$db->updateMagnetToAddressTrackerTimeOffline( $db->updateMagnetToAddressTrackerTimeOffline(
$queue->magnetToAddressTrackerId, $queue->magnetToAddressTrackerId,

109
src/library/database.php

@ -248,6 +248,50 @@ class Database {
return $this->addUri($value); return $this->addUri($value);
} }
// Info Hash
public function addInfoHash(mixed $value, int $version) : int {
$this->_debug->query->insert->total++;
$query = $this->_db->prepare('INSERT INTO `infoHash` SET `value` = ?, `version` = ?');
$query->execute([$value, $version]);
return $this->_db->lastInsertId();
}
public function getInfoHash(int $infoHashId) {
$this->_debug->query->select->total++;
$query = $this->_db->prepare('SELECT * FROM `infoHash` WHERE `infoHashId` = ?');
$query->execute([$infoHashId]);
return $query->fetch();
}
public function findInfoHash(string $value, int $version) {
$this->_debug->query->select->total++;
$query = $this->_db->prepare('SELECT * FROM `infoHash` WHERE `value` = ? AND `version` = ?');
$query->execute([$value, $version]);
return $query->fetch();
}
public function initInfoHashId(mixed $value, int $version) : int {
if ($result = $this->findInfoHash($value, $version)) {
return $result->infoHashId;
}
return $this->addInfoHash($value, $version);
}
// Address Tracker // Address Tracker
public function addAddressTracker(int $schemeId, int $hostId, mixed $portId, mixed $uriId) : int { public function addAddressTracker(int $schemeId, int $hostId, mixed $portId, mixed $uriId) : int {
@ -495,7 +539,6 @@ class Database {
// Magnet // Magnet
public function addMagnet(int $userId, public function addMagnet(int $userId,
string $xt,
int $xl, int $xl,
string $dn, string $dn,
string $linkSource, string $linkSource,
@ -508,7 +551,6 @@ class Database {
$this->_debug->query->insert->total++; $this->_debug->query->insert->total++;
$query = $this->_db->prepare('INSERT INTO `magnet` SET `userId` = ?, $query = $this->_db->prepare('INSERT INTO `magnet` SET `userId` = ?,
`xt` = ?,
`xl` = ?, `xl` = ?,
`dn` = ?, `dn` = ?,
`linkSource` = ?, `linkSource` = ?,
@ -521,7 +563,6 @@ class Database {
$query->execute( $query->execute(
[ [
$userId, $userId,
$xt,
$xl, $xl,
$dn, $dn,
$linkSource, $linkSource,
@ -569,45 +610,6 @@ class Database {
return $query->fetch()->result; return $query->fetch()->result;
} }
public function findMagnet(int $userId, string $xt) {
$this->_debug->query->select->total++;
$query = $this->_db->prepare('SELECT * FROM `magnet` WHERE `userId` = ? AND `xt` = ?');
$query->execute([$userId, $xt]);
return $query->fetch();
}
public function initMagnetId( int $userId,
string $xt,
int $xl,
string $dn,
string $linkSource,
bool $public,
bool $comments,
bool $sensitive,
bool $approved,
int $timeAdded) : int {
if ($result = $this->findMagnet($userId, $xt)) {
return $result->magnetId;
}
return $this->addMagnet($userId,
$xt,
$xl,
$dn,
$linkSource,
$public,
$comments,
$sensitive,
$approved,
$timeAdded);
}
public function updateMagnetDn(int $magnetId, string $dn, int $timeUpdated) : int { public function updateMagnetDn(int $magnetId, string $dn, int $timeUpdated) : int {
$this->_debug->query->update->total++; $this->_debug->query->update->total++;
@ -696,6 +698,29 @@ class Database {
return $query->rowCount(); return $query->rowCount();
} }
// Magnet to Info Hash
public function addMagnetToInfoHash(int $magnetId, int $infoHashId) : int {
$this->_debug->query->insert->total++;
$query = $this->_db->prepare('INSERT INTO `magnetToInfoHash` SET `magnetId` = ?, `infoHashId` = ?');
$query->execute([$magnetId, $infoHashId]);
return $this->_db->lastInsertId();
}
public function findMagnetToInfoHashByMagnetId(int $magnetId)
{
$this->_debug->query->select->total++;
$query = $this->_db->prepare('SELECT * FROM `magnetToInfoHash` WHERE `magnetId` = ?');
$query->execute([$magnetId]);
return $query->fetchAll();
}
// Magnet to AddressTracker // Magnet to AddressTracker
public function addMagnetToAddressTracker(int $magnetId, int $addressTrackerId) : int { public function addMagnetToAddressTracker(int $magnetId, int $addressTrackerId) : int {

228
src/public/action.php

@ -431,7 +431,30 @@ switch (isset($_GET['target']) ? urldecode($_GET['target']) : false)
$link = []; $link = [];
/// Exact Topic /// Exact Topic
$link[] = sprintf('magnet:?xt=%s', $magnet->xt); $xt = [];
foreach ($db->findMagnetToInfoHashByMagnetId($magnet->magnetId) as $result)
{
if ($infoHash = $db->getInfoHash($result->infoHashId))
{
switch ($infoHash->version)
{
case 1:
$xt[] = sprintf('xt=urn:btih:%s', $infoHash->value);
break;
case 2:
$xt[] = sprintf('xt=urn:btmh:%s', $infoHash->value);
break;
}
}
}
$link[] = sprintf('magnet:?%s', implode('&', $xt));
/// Display Name /// Display Name
$link[] = sprintf('dn=%s', urlencode($magnet->dn)); $link[] = sprintf('dn=%s', urlencode($magnet->dn));
@ -591,118 +614,137 @@ switch (isset($_GET['target']) ? urldecode($_GET['target']) : false)
$db->beginTransaction(); $db->beginTransaction();
// Init magnet // Init magnet
if (Yggverse\Parser\Urn::parse($magnet->xt)) if ($magnetId = $db->addMagnet( $user->userId,
$magnet->xl,
$magnet->dn,
$link,
MAGNET_DEFAULT_PUBLIC,
MAGNET_DEFAULT_COMMENTS,
MAGNET_DEFAULT_SENSITIVE,
$user->approved ? true : MAGNET_DEFAULT_APPROVED,
time()))
{ {
if ($magnetId = $db->initMagnetId($user->userId, foreach ($magnet as $key => $value)
strip_tags($magnet->xt),
strip_tags($magnet->xl),
strip_tags($magnet->dn),
$link,
MAGNET_DEFAULT_PUBLIC,
MAGNET_DEFAULT_COMMENTS,
MAGNET_DEFAULT_SENSITIVE,
$user->approved ? true : MAGNET_DEFAULT_APPROVED,
time()))
{ {
foreach ($magnet as $key => $value) switch ($key)
{ {
switch ($key) case 'xt':
{ foreach ($value as $xt)
case 'tr': {
foreach ($value as $tr) if (Yggverse\Parser\Magnet::isXTv1($xt))
{ {
if ($url = Yggverse\Parser\Url::parse($tr)) $db->addMagnetToInfoHash(
{ $magnetId,
if (preg_match(YGGDRASIL_URL_REGEX, str_replace(['[',']'], false, $url->host->name))) $db->initInfoHashId(
{ Yggverse\Parser\Magnet::filterInfoHash($xt), 1
$db->initMagnetToAddressTrackerId( )
$magnetId, );
$db->initAddressTrackerId(
$db->initSchemeId($url->host->scheme),
$db->initHostId($url->host->name),
$db->initPortId($url->host->port),
$db->initUriId($url->page->uri)
)
);
}
}
} }
break; if (Yggverse\Parser\Magnet::isXTv2($xt))
case 'ws':
foreach ($value as $ws)
{ {
// @TODO $db->addMagnetToInfoHash(
$magnetId,
$db->initInfoHashId(
Yggverse\Parser\Magnet::filterInfoHash($xt), 2
)
);
} }
break; }
case 'as': break;
foreach ($value as $as) case 'tr':
foreach ($value as $tr)
{
if ($url = Yggverse\Parser\Url::parse($tr))
{ {
if ($url = Yggverse\Parser\Url::parse($as)) if (preg_match(YGGDRASIL_URL_REGEX, str_replace(['[',']'], false, $url->host->name)))
{ {
if (preg_match(YGGDRASIL_URL_REGEX, str_replace(['[',']'], false, $url->host->name))) $db->initMagnetToAddressTrackerId(
{ $magnetId,
$db->initMagnetToAcceptableSourceId( $db->initAddressTrackerId(
$magnetId, $db->initSchemeId($url->host->scheme),
$db->initAcceptableSourceId( $db->initHostId($url->host->name),
$db->initSchemeId($url->host->scheme), $db->initPortId($url->host->port),
$db->initHostId($url->host->name), $db->initUriId($url->page->uri)
$db->initPortId($url->host->port), )
$db->initUriId($url->page->uri) );
)
);
}
} }
} }
break; }
case 'xs': break;
foreach ($value as $xs) case 'ws':
foreach ($value as $ws)
{
// @TODO
}
break;
case 'as':
foreach ($value as $as)
{
if ($url = Yggverse\Parser\Url::parse($as))
{ {
if ($url = Yggverse\Parser\Url::parse($xs)) if (preg_match(YGGDRASIL_URL_REGEX, str_replace(['[',']'], false, $url->host->name)))
{ {
if (preg_match(YGGDRASIL_URL_REGEX, str_replace(['[',']'], false, $url->host->name))) $db->initMagnetToAcceptableSourceId(
{ $magnetId,
$db->initMagnetToExactSourceId( $db->initAcceptableSourceId(
$magnetId, $db->initSchemeId($url->host->scheme),
$db->initExactSourceId( $db->initHostId($url->host->name),
$db->initSchemeId($url->host->scheme), $db->initPortId($url->host->port),
$db->initHostId($url->host->name), $db->initUriId($url->page->uri)
$db->initPortId($url->host->port), )
$db->initUriId($url->page->uri) );
)
);
}
} }
} }
break; }
case 'mt': break;
foreach ($value as $mt) case 'xs':
{ foreach ($value as $xs)
// @TODO {
} if ($url = Yggverse\Parser\Url::parse($xs))
break;
case 'x.pe':
foreach ($value as $xPe)
{
// @TODO
}
break;
case 'kt':
foreach ($value as $kt)
{ {
$db->initMagnetToKeywordTopicId( if (preg_match(YGGDRASIL_URL_REGEX, str_replace(['[',']'], false, $url->host->name)))
$magnetId, {
$db->initKeywordTopicId(trim(mb_strtolower(strip_tags(html_entity_decode($kt))))) $db->initMagnetToExactSourceId(
); $magnetId,
$db->initExactSourceId(
$db->initSchemeId($url->host->scheme),
$db->initHostId($url->host->name),
$db->initPortId($url->host->port),
$db->initUriId($url->page->uri)
)
);
}
} }
break; }
} break;
case 'mt':
foreach ($value as $mt)
{
// @TODO
}
break;
case 'x.pe':
foreach ($value as $xPe)
{
// @TODO
}
break;
case 'kt':
foreach ($value as $kt)
{
$db->initMagnetToKeywordTopicId(
$magnetId,
$db->initKeywordTopicId(trim(mb_strtolower(strip_tags(html_entity_decode($kt)))))
);
}
break;
} }
}
$db->commit(); $db->commit();
// Redirect to edit page // Redirect to edit page
header(sprintf('Location: %s/edit.php?magnetId=%s', trim(WEBSITE_URL, '/'), $magnetId)); header(sprintf('Location: %s/edit.php?magnetId=%s', trim(WEBSITE_URL, '/'), $magnetId));
}
} }
} catch (Exception $e) { } catch (Exception $e) {

142
src/public/edit.php

@ -51,7 +51,7 @@ $response = (object)
'message' => false, 'message' => false,
] ]
], ],
'xt' => (object) 'dn' => (object)
[ [
'value' => false, 'value' => false,
'valid' => (object) 'valid' => (object)
@ -60,9 +60,9 @@ $response = (object)
'message' => false, 'message' => false,
] ]
], ],
'dn' => (object) 'xt' => (object)
[ [
'value' => false, 'value' => [],
'valid' => (object) 'valid' => (object)
[ [
'success' => true, 'success' => true,
@ -71,7 +71,7 @@ $response = (object)
], ],
'kt' => (object) 'kt' => (object)
[ [
'value' => false, 'value' => [],
'valid' => (object) 'valid' => (object)
[ [
'success' => true, 'success' => true,
@ -80,7 +80,7 @@ $response = (object)
], ],
'tr' => (object) 'tr' => (object)
[ [
'value' => false, 'value' => [],
'valid' => (object) 'valid' => (object)
[ [
'success' => true, 'success' => true,
@ -89,7 +89,7 @@ $response = (object)
], ],
'as' => (object) 'as' => (object)
[ [
'value' => false, 'value' => [],
'valid' => (object) 'valid' => (object)
[ [
'success' => true, 'success' => true,
@ -98,7 +98,7 @@ $response = (object)
], ],
'xs' => (object) 'xs' => (object)
[ [
'value' => false, 'value' => [],
'valid' => (object) 'valid' => (object)
[ [
'success' => true, 'success' => true,
@ -267,6 +267,76 @@ else {
$db->updateMagnetDn($magnet->magnetId, trim(strip_tags(html_entity_decode($_POST['dn']))), time()); $db->updateMagnetDn($magnet->magnetId, trim(strip_tags(html_entity_decode($_POST['dn']))), time());
} }
// Exact Topic
if (isset($_POST['xt']))
{
foreach ((array) $_POST['xt'] as $version => $value)
{
switch ($version)
{
case 1:
if (!empty($value))
{
$exist = false;
foreach ($db->findMagnetToInfoHashByMagnetId($magnet->magnetId) as $result)
{
if ($infoHash = $db->getInfoHash($result->infoHashId))
{
if ($infoHash->version == 1)
{
$exist = true;
}
}
}
if (!$exist)
{
$db->addMagnetToInfoHash(
$magnet->magnetId,
$db->initInfoHashId(
Yggverse\Parser\Magnet::filterInfoHash($value), 1
)
);
}
}
break;
case 2:
if (!empty($value))
{
$exist = false;
foreach ($db->findMagnetToInfoHashByMagnetId($magnet->magnetId) as $result)
{
if ($infoHash = $db->getInfoHash($result->infoHashId))
{
if ($infoHash->version == 2)
{
$exist = true;
}
}
}
if (!$exist)
{
$db->addMagnetToInfoHash(
$magnet->magnetId,
$db->initInfoHashId(
Yggverse\Parser\Magnet::filterInfoHash($value), 2
)
);
}
}
break;
}
}
}
// Keyword Topic // Keyword Topic
$db->deleteMagnetToKeywordTopicByMagnetId($magnet->magnetId); $db->deleteMagnetToKeywordTopicByMagnetId($magnet->magnetId);
@ -437,12 +507,18 @@ else {
$response->form->sensitive->value = (bool) $magnet->sensitive; $response->form->sensitive->value = (bool) $magnet->sensitive;
$response->form->approved->value = (bool) $magnet->approved; $response->form->approved->value = (bool) $magnet->approved;
// Exact Topic
$response->form->xt->value = $magnet->xt;
// Display Name // Display Name
$response->form->dn->value = $magnet->dn; $response->form->dn->value = $magnet->dn;
// Exact Topic
foreach ($db->findMagnetToInfoHashByMagnetId($magnet->magnetId) as $result)
{
if ($infoHash = $db->getInfoHash($result->infoHashId))
{
$response->form->xt->value[$infoHash->version] = $infoHash->value;
}
}
// Keyword Topic // Keyword Topic
$kt = []; $kt = [];
foreach ($db->findKeywordTopicByMagnetId($magnet->magnetId) as $result) foreach ($db->findKeywordTopicByMagnetId($magnet->magnetId) as $result)
@ -596,15 +672,45 @@ else {
</fieldset> </fieldset>
<fieldset class="display-block margin-b-16"> <fieldset class="display-block margin-b-16">
<legend class="text-right width-100 padding-y-8 margin-b-8 border-bottom-default"><?php echo _('BitTorrent') ?></legend> <legend class="text-right width-100 padding-y-8 margin-b-8 border-bottom-default"><?php echo _('BitTorrent') ?></legend>
<label class="display-block margin-y-8 padding-t-4" for="xt"> <label class="display-block margin-y-8 padding-t-4" for="xt-1">
<?php echo _('Exact Topic (xt)') ?> <?php echo _('Info Hash v1 (xt)') ?>
<sub class="opacity-0 parent-hover-opacity-09" title="<?php echo _('URN containing file hash, could not be changed') ?>"> <?php if (empty($response->form->xt->value[1])) { ?>
<svg class="width-13px" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle-fill" viewBox="0 0 16 16"> <sub class="opacity-0 parent-hover-opacity-09" title="<?php echo _('Info info hash (btih) not provided and could be changed once') ?>">
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/> <svg class="width-13px" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle-fill" viewBox="0 0 16 16">
</svg> <path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
</sub> </svg>
<input class="width-100 margin-t-8" type="text" name="xt" id="xt" value="<?php echo $response->form->xt->value ?>" readonly="readonly" disabled="disabled" /> </sub>
<input class="width-100 margin-t-8 <?php echo (empty($response->form->xt->value[2]) ? 'background-color-red' : false) ?>" type="text" name="xt[1]" id="xt-1" value="" />
<?php } else { ?>
<sub class="opacity-0 parent-hover-opacity-09" title="<?php echo _('Unique info hash (btih)') ?>">
<svg class="width-13px" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle-fill" viewBox="0 0 16 16">
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
</svg>
</sub>
<input class="width-100 margin-t-8" type="text" name="xt[1]" id="xt-1" value="<?php echo $response->form->xt->value[1] ?>" readonly="readonly" disabled="disabled" />
<?php } ?>
</label>
<label class="display-block margin-y-8 padding-t-4" for="xt-2">
<?php echo _('Info Hash v2 (xt)') ?>
<?php if (empty($response->form->xt->value[2])) { ?>
<sub class="opacity-0 parent-hover-opacity-09" title="<?php echo _('Info info hash (btmh) not provided and could be changed once') ?>">
<svg class="width-13px" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle-fill" viewBox="0 0 16 16">
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
</svg>
</sub>
<input class="width-100 margin-t-8 <?php echo (empty($response->form->xt->value[1]) ? 'background-color-red' : false) ?>" type="text" name="xt[2]" id="xt-2" value="" />
<?php } else { ?>
<sub class="opacity-0 parent-hover-opacity-09" title="<?php echo _('Unique info hash (btmh)') ?>">
<svg class="width-13px" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle-fill" viewBox="0 0 16 16">
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
</svg>
</sub>
<input class="width-100 margin-t-8" type="text" name="xt[2]" id="xt-2" value="<?php echo $response->form->xt->value[2] ?>" readonly="readonly" disabled="disabled" />
<?php } ?>
</label> </label>
<?php if (empty($response->form->xt->value[1]) && empty($response->form->xt->value[2])) { ?>
<div class="margin-b-8"><?php echo _('At least v1 or v2 info hash required for download') ?></div>
<?php } ?>
<label class="display-block margin-y-8 padding-t-4" for="dn"> <label class="display-block margin-y-8 padding-t-4" for="dn">
<?php echo _('Display Name (dn)') ?> <?php echo _('Display Name (dn)') ?>
<sub class="opacity-0 parent-hover-opacity-09" title="<?php echo _('Filename display to the user in BitTorrent client') ?>"> <sub class="opacity-0 parent-hover-opacity-09" title="<?php echo _('Filename display to the user in BitTorrent client') ?>">

Loading…
Cancel
Save