From 2efd67ef8594e55dbd09f19b28d2398aa1c419a2 Mon Sep 17 00:00:00 2001 From: Zankaria Date: Wed, 24 Jan 2024 12:59:56 +0100 Subject: [PATCH] Backport vichan 5.1.5 catalog implementation, enabling mod catalog. --- inc/config.php | 1 + inc/mod/pages.php | 12 + mod.php | 1 + templates/index.html | 4 +- templates/themes/catalog/catalog.html | 8 +- templates/themes/catalog/theme.php | 363 ++++++-------------------- templates/thread.html | 2 +- 7 files changed, 103 insertions(+), 288 deletions(-) diff --git a/inc/config.php b/inc/config.php index 4238484a..0f17bc5b 100644 --- a/inc/config.php +++ b/inc/config.php @@ -1260,6 +1260,7 @@ // Location of files. $config['file_index'] = 'index.html'; $config['file_page'] = '%d.html'; // NB: page is both an index page and a thread + $config['file_catalog'] = 'catalog.html'; $config['file_page50'] = '%d+50.html'; $config['file_page_slug'] = '%d-%s.html'; $config['file_page50_slug'] = '%d-%s+50.html'; diff --git a/inc/mod/pages.php b/inc/mod/pages.php index c2927de0..6a1cd4cb 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -754,6 +754,18 @@ function mod_board_log($board, $page_no = 1, $hide_names = false, $public = fals mod_page(_('Board log'), 'mod/log.html', array('logs' => $logs, 'count' => $count, 'board' => $board, 'hide_names' => $hide_names, 'public' => $public)); } +function mod_view_catalog($boardName) { + global $config; + require_once($config['dir']['themes'].'/catalog/theme.php'); + $settings = array(); + $settings['boards'] = $boardName; + $settings['update_on_posts'] = true; + $settings['title'] = 'Catalog'; + $settings['use_tooltipster'] = true; + $catalog = new Catalog($settings); + echo $catalog->build($boardName, true); +} + function mod_view_board($boardName, $page_no = 1) { global $config, $mod; diff --git a/mod.php b/mod.php index 0a7b1aec..d2c98343 100644 --- a/mod.php +++ b/mod.php @@ -112,6 +112,7 @@ $pages = array( // This should always be at the end: '/(\%b)/' => 'view_board', '/(\%b)/' . preg_quote($config['file_index'], '!') => 'view_board', + '/(\%b)/' . preg_quote($config['file_catalog'], '!') => 'view_catalog', '/(\%b)/' . str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) => 'view_board', '/(\%b)/' . preg_quote($config['dir']['res'], '!') . str_replace('%d', '(\d+)', preg_quote($config['file_page50'], '!')) => 'view_thread50', diff --git a/templates/index.html b/templates/index.html index db04fa05..52059a3c 100644 --- a/templates/index.html +++ b/templates/index.html @@ -75,7 +75,7 @@ {% if config.global_message %}
{{ config.global_message }}
{% endif %}
{% if config.catalog_link %} - | Catalog + | {% trans %}Catalog{% endtrans %} {% endif %} {% if config.home_link %} @@ -122,7 +122,7 @@ {{ page.num }}{% if not loop.last %} /{% endif %} {% endfor %} ] {{ btn.next }} {% if config.catalog_link %} - | Catalog + | {% trans %}Catalog{% endtrans %} {% endif %} {% if config.home_link %} | Home diff --git a/templates/themes/catalog/catalog.html b/templates/themes/catalog/catalog.html index 00cc21e2..be820179 100644 --- a/templates/themes/catalog/catalog.html +++ b/templates/themes/catalog/catalog.html @@ -18,7 +18,9 @@

{{ settings.title }} (/{{ board.title|e }}/)

-
{{ settings.subtitle }}
+
{{ settings.subtitle }} + {% if mod %}

{% trans %}Return to dashboard{% endtrans %}

{% endif %} +
{% if not no_post_form %}
@@ -58,7 +60,7 @@
{% for post in recent_posts %}
- R: {{ post.replies }} / I: {{ post.images }}{% if post.sticky %} (sticky){% endif %}{% if post.sage %} (sage){% endif %}{% if (config.reply_limit > 0) and (post.replies >= config.reply_limit) %} (full){% endif %}{% if post.locked %}  {% endif %} + R: {{ post.reply_count }} / I: {{ post.image_count }}{% if post.sticky %} (sticky){% endif %}{% if post.sage %} (sage){% endif %}{% if (config.reply_limit > 0) and (post.reply_count >= config.reply_limit) %} (full){% endif %}{% if post.locked %}  {% endif %} {% if post.subject %}

