diff --git a/README.md b/README.md index 7684e8c..149c713 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ git checkout -b my-pr-branch-name * [SVG icons](https://icons.getbootstrap.com) * [PHP Scrapper](https://github.com/medariox/scrapeer) +* [PHP Bencode Library](https://github.com/Rhilip/Bencode) * [Identicons](https://github.com/dmester/jdenticon-php) #### Feedback diff --git a/composer.json b/composer.json index d53f074..f6fafed 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,6 @@ "php": ">=8.1", "ext-ctype": "*", "ext-iconv": "*", - "christeredvartsen/php-bittorrent": "^2.0", "doctrine/annotations": "^2.0", "doctrine/doctrine-bundle": "^2.10", "doctrine/doctrine-migrations-bundle": "^3.2", @@ -17,6 +16,7 @@ "jdenticon/jdenticon": "^1.0", "phpdocumentor/reflection-docblock": "^5.3", "phpstan/phpdoc-parser": "^1.24", + "rhilip/bencode": "^2.3", "symfony/asset": "6.3.*", "symfony/console": "6.3.*", "symfony/crowdin-translation-provider": "6.3.*", diff --git a/composer.lock b/composer.lock index 9dbd264..ea51c06 100644 --- a/composer.lock +++ b/composer.lock @@ -4,58 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "42f94769f35af5500e3ae6ce20dcb64e", + "content-hash": "d46bb514c4109b10e7327ef9f913c11a", "packages": [ - { - "name": "christeredvartsen/php-bittorrent", - "version": "v2.0.0", - "source": { - "type": "git", - "url": "https://github.com/christeredvartsen/php-bittorrent.git", - "reference": "1e4f17ef840cd56b10e9c507df0064048fc91778" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/christeredvartsen/php-bittorrent/zipball/1e4f17ef840cd56b10e9c507df0064048fc91778", - "reference": "1e4f17ef840cd56b10e9c507df0064048fc91778", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "require-dev": { - "phploc/phploc": "^5.0", - "phpstan/phpstan": "^0.12", - "phpunit/phpunit": "^8.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "BitTorrent\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Christer Edvartsen", - "email": "cogo@starzinger.net" - } - ], - "description": "A set of components that can be used to interact with torrent files (read+write) and classes that can encode/decode to/from the BitTorrent format.", - "homepage": "https://github.com/christeredvartsen/php-bittorrent", - "keywords": [ - "bittorrent", - "torrent" - ], - "support": { - "issues": "https://github.com/christeredvartsen/php-bittorrent/issues", - "source": "https://github.com/christeredvartsen/php-bittorrent" - }, - "time": "2020-01-21T19:12:01+00:00" - }, { "name": "doctrine/annotations", "version": "2.0.1", @@ -2184,6 +2134,57 @@ }, "time": "2021-07-14T16:46:02+00:00" }, + { + "name": "rhilip/bencode", + "version": "v2.3.3", + "source": { + "type": "git", + "url": "https://github.com/Rhilip/Bencode.git", + "reference": "fd37d13bb745352d40879dbbfa6da85af91e49f1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Rhilip/Bencode/zipball/fd37d13bb745352d40879dbbfa6da85af91e49f1", + "reference": "fd37d13bb745352d40879dbbfa6da85af91e49f1", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "suggest": { + "php-64bit": "Running 64 bit is recommended to prevent integer overflow" + }, + "type": "library", + "autoload": { + "psr-4": { + "Rhilip\\Bencode\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rhilip", + "email": "rhilipruan@gmail.com" + } + ], + "description": "A pure and simple PHP library for encoding and decoding Bencode data", + "keywords": [ + "bencode", + "bittorrent", + "torrent" + ], + "support": { + "issues": "https://github.com/Rhilip/Bencode/issues", + "source": "https://github.com/Rhilip/Bencode/tree/v2.3.3" + }, + "time": "2023-05-27T01:47:00+00:00" + }, { "name": "symfony/asset", "version": "v6.3.0", diff --git a/public/asset/default/css/common.css b/public/asset/default/css/common.css index c99e376..eec5496 100644 --- a/public/asset/default/css/common.css +++ b/public/asset/default/css/common.css @@ -101,6 +101,10 @@ input[type="submit"] { cursor: pointer; } +ul { + list-style: none; +} + td { padding: 2px 0; } diff --git a/public/asset/default/css/framework.css b/public/asset/default/css/framework.css index 5f3f6cb..ebfb3bc 100644 --- a/public/asset/default/css/framework.css +++ b/public/asset/default/css/framework.css @@ -245,6 +245,10 @@ a:visited.background-color-hover-night-light:hover { padding: 4px; } +.padding-l-4-px { + padding-left: 4px; +} + .padding-t-4-px { padding-top: 4px; } @@ -273,6 +277,10 @@ a:visited.background-color-hover-night-light:hover { padding: 8px; } +.padding-l-8-px { + padding-left: 8px; +} + .padding-t-8-px { padding-top: 8px; } diff --git a/src/Controller/PageController.php b/src/Controller/PageController.php index 60a3cf6..01b7296 100644 --- a/src/Controller/PageController.php +++ b/src/Controller/PageController.php @@ -189,7 +189,7 @@ class PageController extends AbstractController continue; } - if (empty($torrentService->getTorrentFilenameByFilepath($file->getPathName()))) + if (empty($torrentService->getTorrentInfoNameByFilepath($file->getPathName()))) { $form['torrent']['error'][] = $translator->trans('Could not parse torrent file'); diff --git a/src/Controller/TorrentController.php b/src/Controller/TorrentController.php index af80317..dc12c5a 100644 --- a/src/Controller/TorrentController.php +++ b/src/Controller/TorrentController.php @@ -40,28 +40,63 @@ class TorrentController extends AbstractController $request->getClientIp() ); + // Init torrent if (!$torrent = $torrentService->getTorrent($request->get('id'))) { throw $this->createNotFoundException(); } + // Init file + try + { + $file = \Rhilip\Bencode\TorrentFile::load( + $torrentService->getStoragePathById( + $torrent->getId() + ) + ); + } + + catch (ParseException $e) + { + throw $this->createNotFoundException(); + } + /* if (!$torrent = $torrentService->getTorrentLocales($request->get('id'))) { throw $this->createNotFoundException(); } */ - +//print_r($file->getFileTree());exit; return $this->render('default/torrent/info.html.twig', [ 'torrent' => [ 'id' => $torrent->getId(), + 'added' => 0, // @TODO 'locales' => [], //$torrent->getLocales(), 'pages' => [] ], - 'file' => $torrentService->decodeTorrentById( - $torrent->getId() - ), + 'file' => + [ + 'name' => $file->getName(), + 'size' => $file->getSize(), + 'count' => $file->getFileCount(), + 'pieces' => $file->getPieceLength(), + 'created' => $file->getCreationDate(), + 'software' => $file->getCreatedBy(), + 'protocol' => $file->getProtocol(), + 'private' => $file->isPrivate(), + 'source' => $file->getSource(), + 'comment' => $file->getComment(), + 'tree' => $file->getFileTree(), + 'trackers' => $file->getAnnounceList(), + 'hash' => + [ + 'v1' => $file->getInfoHashV1(false), + 'v2' => $file->getInfoHashV2(false) + ], + 'magnet' => $file->getMagnetLink() + ], 'trackers' => explode('|', $this->getParameter('app.trackers')), ]); } @@ -158,7 +193,7 @@ class TorrentController extends AbstractController $form['torrent']['error'][] = $translator->trans('Torrent file out of size limit'); } - if (empty($torrentService->getTorrentFilenameByFilepath($file->getPathName()))) + if (empty($torrentService->getTorrentInfoNameByFilepath($file->getPathName()))) { $form['torrent']['error'][] = $translator->trans('Could not parse torrent file'); } diff --git a/src/Service/TorrentService.php b/src/Service/TorrentService.php index d99dad5..c9ec05d 100644 --- a/src/Service/TorrentService.php +++ b/src/Service/TorrentService.php @@ -29,38 +29,16 @@ class TorrentService $this->entityManagerInterface = $entityManagerInterface; } - public function decodeTorrentById(int $id): array + public function getStoragePathById(int $id): string { - $decoder = new \BitTorrent\Decoder(); - - return $decoder->decodeFile( - sprintf( - '%s/var/torrents/%s.torrent', - $this->kernelInterface->getProjectDir(), - implode('/', str_split($id)) - ) + return sprintf( + '%s/var/torrents/%s.torrent', + $this->kernelInterface->getProjectDir(), + implode('/', str_split($id)) ); } - public function decodeTorrentByFilepath(string $filepath): array - { - $decoder = new \BitTorrent\Decoder(); - - return $decoder->decodeFile($filepath); - } - - public function getTorrentFilenameByFilepath(string $filepath): string - { - $data = $this->decodeTorrentByFilepath($filepath); - - if (!empty($data['info']['name'])) - { - return $data['info']['name']; - } - - return $data['info']['name']; - } - + /* public function getTorrentKeywordsByFilepath(string $filepath): string { $data = $this->decodeTorrentByFilepath($filepath); @@ -82,6 +60,7 @@ class TorrentService return ''; } + */ public function getTorrent(int $id): ?Torrent { @@ -100,17 +79,15 @@ class TorrentService ): ?Torrent { $torrent = $this->saveTorrent( - $this->getTorrentFilenameByFilepath($filepath), + $this->getTorrentInfoNameByFilepath($filepath), $this->getTorrentKeywordsByFilepath($filepath) ); $filesystem = new Filesystem(); $filesystem->copy( $filepath, - sprintf( - '%s/var/torrents/%s.torrent', - $this->kernelInterface->getProjectDir(), - implode('/', str_split($torrent->getId())) + $this->getStoragePathById( + $torrent->getId() ) ); diff --git a/templates/default/torrent/info.html.twig b/templates/default/torrent/info.html.twig index be42910..2a131a9 100644 --- a/templates/default/torrent/info.html.twig +++ b/templates/default/torrent/info.html.twig @@ -1,3 +1,24 @@ +{% macro recursive_file_tree(tree) %} + {% import _self as self %} + {% for key, value in tree %} + {% if value is iterable %} +
+
+ {{ key }} +
+ {{ self.recursive_file_tree(value) }} +
+ {% else %} +
+ {{ key }} +
+ {{ value | format_bytes }} +
+
+ {% endif %} + {% endfor %} +{% endmacro %} +{% from _self import recursive_file_tree %} {% extends 'default/layout.html.twig' %} {% block title %}{{ 'Torrent'|trans }} #{{ torrent.id }} - {{ name }}{% endblock %} {% block main_content %} @@ -24,7 +45,7 @@ - {% if file.info.name is defined %} + {% if file.name %} {% endif %} - {% if file['creation date'] is defined %} + {% if file.created %} {% endif %} - {% if file['created by'] is defined %} + {% if file.hash.v1 %} {% endif %} - {% if file.encoding is defined %} + {% if file.hash.v2 %} + + {% endif %} + {% if file['created by'] is defined %} + + + + + {% endif %} @@ -89,29 +122,13 @@ {{ 'Files'|trans }} - - - - - - - {% for info in file.info.files %} + {% for tree in file.tree %} - - {% endfor %} - - - {% endfor %} + {# - {% for announces in file['announce-list'] %} - {% for announce in announces %} + #} + {% for announces in trackers %} + {% for tracker in announces %}
{{ 'Name'|trans }} @@ -32,11 +53,11 @@
- {{ file.info.name }} + {{ file.name }}
{{ 'Created'|trans }} @@ -44,31 +65,43 @@
- {{ file['creation date'] | format_date }} + {{ file.created | format_date }}
- {{ 'Generated'|trans }} + {{ 'Info hash v1'|trans }}
- {{ file['created by'] }} + {{ file.hash.v1 }}
- {{ 'Encoding'|trans }} + {{ 'Info hash v2'|trans }}
- {{ file.encoding }} + {{ file.hash.v2 }} +
+ {{ 'Generated'|trans }} +
+ {{ file['created by'] }}
 
-
/..
-
- {% for path in info.path %} -
../{{ path }}
- {% endfor %} -
-
{{  info.length | format_bytes }}
+
+ {{ recursive_file_tree(tree) }}
 
{{ 'Trackers'|trans }} @@ -127,6 +144,7 @@
{{ file.announce }} @@ -141,14 +159,15 @@ {% endif %}
- {{ announce }} + {{ tracker }} - {% if announce not in trackers %} + {% if tracker not in trackers %}