From fa9a3da9137457083be12f7c8409e4aafa246d28 Mon Sep 17 00:00:00 2001 From: 8chan Date: Wed, 3 Dec 2014 00:10:28 -0800 Subject: [PATCH] New boards.html page now with tags --- boards.php | 33 +++++- inc/functions.php | 172 ++++++++++----------------- install.sql | 15 +++ read.php | 183 ----------------------------- templates/8chan/boards-tags.html | 157 +++++++++++++++++++++++++ templates/themes/catalog/theme.php | 30 ++--- 6 files changed, 274 insertions(+), 316 deletions(-) delete mode 100644 read.php create mode 100644 templates/8chan/boards-tags.html diff --git a/boards.php b/boards.php index f22cb524..de7f15e8 100644 --- a/boards.php +++ b/boards.php @@ -10,10 +10,17 @@ if (php_sapi_name() == 'fpm-fcgi' && !$admin) { error('Cannot be run directly.'); } $boards = listBoards(); - +$all_tags = array(); $total_posts_hour = 0; $total_posts = 0; +function to_tag($str) { + $str = trim($str); + $str = strtolower($str); + $str = str_replace(['_', ' '], '-', $str); + return $str; +} + foreach ($boards as $i => $board) { //$query = prepare(sprintf("SELECT (SELECT MAX(id) from ``posts_%s``) AS max, (SELECT MAX(id) FROM ``posts_%s`` WHERE FROM_UNIXTIME(time) < DATE_SUB(NOW(), INTERVAL 1 HOUR)) AS oldmax, (SELECT MAX(id) from ``posts_%s``) AS max_d, (SELECT MAX(id) FROM ``posts_%s`` WHERE FROM_UNIXTIME(time) < DATE_SUB(NOW(), INTERVAL 1 DAY)) AS oldmax_d, (SELECT count(id) FROM ``posts_%s``) AS count;", $board['uri'], $board['uri'], $board['uri'], $board['uri'], $board['uri'])); @@ -28,6 +35,23 @@ SELECT MAX(id) max, (SELECT COUNT(*) FROM ``posts_%s`` WHERE FROM_UNIXTIME(time) $query->execute() or error(db_error($query)); $r = $query->fetch(PDO::FETCH_ASSOC); + $tquery = prepare("SELECT `tag` FROM ``board_tags`` WHERE `uri` = :uri"); + $tquery->execute([":uri" => $board['uri']]) or error(db_error($tquery)); + $r2 = $tquery->fetchAll(PDO::FETCH_ASSOC); + + $tags = array(); + if ($r2) { + foreach ($r2 as $ii => $t) { + $tag=to_tag($t['tag']); + $tags[] = $tag; + if (!isset($all_tags[$tag])) { + $all_tags[$tag] = (int)$r['uniq_ip']; + } else { + $all_tags[$tag] += $r['uniq_ip']; + } + } + } + $pph = $r['pph']; $ppd = $r['ppd']; @@ -38,6 +62,7 @@ SELECT MAX(id) max, (SELECT COUNT(*) FROM ``posts_%s`` WHERE FROM_UNIXTIME(time) $boards[$i]['ppd'] = $ppd; $boards[$i]['max'] = $r['max']; $boards[$i]['uniq_ip'] = $r['uniq_ip']; + $boards[$i]['tags'] = $tags; } usort($boards, @@ -86,14 +111,18 @@ foreach ($boards as $i => &$board) { $n_boards = sizeof($boards); $t_boards = $hidden_boards_total + $n_boards; +$boards = array_values($boards); +arsort($all_tags); + $config['additional_javascript'] = array('js/jquery.min.js', 'js/jquery.tablesorter.min.js'); -$body = Element("8chan/boards.html", array("config" => $config, "n_boards" => $n_boards, "t_boards" => $t_boards, "hidden_boards_total" => $hidden_boards_total, "total_posts" => $total_posts, "total_posts_hour" => $total_posts_hour, "boards" => $boards, "last_update" => date('r'), "uptime_p" => shell_exec('uptime -p'))); +$body = Element("8chan/boards-tags.html", array("config" => $config, "n_boards" => $n_boards, "t_boards" => $t_boards, "hidden_boards_total" => $hidden_boards_total, "total_posts" => $total_posts, "total_posts_hour" => $total_posts_hour, "boards" => $boards, "last_update" => date('r'), "uptime_p" => shell_exec('uptime -p'), 'tags' => $all_tags)); $html = Element("page.html", array("config" => $config, "body" => $body, "title" => "Boards on ∞chan")); if ($admin) { echo $html; } else { file_write("boards.json", json_encode($boards)); + file_write("tags.json", json_encode($all_tags)); foreach ($boards as $i => $b) { if (in_array($b['uri'], $config['no_top_bar_boards'])) { unset($boards[$i]); diff --git a/inc/functions.php b/inc/functions.php index f02abd3d..2ffdc222 100755 --- a/inc/functions.php +++ b/inc/functions.php @@ -1099,12 +1099,6 @@ function deletePost($id, $error_if_doesnt_exist=true, $rebuild_after=true) { $antispam_query->bindValue(':board', $board['uri']); $antispam_query->bindValue(':thread', $post['id']); $antispam_query->execute() or error(db_error($antispam_query)); - - cache::delete("thread_index_{$board['uri']}_{$post['id']}"); - cache::delete("thread_index_display_{$board['uri']}_{$post['id']}"); - cache::delete("thread_{$board['uri']}_{$post['id']}"); - cache::delete("thread_50_{$board['uri']}_{$post['id']}"); - cache::delete("catalog_{$board['uri']}"); } elseif ($query->rowCount() == 1) { // Rebuild thread $rebuild = &$post['thread']; @@ -1196,62 +1190,57 @@ function index($page, $mod=false) { return false; $threads = array(); - + while ($th = $query->fetch(PDO::FETCH_ASSOC)) { - if (($config['cache']['enabled'] && !($thread = cache::get("thread_index_display_{$board['uri']}_{$th['id']}")) || $mod)) { - $thread = new Thread($th, $mod ? '?/' : $config['root'], $mod); + $thread = new Thread($th, $mod ? '?/' : $config['root'], $mod); - if ($config['cache']['enabled']) { - $cached = cache::get("thread_index_{$board['uri']}_{$th['id']}"); - if (isset($cached['replies'], $cached['omitted'])) { - $replies = $cached['replies']; - $omitted = $cached['omitted']; - } else { - unset($cached); - } + if ($config['cache']['enabled']) { + $cached = cache::get("thread_index_{$board['uri']}_{$th['id']}"); + if (isset($cached['replies'], $cached['omitted'])) { + $replies = $cached['replies']; + $omitted = $cached['omitted']; + } else { + unset($cached); } - if (!isset($cached)) { - $posts = prepare(sprintf("SELECT * FROM ``posts_%s`` WHERE `thread` = :id ORDER BY `id` DESC LIMIT :limit", $board['uri'])); - $posts->bindValue(':id', $th['id']); - $posts->bindValue(':limit', ($th['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview']), PDO::PARAM_INT); - $posts->execute() or error(db_error($posts)); - - $replies = array_reverse($posts->fetchAll(PDO::FETCH_ASSOC)); - - if (count($replies) == ($th['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview'])) { - $count = numPosts($th['id']); - $omitted = array('post_count' => $count['replies'], 'image_count' => $count['images']); - } else { - $omitted = false; - } - - if ($config['cache']['enabled']) - cache::set("thread_index_{$board['uri']}_{$th['id']}", array( - 'replies' => $replies, - 'omitted' => $omitted, - )); - } - - $num_images = 0; - foreach ($replies as $po) { - if ($po['num_files']) - $num_images+=$po['num_files']; - - $thread->add(new Post($po, $mod ? '?/' : $config['root'], $mod)); - } - - $thread->images = $num_images; - $thread->replies = isset($omitted['post_count']) ? $omitted['post_count'] : count($replies); - - if ($omitted) { - $thread->omitted = $omitted['post_count'] - ($th['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview']); - $thread->omitted_images = $omitted['image_count'] - $num_images; - } - - if ($config['cache']['enabled'] && !$mod) - cache::set("thread_index_display_{$board['uri']}_{$th['id']}", $thread); - } + if (!isset($cached)) { + $posts = prepare(sprintf("SELECT * FROM ``posts_%s`` WHERE `thread` = :id ORDER BY `id` DESC LIMIT :limit", $board['uri'])); + $posts->bindValue(':id', $th['id']); + $posts->bindValue(':limit', ($th['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview']), PDO::PARAM_INT); + $posts->execute() or error(db_error($posts)); + + $replies = array_reverse($posts->fetchAll(PDO::FETCH_ASSOC)); + + if (count($replies) == ($th['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview'])) { + $count = numPosts($th['id']); + $omitted = array('post_count' => $count['replies'], 'image_count' => $count['images']); + } else { + $omitted = false; + } + + if ($config['cache']['enabled']) + cache::set("thread_index_{$board['uri']}_{$th['id']}", array( + 'replies' => $replies, + 'omitted' => $omitted, + )); + } + + $num_images = 0; + foreach ($replies as $po) { + if ($po['num_files']) + $num_images+=$po['num_files']; + + $thread->add(new Post($po, $mod ? '?/' : $config['root'], $mod)); + } + + $thread->images = $num_images; + $thread->replies = isset($omitted['post_count']) ? $omitted['post_count'] : count($replies); + + if ($omitted) { + $thread->omitted = $omitted['post_count'] - ($th['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview']); + $thread->omitted_images = $omitted['image_count'] - $num_images; + } + $threads[] = $thread; $body .= $thread->build(true); } @@ -1469,10 +1458,6 @@ function checkMute() { function buildIndex() { global $board, $config, $build_pages; - if ($config['use_read_php']) { - cache::delete("catalog_{$board['uri']}"); - return; - } $pages = getPages(); if (!$config['try_smarter']) @@ -1550,17 +1535,6 @@ function buildIndex() { function buildJavascript() { global $config; - if ($config['cache']['enabled']) { - if (false === strpos($config['file_script'], '/')) { - $cache_name = 'main_js'; - } else { - $b = explode('/', $config['file_script'])[0]; - $cache_name = "board_{$b}_js"; - } - - cache::delete($cache_name); - } - $script = Element('main.js', array( 'config' => $config, )); @@ -1582,14 +1556,7 @@ function buildJavascript() { $script = JSMin::minify($script); } - if ($config['cache']['enabled']) - cache::set($cache_name, $script); - - if (!$config['use_read_php']) { - file_write($config['file_script'], $script); - } else { - return $script; - } + file_write($config['file_script'], $script); } function checkDNSBL() { @@ -2023,35 +1990,27 @@ function strip_combining_chars($str) { function buildThread($id, $return = false, $mod = false) { global $board, $config, $build_pages; - if (!$return && $config['use_read_php']) { - cache::delete("thread_index_{$board['uri']}_{$id}"); - cache::delete("thread_50_{$board['uri']}_{$id}"); - cache::delete("thread_index_display_{$board['uri']}_{$id}"); - cache::delete("thread_{$board['uri']}_{$id}"); - cache::delete("catalog_{$board['uri']}"); - return; - } - $id = round($id); if (event('build-thread', $id)) return; - if (!($thread = cache::get("thread_{$board['uri']}_{$id}")) || $mod) { - unset($thread); - $query = prepare(sprintf("SELECT * FROM ``posts_%s`` WHERE (`thread` IS NULL AND `id` = :id) OR `thread` = :id ORDER BY `thread`,`id`", $board['uri'])); - $query->bindValue(':id', $id, PDO::PARAM_INT); - $query->execute() or error(db_error($query)); + if ($config['cache']['enabled'] && !$mod) { + // Clear cache + cache::delete("thread_index_{$board['uri']}_{$id}"); + cache::delete("thread_{$board['uri']}_{$id}"); + } - while ($post = $query->fetch(PDO::FETCH_ASSOC)) { - if (!isset($thread)) { - $thread = new Thread($post, $mod ? '?/' : $config['root'], $mod); - } else { - $thread->add(new Post($post, $mod ? '?/' : $config['root'], $mod)); - } + $query = prepare(sprintf("SELECT * FROM ``posts_%s`` WHERE (`thread` IS NULL AND `id` = :id) OR `thread` = :id ORDER BY `thread`,`id`", $board['uri'])); + $query->bindValue(':id', $id, PDO::PARAM_INT); + $query->execute() or error(db_error($query)); + + while ($post = $query->fetch(PDO::FETCH_ASSOC)) { + if (!isset($thread)) { + $thread = new Thread($post, $mod ? '?/' : $config['root'], $mod); + } else { + $thread->add(new Post($post, $mod ? '?/' : $config['root'], $mod)); } - - if (isset($thread)) cache::set("thread_{$board['uri']}_{$id}", $thread); } // Check if any posts were found @@ -2079,7 +2038,7 @@ function buildThread($id, $return = false, $mod = false) { $build_pages[] = thread_find_page($id); // json api - if ($config['api']['enabled'] && !$config['use_read_php']) { + if ($config['api']['enabled']) { $api = new Api(); $json = json_encode($api->translateThread($thread)); $jsonFilename = $board['dir'] . $config['dir']['res'] . $id . '.json'; @@ -2105,8 +2064,7 @@ function buildThread50($id, $return = false, $mod = false, $thread = null, $anti if ($antibot) $antibot->reset(); - if (!$thread && ($config['cache']['enabled'] && !($thread = cache::get("thread_50_{$board['uri']}_{$id}")))) { - unset($thread); + if (!$thread) { $query = prepare(sprintf("SELECT * FROM ``posts_%s`` WHERE (`thread` IS NULL AND `id` = :id) OR `thread` = :id ORDER BY `thread`,`id` DESC LIMIT :limit", $board['uri'])); $query->bindValue(':id', $id, PDO::PARAM_INT); $query->bindValue(':limit', $config['noko50_count']+1, PDO::PARAM_INT); @@ -2143,8 +2101,6 @@ function buildThread50($id, $return = false, $mod = false, $thread = null, $anti } $thread->posts = array_reverse($thread->posts); - if ($config['cache']['enabled']) - cache::set("thread_50_{$board['uri']}_{$id}", $thread); } else { $allPosts = $thread->posts; diff --git a/install.sql b/install.sql index 9e15396a..9a03736f 100644 --- a/install.sql +++ b/install.sql @@ -67,6 +67,8 @@ CREATE TABLE IF NOT EXISTS `boards` ( `subtitle` tinytext, `indexed` boolean default true, `public_bans` boolean default true, + `8archive` boolean default false, + `sfw` boolean default false, PRIMARY KEY (`uri`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4; @@ -316,6 +318,19 @@ CREATE TABLE `post_clean` ( UNIQUE KEY `clean_id_UNIQUE` (`clean_id`) ); +-- -------------------------------------------------------- + +-- +-- Table structure for table `board_tags` +-- + +CREATE TABLE `board_tags` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `uri` varchar(30) DEFAULT NULL, + `tag` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +); + /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/read.php b/read.php deleted file mode 100644 index 64fee794..00000000 --- a/read.php +++ /dev/null @@ -1,183 +0,0 @@ - 'view_board', - '/(\%b)/(\d+)\.json' => 'view_api_index', - '/(\%b)/catalog\.json' => 'view_api_catalog', - '/(\%b)/threads\.json' => 'view_api_threads', - '/(\%b)/main\.js' => 'view_js', - '/main\.js' => 'view_js', - '/(\%b)/catalog(\.html)?' => 'view_catalog', - '/(\%b)/' . preg_quote($config['file_index'], '!') => 'view_board', - '/(\%b)/' . str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) => 'view_board', - '/(\%b)/' . preg_quote($config['dir']['res'], '!') . - str_replace('%d', '(\d+)', '%d\+50(\.html)?') => 'view_thread50', - '/(\%b)/' . preg_quote($config['dir']['res'], '!') . - str_replace('%d', '(\d+)', '%d(\.html)?') => 'view_thread', -); - -$new_pages = array(); -foreach ($pages as $key => $callback) { - if (is_string($callback) && preg_match('/^secure /', $callback)) - $key .= '(/(?P[a-f0-9]{8}))?'; - $key = str_replace('\%b', '?P' . sprintf(substr($config['board_path'], 0, -1), $config['board_regex']), $key); - $new_pages[@$key[0] == '!' ? $key : '!^' . $key . '(?:&[^&=]+=[^&]*)*$!u'] = $callback; -} -$pages = $new_pages; - -function view_thread50($boardName, $thread) { - global $config, $mod; - - if (!openBoard($boardName)) { - include '404.php'; - return; - } - - $page = buildThread50($thread, true, false); - echo $page; -} - -function view_thread($boardName, $thread) { - global $config, $mod; - - if (!openBoard($boardName)) { - include '404.php'; - return; - } - - $page = buildThread($thread, true, false); - echo $page; -} - -function view_api_index($boardName, $page) { - global $config, $board; - - $api = new Api(); - - if (!openBoard($boardName)) { - include '404.php'; - return; - } - - $content = index($page+1); - - if (!$content) - return; - - if ($config['api']['enabled']) { - $threads = $content['threads']; - $json = json_encode($api->translatePage($threads)); - header('Content-Type: text/json'); - - echo $json; - } -} - -function APICatalog($boardName, $gen_threads = false) { - global $config; - if (!openBoard($boardName)) { - include '404.php'; - return; - } - - header('Content-Type: text/json'); - - $catalog = array(); - $api = new Api(); - - for ($page = 1; $page <= $config['max_pages']; $page++) { - $content = index($page); - - if (!$content) - break; - - $catalog[$page-1] = $content['threads']; - } - - echo json_encode($api->translateCatalog($catalog, $gen_threads)); -} - -function view_api_catalog($boardName) { - APICatalog($boardName, false); -} - -function view_api_threads($boardName) { - APICatalog($boardName, true); -} - -function view_board($boardName, $page_no = 1) { - global $config, $mod; - - if (!openBoard($boardName)) { - include '404.php'; - return; - } - - if (!$page = index($page_no, $mod)) { - error($config['error']['404']); - } - - $page['pages'] = getPages(false); - $page['pages'][$page_no-1]['selected'] = true; - $page['btn'] = getPageButtons($page['pages'], false); - $page['mod'] = false; - $page['config'] = $config; - - echo Element('index.html', $page); -} - -function view_js($boardName = false) { - global $config; - - if ($boardName && !openBoard($boardName)) - error($config['error']['noboard']); - - if (!$boardName) { - $cache_name = 'main_js'; - } else { - $cache_name = "board_{$boardName}_js"; - } - - if (!($script = cache::get($cache_name))) { - $script = buildJavascript(); - } - - echo $script; -} - -function view_catalog($boardName) { - global $board, $config; - $_theme = 'catalog'; - - $theme = loadThemeConfig($_theme); - - if (!openBoard($boardName)) { - include '404.php'; - return; - } - - require_once $config['dir']['themes'] . '/' . $_theme . '/theme.php'; - - $catalog = $theme['build_function']('read_php', themeSettings($_theme), $board['uri']); - echo $catalog; -} - -$found = false; -foreach ($pages as $uri => $handler) { - if (preg_match($uri, $query, $matches)) { - $matches = array_slice($matches, 2); - if (is_callable($handler)) { - $found = true; - call_user_func_array($handler, $matches); - } - } -} - -if (!$found) - include '404.php'; diff --git a/templates/8chan/boards-tags.html b/templates/8chan/boards-tags.html new file mode 100644 index 00000000..7ac4bcc3 --- /dev/null +++ b/templates/8chan/boards-tags.html @@ -0,0 +1,157 @@ + + +

{% trans %}There are currently {{n_boards}} boards + {{hidden_boards_total}} unindexed boards = {{t_boards}} total boards. Site-wide, {{total_posts_hour}} posts have been made in the last hour, with {{total_posts}} being made on all active boards since October 23, 2013.{% endtrans %}

+ +
+ Tags:  + {% for tag, pop in tags %} + {% if pop > 1000 %} + {{ tag }} + {% elseif pop > 500 %} + {{ tag }} + {% elseif pop > 100 %} + {{ tag }} + {% else %} + {{ tag }} + {% endif %} + {% endfor %} +
+ + + + + + + + + + + +{% for board in boards %} + + + + + + + + +{% endfor %} +
B{% trans %}Board{% endtrans %}{% trans %}Title{% endtrans %}{% trans %}PPH{% endtrans %}{% trans %}Total posts{% endtrans %}{% trans %}Active users{% endtrans %}{% trans %}Tags{% endtrans %}
{{ board.img|raw }} {% if board['sfw'] %}{% else %}{% endif %}
/{{board['uri']}}/{{lock|raw}}
{{ board['title'] }}
{{board['pph']}}{{board['max']}}{{board['uniq_ip']}}
{% for tag in board.tags %}{{ tag }} {% endfor %}
+

Page last updated: {{last_update}}

+

{{uptime_p}} without interruption (read)

+ + diff --git a/templates/themes/catalog/theme.php b/templates/themes/catalog/theme.php index 2f3c61f1..5b940167 100644 --- a/templates/themes/catalog/theme.php +++ b/templates/themes/catalog/theme.php @@ -17,29 +17,22 @@ $boards = explode(' ', $settings['boards']); } - if (!$config['use_read_php']) { - if ($action == 'all') { - foreach ($boards as $board) { - $b = new Catalog(); - $b->build($settings, $board); - } - } elseif ($action == 'post-thread' || ($settings['update_on_posts'] && $action == 'post') || ($settings['update_on_posts'] && $action == 'post-delete') && (in_array($board, $boards) | $settings['all'])) { + if ($action == 'all') { + foreach ($boards as $board) { $b = new Catalog(); $b->build($settings, $board); } - } - if ($action == 'read_php') { + } elseif ($action == 'post-thread' || ($settings['update_on_posts'] && $action == 'post') || ($settings['update_on_posts'] && $action == 'post-delete') && (in_array($board, $boards) | $settings['all'])) { $b = new Catalog(); - return $b->build($settings, $board, true); + $b->build($settings, $board); } } // Wrap functions in a class so they don't interfere with normal Tinyboard operations class Catalog { - public function build($settings, $board_name, $return = false) { + public function build($settings, $board_name) { global $config, $board; - if (!($config['cache']['enabled'] && $catalog_out = cache::get("catalog_{$board['uri']}"))) {; openBoard($board_name); $recent_images = array(); @@ -97,7 +90,7 @@ $config['additional_javascript'][] = $s; } - $catalog_out = Element('themes/catalog/catalog.html', Array( + file_write($config['dir']['home'] . $board_name . '/catalog.html', Element('themes/catalog/catalog.html', Array( 'settings' => $settings, 'config' => $config, 'boardlist' => createBoardlist(), @@ -106,15 +99,6 @@ 'stats' => $stats, 'board' => $board_name, 'link' => $config['root'] . $board['dir'] - )); - - cache::set("catalog_{$board['uri']}", $catalog_out); - } - - if ($return) { - return $catalog_out; - } else { - file_write($config['dir']['home'] . $board_name . '/catalog.html', $catalog_out); - } + ))); } };