Browse Source

replace bencode library to rhilip/bencode, fix files tree builder #11

main
ghost 1 year ago
parent
commit
86e1455c6b
  1. 1
      README.md
  2. 2
      composer.json
  3. 103
      composer.lock
  4. 4
      public/asset/default/css/common.css
  5. 8
      public/asset/default/css/framework.css
  6. 2
      src/Controller/PageController.php
  7. 45
      src/Controller/TorrentController.php
  8. 43
      src/Service/TorrentService.php
  9. 85
      templates/default/torrent/info.html.twig

1
README.md

@ -48,6 +48,7 @@ git checkout -b my-pr-branch-name
* [SVG icons](https://icons.getbootstrap.com) * [SVG icons](https://icons.getbootstrap.com)
* [PHP Scrapper](https://github.com/medariox/scrapeer) * [PHP Scrapper](https://github.com/medariox/scrapeer)
* [PHP Bencode Library](https://github.com/Rhilip/Bencode)
* [Identicons](https://github.com/dmester/jdenticon-php) * [Identicons](https://github.com/dmester/jdenticon-php)
#### Feedback #### Feedback

2
composer.json

@ -9,7 +9,6 @@
"php": ">=8.1", "php": ">=8.1",
"ext-ctype": "*", "ext-ctype": "*",
"ext-iconv": "*", "ext-iconv": "*",
"christeredvartsen/php-bittorrent": "^2.0",
"doctrine/annotations": "^2.0", "doctrine/annotations": "^2.0",
"doctrine/doctrine-bundle": "^2.10", "doctrine/doctrine-bundle": "^2.10",
"doctrine/doctrine-migrations-bundle": "^3.2", "doctrine/doctrine-migrations-bundle": "^3.2",
@ -17,6 +16,7 @@
"jdenticon/jdenticon": "^1.0", "jdenticon/jdenticon": "^1.0",
"phpdocumentor/reflection-docblock": "^5.3", "phpdocumentor/reflection-docblock": "^5.3",
"phpstan/phpdoc-parser": "^1.24", "phpstan/phpdoc-parser": "^1.24",
"rhilip/bencode": "^2.3",
"symfony/asset": "6.3.*", "symfony/asset": "6.3.*",
"symfony/console": "6.3.*", "symfony/console": "6.3.*",
"symfony/crowdin-translation-provider": "6.3.*", "symfony/crowdin-translation-provider": "6.3.*",

103
composer.lock generated

@ -4,58 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "42f94769f35af5500e3ae6ce20dcb64e", "content-hash": "d46bb514c4109b10e7327ef9f913c11a",
"packages": [ "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", "name": "doctrine/annotations",
"version": "2.0.1", "version": "2.0.1",
@ -2184,6 +2134,57 @@
}, },
"time": "2021-07-14T16:46:02+00:00" "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", "name": "symfony/asset",
"version": "v6.3.0", "version": "v6.3.0",

4
public/asset/default/css/common.css

@ -101,6 +101,10 @@ input[type="submit"] {
cursor: pointer; cursor: pointer;
} }
ul {
list-style: none;
}
td { td {
padding: 2px 0; padding: 2px 0;
} }

8
public/asset/default/css/framework.css

@ -245,6 +245,10 @@ a:visited.background-color-hover-night-light:hover {
padding: 4px; padding: 4px;
} }
.padding-l-4-px {
padding-left: 4px;
}
.padding-t-4-px { .padding-t-4-px {
padding-top: 4px; padding-top: 4px;
} }
@ -273,6 +277,10 @@ a:visited.background-color-hover-night-light:hover {
padding: 8px; padding: 8px;
} }
.padding-l-8-px {
padding-left: 8px;
}
.padding-t-8-px { .padding-t-8-px {
padding-top: 8px; padding-top: 8px;
} }

2
src/Controller/PageController.php

