diff --git a/app/Console/Commands/Test.php b/app/Console/Commands/Test.php index 488adcda..2b2d3339 100644 --- a/app/Console/Commands/Test.php +++ b/app/Console/Commands/Test.php @@ -36,6 +36,7 @@ use Illuminate\Support\Facades\Storage; use JeroenG\Explorer\Domain\Syntax\Matching; use JeroenG\Explorer\Infrastructure\Scout\ElasticEngine; use Nexus\Database\NexusDB; +use Nexus\Imdb\Imdb; use Rhilip\Bencode\Bencode; class Test extends Command @@ -118,14 +119,17 @@ class Test extends Command // $r = $searchRep->deleteBookmark(1); // $r = $searchRep->addBookmark(1); - $rep = new AttendanceRepository(); - $uid = 1; - $attendance = $rep->getAttendance($uid); +// $rep = new AttendanceRepository(); +// $uid = 1; +// $attendance = $rep->getAttendance($uid); // $r = $rep->migrateAttendanceLogs($uid); // $r = $rep->getContinuousDays($attendance); - $r = $rep->getContinuousPoints(11); - dd($r); +// $r = $rep->getContinuousPoints(11); + $url = 'https://www.imdb.com/title/tt4574334/?ref_=vp_vi_tt'; + $imdb = new Imdb(); + $rating = $imdb->getRating($url); + dd($rating); } diff --git a/app/Models/Language.php b/app/Models/Language.php index 8b0deb76..9d2b29b5 100644 --- a/app/Models/Language.php +++ b/app/Models/Language.php @@ -4,9 +4,19 @@ namespace App\Models; class Language extends NexusModel { + const DEFAULT_ENABLED = ['en', 'chs', 'cht']; + protected $table = 'language'; protected $fillable = [ 'lang_name', 'site_lang_folder', ]; + + public static function listEnabled($withoutCache = false) + { + if ($withoutCache) { + return Setting::getFromDb('main.site_language_enabled', self::DEFAULT_ENABLED); + } + return Setting::get('main.site_language_enabled', self::DEFAULT_ENABLED); + } } diff --git a/app/Models/Torrent.php b/app/Models/Torrent.php index 24d73f41..a78c329b 100644 --- a/app/Models/Torrent.php +++ b/app/Models/Torrent.php @@ -25,7 +25,8 @@ class Torrent extends NexusModel const BANNED_NO = 'no'; protected $casts = [ - 'added' => 'datetime' + 'added' => 'datetime', + 'pt_gen' => 'array', ]; public static $commentFields = [ diff --git a/classes/class_cache_redis.php b/classes/class_cache_redis.php index dc0d3b27..7f93c4e5 100644 --- a/classes/class_cache_redis.php +++ b/classes/class_cache_redis.php @@ -288,14 +288,12 @@ class class_cache_redis { if (!$this->getIsEnabled()) { return 0; } + $this->redis->del($Key); if ($AllLang){ $langfolder_array = $this->getLanguageFolderArray(); foreach($langfolder_array as $lf) $this->redis->del($lf."_".$Key); } - else { - $this->redis->del($Key); - } } function getCacheReadTimes() { diff --git a/include/constants.php b/include/constants.php index 4bef625e..6816791b 100644 --- a/include/constants.php +++ b/include/constants.php @@ -1,6 +1,6 @@
%s
%s
', $lang_functions['spoiler_expand_collapse'], $title, $contentClass, $content ); - $js = <<%s', $align, $text)); +} + function format_urls($text, $newWindow = false) { // return preg_replace("/((https?|ftp|gopher|news|telnet|mms|rtsp):\/\/[^()\[\]<>\s]+)/ei", "formatUrl('\\1', ".($newWindow==true ? 1 : 0).", '', 'faqlink')", $text); return preg_replace_callback("/((https?|ftp|gopher|news|telnet|mms|rtsp):\/\/[^()\[\]<>\s]+)/i", function ($matches) use ($newWindow) { @@ -340,12 +335,12 @@ function format_comment($text, $strip_html = true, $xssclean = false, $newtab = if ($enableimage) { // $s = preg_replace("/\[img\]([^\<\r\n\"']+?)\[\/img\]/ei", "formatImg('\\1',".$imageresizer.",".$image_max_width.",".$image_max_height.")", $s, $imagenum, $imgReplaceCount); $s = preg_replace_callback("/\[img\]([^\<\r\n\"']+?)\[\/img\]/i", function ($matches) use ($imageresizer, $image_max_width, $image_max_height) { - return formatImg($matches[1],".$imageresizer.",".$image_max_width.",".$image_max_height."); + return formatImg($matches[1],$imageresizer,$image_max_width,$image_max_height); }, $s, $imagenum, $imgReplaceCount); // $s = preg_replace("/\[img=([^\<\r\n\"']+?)\]/ei", "formatImg('\\1',".$imageresizer.",".$image_max_width.",".$image_max_height.")", $s, ($imagenum != -1 ? max($imagenum-$imgReplaceCount, 0) : -1)); $s = preg_replace_callback("/\[img=([^\<\r\n\"']+?)\]/i", function ($matches) use ($imageresizer, $image_max_width, $image_max_height) { - return formatImg($matches[1],".$imageresizer.",".$image_max_width.",".$image_max_height."); + return formatImg($matches[1],$imageresizer,$image_max_width,$image_max_height); }, $s, ($imagenum != -1 ? max($imagenum-$imgReplaceCount, 0) : -1)); } else { $s = preg_replace("/\[img\]([^\<\r\n\"']+?)\[\/img\]/i", '', $s, -1); @@ -380,12 +375,6 @@ function format_comment($text, $strip_html = true, $xssclean = false, $newtab = return formatYoutube($matches[4], $matches[2], $matches[3]); }, $s); } - //[spoiler=What happens to the hero?]The hero dies at the end![/spoiler] - if (str_contains($s, '[spoiler')) { - $s = preg_replace_callback("/\[spoiler(=(.*))?\](.*)\[\/spoiler\]/isU", function ($matches) { - return formatSpoiler($matches[3], $matches[2], nexus()->getScript() != 'preview'); - }, $s); - } // [url=http://www.example.com]Text[/url] if ($adid) { @@ -406,6 +395,22 @@ function format_comment($text, $strip_html = true, $xssclean = false, $newtab = return formatUrl($matches[1], ".($newtab==true ? 1 : 0).", '', 'faqlink'); }, $s); + // [left]Left text[/left] + $s = preg_replace_callback("/\[left\](.*)\[\/left\]/isU", function ($matches) { + return formatTextAlign($matches[1], 'left'); + }, $s); + + // [center]Center text[/center] + $s = preg_replace_callback("/\[center\](.*)\[\/center\]/isU", function ($matches) { + return formatTextAlign($matches[1], 'center'); + }, $s); + + // [right]Right text[/right] + $s = preg_replace_callback("/\[right\](.*)\[\/right\]/isU", function ($matches) { + return formatTextAlign($matches[1], 'right'); + }, $s); + + $s = format_urls($s, $newtab); // Quotes if (strpos($s,"[quote") !== false && strpos($s,"[/quote]") !== false) { //format_quote is kind of slow. Better check if [quote] exists beforehand @@ -417,6 +422,14 @@ function format_comment($text, $strip_html = true, $xssclean = false, $newtab = $smile = get_smile($matches[1]); return $smile ? '[em' . $matches[1] . ']' : '[em' . $matches[1] . ']'; }, $s); + + //[spoiler=What happens to the hero?]The hero dies at the end![/spoiler] + if (str_contains($s, '[spoiler')) { + $s = preg_replace_callback("/\[spoiler(=(.*))?\](.*)\[\/spoiler\]/isU", function ($matches) { + return formatSpoiler($matches[3], $matches[2], nexus()->getScript() != 'preview'); + }, $s); + } + reset($tempCode); $j = $i = 0; while(count($tempCode) || $j > 5) { @@ -1139,8 +1152,15 @@ function get_external_tr($imdb_url = "") { global $lang_functions; global $showextinfo; + if ($showextinfo['imdb'] != 'yes') { + return ''; + } + $ptGen = new Nexus\PTGen\PTGen(); $imdbNumber = parse_imdb_id($imdb_url); - ($showextinfo['imdb'] == 'yes' ? tr($lang_functions['row_imdb_url'], "
".$lang_functions['text_imdb_url_note']."", 1) : ""); + $y = $ptGen->buildInput("url", $imdbNumber ? "http://www.imdb.com/title/tt".parse_imdb_id($imdb_url) : "", $lang_functions['text_imdb_url_note'], $lang_functions['pt_gen_get_description']); + return tr($lang_functions['row_imdb_url'], $y, 1); + +// ($showextinfo['imdb'] == 'yes' ? tr($lang_functions['row_imdb_url'], "
".$lang_functions['text_imdb_url_note']."", 1) : ""); } function get_torrent_extinfo_identifier($torrentid) @@ -2431,19 +2451,19 @@ if ($CURUSER){ } ?> - - - - - - - + + + + + + + - + @@ -2770,15 +2790,16 @@ function stdfoot() { foreach (\Nexus\Nexus::getAppendFooters() as $value) { print($value); } - $backToTop = << + $js = << + -TOTOP; - print($backToTop); +JS; + print($js); print(""); //echo replacePngTags(ob_get_clean()); @@ -3094,16 +3115,24 @@ function searchbox_item_list($table = "sources"){ return $ret; } -function langlist($type) { +function langlist($type, $enabled = null) { global $Cache; - if (!$ret = $Cache->get_value($type.'_lang_list')){ - $ret = array(); - $res = sql_query("SELECT id, lang_name, flagpic, site_lang_folder FROM language WHERE ". $type ."=1 ORDER BY site_lang DESC, id ASC"); - while ($row = mysql_fetch_array($res)) - $ret[] = $row; - $Cache->cache_value($type.'_lang_list', $ret, 152800); - } - return $ret; + $cacheKey = $type.'_lang_list'; + return \Nexus\Database\NexusDB::remember($cacheKey, 600, function () use ($type, $enabled) { + $query = \App\Models\Language::query()->where($type, 1); + if ($enabled !== null) { + $query->whereIn('site_lang_folder', \App\Models\Language::listEnabled(true)); + } + return $query->get()->toArray(); + }); +// if (!$ret = $Cache->get_value($type.'_lang_list')){ +// $ret = array(); +// $res = sql_query("SELECT id, lang_name, flagpic, site_lang_folder FROM language WHERE ". $type ."=1 ORDER BY site_lang DESC, id ASC"); +// while ($row = mysql_fetch_array($res)) +// $ret[] = $row; +// $Cache->cache_value($type.'_lang_list', $ret, 152800); +// } +// return $ret; } function linkcolor($num) { @@ -3169,11 +3198,6 @@ function torrenttable($rows, $variant = "torrent") { global $torrentmanage_class, $smalldescription_main, $enabletooltip_tweak; global $CURLANGDIR; - $setting = get_setting('main'); - $enablePtGen = $setting['enable_pt_gen_system'] == 'yes'; - $enableImdb = $setting['showimdbinfo'] == 'yes'; - $ptGen = new Nexus\PTGen\PTGen(); - $imdb = new Nexus\Imdb\Imdb(); $torrent = new Nexus\Torrent\Torrent(); $torrentIdArr = array_column($rows, 'id'); $torrentSeedingLeechingStatus = $torrent->listLeechingSeedingStatus($CURUSER['id'], $torrentIdArr); @@ -3406,11 +3430,9 @@ foreach ($rows as $row) echo $torrent->renderProgressBar($torrentSeedingLeechingStatus[$row['id']]['active_status'], $torrentSeedingLeechingStatus[$row['id']]['progress']); } print(""); - if ($enablePtGen && !empty($row['pt_gen'])) { - echo $ptGen->renderTorrentsPageAverageRating(json_decode($row['pt_gen'], true)); - } elseif ($enableImdb) { - echo $imdb->renderTorrentsPageAverageRating($row['url']); - } + + echo $torrent->renderTorrentsPageAverageRating($row); + $act = ""; if ($CURUSER["dlicon"] != 'no' && $CURUSER["downloadpos"] != "no") $act .= "\"download\"" ; diff --git a/lang/chs/lang_functions.php b/lang/chs/lang_functions.php index 0943c4d9..881eb05c 100644 --- a/lang/chs/lang_functions.php +++ b/lang/chs/lang_functions.php @@ -322,6 +322,7 @@ $lang_functions = array 'text_seed_points' => '做种积分', 'spoiler_expand_collapse' => '点击展开/收缩', 'spoiler_default_title' => '折叠内容', + 'pt_gen_get_description' => '获取简介', ); ?> diff --git a/lang/chs/lang_settings.php b/lang/chs/lang_settings.php index 265fe194..891eb437 100644 --- a/lang/chs/lang_settings.php +++ b/lang/chs/lang_settings.php @@ -736,6 +736,9 @@ $lang_settings = array 'text_attendance_continuous_add_rules' => '请请从小到大添加规则', 'row_attendance_card' => '购买补签卡', 'text_attendance_card_note' => "个魔力值,如果他需要购买一张补签卡。默认'" . \App\Models\BonusLogs::DEFAULT_BONUS_BUY_ATTENDANCE_CARD . "'。", + 'row_site_language_enabled' => '站点启用语言', + 'text_site_language_enabled_note' => '选择站点启用的语言', + 'keep_at_least_one' => '至少保留一个', ); ?> diff --git a/lang/chs/lang_tags.php b/lang/chs/lang_tags.php index f9bb4135..2bf86787 100644 --- a/lang/chs/lang_tags.php +++ b/lang/chs/lang_tags.php @@ -133,6 +133,21 @@ $lang_tags = array 'text_spoiler_description' => '在页面插入可展开/收缩的内容', 'text_spoiler_syntax' => '[spoiler=标题]这是被折叠的内容[/spoiler]', 'text_spoiler_example' => '[spoiler=英雄最后的结局怎么样了?]英雄最后死掉了![/spoiler]', + + 'text_left' => '靠左对齐', + 'text_left_description' => '在页面插入靠左对齐的内容', + 'text_left_syntax' => '[left]这是靠左对齐的内容[/left]', + 'text_left_example' => '[left]这是靠左对齐的内容[/left]', + + 'text_center' => '居中对齐', + 'text_center_description' => '在页面插入居中对齐的内容', + 'text_center_syntax' => '[center]这是居中对齐的内容[/center]', + 'text_center_example' => '[center]这是居中对齐的内容[/center]', + + 'text_right' => '靠右对齐', + 'text_right_description' => '在页面插入靠右对齐的内容', + 'text_right_syntax' => '[right]这是靠右对齐的内容[/right]', + 'text_right_example' => '[right]这是靠右对齐的内容[/right]', ); ?> diff --git a/lang/cht/lang_functions.php b/lang/cht/lang_functions.php index 0936fe9d..09709085 100644 --- a/lang/cht/lang_functions.php +++ b/lang/cht/lang_functions.php @@ -323,6 +323,7 @@ $lang_functions = array 'text_seed_points' => '做種積分', 'spoiler_expand_collapse' => '點擊展開/收縮', 'spoiler_default_title' => '折疊內容', + 'pt_gen_get_description' => '獲取簡介', ); ?> diff --git a/lang/cht/lang_settings.php b/lang/cht/lang_settings.php index 788bbd13..c89eac51 100644 --- a/lang/cht/lang_settings.php +++ b/lang/cht/lang_settings.php @@ -735,6 +735,9 @@ $lang_settings = array 'text_attendance_continuous_add_rules' => '請請從小到大添加規則', 'row_attendance_card' => '購買補簽卡', 'text_attendance_card_note' => "個魔力值,如果他需要購買一張補簽卡。默認'" . \App\Models\BonusLogs::DEFAULT_BONUS_BUY_ATTENDANCE_CARD . "'。", + 'row_site_language_enabled' => '站點啟用語言', + 'text_site_language_enabled_note' => '選擇站點啟用的語言', + 'keep_at_least_one' => '至少保留一個', ); ?> diff --git a/lang/cht/lang_tags.php b/lang/cht/lang_tags.php index ef9d6f3d..0cd20761 100644 --- a/lang/cht/lang_tags.php +++ b/lang/cht/lang_tags.php @@ -134,6 +134,21 @@ $lang_tags = array 'text_spoiler_syntax' => '[spoiler=標題]這是被折疊的內容[/spoiler]', 'text_spoiler_example' => '[spoiler=英雄最後的結局怎麽樣了?]英雄最後死掉了![/spoiler]', + 'text_left' => '靠左對齊', + 'text_left_description' => '在頁面插入靠左對齊的內容', + 'text_left_syntax' => '[left]這是靠左對齊的內容[/left]', + 'text_left_example' => '[left]這是靠左對齊的內容[/left]', + + 'text_center' => '居中對齊', + 'text_center_description' => '在頁面插入居中對齊的內容', + 'text_center_syntax' => '[center]這是居中對齊的內容[/center]', + 'text_center_example' => '[center]這是居中對齊的內容[/center]', + + 'text_right' => '靠右對齊', + 'text_right_description' => '在頁面插入靠右對齊的內容', + 'text_right_syntax' => '[right]這是靠右對齊的內容[/right]', + 'text_right_example' => '[right]這是靠右對齊的內容[/right]', + ); ?> diff --git a/lang/en/lang_functions.php b/lang/en/lang_functions.php index 7a5a3690..88143e48 100644 --- a/lang/en/lang_functions.php +++ b/lang/en/lang_functions.php @@ -324,6 +324,7 @@ $lang_functions = array 'text_seed_points' => 'Seed points', 'spoiler_expand_collapse' => 'Click to expand/collapse', 'spoiler_default_title' => 'Collapse content', + 'pt_gen_get_description' => 'Get desc', ); ?> diff --git a/lang/en/lang_settings.php b/lang/en/lang_settings.php index 4f72eeb5..b10130a2 100644 --- a/lang/en/lang_settings.php +++ b/lang/en/lang_settings.php @@ -735,6 +735,9 @@ $lang_settings = array 'text_attendance_continuous_add_rules' => 'Please add rules from lowest to highest', 'row_attendance_card' => 'Buy attendance card', 'text_attendance_card_note' => "bonus points to buy a attendance card. Default'" . \App\Models\BonusLogs::DEFAULT_BONUS_BUY_ATTENDANCE_CARD . "'.", + 'row_site_language_enabled' => 'Site enabled language', + 'text_site_language_enabled_note' => 'Select site enabled language', + 'keep_at_least_one' => 'Keep at least one', ); ?> diff --git a/lang/en/lang_tags.php b/lang/en/lang_tags.php index e3c01196..572416f1 100644 --- a/lang/en/lang_tags.php +++ b/lang/en/lang_tags.php @@ -133,6 +133,21 @@ $lang_tags = array 'text_spoiler_description' => 'Insert expandable/collapsible content on the page', 'text_spoiler_syntax' => '[spoiler=title]This is the folded content[/spoiler]', 'text_spoiler_example' => '[spoiler=What happened to the final ending of the hero?]The hero died last![/spoiler]', + + 'text_left' => 'Text align left', + 'text_left_description' => 'Insert left-justified content on the page', + 'text_left_syntax' => '[left]This is the left-aligned content[/left]', + 'text_left_example' => '[left]This is the left-aligned content[/left]', + + 'text_center' => 'Text align center', + 'text_center_description' => 'Insert center-justified content on the page', + 'text_center_syntax' => '[center]This is the center-aligned content[/center]', + 'text_center_example' => '[center]This is the center-aligned content[/center]', + + 'text_right' => 'Text align right', + 'text_right_description' => 'Insert right-justified content on the page', + 'text_right_syntax' => '[right]This is the right-aligned content[/right]', + 'text_right_example' => '[right]This is the right-aligned content[/right]', ); ?> diff --git a/nexus/Database/NexusDB.php b/nexus/Database/NexusDB.php index c434677b..1e520260 100644 --- a/nexus/Database/NexusDB.php +++ b/nexus/Database/NexusDB.php @@ -276,10 +276,10 @@ class NexusDB $result = $Cache->get_value($key); if ($result === false) { $result = $callback(); - do_log("cache miss [$key]" ); + do_log("cache miss [$key]", 'debug'); $Cache->cache_value($key, $result, $ttl); } else { - do_log("cache hit [$key]"); + do_log("cache hit [$key]", 'debug'); } return $result; } else { diff --git a/nexus/Imdb/Imdb.php b/nexus/Imdb/Imdb.php index 82ae5df4..0be00d24 100644 --- a/nexus/Imdb/Imdb.php +++ b/nexus/Imdb/Imdb.php @@ -262,7 +262,12 @@ class Imdb } - public function renderTorrentsPageAverageRating($imdbId) + public function renderTorrentsPageAverageRating($imdbId): string + { + return $this->getPtGen()->buildRatingSpan([PTGen::SITE_IMDB => $this->getRating($imdbId)]); + } + + public function getRating($imdbId): float|string { $imdbId = parse_imdb_id($imdbId); $defaultRating = $rating = 'N/A'; @@ -273,7 +278,7 @@ class Imdb if (!is_numeric($rating)) { $rating = $defaultRating; } - return $this->getPtGen()->buildRatingSpan([PTGen::SITE_IMDB => $rating]); + return $rating; } public function getPtGen() diff --git a/nexus/Install/Install.php b/nexus/Install/Install.php index ee1b327f..3083dc26 100644 --- a/nexus/Install/Install.php +++ b/nexus/Install/Install.php @@ -128,7 +128,7 @@ class Install public function listRequirementTableRows() { $gdInfo = function_exists('gd_info') ? gd_info() : []; - $extensions = ['ctype', 'fileinfo', 'json', 'mbstring', 'openssl', 'pdo_mysql', 'tokenizer', 'xml', 'mysqli', 'bcmath', 'redis', 'gd', 'pcntl', 'sockets', 'posix']; + $extensions = ['ctype', 'fileinfo', 'json', 'mbstring', 'openssl', 'pdo_mysql', 'tokenizer', 'xml', 'mysqli', 'bcmath', 'redis', 'gd', 'sockets', 'posix']; $tableRows = []; $tableRows[] = [ 'label' => 'PHP version', @@ -140,10 +140,17 @@ class Install $tableRows[] = [ 'label' => "PHP extension $extension", 'required' => 'enabled', - 'current' => extension_loaded($extension), + 'current' => (int)extension_loaded($extension), 'result' => $this->yesOrNo(extension_loaded($extension)), ]; } + $tableRows[] = [ + 'label' => 'PHP extension pcntl', + 'required' => 'true', + 'current' => (int)extension_loaded($extension), + 'result' => "If 'current' showing 0, make sure it's on php -m", + ]; + $tableRows[] = [ 'label' => 'PHP extension gd JPEG Support', 'required' => 'true', diff --git a/nexus/Install/settings.default.php b/nexus/Install/settings.default.php index 6d1b41e0..5710f24f 100644 --- a/nexus/Install/settings.default.php +++ b/nexus/Install/settings.default.php @@ -88,6 +88,7 @@ return array ( 'pt_gen_api_point' => '', 'enable_pt_gen_system' => 'no', 'enable_technical_info' => 'no', + 'site_language_enabled' => \App\Models\Language::DEFAULT_ENABLED, ), 'smtp' => array ( diff --git a/nexus/PTGen/PTGen.php b/nexus/PTGen/PTGen.php index 25f73ac6..e7187cde 100644 --- a/nexus/PTGen/PTGen.php +++ b/nexus/PTGen/PTGen.php @@ -8,8 +8,10 @@ */ namespace Nexus\PTGen; +use App\Models\Torrent; use GuzzleHttp\Client; use Illuminate\Support\Str; +use Nexus\Imdb\Imdb; class PTGen { @@ -19,16 +21,18 @@ class PTGen const SITE_IMDB = 'imdb'; const SITE_BANGUMI = 'bangumi'; - private static $validSites = [ + public static array $validSites = [ self::SITE_IMDB => [ 'url_pattern' => '/(?:https?:\/\/)?(?:www\.)?imdb\.com\/title\/(tt\d+)\/?/', 'home_page' => 'https://www.imdb.com/', 'rating_average_img' => 'pic/imdb2.png', + 'rating_pattern_in_desc' => "/IMDb评分.*([\d\.]+)\//isU", ], self::SITE_DOUBAN => [ 'url_pattern' => '/(?:https?:\/\/)?(?:(?:movie|www)\.)?douban\.com\/(?:subject|movie)\/(\d+)\/?/', 'home_page' => 'https://www.douban.com/', 'rating_average_img' => 'pic/douban2.png', + 'rating_pattern_in_desc' => "/豆瓣评分.*([\d\.]+)\//isU", ], self::SITE_BANGUMI => [ 'url_pattern' => '/(?:https?:\/\/)?(?:bgm\.tv|bangumi\.tv|chii\.in)\/subject\/(\d+)\/?/', @@ -51,7 +55,7 @@ class PTGen public function setApiPoint(string $apiPoint) { - $this->apiPoint = $apiPoint; + $this->apiPoint = trim($apiPoint); } public function generate(string $url, bool $withoutCache = false): array @@ -63,7 +67,7 @@ class PTGen } else { $targetUrl .= "?"; } - $targetUrl .= sprintf('site=%s&sid=%s', $parsed['site'] , $parsed['id']); + $targetUrl .= sprintf('site=%s&sid=%s&url=%s', $parsed['site'] , $parsed['id'], urlencode($parsed['url'])); return $this->request($targetUrl, $withoutCache); } @@ -81,24 +85,39 @@ class PTGen throw new PTGenException("invalid url: $url"); } - private function buildDetailsPageTableRow($torrentId, $ptGenArr, $site) + private function buildDetailsPageTableRow($torrentId, $ptGenArr, $site): string { global $lang_details; - $ptGenFormatted = $ptGenArr['format']; + if ($this->isRawPTGen($ptGenArr)) { + $ptGenFormatted = $ptGenArr['format']; + } elseif ($this->isIyuu($ptGenArr)) { + $ptGenFormatted = $ptGenArr['data']['format']; + } else { + do_log("Invalid pt gen data", 'error'); + return ''; + } $poster = ''; if (!empty($ptGenArr['poster'])) { $poster = $ptGenArr['poster']; + } elseif (preg_match('/\[img\](.*)\[\/img\]/iU', $ptGenFormatted, $matches)) { + $poster = $matches[1]; + } + if ($poster) { $prefix = sprintf("[img]%s[/img]\n", $poster); $ptGenFormatted = mb_substr($ptGenFormatted, mb_strlen($prefix, 'utf-8') + 1); } $ptGenFormatted = format_comment($ptGenFormatted); $ptGenFormatted .= sprintf( - '%s%s%s%s', - $lang_details['text_information_updated_at'], !empty($ptGenArr['generate_at']) ? date('Y-m-d H:i:s', intval($ptGenArr['generate_at'] / 1000)) : '', $lang_details['text_might_be_outdated'], + '%s %s%s%s', + $lang_details['text_information_updated_at'], $ptGenArr['__updated_at'], $lang_details['text_might_be_outdated'], $torrentId, $site, $lang_details['text_here_to_update'] ); $titleShowOrHide = $lang_details['title_show_or_hide'] ?? ''; $id = 'pt-gen-' . $site; + $posterHtml = ""; + if ($poster) { + $posterHtml = sprintf('
@@ -108,9 +127,7 @@ class PTGen PT-Gen-{$site} -
- poster -
+ $posterHtml
@@ -156,14 +173,16 @@ HTML; do_log("$logPrefix, $msg"); throw new PTGenException($msg); } - if (!isset($bodyArr['success']) || !$bodyArr['success']) { + if ($this->isRawPTGen($bodyArr) || $this->isIyuu($bodyArr)) { + $Cache->cache_value($cacheKey, $bodyArr, 24 * 3600); + do_log("$logPrefix, success get from api point, use time: " . (microtime(true) - $begin)); + $bodyArr['__updated_at'] = now()->toDateTimeString(); + return $bodyArr; + } else { $msg = "error: " . $bodyArr['error'] ?? ''; do_log("$logPrefix, response: $bodyString"); throw new PTGenException($msg); } - $Cache->cache_value($cacheKey, $bodyArr, 24 * 3600); - do_log("$logPrefix, success get from api point, use time: " . (microtime(true) - $begin)); - return $bodyArr; } public function deleteApiPointResultCache($url) @@ -185,12 +204,30 @@ HTML; foreach (self::$validSites as $site => $info) { $value = $ptGen[$site]['link'] ?? ''; $x = $lang_functions["row_pt_gen_{$site}_url"]; - $y = "
".$lang_functions["text_pt_gen_{$site}_url_note"].""; + $y = $this->buildInput("pt_gen[{$site}][link]", $value, $lang_functions["text_pt_gen_{$site}_url_note"], $lang_functions['pt_gen_get_description']); $html .= tr($x, $y, 1); } return $html; } + public function buildInput($name, $value, $note, $btnText): string + { + $btn = ''; + if ($this->apiPoint != '') { + $btn = '
'; + } + $input = << +
+ + {$note} +
+ $btn +
+HTML; + return $input; + } + public function renderDetailsPageDescription($torrentId, $torrentPtGenArr): array { $html = ''; @@ -233,21 +270,7 @@ HTML; return ['json_arr' => $jsonArr, 'html' => $html, 'update' => $update]; } - public function renderTorrentsPageAverageRating($ptGenData) - { - $siteIdAndRating = []; - $ptGenData = (array)$ptGenData; - foreach (self::$validSites as $site => $info) { - $rating = $ptGenData[$site]['data']["{$site}_rating_average"] ?? ''; - if (empty($rating)) { - continue; - } - $siteIdAndRating[$site] = $rating; - } - return $this->buildRatingSpan($siteIdAndRating); - } - - public function buildRatingSpan(array $siteIdAndRating) + public function buildRatingSpan(array $siteIdAndRating): string { $result = '
'; $count = 1; @@ -275,12 +298,119 @@ HTML; return $result; } - public function getRatingIcon($siteId, $rating) + public function getRatingIcon($siteId, $rating): string { + if (is_numeric($rating)) { + $rating = number_format($rating, 1); + } $result = sprintf( '
%s%s
', self::$validSites[$siteId]['rating_average_img'], $siteId, $siteId, $rating ); return $result; } + + public function isRawPTGen(array $bodyArr): bool + { + return isset($bodyArr['success']) && $bodyArr['success']; + } + + public function isIyuu(array $bodyArr): bool + { + return isset($bodyArr['ret']) && $bodyArr['ret'] == 200; + } + + public function listRatings(array $ptGenData, string $imdbLink, string $desc = ''): array + { + $results = []; + $log = ""; + //First, get from PTGen + foreach (self::$validSites as $site => $info) { + if (!isset($ptGenData[$site]['data'])) { + continue; + } + $data = $ptGenData[$site]['data']; + $log .= ", handling site: $site"; + $rating = ''; + if (isset($data['__rating'])) { + //__rating is new add + $rating = $data['__rating']; + $log .= ", from __rating"; + } else { + // from original structure fetch + if ($this->isRawPTGen($data)) { + $log .= ", isRawPTGen"; + $rating = $data["{$site}_rating_average"] ?? ''; + } elseif ($this->isIyuu($data)) { + $log .= ", isIyuu"; + $pattern = $info['rating_pattern_in_desc'] ?? null; + if ($pattern && preg_match($pattern,$data['data']['format'], $matches)) { + $rating = $matches[1]; + } + } + } + if (!empty($rating)) { + $results[$site] = $rating; + $log .= ", get rating: $rating"; + } else { + $log .= ", can't get rating"; + } + } + //Second, imdb can get from imdb api + if (!isset($results[self::SITE_IMDB]) && !empty($imdbLink)) { + $imdb = new Imdb(); + $imdbRating = $imdb->getRating($imdbLink); + $results[self::SITE_IMDB] = $imdbRating; + $log .= ", again 'imdb' from: $imdbLink} -> $imdbRating"; + } + //Otherwise, get from desc + if (!empty($desc)) { + foreach (self::$validSites as $site => $info) { + if (isset($results[$site])) { + continue; + } + if (empty($info['rating_pattern_in_desc'])) { + continue; + } + $pattern = $info['rating_pattern_in_desc']; + $log .= ", at last, trying to get '$site' from desc with pattern: $pattern"; + if (preg_match($pattern, $desc, $matches)) { + $log .= ", get " . $matches[1]; + $results[$site] = $matches[1]; + } else { + $log .= ", not match"; + } + } + } + do_log($log); + return $results; + } + + public function updateTorrentPtGen(array $torrentInfo, $siteId = null) + { + $ptGenInfo = json_decode($torrentInfo['pt_gen'], true); + foreach (self::$validSites as $site => $siteConfig) { + if ($siteId !== null && $siteId != $site) { + //If specific, only update it + continue; + } + if (empty($ptGenInfo[$site]['link'])) { + do_log("site: $site no link..."); + continue; + } + try { + $response = $this->generate($ptGenInfo[$site]['link'], true); + $ptGenInfo[$site]['data'] = $response; + } catch (\Exception $exception) { + do_log("site: $site can not be updated: " . $exception->getMessage(), 'error'); + } + } + $siteIdAndRating = $this->listRatings($ptGenInfo, $torrentInfo['url'], $torrentInfo['descr']); + foreach ($siteIdAndRating as $key => $value) { + $ptGenInfo[$key]['data']["__rating"] = $value; + } + Torrent::query()->where('id', $torrentInfo['id'])->update(['pt_gen' => $ptGenInfo]); + return $ptGenInfo; + } + } diff --git a/nexus/Torrent/Torrent.php b/nexus/Torrent/Torrent.php index d23afd5b..0a4951c0 100644 --- a/nexus/Torrent/Torrent.php +++ b/nexus/Torrent/Torrent.php @@ -2,7 +2,10 @@ namespace Nexus\Torrent; +use App\Models\Setting; use Nexus\Database\NexusDB; +use Nexus\Imdb\Imdb; +use Nexus\PTGen\PTGen; class Torrent { @@ -49,7 +52,7 @@ class Torrent return $snatchedList; } - public function renderProgressBar($activeStatus, $progress) + public function renderProgressBar($activeStatus, $progress): string { $color = '#aaa'; if ($activeStatus == 'seeding') { @@ -64,4 +67,19 @@ class Torrent ); return $result; } + + public function renderTorrentsPageAverageRating(array $torrentInfo): string + { + static $ptGen; + if (is_null($ptGen)) { + $ptGen = new PTGen(); + } + $ptGenInfo = json_decode($torrentInfo['pt_gen'], true); + $log = "torrent: " . $torrentInfo['id']; + $siteIdAndRating = $ptGen->listRatings($ptGenInfo, $torrentInfo['url']); + $log .= "siteIdAndRating: " . json_encode($siteIdAndRating); + do_log($log); + return $ptGen->buildRatingSpan($siteIdAndRating); + } + } diff --git a/public/ajax.php b/public/ajax.php index 0c8098e6..87724836 100644 --- a/public/ajax.php +++ b/public/ajax.php @@ -34,3 +34,16 @@ function attendanceRetroactive($params) return $rep->retroactive($CURUSER['id'], $params['timestamp']); } +function getPtGen($params) +{ + $rep = new Nexus\PTGen\PTGen(); + $result = $rep->generate($params['url']); + if ($rep->isRawPTGen($result)) { + return $result['format']; + } elseif ($rep->isIyuu($result)) { + return $result['data']['format']; + } else { + return ''; + } +} + diff --git a/public/details.php b/public/details.php index 67fd3432..5295ff80 100644 --- a/public/details.php +++ b/public/details.php @@ -207,7 +207,7 @@ if (!$row) { { $thenumbers = $imdb_id; - $Cache->new_page('imdb_id_'.$thenumbers.'_large', 1296000, true); + $Cache->new_page('imdb_id_'.$thenumbers.'_large', 3600*24, true); if (!$Cache->get_page()){ switch ($imdb->getCacheStatus($imdb_id)) { @@ -225,7 +225,7 @@ if (!$row) { if (($photo_url = $movie->photo() ) != FALSE) $smallth = "\"poster\""; else - $smallth = "\"no"; + $smallth = "\"no"; $autodata = $imdb->renderDetailsPageDescription($row['id'], $imdb_id); $cache_time = $imdb->getCachedAt($imdb_id); diff --git a/public/edit.php b/public/edit.php index 56b1cf99..46eaf4c6 100644 --- a/public/edit.php +++ b/public/edit.php @@ -267,6 +267,8 @@ jQuery(function($){ EOT; } +\Nexus\Nexus::js('vendor/jquery-loading/jquery.loading.min.js', 'footer', true); +\Nexus\Nexus::js('js/ptgen.js', 'footer', true); stdfoot(); function getAddedTimeOption($timeStamp, $addSeconds) { $timeStamp += $addSeconds; diff --git a/public/ajaxbasic.js b/public/js/ajaxbasic.js similarity index 100% rename from public/ajaxbasic.js rename to public/js/ajaxbasic.js diff --git a/public/colorfade.js b/public/js/colorfade.js similarity index 100% rename from public/colorfade.js rename to public/js/colorfade.js diff --git a/public/common.js b/public/js/common.js similarity index 100% rename from public/common.js rename to public/js/common.js diff --git a/public/curtain_imageresizer.js b/public/js/curtain_imageresizer.js similarity index 100% rename from public/curtain_imageresizer.js rename to public/js/curtain_imageresizer.js diff --git a/public/domLib.js b/public/js/domLib.js similarity index 100% rename from public/domLib.js rename to public/js/domLib.js diff --git a/public/domTT.js b/public/js/domTT.js similarity index 100% rename from public/domTT.js rename to public/js/domTT.js diff --git a/public/domTT_drag.js b/public/js/domTT_drag.js similarity index 100% rename from public/domTT_drag.js rename to public/js/domTT_drag.js diff --git a/public/fadomatic.js b/public/js/fadomatic.js similarity index 100% rename from public/fadomatic.js rename to public/js/fadomatic.js diff --git a/public/jquery-1.12.4.min.js b/public/js/jquery-1.12.4.min.js similarity index 100% rename from public/jquery-1.12.4.min.js rename to public/js/jquery-1.12.4.min.js diff --git a/public/js/nexus.js b/public/js/nexus.js new file mode 100644 index 00000000..a8d4dcd3 --- /dev/null +++ b/public/js/nexus.js @@ -0,0 +1,10 @@ +; +jQuery('.spoiler-title').on('click', function () { + let content = jQuery(this).parent().next(); + if (content.hasClass('collapse')) { + content.height(content[0].scrollHeight).removeClass('collapse') + } else { + content.height(0).addClass('collapse') + } +}); + diff --git a/public/js/ptgen.js b/public/js/ptgen.js new file mode 100644 index 00000000..2c15a997 --- /dev/null +++ b/public/js/ptgen.js @@ -0,0 +1,22 @@ +jQuery('.btn-get-pt-gen').on('click', function () { + let input = jQuery(this).closest('td').find('[data-pt-gen]') + let value = input.val().trim() + if (value == '') { + return + } + let params = { + action: 'getPtGen', + params: {url: value} + } + jQuery('body').loading({ + stoppable: false + }); + jQuery.post('ajax.php', params, function (response) { + jQuery('body').loading('stop'); + if (response.ret != 0) { + alert(response.msg) + return + } + doInsert(response.data, '', false) + }, 'json') +}) diff --git a/public/suggest.js b/public/js/suggest.js similarity index 100% rename from public/suggest.js rename to public/js/suggest.js diff --git a/public/login.php b/public/login.php index 6f2aa983..8d43d0f1 100644 --- a/public/login.php +++ b/public/login.php @@ -6,10 +6,14 @@ $langid = intval($_GET['sitelanguage'] ?? 0); if ($langid) { $lang_folder = validlang($langid); + $enabled = \App\Models\Language::listEnabled(); + if (!in_array($lang_folder, $enabled)) { + nexus_redirect(getBaseUrl()); + } if(get_langfolder_cookie() != $lang_folder) { set_langfolder_cookie($lang_folder); - header("Location: " . $_SERVER['REQUEST_URI']); + nexus_redirect($_SERVER['REQUEST_URI']); } } require_once(get_langfile_path("", false, $CURLANGDIR)); @@ -20,8 +24,7 @@ stdhead($lang_login['head_login']); $s = "%s ', $lang->site_lang_folder, in_array($lang->site_lang_folder, $allEnabled) ? " checked" : "", $lang->lang_name); + } + tr($lang_settings['row_site_language_enabled'], $langlist."
".$lang_settings['text_site_language_enabled_note'], 1); + $langlist = ""; - while($array = mysql_fetch_array($res)) - $langlist .= "".$array['lang_name']." "; + foreach ($allSiteLanguages as $lang) { + $langlist .= sprintf( + ' ', + $lang->site_lang_folder, + $MAIN["defaultlang"] == $lang->site_lang_folder ? " checked" : "", + !in_array($lang->site_lang_folder, $allEnabled) ? " disabled" : "", + $lang->lang_name + ); + } tr($lang_settings['row_default_site_language'], $langlist."
".$lang_settings['text_default_site_language_note'], 1); + $changeDefaultLangJs = <<\n"; -$langs = langlist("site_lang"); +$langs = langlist("site_lang", true); foreach ($langs as $row) { diff --git a/public/tags.php b/public/tags.php index a98bab17..40c98a1d 100644 --- a/public/tags.php +++ b/public/tags.php @@ -187,6 +187,30 @@ insert_tag( "" ); +insert_tag( + $lang_tags['text_left'], + $lang_tags['text_left_description'], + $lang_tags['text_left_syntax'], + $lang_tags['text_left_example'], + "" +); + +insert_tag( + $lang_tags['text_center'], + $lang_tags['text_center_description'], + $lang_tags['text_center_syntax'], + $lang_tags['text_center_example'], + "" +); + +insert_tag( + $lang_tags['text_right'], + $lang_tags['text_right_description'], + $lang_tags['text_right_syntax'], + $lang_tags['text_right_example'], + "" +); + insert_tag( $lang_tags['text_flash'], $lang_tags['text_flash_description'], diff --git a/public/upload.php b/public/upload.php index 56538d8c..e08b7ec8 100644 --- a/public/upload.php +++ b/public/upload.php @@ -162,4 +162,6 @@ stdhead($lang_upload['head_upload']); + +``` + +Use it: + +```javascript +$("#some-element").loading(); +``` + +Visit [the website](http://carlosbonetti.github.io/jquery-loading/) for full list of options, methods and customization. + +## Contributing to this project + +Install dependencies once: + +``` +$ yarn install +``` + +Then build the project (generates `dist/` files): + +``` +$ yarn build +``` + +Run all tests with: + +``` +$ yarn test +``` diff --git a/public/vendor/jquery-loading/jquery.loading.min.js b/public/vendor/jquery-loading/jquery.loading.min.js new file mode 100644 index 00000000..7c491db6 --- /dev/null +++ b/public/vendor/jquery-loading/jquery.loading.min.js @@ -0,0 +1 @@ +!function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e(require("jquery"));else if("function"==typeof define&&define.amd)define(["jquery"],e);else{var n="object"==typeof exports?e(require("jquery")):e(t.jQuery);for(var i in n)("object"==typeof exports?exports:t)[i]=n[i]}}(window,function(t){return function(t){var e={};function n(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return t[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=e,n.d=function(t,e,i){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(i,o,function(e){return t[e]}.bind(null,o));return i},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=1)}([function(e,n){e.exports=t},function(t,e,n){"use strict";n.r(e);var i=n(0),o=n.n(i);n(2);const r=function(t,e){this.element=t,this.settings=o.a.extend({},r.defaults,e),this.settings.fullPage=this.element.is("body"),this.init(),this.settings.start&&this.start()};r.defaults={overlay:void 0,zIndex:void 0,message:"Loading...",theme:"light",shownClass:"loading-shown",hiddenClass:"loading-hidden",stoppable:!1,start:!0,onStart:function(t){t.overlay.fadeIn(150)},onStop:function(t){t.overlay.fadeOut(150)},onClick:function(){}},r.setDefaults=function(t){r.defaults=o.a.extend({},r.defaults,t)},o.a.extend(r.prototype,{init:function(){this.isActive=!1,this.overlay=this.settings.overlay||this.createOverlay(),this.resize(),this.attachMethodsToExternalEvents(),this.attachOptionsHandlers()},createOverlay:function(){var t=o()('
'+this.settings.message+"
").addClass(this.settings.hiddenClass).hide().appendTo("body"),e=this.element.attr("id");return e&&t.attr("id",e+"_loading-overlay"),t},attachMethodsToExternalEvents:function(){var t=this;t.element.on("loading.start",function(){t.overlay.removeClass(t.settings.hiddenClass).addClass(t.settings.shownClass)}),t.element.on("loading.stop",function(){t.overlay.removeClass(t.settings.shownClass).addClass(t.settings.hiddenClass)}),t.settings.stoppable&&t.overlay.on("click",function(){t.stop()}),t.overlay.on("click",function(){t.element.trigger("loading.click",t)}),o()(window).on("resize",function(){t.resize()}),o()(function(){t.resize()})},attachOptionsHandlers:function(){var t=this;t.element.on("loading.start",function(e,n){t.settings.onStart(n)}),t.element.on("loading.stop",function(e,n){t.settings.onStop(n)}),t.element.on("loading.click",function(e,n){t.settings.onClick(n)})},calcZIndex:function(){return void 0!==this.settings.zIndex?this.settings.zIndex:(parseInt(this.element.css("z-index"))||0)+1+this.settings.fullPage},resize:function(){var t=this.element,e=t.outerWidth(),n=t.outerHeight();this.settings.fullPage&&(n="100%",e="100%"),this.overlay.css({position:this.settings.fullPage?"fixed":"absolute",zIndex:this.calcZIndex(),top:t.offset().top,left:t.offset().left,width:e,height:n})},start:function(){this.isActive=!0,this.resize(),this.element.trigger("loading.start",this)},stop:function(){this.isActive=!1,this.element.trigger("loading.stop",this)},active:function(){return this.isActive},toggle:function(){this.active()?this.stop():this.start()},destroy:function(){this.overlay.remove()}});var s="jquery-loading";o.a.fn.loading=function(t){return this.each(function(){var e=o.a.data(this,s);e?void 0===t?e.start():"string"==typeof t?e[t].apply(e):(e.destroy(),o.a.data(this,s,new r(o()(this),t))):void 0!==t&&"object"!=typeof t&&"start"!==t&&"toggle"!==t||o.a.data(this,s,new r(o()(this),t))})},o.a.fn.Loading=function(t){var e=o()(this).data(s);return e&&void 0===t||o()(this).data(s,e=new r(o()(this),t)),e},o.a.expr[":"].loading=function(t){var e=o.a.data(t,s);return!!e&&e.active()},o.a.Loading=r},function(t,e,n){var i=n(3);"string"==typeof i&&(i=[[t.i,i,""]]);var o={insert:"head",singleton:!1};n(5)(i,o);i.locals&&(t.exports=i.locals)},function(t,e,n){(t.exports=n(4)(!1)).push([t.i,"/* Default jquery-loading styles */\r\n\r\n.loading-overlay {\r\n display: table;\r\n opacity: 0.7;\r\n}\r\n\r\n.loading-overlay-content {\r\n text-transform: uppercase;\r\n letter-spacing: 0.4em;\r\n font-size: 1.15em;\r\n font-weight: bold;\r\n text-align: center;\r\n display: table-cell;\r\n vertical-align: middle;\r\n}\r\n\r\n.loading-overlay.loading-theme-light {\r\n background-color: #fff;\r\n color: #000;\r\n}\r\n\r\n.loading-overlay.loading-theme-dark {\r\n background-color: #000;\r\n color: #fff;\r\n}\r\n",""])},function(t,e,n){"use strict";t.exports=function(t){var e=[];return e.toString=function(){return this.map(function(e){var n=function(t,e){var n=t[1]||"",i=t[3];if(!i)return n;if(e&&"function"==typeof btoa){var o=(s=i,a=btoa(unescape(encodeURIComponent(JSON.stringify(s)))),l="sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(a),"/*# ".concat(l," */")),r=i.sources.map(function(t){return"/*# sourceURL=".concat(i.sourceRoot).concat(t," */")});return[n].concat(r).concat([o]).join("\n")}var s,a,l;return[n].join("\n")}(e,t);return e[2]?"@media ".concat(e[2],"{").concat(n,"}"):n}).join("")},e.i=function(t,n){"string"==typeof t&&(t=[[null,t,""]]);for(var i={},o=0;o