diff --git a/CHANGELOG.md b/CHANGELOG.md
index e172eab55..9b476cc23 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,8 +18,8 @@
- Fixed template caching issue [\#1622](https://github.com/torrentpier/torrentpier/pull/1622) ([belomaxorka](https://github.com/belomaxorka))
- Fixed `md5()` deprecated in PHP 8.4 [\#1561](https://github.com/torrentpier/torrentpier/pull/1561) ([belomaxorka](https://github.com/belomaxorka))
- Increased `USEREMAIL_MAX_LENGTH` [\#1566](https://github.com/torrentpier/torrentpier/pull/1566) ([belomaxorka](https://github.com/belomaxorka))
-- Minor improvements [\#1570](https://github.com/torrentpier/torrentpier/pull/1570), [\#1571](https://github.com/torrentpier/torrentpier/pull/1571), [\#1575](https://github.com/torrentpier/torrentpier/pull/1575), [\#1589](https://github.com/torrentpier/torrentpier/pull/1589), [\#1592](https://github.com/torrentpier/torrentpier/pull/1592), [\#1605](https://github.com/torrentpier/torrentpier/pull/1605), [\#1611](https://github.com/torrentpier/torrentpier/pull/1611), [\#1612](https://github.com/torrentpier/torrentpier/pull/1612), [\#1615](https://github.com/torrentpier/torrentpier/pull/1615), [\#1627](https://github.com/torrentpier/torrentpier/pull/1627) ([belomaxorka](https://github.com/belomaxorka))
-- Updated deps [\#1563](https://github.com/torrentpier/torrentpier/pull/1563), [\#1564](https://github.com/torrentpier/torrentpier/pull/1564), [\#1608](https://github.com/torrentpier/torrentpier/pull/1608), [\#1609](https://github.com/torrentpier/torrentpier/pull/1609), [\#1610](https://github.com/torrentpier/torrentpier/pull/1610) ([belomaxorka](https://github.com/belomaxorka))
+- Minor improvements [\#1570](https://github.com/torrentpier/torrentpier/pull/1570), [\#1571](https://github.com/torrentpier/torrentpier/pull/1571), [\#1575](https://github.com/torrentpier/torrentpier/pull/1575), [\#1589](https://github.com/torrentpier/torrentpier/pull/1589), [\#1592](https://github.com/torrentpier/torrentpier/pull/1592), [\#1605](https://github.com/torrentpier/torrentpier/pull/1605), [\#1611](https://github.com/torrentpier/torrentpier/pull/1611), [\#1612](https://github.com/torrentpier/torrentpier/pull/1612), [\#1615](https://github.com/torrentpier/torrentpier/pull/1615), [\#1627](https://github.com/torrentpier/torrentpier/pull/1627), [\#1633](https://github.com/torrentpier/torrentpier/pull/1633) ([belomaxorka](https://github.com/belomaxorka))
+- Updated deps [\#1563](https://github.com/torrentpier/torrentpier/pull/1563), [\#1564](https://github.com/torrentpier/torrentpier/pull/1564), [\#1608](https://github.com/torrentpier/torrentpier/pull/1608), [\#1609](https://github.com/torrentpier/torrentpier/pull/1609), [\#1610](https://github.com/torrentpier/torrentpier/pull/1610), [\#1637](https://github.com/torrentpier/torrentpier/pull/1637) ([belomaxorka](https://github.com/belomaxorka))
- New Crowdin updates [\#1569](https://github.com/torrentpier/torrentpier/pull/1569), [\#1572](https://github.com/torrentpier/torrentpier/pull/1572), [\#1573](https://github.com/torrentpier/torrentpier/pull/1573), [\#1574](https://github.com/torrentpier/torrentpier/pull/1574), [\#1588](https://github.com/torrentpier/torrentpier/pull/1588), [\#1590](https://github.com/torrentpier/torrentpier/pull/1590), [\#1600](https://github.com/torrentpier/torrentpier/pull/1600), [\#1601](https://github.com/torrentpier/torrentpier/pull/1601), [\#1606](https://github.com/torrentpier/torrentpier/pull/1606), [\#1607](https://github.com/torrentpier/torrentpier/pull/1607), [\#1625](https://github.com/torrentpier/torrentpier/pull/1625), [\#1626](https://github.com/torrentpier/torrentpier/pull/1626), [\#1629](https://github.com/torrentpier/torrentpier/pull/1629), [\#1630](https://github.com/torrentpier/torrentpier/pull/1630), [\#1631](https://github.com/torrentpier/torrentpier/pull/1631), [\#1632](https://github.com/torrentpier/torrentpier/pull/1632) ([Exileum](https://github.com/Exileum))
## [v2.4.4](https://github.com/torrentpier/torrentpier/tree/v2.4.4) (2024-07-22)
diff --git a/admin/admin_forums.php b/admin/admin_forums.php
index 85b14adaf..864350e48 100644
--- a/admin/admin_forums.php
+++ b/admin/admin_forums.php
@@ -865,7 +865,7 @@ function get_list($mode, $id, $select)
if ($row[$idfield] == $id) {
$s = ' selected';
}
- $catlist .= '\n';
+ $catlist .= '\n';
}
return $catlist;
@@ -1102,7 +1102,7 @@ function sf_get_list($mode, $exclude = 0, $select = 0)
$selected = ($fid == $select) ? HTML_SELECTED : '';
$disabled = ($fid == $exclude && !$forum_parent) ? HTML_DISABLED : '';
$style = $disabled ? ' style="color: gray" ' : (($fid == $exclude) ? ' style="color: darkred" ' : '');
- $opt .= '\n";
+ $opt .= '\n";
}
$opt .= '';
diff --git a/bt/announce.php b/bt/announce.php
index 9a8648a35..e18702c78 100644
--- a/bt/announce.php
+++ b/bt/announce.php
@@ -214,10 +214,9 @@ if ($lp_info) {
// Check hybrid status
if (!empty($row['info_hash']) && !empty($row['info_hash_v2'])) {
- $stat_protocol = match ($bb_cfg['tracker']['hybrid_stat_protocol']) {
- 1 => $row['info_hash'],
+ $stat_protocol = match ((int)$bb_cfg['tracker']['hybrid_stat_protocol']) {
2 => substr($row['info_hash_v2'], 0, 20),
- default => $row['info_hash']
+ default => $row['info_hash'] // 1
};
if ($info_hash !== $stat_protocol) {
$hybrid_unrecord = true; // This allows us to announce only for one info-hash
diff --git a/common.php b/common.php
index 47c39eb68..9c619ba1a 100644
--- a/common.php
+++ b/common.php
@@ -244,7 +244,7 @@ function htmlCHR($txt, bool $double_encode = false, int $quote_style = ENT_QUOTE
*/
function str_compact($str)
{
- return preg_replace('#\s+#u', ' ', trim($str ?? ''));
+ return preg_replace('/\s\s+/', ' ', trim($str ?? ''));
}
/**
diff --git a/dl.php b/dl.php
index d28b5e836..ce37c5b80 100644
--- a/dl.php
+++ b/dl.php
@@ -20,6 +20,7 @@ $datastore->enqueue([
$download_id = request_var('id', 0);
$thumbnail = request_var('thumb', 0);
+$m3u = isset($_GET['m3u']) && $_GET['m3u'];
// Send file to browser
function send_file_to_browser($attachment, $upload_dir)
@@ -100,9 +101,18 @@ if (!($attachment = DB()->sql_fetchrow($result))) {
$attachment['physical_filename'] = basename($attachment['physical_filename']);
-// Re-define $attachment['physical_filename'] for thumbnails
if ($thumbnail) {
+ // Re-define $attachment['physical_filename'] for thumbnails
$attachment['physical_filename'] = THUMB_DIR . '/t_' . $attachment['physical_filename'];
+} elseif ($m3u) {
+ // Check m3u file exist
+ if (!$m3uFile = (new \TorrentPier\TorrServerAPI())->getM3UPath($download_id)) {
+ bb_die($lang['ERROR_NO_ATTACHMENT']);
+ }
+
+ $attachment['physical_filename'] = $attachment['real_filename'] = basename($m3uFile);
+ $attachment['mimetype'] = mime_content_type($m3uFile);
+ $attachment['extension'] = str_replace('.', '', \TorrentPier\TorrServerAPI::M3U['extension']);
}
DB()->sql_freeresult($result);
@@ -194,7 +204,7 @@ if (isset($download_mode[$attachment['extension']])) {
}
// Update download count
-if (!$thumbnail && is_file(realpath($upload_dir . '/' . $attachment['physical_filename']))) {
+if (!$m3u && !$thumbnail && is_file(realpath($upload_dir . '/' . $attachment['physical_filename']))) {
$sql = 'UPDATE ' . BB_ATTACHMENTS_DESC . ' SET download_count = download_count + 1 WHERE attach_id = ' . (int)$attachment['attach_id'];
if (!DB()->sql_query($sql)) {
diff --git a/filelist.php b/filelist.php
index 8c87d76d2..1baa76c2a 100644
--- a/filelist.php
+++ b/filelist.php
@@ -92,14 +92,14 @@ foreach ($files as $file) {
]);
}
-$torrent_name = !empty($t_name = $torrent->getName()) ? htmlCHR(str_short($t_name, 200)) : $lang['UNKNOWN'];
+$torrent_name = !empty($t_name = $torrent->getName()) ? str_short(htmlCHR($t_name), 200) : $lang['UNKNOWN'];
$torrent_size = humn_size($row['size'], 2);
$template->assign_vars([
'PAGE_TITLE' => "$torrent_name (" . $torrent_size . ")",
'FILES_COUNT' => sprintf($lang['BT_FLIST_FILE_PATH'], declension(iterator_count($files), 'files')),
'TORRENT_CREATION_DATE' => (!empty($dt = $torrent->getCreationDate()) && is_numeric($creation_date = $dt->getTimestamp())) ? date('d-M-Y H:i (e)', $creation_date) : $lang['UNKNOWN'],
- 'TORRENT_CLIENT' => !empty($creator = $torrent->getCreatedBy()) ? htmlCHR(str_short($creator, 20)) : $lang['UNKNOWN'],
+ 'TORRENT_CLIENT' => !empty($creator = $torrent->getCreatedBy()) ? htmlCHR($creator) : $lang['UNKNOWN'],
'BTMR_NOTICE' => sprintf($lang['BT_FLIST_BTMR_NOTICE'], 'https://github.com/kovalensky/tmrr'),
'U_TOPIC' => TOPIC_URL . $topic_id,
diff --git a/group.php b/group.php
index 712eb2e05..2b4c5500e 100644
--- a/group.php
+++ b/group.php
@@ -103,7 +103,7 @@ if (!$group_id) {
$options = '';
foreach ($params as $name => $data) {
- $text = htmlCHR(str_short(rtrim($name), HTML_SELECT_MAX_LENGTH));
+ $text = str_short(rtrim(htmlCHR($name)), HTML_SELECT_MAX_LENGTH);
$members = ($data['m']) ? $lang['MEMBERS_IN_GROUP'] . ': ' . $data['m'] : $lang['NO_GROUP_MEMBERS'];
$candidates = ($data['c']) ? $lang['PENDING_MEMBERS'] . ': ' . $data['c'] : $lang['NO_PENDING_GROUP_MEMBERS'];
diff --git a/install/sql/mysql.sql b/install/sql/mysql.sql
index d072fb9f0..9c01caae0 100644
--- a/install/sql/mysql.sql
+++ b/install/sql/mysql.sql
@@ -715,6 +715,7 @@ VALUES ('1', 'gif', ''),
('3', 'cpp', ''),
('3', 'hpp', ''),
('3', 'diz', ''),
+ ('3', 'm3u', ''),
('4', 'xls', ''),
('4', 'doc', ''),
('4', 'dot', ''),
diff --git a/library/ajax/ffprobe_info.php b/library/ajax/ffprobe_info.php
index 755d558ab..d854b4af6 100644
--- a/library/ajax/ffprobe_info.php
+++ b/library/ajax/ffprobe_info.php
@@ -17,11 +17,13 @@ if (!$bb_cfg['torr_server']['enabled']) {
$this->ajax_die($lang['MODULE_OFF']);
}
-if (!$attach_id = (int)$this->request['attach_id'] or !is_numeric($attach_id)) {
+$attach_id = $this->request['attach_id'] ?? '';
+if (empty($attach_id) || !is_numeric($attach_id)) {
$this->ajax_die($lang['INVALID_ATTACH_ID']);
}
-if (!$file_index = (int)$this->request['file_index'] or !is_numeric($file_index)) {
+$file_index = $this->request['file_index'] ?? '';
+if (empty($file_index) || !is_numeric($file_index)) {
$this->ajax_die("Invalid file index: $file_index");
}
@@ -61,11 +63,11 @@ if (isset($ffpInfo->streams)) {
if (!empty($stream->codec_name)) {
$result .= sprintf($lang['AUDIO_CODEC'], $stream->codec_long_name, mb_strtoupper($stream->codec_name, 'UTF-8')) . '
';
}
- if (!empty($stream->bit_rate)) {
+ if (!empty($stream->bit_rate) && is_int($stream->bit_rate)) {
$result .= sprintf($lang['BITRATE'], humn_bitrate($stream->bit_rate)) . '
';
}
- if (!empty($stream->sample_rate)) {
- $result .= sprintf($lang['SAMPLE_RATE'], $stream->sample_rate) . '
';
+ if (!empty($stream->sample_rate) && is_int($stream->sample_rate)) {
+ $result .= sprintf($lang['SAMPLE_RATE'], humn_sample_rate($stream->sample_rate)) . '
';
}
if (!empty($stream->channels)) {
$result .= sprintf($lang['CHANNELS'], $stream->channels) . '
';
@@ -103,4 +105,39 @@ if (isset($ffpInfo->streams)) {
$this->response['ffprobe_data'] = $result;
}
+/**
+ * Bitrate to human-readable format
+ *
+ * @param int $bitrate
+ * @param string $space
+ * @return string
+ */
+function humn_bitrate(int $bitrate, string $space = ' '): string
+{
+ if ($bitrate >= 1000000) {
+ $unit = 'Mbps';
+ $bitrate /= 1000000;
+ } elseif ($bitrate >= 1000) {
+ $unit = 'kbps';
+ $bitrate /= 1000;
+ } else {
+ $unit = 'bps';
+ }
+
+ return sprintf('%d', commify($bitrate)) . $space . $unit;
+}
+
+/**
+ * Sample rate to human-readable format
+ *
+ * @param int $sample_rate
+ * @param string $space
+ * @return string
+ */
+function humn_sample_rate(int $sample_rate, string $space = ' '): string
+{
+ $unit = '';
+ return sprintf('%.1f', commify($sample_rate)) . $space . $unit;
+}
+
$this->response['file_index'] = $file_index;
diff --git a/library/includes/functions.php b/library/includes/functions.php
index b04ce7a92..aeb9e04d2 100644
--- a/library/includes/functions.php
+++ b/library/includes/functions.php
@@ -595,29 +595,6 @@ function humn_size($size, $rounder = null, $min = null, $space = ' ')
return round($size, $rounder) . $space . $ext;
}
-/**
- * Bitrate to human-readable format
- *
- * @param int $bitrate
- * @param string $space
- * @return string
- */
-function humn_bitrate(int $bitrate, string $space = ' '): string
-{
- if ($bitrate >= 1000000) {
- $unit = 'Mbps';
- $bitrate /= 1000000;
- } elseif ($bitrate >= 1000) {
- $unit = 'kbps';
- $bitrate /= 1000;
- } else {
- $unit = 'bps';
- }
-
- $formattedBitrate = number_format($bitrate, 2);
- return $formattedBitrate . $space . $unit;
-}
-
function bt_show_ip($ip, $port = '')
{
global $bb_cfg;
diff --git a/library/includes/page_footer_dev.php b/library/includes/page_footer_dev.php
index 932a09bb6..c8dac36d8 100644
--- a/library/includes/page_footer_dev.php
+++ b/library/includes/page_footer_dev.php
@@ -42,6 +42,10 @@ if (!defined('BB_ROOT')) {
cursor: pointer;
}
+ .sqlLogRow:hover {
+ border-color: #8B0000;
+ }
+
.sqlLogWrapped {
white-space: normal;
overflow: visible;
@@ -53,10 +57,6 @@ if (!defined('BB_ROOT')) {
cursor: inherit !important;
}
- .sqlHover {
- border-color: #8B0000;
- }
-
.sqlHighlight {
background: #FFE4E1;
}
diff --git a/library/language/source/main.php b/library/language/source/main.php
index e2f2ab599..af4938fc6 100644
--- a/library/language/source/main.php
+++ b/library/language/source/main.php
@@ -1286,6 +1286,7 @@ $lang['DOWNLOAD_M3U_FILE'] = 'Download .m3u file';
$lang['PLAYBACK_M3U'] = 'Playback .m3u file';
$lang['COPY_STREAM_LINK'] = 'Copy stream link to clipboard';
$lang['M3U_NOT_SUPPORTED'] = 'This file cannot be played in the browser...';
+$lang['M3U_FFPROBE_NO_DATA'] = 'It seems ffprobe will not be able to return data about this codec...';
$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';
diff --git a/playback_m3u.php b/playback_m3u.php
index 7cea73c4c..e7ba3a991 100644
--- a/playback_m3u.php
+++ b/playback_m3u.php
@@ -91,7 +91,7 @@ foreach ($m3uData as $entry) {
'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,
+ 'M3U_DL_LINK' => DL_URL . $row['attach_id'] . '&m3u=1',
'TITLE' => $title,
]);
}
diff --git a/src/Dev.php b/src/Dev.php
index 9186ad51c..4afb1c718 100644
--- a/src/Dev.php
+++ b/src/Dev.php
@@ -243,7 +243,7 @@ class Dev
$perc = '[' . round($dbg['time'] * 100 / $db_obj->sql_timetotal) . '%]';
$info = !empty($dbg['info']) ? $dbg['info'] . ' [' . $dbg['src'] . ']' : $dbg['src'];
- $log .= '