diff --git a/templates/themes/catalog/theme.php b/templates/themes/catalog/theme.php index e9f01d5e..98f08e39 100644 --- a/templates/themes/catalog/theme.php +++ b/templates/themes/catalog/theme.php @@ -7,17 +7,12 @@ $b = new Catalog($settings); $boards = explode(' ', $settings['boards']); - if (isset($settings['has_overboard']) && $settings['has_overboard']) { - // Include overboard settings so that we can find them all and process exclusions - require "templates/themes/overboards/overboards.php"; - } - // Possible values for $action: - // - all (rebuild everything, initialization) - // - news (news has been updated) - // - boards (board list changed) - // - post (a reply has been made) - // - post-thread (a thread has been made) + // - all (rebuild everything, initialization) + // - news (news has been updated) + // - boards (board list changed) + // - post (a reply has been made) + // - post-thread (a thread has been made) if ($action === 'all') { foreach ($boards as $board) { $action = generation_strategy("sb_catalog", array($board)); @@ -26,24 +21,10 @@ file_unlink($config['dir']['home'] . $board . '/index.rss'); } elseif ($action == 'rebuild') { - $b->build($settings, $board); - } - } - if(isset($settings['has_overboard']) && $settings['has_overboard']) { - foreach ($overboards_config as &$overboard) { - $included_boards = array_diff(listBoards(true), $overboard['exclude']); - $action = generation_strategy("sb_catalog", array($overboard)); - if ($action == 'delete') { - file_unlink($config['dir']['home'] . $overboard . '/catalog.html'); - file_unlink($config['dir']['home'] . $overboard . '/index.rss'); - } - elseif ($action == 'rebuild') { - $b->buildOverboardCatalog($overboard['uri'], $settings, $included_boards); - } + $b->build($board); } } - } elseif ($action == 'post-thread' || ($settings['update_on_posts'] && $action == 'post') || ($settings['update_on_posts'] && $action == 'post-delete') - || $action == 'sticky' || ($action == 'lock' && in_array($board, $boards))) { + } elseif ($action == 'post-thread' || ($settings['update_on_posts'] && $action == 'post') || ($settings['update_on_posts'] && $action == 'post-delete') && in_array($board, $boards)) { $b = new Catalog($settings); $action = generation_strategy("sb_catalog", array($board)); @@ -52,15 +33,10 @@ file_unlink($config['dir']['home'] . $board . '/index.rss'); } elseif ($action == 'rebuild') { - $b->build($settings, $board); - if(isset($settings['has_overboard']) && $settings['has_overboard']) { - foreach ($overboards_config as &$overboard) { - $included_boards = array_diff(listBoards(true), $overboard['exclude']); - $b->buildOverboardCatalog($overboard['uri'], $settings, $included_boards); - } - } + $b->build($board); } } + // FIXME: Check that Ukko is actually enabled if ($settings['enable_ukko'] && ( $action === 'all' || $action === 'post' || @@ -69,28 +45,6 @@ $b->buildUkko(); } - // FIXME: Check that Ukko2 is actually enabled - if ($settings['enable_ukko2'] && ( - $action === 'all' || $action === 'post' || - $action === 'post-thread' || $action === 'post-delete' || $action === 'rebuild')) - { - $b->buildUkko2(); - } - - // FIXME: Check that Ukko3 is actually enabled - if ($settings['enable_ukko3'] && ( - $action === 'all' || $action === 'post' || - $action === 'post-thread' || $action === 'post-delete' || $action === 'rebuild')) - { - $b->buildUkko3(); - } - // FIXME: Check that Ukko3 is actually enabled - if ($settings['enable_ukko4'] && ( - $action === 'all' || $action === 'post' || - $action === 'post-thread' || $action === 'post-delete' || $action === 'rebuild')) - { - $b->buildUkko4(); - } // FIXME: Check that Rand is actually enabled if ($settings['enable_rand'] && ( $action === 'all' || $action === 'post' || @@ -113,11 +67,11 @@ /** * Build and save the HTML of the catalog for the Ukko theme */ - public function buildUkko() { - global $config; + public function buildUkko($mod = false) { + global $board, $config; $ukkoSettings = themeSettings('ukko'); - $queries = array(); + $queries = array(); $threads = array(); $exclusions = explode(' ', $ukkoSettings['exclude']); @@ -143,134 +97,31 @@ return strcmp($b['bump'], $a['bump']); }); // Generate data for the template - $recent_posts = $this->generateRecentPosts($threads); - - $this->saveForBoard($ukkoSettings['uri'], $recent_posts, - $config['root'] . $ukkoSettings['uri']); - } - /** - * Build and save the HTML of the catalog for the Ukko2 theme - */ - public function buildUkko2() { - global $config; - $ukkoSettings = themeSettings('ukko2'); - $queries = array(); - $threads = array(); + $recent_posts = $this->generateRecentPosts($threads, $mod); - $inclusions = explode(' ', $ukkoSettings['include']); - $boards = array_intersect(listBoards(true), $inclusions); + // Generate board data for building + $board_original = $board; + $board = []; + $board['uri'] = $ukkoSettings['uri']; + $board['title'] = $ukkoSettings['title']; + $board['subtitle'] = $ukkoSettings['subtitle']; - foreach ($boards as $b) { - if (array_key_exists($b, $this->threadsCache)) { - $threads = array_merge($threads, $this->threadsCache[$b]); - } else { - $queries[] = $this->buildThreadsQuery($b); - } - } - - // Fetch threads from boards that haven't beenp processed yet - if (!empty($queries)) { - $sql = implode(' UNION ALL ', $queries); - $res = query($sql) or error(db_error()); - $threads = array_merge($threads, $res->fetchAll(PDO::FETCH_ASSOC)); - } + $ret = $this->saveForBoard($ukkoSettings['uri'], $recent_posts, + $config['root'] . $ukkoSettings['uri'], $mod); - // Sort in bump order - usort($threads, function($a, $b) { - return strcmp($b['bump'], $a['bump']); - }); - // Generate data for the template - $recent_posts = $this->generateRecentPosts($threads); + $board = $board_original; - $this->saveForBoard($ukkoSettings['uri'], $recent_posts, - $config['root'] . $ukkoSettings['uri']); - } - - /** - * Build and save the HTML of the catalog for the Ukko3 theme - */ - public function buildUkko3() { - global $config; - - $ukkoSettings = themeSettings('ukko3'); - $queries = array(); - $threads = array(); - - $inclusions = explode(' ', $ukkoSettings['include']); - $boards = array_intersect(listBoards(true), $inclusions); - - foreach ($boards as $b) { - if (array_key_exists($b, $this->threadsCache)) { - $threads = array_merge($threads, $this->threadsCache[$b]); - } else { - $queries[] = $this->buildThreadsQuery($b); - } - } - - // Fetch threads from boards that haven't beenp processed yet - if (!empty($queries)) { - $sql = implode(' UNION ALL ', $queries); - $res = query($sql) or error(db_error()); - $threads = array_merge($threads, $res->fetchAll(PDO::FETCH_ASSOC)); - } - - // Sort in bump order - usort($threads, function($a, $b) { - return strcmp($b['bump'], $a['bump']); - }); - // Generate data for the template - $recent_posts = $this->generateRecentPosts($threads); - - $this->saveForBoard($ukkoSettings['uri'], $recent_posts, - $config['root'] . $ukkoSettings['uri']); - } - - /** - * Build and save the HTML of the catalog for the Ukko theme - */ - public function buildUkko4() { - global $config; - - $ukkoSettings = themeSettings('ukko4'); - $queries = array(); - $threads = array(); - - $exclusions = explode(' ', $ukkoSettings['exclude']); - $boards = array_diff(listBoards(true), $exclusions); - - foreach ($boards as $b) { - if (array_key_exists($b, $this->threadsCache)) { - $threads = array_merge($threads, $this->threadsCache[$b]); - } else { - $queries[] = $this->buildThreadsQuery($b); - } - } - - // Fetch threads from boards that haven't beenp processed yet - if (!empty($queries)) { - $sql = implode(' UNION ALL ', $queries); - $res = query($sql) or error(db_error()); - $threads = array_merge($threads, $res->fetchAll(PDO::FETCH_ASSOC)); - } - - // Sort in bump order - usort($threads, function($a, $b) { - return strcmp($b['bump'], $a['bump']); - }); - // Generate data for the template - $recent_posts = $this->generateRecentPosts($threads); - - $this->saveForBoard($ukkoSettings['uri'], $recent_posts, - $config['root'] . $ukkoSettings['uri']); + return $ret; } + /** * Build and save the HTML of the catalog for the Rand theme */ - public function buildRand() { - global $config; + public function buildRand($mod = false) { + global $board, $config; $randSettings = themeSettings('rand'); - $queries = array(); + $queries = array(); $threads = array(); $exclusions = explode(' ', $randSettings['exclude']); @@ -291,26 +142,32 @@ $threads = array_merge($threads, $res->fetchAll(PDO::FETCH_ASSOC)); } - // Sort in bump order - usort($threads, function($a, $b) { - return strcmp($b['bump'], $a['bump']); - }); + // Randomize order + shuffle($threads); // Generate data for the template - $recent_posts = $this->generateRecentPosts($threads); + $recent_posts = $this->generateRecentPosts($threads, $mod); + + // Generate board data for building + $board_original = $board; + $board = []; + $board['uri'] = $randSettings['uri']; + $board['title'] = $randSettings['title']; + $board['subtitle'] = $randSettings['subtitle']; + + $ret = $this->saveForBoard($randSettings['uri'], $recent_posts, + $config['root'] . $randSettings['uri'], $mod); - $this->saveForBoard($randSettings['uri'], $recent_posts, - $config['root'] . $randSettings['uri'], true); + $board = $board_original; + + return $ret; } /** * Build and save the HTML of the catalog for the given board */ - public function build($settings, $board_name) { - global $board; - if (is_null($board) || $board['uri'] != $board_name) { - if (!openBoard($board_name)) { - error(sprintf(_("Board %s doesn't exist"), $board_name)); - } + public function build($board_name, $mod = false) { + if (!openBoard($board_name)) { + error(sprintf(_("Board %s doesn't exist"), $post['board'])); } if (array_key_exists($board_name, $this->threadsCache)) { @@ -324,76 +181,20 @@ } // Generate data for the template - $recent_posts = $this->generateRecentPosts($threads); + $recent_posts = $this->generateRecentPosts($threads, $mod); - $this->saveForBoard($board_name, $recent_posts); + return $this->saveForBoard($board_name, $recent_posts, null, $mod); } private function buildThreadsQuery($board) { $sql = "SELECT *, `id` AS `thread_id`, " . - "(SELECT COUNT(`id`) FROM ``posts_$board`` WHERE `thread` = `thread_id`) AS `replies`, " . - "(SELECT SUM(`num_files`) FROM ``posts_$board`` WHERE `thread` = `thread_id` AND `num_files` IS NOT NULL) AS `images`, " . + "(SELECT COUNT(`id`) FROM ``posts_$board`` WHERE `thread` = `thread_id`) AS `reply_count`, " . + "(SELECT SUM(`num_files`) FROM ``posts_$board`` WHERE `thread` = `thread_id` AND `num_files` IS NOT NULL) AS `image_count`, " . "'$board' AS `board` FROM ``posts_$board`` WHERE `thread` IS NULL"; return $sql; } - /** - * Build and save the HTML of the catalog for the overboard - */ - public function buildOverboardCatalog($board_name, $settings, $boards) { - global $config; - - if (array_key_exists($board_name, $this->threadsCache)) { - $threads = $this->threadsCache[$board_name]; - } else { - $sql = ''; - foreach ($boards as $board) { - $sql .= '('. $this->buildThreadsQuery($board) . ')'; - $sql .= " UNION ALL "; - } - $sql = preg_replace('/UNION ALL $/', 'ORDER BY `bump` DESC LIMIT :limit', $sql); - $query = prepare($sql); - $query->bindValue(':limit', $settings['overboard_limit'], PDO::PARAM_INT); - $query->execute() or error(db_error($query)); - - $threads = $query->fetchAll(PDO::FETCH_ASSOC); - // Save for posterity - $this->threadsCache[$board_name] = $threads; - } - // Generate data for the template - $recent_posts = $this->generateRecentPosts($threads); - - $this->saveForBoard($board_name, $recent_posts, '/' . $board_name, true); - - // Build the overboard JSON outputs - if ($config['api']['enabled']) { - $api = new Api(); - - // Separate the threads into pages - $pages = array(array()); - $totalThreads = count($recent_posts); - $page = 0; - for ($i = 1; $i <= $totalThreads; $i++) { - $pages[$page][] = new Thread($recent_posts[$i-1]); - - // If we have not yet visited all threads, - // and we hit the limit on the current page, - // skip to the next page - if ($i < $totalThreads && ($i % $config['threads_per_page'] == 0)) { - $page++; - $pages[$page] = array(); - } - } - - $json = json_encode($api->translateCatalog($pages)); - file_write($config['dir']['home'] . $board_name . '/catalog.json', $json); - - $json = json_encode($api->translateCatalog($pages, true)); - file_write($config['dir']['home'] . $board_name . '/threads.json', $json); - } - } - private function filepathForThumb($thumb_or_special, $path_when_file) { global $config; @@ -416,7 +217,7 @@ } } - private function generateRecentPosts($threads) { + private function generateRecentPosts($threads, $mod = false) { global $config, $board; $posts = array(); @@ -425,7 +226,10 @@ openBoard($post['board']); } - $post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . link_for($post); + if ($mod) + $post['link'] = $config['root'] . $config['file_mod'] . '?/'. $board['dir'] . $config['dir']['res'] . link_for($post); + else + $post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . link_for($post); $post['board_name'] = $board['name']; if ($post['embed'] && preg_match('/^https?:\/\/(\w+\.)?(?:youtube\.com\/watch\?v=|youtu\.be\/)([a-zA-Z0-9\-_]{10,11})(&.+)?$/i', $post['embed'], $matches)) { @@ -454,23 +258,18 @@ $post['file'] = $this->filepathForThumb('deleted', null); } - if (empty($post['images'])) - $post['images'] = 0; + if (empty($post['image_count'])) + $post['image_count'] = 0; $post['pubdate'] = date('r', $post['time']); - $posts[] = $post; } return $posts; } - private function saveForBoard($board_name, $recent_posts, $board_link = null, $is_overboard = false) { + private function saveForBoard($board_name, $recent_posts, $board_link = null, $mod = false) { global $board, $config; - if ($board_link === null) { - $board_link = $config['root'] . $board['dir']; - } - $required_scripts = array('js/jquery.min.js', 'js/jquery.mixitup.min.js', 'js/catalog.js'); @@ -480,37 +279,37 @@ $config['additional_javascript'][] = $s; } - $template_config = Array( + $antibot = create_antibot($board_name); + $antibot->reset(); + + if ($board_link === null) { + $board_link = ($mod) ? $config['root'] . $config['file_mod'] . '?/' . $board['dir'] : $config['root'] . $board['dir']; + } + + $element = Element('themes/catalog/catalog.html', Array( 'settings' => $this->settings, 'config' => $config, - 'boardlist' => createBoardlist(), + 'boardlist' => createBoardlist($mod), 'recent_images' => array(), 'recent_posts' => $recent_posts, 'stats' => array(), + 'board_name' => $board_name, 'board' => $board, - 'is_overboard' => $is_overboard, + 'antibot' => $antibot, 'link' => $board_link, - 'no_post_form' => false, - ); - - if ($is_overboard) { - // fake board, I vomit - $template_config['board'] = Array( - 'uri' => $board_name, - 'title' => $board_name, - 'name' => $board_name, - 'dir' => $board_name . '/', - 'url' => '/' . $board_name . '/' - ); - $template_config['no_post_form'] = true; - } + 'mod' => $mod + )); - file_write($config['dir']['home'] . $board_name . '/catalog.html', Element('themes/catalog/catalog.html', $template_config)); + if ($mod) { + return $element; + } else { + file_write($config['dir']['home'] . $board_name . '/catalog.html', $element); - file_write($config['dir']['home'] . $board_name . '/index.rss', Element('themes/catalog/index.rss', Array( - 'config' => $config, - 'recent_posts' => $recent_posts, - 'board' => $board - ))); + file_write($config['dir']['home'] . $board_name . '/index.rss', Element('themes/catalog/index.rss', Array( + 'config' => $config, + 'recent_posts' => $recent_posts, + 'board' => $board + ))); + } } } diff --git a/templates/thread.html b/templates/thread.html index 8e38d40c..1be7f568 100644 --- a/templates/thread.html +++ b/templates/thread.html @@ -75,7 +75,7 @@ [{% trans %}Return{% endtrans %}] [{% trans %}Go to top{% endtrans %}] {% if config.catalog_link %} - [{% trans %}Catalog{% endtrans %}] + [{% trans %}Catalog{% endtrans %}] {% endif %} {% if config.home_link %} | [{% trans %}Home{% endtrans %}]