diff --git a/CHANGELOG.md b/CHANGELOG.md index 84ae28eec..c2592340f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ - [CLI] TorrentPier installer ☕️ [\#1576](https://github.com/torrentpier/torrentpier/pull/1576), [\#1582](https://github.com/torrentpier/torrentpier/pull/1582), [\#1585](https://github.com/torrentpier/torrentpier/pull/1585), [\#1591](https://github.com/torrentpier/torrentpier/pull/1591) ([belomaxorka](https://github.com/belomaxorka)) - Added some new HTML meta-tags [\#1562](https://github.com/torrentpier/torrentpier/pull/1562) ([belomaxorka](https://github.com/belomaxorka)) - Added robots meta-tag support 🤖 [\#1587](https://github.com/torrentpier/torrentpier/pull/1587) ([belomaxorka](https://github.com/belomaxorka)) -- Added [TorrServer](https://github.com/YouROK/TorrServer) instance support! 🎞 [\#1603](https://github.com/torrentpier/torrentpier/pull/1603), [\#1623](https://github.com/torrentpier/torrentpier/pull/1623) ([belomaxorka](https://github.com/belomaxorka)) +- Added [TorrServer](https://github.com/YouROK/TorrServer) instance support! 🎞 [\#1603](https://github.com/torrentpier/torrentpier/pull/1603), [\#1623](https://github.com/torrentpier/torrentpier/pull/1623), [\#1624](https://github.com/torrentpier/torrentpier/pull/1624) ([belomaxorka](https://github.com/belomaxorka)) - Newtopic: Added configuring robots indexing [\#1599](https://github.com/torrentpier/torrentpier/pull/1599) ([belomaxorka](https://github.com/belomaxorka)) - Added showing releaser stats in profile [\#1568](https://github.com/torrentpier/torrentpier/pull/1568) ([belomaxorka](https://github.com/belomaxorka)) - Improved `filelist.php` [\#1586](https://github.com/torrentpier/torrentpier/pull/1586) ([belomaxorka](https://github.com/belomaxorka)) diff --git a/composer.json b/composer.json index 1b9ff62a1..1f038b28d 100644 --- a/composer.json +++ b/composer.json @@ -59,6 +59,7 @@ "google/recaptcha": "^1.3", "jacklul/monolog-telegram": "^3.1", "josantonius/cookie": "^2.0", + "gemorroj/m3u-parser": "dev-master", "php-curl-class/php-curl-class": "^11.0.0", "league/flysystem": "^3.28", "longman/ip-tools": "1.2.1", diff --git a/composer.lock b/composer.lock index 4cd71fc06..646c90f0a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "26d2ba6114d7c2482dcf968c0530d259", + "content-hash": "67c39c20b9970112162ecb7f43172f9c", "packages": [ { "name": "arokettu/bencode", @@ -78,20 +78,20 @@ }, { "name": "arokettu/is-resource", - "version": "1.0.3", + "version": "1.0.4", "source": { "type": "git", "url": "https://github.com/arokettu/is-resource.git", - "reference": "1143639fb55e1430b518acda273c84c9fa98ff7b" + "reference": "6a4966bf4608c69d20b7bf01670b49901a51eb9d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/arokettu/is-resource/zipball/1143639fb55e1430b518acda273c84c9fa98ff7b", - "reference": "1143639fb55e1430b518acda273c84c9fa98ff7b", + "url": "https://api.github.com/repos/arokettu/is-resource/zipball/6a4966bf4608c69d20b7bf01670b49901a51eb9d", + "reference": "6a4966bf4608c69d20b7bf01670b49901a51eb9d", "shasum": "" }, "require": { - "php": ">= 5.3 < 8.4" + "php": ">= 5.3 < 8.5" }, "type": "library", "autoload": { @@ -114,7 +114,7 @@ "role": "developer" } ], - "description": "Future compatible is_resource() and get_resource_type() that can understand opaque objects", + "description": "Future compatible is_resource() and get_resource_type() that can understand objects that replaced earlier resources", "homepage": "https://sandfox.dev/php/is-resource.html", "keywords": [ "compatibility", @@ -130,11 +130,12 @@ "sockets" ], "support": { + "chat": "https://gitter.im/arokettu/community", "docs": "https://is-resource.readthedocs.io/", "issues": "https://gitlab.com/sandfox/is-resource/-/issues", "source": "https://gitlab.com/sandfox/is-resource" }, - "time": "2023-08-28T12:32:54+00:00" + "time": "2024-08-27T04:34:45+00:00" }, { "name": "arokettu/monsterid", @@ -805,6 +806,56 @@ ], "time": "2023-11-03T12:00:00+00:00" }, + { + "name": "gemorroj/m3u-parser", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/Gemorroj/M3uParser.git", + "reference": "fcb37acd137a6e1d6aa2ef3745e1bc7a6e0b46e6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Gemorroj/M3uParser/zipball/fcb37acd137a6e1d6aa2ef3745e1bc7a6e0b46e6", + "reference": "fcb37acd137a6e1d6aa2ef3745e1bc7a6e0b46e6", + "shasum": "" + }, + "require": { + "php": ">=8.0.2" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.46", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.6" + }, + "default-branch": true, + "type": "library", + "autoload": { + "psr-4": { + "M3uParser\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Gemorroj" + } + ], + "description": "m3u playlist parser/generator", + "keywords": [ + "m3u", + "m3u8", + "playlist" + ], + "support": { + "issues": "https://github.com/Gemorroj/M3uParser/issues", + "source": "https://github.com/Gemorroj/M3uParser/tree/master" + }, + "time": "2024-07-27T11:53:30+00:00" + }, { "name": "gigablah/sphinxphp", "version": "2.0.8", @@ -2534,16 +2585,16 @@ }, { "name": "psr/log", - "version": "3.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + "reference": "79dff0b268932c640297f5208d6298f71855c03e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "url": "https://api.github.com/repos/php-fig/log/zipball/79dff0b268932c640297f5208d6298f71855c03e", + "reference": "79dff0b268932c640297f5208d6298f71855c03e", "shasum": "" }, "require": { @@ -2578,9 +2629,9 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/3.0.0" + "source": "https://github.com/php-fig/log/tree/3.0.1" }, - "time": "2021-07-14T16:46:02+00:00" + "time": "2024-08-21T13:31:24+00:00" }, { "name": "psr/simple-cache", @@ -4141,7 +4192,8 @@ "aliases": [], "minimum-stability": "dev", "stability-flags": { - "arokettu/monsterid": 20 + "arokettu/monsterid": 20, + "gemorroj/m3u-parser": 20 }, "prefer-stable": true, "prefer-lowest": false, diff --git a/library/attach_mod/displaying_torrent.php b/library/attach_mod/displaying_torrent.php index 0d1126c84..adb1bdcf6 100644 --- a/library/attach_mod/displaying_torrent.php +++ b/library/attach_mod/displaying_torrent.php @@ -224,9 +224,9 @@ if ($tor_reged && $tor_info) { ]); // TorrServer integration - if ($bb_cfg['torr_server']['enabled'] && $m3u_file = (new \TorrentPier\TorrServerAPI())->getM3UPath($attach_id)) { + if ($bb_cfg['torr_server']['enabled'] && (!IS_GUEST || !$bb_cfg['torr_server']['disable_for_guest']) && (new \TorrentPier\TorrServerAPI())->getM3UPath($attach_id)) { $template->assign_block_vars('postrow.attach.tor_reged.tor_server', [ - 'TORR_SERVER_M3U_LINK' => $m3u_file, + 'TORR_SERVER_M3U_LINK' => PLAYBACK_M3U_URL . $attach_id, 'TORR_SERVER_M3U_ICON' => $images['icon_tor_m3u_icon'], ]); } diff --git a/library/config.php b/library/config.php index 06f28411a..503a8f2d5 100644 --- a/library/config.php +++ b/library/config.php @@ -114,7 +114,8 @@ $bb_cfg['torr_server'] = [ // Read more: https://github.com/YouROK/TorrServer 'enabled' => false, 'url' => "http://$domain_name:8090", - 'timeout' => 5 + 'timeout' => 5, + 'disable_for_guest' => true ]; // Ocelot diff --git a/library/includes/init_bb.php b/library/includes/init_bb.php index 1bdf55501..09b42488d 100644 --- a/library/includes/init_bb.php +++ b/library/includes/init_bb.php @@ -302,6 +302,7 @@ define('PROFILE_URL', 'profile.php?mode=viewprofile&' . POST_USERS_URL . '=' define('BONUS_URL', 'profile.php?mode=bonus'); define('TOPIC_URL', 'viewtopic.php?' . POST_TOPIC_URL . '='); define('FILELIST_URL', 'filelist.php?' . POST_TOPIC_URL . '='); +define('PLAYBACK_M3U_URL', 'playback_m3u.php?attach_id='); define('USER_AGENT', strtolower($_SERVER['HTTP_USER_AGENT'])); diff --git a/library/language/source/main.php b/library/language/source/main.php index 31e3ebde2..ab54fedc4 100644 --- a/library/language/source/main.php +++ b/library/language/source/main.php @@ -63,6 +63,7 @@ $lang['SELECT_ACTION'] = 'Select action'; $lang['CLEAR'] = 'Clear'; $lang['MOVE_TO_TOP'] = 'Move to top'; $lang['UNKNOWN'] = 'Unknown'; +$lang['COPY_TO_CLIPBOARD'] = 'Copy to clipboard'; $lang['NEXT_PAGE'] = 'Next'; $lang['PREVIOUS_PAGE'] = 'Previous'; @@ -1268,6 +1269,10 @@ $lang['FILESIZE'] = 'Filesize'; $lang['VIEWED'] = 'Viewed'; $lang['EXTENSION_DISABLED_AFTER_POSTING'] = 'The Extension \'%s\' was deactivated by an board admin, therefore this Attachment is not displayed.'; // used in Posts and PM's, replace %s with mime type $lang['DOWNLOAD_M3U_FILE'] = 'Download .m3u file'; +$lang['PLAYBACK_M3U'] = 'Playback .m3u file'; +$lang['STREAM'] = 'Stream'; +$lang['COPY_STREAM_LINK'] = 'Copy stream link to clipboard'; +$lang['M3U_NOTICE'] = 'Some browsers do not support playback of certain video formats. In such a case, you can download the .m3u file and play it using a third-party player'; $lang['ATTACHMENT'] = 'Attachments'; $lang['ATTACHMENT_THUMBNAIL'] = 'Attachment Thumbnail'; diff --git a/playback_m3u.php b/playback_m3u.php new file mode 100644 index 000000000..c738543bd --- /dev/null +++ b/playback_m3u.php @@ -0,0 +1,89 @@ + ['mp3', 'flac', 'wav'], + 'video' => ['mp4', 'mkv', 'avi'] +]; + +// Start session management +$user->session_start(['req_login' => $bb_cfg['torr_server']['disable_for_guest']]); + +// Disable robots indexing +$page_cfg['allow_robots'] = false; + +// Check attach_id +if (!$attach_id = request_var('attach_id', 0)) { + bb_die($lang['INVALID_ATTACH_ID']); +} + +// Check m3u file exist +if (!$m3uFile = (new \TorrentPier\TorrServerAPI())->getM3UPath($attach_id)) { + bb_die($lang['ERROR_NO_ATTACHMENT']); +} + +// Parse M3U file +$m3uParser = new M3uParser\M3uParser(); +$m3uParser->addDefaultTags(); +$m3uData = $m3uParser->parseFile($m3uFile); + +$filesCount = 0; +foreach ($m3uData as $entry) { + $filesCount++; + $rowClass = ($filesCount % 2) ? 'row1' : 'row2'; + + // Validate URL + $streamLink = $entry->getPath(); + if (!filter_var($streamLink, FILTER_VALIDATE_URL)) { + continue; + } + + // Parse tags + foreach ($entry->getExtTags() as $extTag) { + // #EXTINF tag + if ($extTag == $extTag instanceof \M3uParser\Tag\ExtInf) { + $title = $extTag->getTitle(); + } + } + + // Validate title + if (!isset($title)) { + continue; + } + + // Validate file extension + $getExtension = pathinfo($title, PATHINFO_EXTENSION); + + $template->assign_block_vars('m3ulist', [ + 'ROW_NUMBER' => $filesCount, + 'ROW_CLASS' => $rowClass, + 'IS_VALID' => in_array($getExtension, array_merge($validFormats['audio'], $validFormats['video'])), + 'IS_AUDIO' => in_array($getExtension, $validFormats['audio']), + 'STREAM_LINK' => $streamLink, + 'M3U_DL_LINK' => $m3uFile, + 'TITLE' => $title, + ]); +} + +// Generate output +$template->assign_vars([ + 'PAGE_TITLE' => $lang['PLAYBACK_M3U'], + 'FILES_COUNT' => sprintf($lang['BT_FLIST_FILE_PATH'], declension($filesCount, 'files')), +]); + +print_page('playback_m3u.tpl'); diff --git a/styles/templates/default/playback_m3u.tpl b/styles/templates/default/playback_m3u.tpl new file mode 100644 index 000000000..7870a9304 --- /dev/null +++ b/styles/templates/default/playback_m3u.tpl @@ -0,0 +1,43 @@ +

{PAGE_TITLE}

+ + + + + + + + + + + + + + + + + + + + + + + +
#{FILES_COUNT}{L_STREAM}
{m3ulist.ROW_NUMBER}{m3ulist.TITLE} + {L_COPY_STREAM_LINK} · + {L_DOWNLOAD_M3U_FILE} +
+ + + + +
{L_M3U_NOTICE}
+ + +
+
+
+

{CURRENT_TIME}

+

{S_TIMEZONE}

+
+
+
diff --git a/styles/templates/default/viewtopic_attach.tpl b/styles/templates/default/viewtopic_attach.tpl index 0fbd140a7..dd77ef39e 100644 --- a/styles/templates/default/viewtopic_attach.tpl +++ b/styles/templates/default/viewtopic_attach.tpl @@ -160,8 +160,8 @@ {postrow.attach.tor_reged.TRACKER_LINK} [ {postrow.attach.tor_reged.REGED_TIME} ] -

info_hash: {postrow.attach.tor_reged.HASH} -
info_hash v2: {postrow.attach.tor_reged.HASH_V2} +

info_hash: {postrow.attach.tor_reged.HASH} +
info_hash v2: {postrow.attach.tor_reged.HASH_V2} @@ -176,7 +176,7 @@
-

{L_DOWNLOAD_M3U_FILE}

{L_DOWNLOAD_M3U_FILE}
+

{L_PLAYBACK_M3U}

{L_PLAYBACK_M3U}