@ -189,7 +189,7 @@ class PageController extends AbstractController
continue; continue;
} }
if (empty($torrentService->getTorrentFilenameByFilepath($file->getPathName()))) if (empty($torrentService->getTorrentInfoNameByFilepath($file->getPathName())))
{ {
$form['torrent']['error'][] = $translator->trans('Could not parse torrent file'); $form['torrent']['error'][] = $translator->trans('Could not parse torrent file');

45
src/Controller/TorrentController.php

@ -40,28 +40,63 @@ class TorrentController extends AbstractController
$request->getClientIp() $request->getClientIp()
); );
// Init torrent
if (!$torrent = $torrentService->getTorrent($request->get('id'))) if (!$torrent = $torrentService->getTorrent($request->get('id')))
{ {
throw $this->createNotFoundException(); 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'))) if (!$torrent = $torrentService->getTorrentLocales($request->get('id')))
{ {
throw $this->createNotFoundException(); throw $this->createNotFoundException();
} }
*/ */
//print_r($file->getFileTree());exit;
return $this->render('default/torrent/info.html.twig', [ return $this->render('default/torrent/info.html.twig', [
'torrent' => 'torrent' =>
[ [
'id' => $torrent->getId(), 'id' => $torrent->getId(),
'added' => 0, // @TODO
'locales' => [], //$torrent->getLocales(), 'locales' => [], //$torrent->getLocales(),
'pages' => [] 'pages' => []
], ],
'file' => $torrentService->decodeTorrentById( 'file' =>
$torrent->getId() [
), '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')), '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'); $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'); $form['torrent']['error'][] = $translator->trans('Could not parse torrent file');
} }

43
src/Service/TorrentService.php

@ -29,38 +29,16 @@ class TorrentService
$this->entityManagerInterface = $entityManagerInterface; $this->entityManagerInterface = $entityManagerInterface;
} }
public function decodeTorrentById(int $id): array public function getStoragePathById(int $id): string
{ {
$decoder = new \BitTorrent\Decoder(); return sprintf(
'%s/var/torrents/%s.torrent',
return $decoder->decodeFile( $this->kernelInterface->getProjectDir(),
sprintf( implode('/', str_split($id))
'%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 public function getTorrentKeywordsByFilepath(string $filepath): string
{ {
$data = $this->decodeTorrentByFilepath($filepath); $data = $this->decodeTorrentByFilepath($filepath);
@ -82,6 +60,7 @@ class TorrentService
return ''; return '';
} }
*/
public function getTorrent(int $id): ?Torrent public function getTorrent(int $id): ?Torrent
{ {
@ -100,17 +79,15 @@ class TorrentService
): ?Torrent ): ?Torrent
{ {
$torrent = $this->saveTorrent( $torrent = $this->saveTorrent(
$this->getTorrentFilenameByFilepath($filepath), $this->getTorrentInfoNameByFilepath($filepath),
$this->getTorrentKeywordsByFilepath($filepath) $this->getTorrentKeywordsByFilepath($filepath)
); );
$filesystem = new Filesystem(); $filesystem = new Filesystem();
$filesystem->copy( $filesystem->copy(
$filepath, $filepath,
sprintf( $this->getStoragePathById(
'%s/var/torrents/%s.torrent', $torrent->getId()
$this->kernelInterface->getProjectDir(),
implode('/', str_split($torrent->getId()))
) )
); );

85
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 %}
<div class="padding-l-8-px cursor-default">
<div class="padding-y-4-px">
{{ key }}
</div>
{{ self.recursive_file_tree(value) }}
</div>
{% else %}
<div class="padding-y-4-px padding-l-8-px background-color-hover-night-light cursor-default">
{{ key }}
<div class="float-right padding-x-8-px">
{{ value | format_bytes }}
</div>
</div>
{% endif %}
{% endfor %}
{% endmacro %}
{% from _self import recursive_file_tree %}
{% extends 'default/layout.html.twig' %} {% extends 'default/layout.html.twig' %}
{% block title %}{{ 'Torrent'|trans }} #{{ torrent.id }} - {{ name }}{% endblock %} {% block title %}{{ 'Torrent'|trans }} #{{ torrent.id }} - {{ name }}{% endblock %}
{% block main_content %} {% block main_content %}
@ -24,7 +45,7 @@
</div> </div>
<table class="width-100"> <table class="width-100">
<tbody> <tbody>
{% if file.info.name is defined %} {% if file.name %}
<tr> <tr>
<td class="padding-y-8-px border-bottom-default text-right" colspan="2"> <td class="padding-y-8-px border-bottom-default text-right" colspan="2">
{{ 'Name'|trans }} {{ 'Name'|trans }}
@ -32,11 +53,11 @@
</tr> </tr>
<tr> <tr>
<td class="padding-t-16-px font-size-12" colspan="2"> <td class="padding-t-16-px font-size-12" colspan="2">
{{ file.info.name }} {{ file.name }}
</td> </td>
</tr> </tr>
{% endif %} {% endif %}
{% if file['creation date'] is defined %} {% if file.created %}
<tr> <tr>
<td class="padding-y-8-px border-bottom-default text-right" colspan="2"> <td class="padding-y-8-px border-bottom-default text-right" colspan="2">
{{ 'Created'|trans }} {{ 'Created'|trans }}
@ -44,31 +65,43 @@
</tr> </tr>
<tr> <tr>
<td class="padding-t-16-px font-size-12" colspan="2"> <td class="padding-t-16-px font-size-12" colspan="2">
{{ file['creation date'] | format_date }} {{ file.created | format_date }}
</td> </td>
</tr> </tr>
{% endif %} {% endif %}
{% if file['created by'] is defined %} {% if file.hash.v1 %}
<tr> <tr>
<td class="padding-y-8-px border-bottom-default text-right" colspan="2"> <td class="padding-y-8-px border-bottom-default text-right" colspan="2">
{{ 'Generated'|trans }} {{ 'Info hash v1'|trans }}
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="padding-t-16-px font-size-12" colspan="2"> <td class="padding-t-16-px font-size-12" colspan="2">
{{ file['created by'] }} {{ file.hash.v1 }}
</td> </td>
</tr> </tr>
{% endif %} {% endif %}
{% if file.encoding is defined %} {% if file.hash.v2 %}
<tr> <tr>
<td class="padding-y-8-px border-bottom-default text-right" colspan="2"> <td class="padding-y-8-px border-bottom-default text-right" colspan="2">
{{ 'Encoding'|trans }} {{ 'Info hash v2'|trans }}
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="padding-t-16-px font-size-12" colspan="2"> <td class="padding-t-16-px font-size-12" colspan="2">
{{ file.encoding }} {{ file.hash.v2 }}
</td>
</tr>
{% endif %}
{% if file['created by'] is defined %}
<tr>
<td class="padding-y-8-px border-bottom-default text-right" colspan="2">
{{ 'Generated'|trans }}
</td>
</tr>
<tr>
<td class="padding-t-16-px font-size-12" colspan="2">
{{ file['created by'] }}
</td> </td>
</tr> </tr>
{% endif %} {% endif %}
@ -89,29 +122,13 @@
{{ 'Files'|trans }} {{ 'Files'|trans }}
</td> </td>
</tr> </tr>
<tr> {% for tree in file.tree %}
<td colspan="2">&nbsp;</td>
</tr>
<tr>
<td class="padding-y-4-px font-size-12" colspan="2">
<pre>/..</pre>
</td>
</tr>
{% for info in file.info.files %}
<tr> <tr>
<td class="padding-y-4-px font-size-12"> <td class="padding-y-16-px" colspan="2">
{% for path in info.path %} {{ recursive_file_tree(tree) }}
<pre>../{{ path }}</pre>
{% endfor %}
</td>
<td class="padding-y-4-px font-size-12 text-right">
<pre>{{ info.length | format_bytes }}</pre>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
<tr>
<td colspan="2">&nbsp;</td>
</tr>
<tr> <tr>
<td class="padding-y-8-px border-bottom-default text-right" colspan="2"> <td class="padding-y-8-px border-bottom-default text-right" colspan="2">
{{ 'Trackers'|trans }} {{ 'Trackers'|trans }}
@ -127,6 +144,7 @@
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
{#
<tr> <tr>
<td class="padding-y-4-px font-size-12"> <td class="padding-y-4-px font-size-12">
{{ file.announce }} {{ file.announce }}
@ -141,14 +159,15 @@
{% endif %} {% endif %}
</td> </td>
</tr> </tr>
{% for announces in file['announce-list'] %} #}
{% for announce in announces %} {% for announces in trackers %}
{% for tracker in announces %}
<tr> <tr>
<td class="padding-y-4-px font-size-12"> <td class="padding-y-4-px font-size-12">
{{ announce }} {{ tracker }}
</td> </td>
<td class="padding-y-4-px text-right"> <td class="padding-y-4-px text-right">
{% if announce not in trackers %} {% if tracker not in trackers %}
<span title="{{ 'Blocked'|trans }}"> <span title="{{ 'Blocked'|trans }}">
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" viewBox="0 0 16 16">
<path d="M1.5 1.5A.5.5 0 0 1 2 1h12a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.128.334L10 8.692V13.5a.5.5 0 0 1-.342.474l-3 1A.5.5 0 0 1 6 14.5V8.692L1.628 3.834A.5.5 0 0 1 1.5 3.5v-2z"/> <path d="M1.5 1.5A.5.5 0 0 1 2 1h12a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.128.334L10 8.692V13.5a.5.5 0 0 1-.342.474l-3 1A.5.5 0 0 1 6 14.5V8.692L1.628 3.834A.5.5 0 0 1 1.5 3.5v-2z"/>

Loading…
Cancel
Save