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 .= '
' + $log .= '
' . '' . $time . ' ' . '' . $perc . ' ' . '' . $sql . '' diff --git a/src/Legacy/Common/Html.php b/src/Legacy/Common/Html.php index 5e1c18aa6..530834b6e 100644 --- a/src/Legacy/Common/Html.php +++ b/src/Legacy/Common/Html.php @@ -70,7 +70,7 @@ class Html if (\is_array($opt_val)) { $this->cur_attr =& $this->cur_attr[$opt_name]; - $label = htmlCHR(str_short($opt_name, $this->max_length)); + $label = str_short(htmlCHR($opt_name), $this->max_length); $this->options .= "\t\n"; $this->_build_select_rec($opt_val); @@ -78,7 +78,7 @@ class Html $this->cur_attr =& $this->attr; } else { - $text = htmlCHR(str_short($opt_name, $this->max_length)); + $text = str_short(htmlCHR($opt_name), $this->max_length); $value = ' value="' . htmlCHR($opt_val) . '"'; $class = isset($this->cur_attr[$opt_name]['class']) ? ' class="' . $this->cur_attr[$opt_name]['class'] . '"' : ''; diff --git a/styles/templates/default/playback_m3u.tpl b/styles/templates/default/playback_m3u.tpl index 82bd5effd..81a304ff6 100644 --- a/styles/templates/default/playback_m3u.tpl +++ b/styles/templates/default/playback_m3u.tpl @@ -14,7 +14,11 @@ if (data.ffprobe_data) { $('#ffprobe_' + data.file_index).html(data.ffprobe_data); } else { - $('#ffprobe_' + data.file_index).append('
{L_PLEASE_TRY_AGAIN}'); + if ($('#ffprobe_' + data.file_index).find('span.warnColor2').length >= 3) { + $('#ffprobe_' + data.file_index).html('
{L_M3U_FFPROBE_NO_DATA}'); + } else { + $('#ffprobe_' + data.file_index).append('
{L_PLEASE_TRY_AGAIN}'); + } } } @@ -35,7 +39,7 @@ {m3ulist.TITLE}