From 296e4fd5fa2510623a9680df4fa37ddf0bd6485a Mon Sep 17 00:00:00 2001 From: kaf Date: Wed, 1 Oct 2014 10:40:51 +0000 Subject: Added an option to hide sages --- inc/config.php | 3 +++ 1 file changed, 3 insertions(+) (limited to 'inc/config.php') diff --git a/inc/config.php b/inc/config.php index e2cc2ebd..93fc7687 100644 --- a/inc/config.php +++ b/inc/config.php @@ -529,6 +529,9 @@ // When true, users are instead presented a selectbox for email. Contains, blank, noko and sage. $config['field_email_selectbox'] = false; + // When true, the sage won't be displayed + $config['hide_sage'] = false; + // Attach country flags to posts. $config['country_flags'] = false; -- cgit v1.3 From 3c2529e157c4f51e59e107016c4c06d3026d43d6 Mon Sep 17 00:00:00 2001 From: kaf Date: Sun, 5 Oct 2014 12:03:30 +0000 Subject: [bugfix]$config['error']['genwebmerror'] wasn't set in config.php --- inc/config.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'inc/config.php') diff --git a/inc/config.php b/inc/config.php index e2cc2ebd..64ba301e 100644 --- a/inc/config.php +++ b/inc/config.php @@ -1046,10 +1046,11 @@ $config['error']['unknownext'] = _('Unknown file extension.'); $config['error']['filesize'] = _('Maximum file size: %maxsz% bytes
Your file\'s size: %filesz% bytes'); $config['error']['maxsize'] = _('The file was too big.'); - $config['error']['webmerror'] = _('There was a problem processing your webm.'); - $config['error']['invalidwebm'] = _('Invalid webm uploaded.'); - $config['error']['webmhasaudio'] = _('The uploaded webm contains an audio or another type of additional stream.'); - $config['error']['webmtoolong'] = _('The uploaded webm is longer than ' . $config['webm']['max_length'] . ' seconds.'); + $config['error']['genwebmerror'] = _('There was a problem processing your webm.'); + $config['error']['webmerror'] = _('There was a problem processing your webm.');//Is this error used anywhere ? + $config['error']['invalidwebm'] = _('Invalid webm uploaded.'); + $config['error']['webmhasaudio'] = _('The uploaded webm contains an audio or another type of additional stream.'); + $config['error']['webmtoolong'] = _('The uploaded webm is longer than ' . $config['webm']['max_length'] . ' seconds.'); $config['error']['fileexists'] = _('That file already exists!'); $config['error']['fileexistsinthread'] = _('That file already exists in this thread!'); $config['error']['delete_too_soon'] = _('You\'ll have to wait another %s before deleting that.'); -- cgit v1.3 From 8b9932218ffa0e53b05cad5bc769f9317687e6da Mon Sep 17 00:00:00 2001 From: Bui Date: Mon, 6 Oct 2014 03:37:13 +0900 Subject: add forward-confirmed reverse DNS --- inc/config.php | 5 ++++- inc/functions.php | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'inc/config.php') diff --git a/inc/config.php b/inc/config.php index 1a75cad0..bd5c5db3 100644 --- a/inc/config.php +++ b/inc/config.php @@ -66,7 +66,10 @@ // Use `host` via shell_exec() to lookup hostnames, avoiding query timeouts. May not work on your system. // Requires safe_mode to be disabled. $config['dns_system'] = false; - + + // Check validity of the reverse DNS of IP addresses. Highly recommended. + $config['fcrdns'] = true; + // When executing most command-line tools (such as `convert` for ImageMagick image processing), add this // to the environment path (seperated by :). $config['shell_path'] = '/usr/local/bin'; diff --git a/inc/functions.php b/inc/functions.php index 357666d6..8c5f46b9 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -2265,6 +2265,7 @@ function rDNS($ip_addr) { if (!$config['dns_system']) { $host = gethostbyaddr($ip_addr); + $isip = filter_var($host, FILTER_VALIDATE_IP); } else { $resp = shell_exec_error('host -W 1 ' . $ip_addr); if (preg_match('/domain name pointer ([^\s]+)$/', $resp, $m)) @@ -2273,6 +2274,10 @@ function rDNS($ip_addr) { $host = $ip_addr; } + if ($config['fcrdns'] && !$isip && gethostbyname($host) != $ip_addr) { + $host = $ip_addr; + } + if ($config['cache']['enabled']) cache::set('rdns_' . $ip_addr, $host); -- cgit v1.3 From daad519b85463ce21600af22adae8207517f35c5 Mon Sep 17 00:00:00 2001 From: czaks Date: Fri, 24 Oct 2014 13:24:33 +0200 Subject: config[php_md5] feature --- inc/config.php | 3 +++ post.php | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'inc/config.php') diff --git a/inc/config.php b/inc/config.php index bd5c5db3..016b7f77 100644 --- a/inc/config.php +++ b/inc/config.php @@ -780,6 +780,9 @@ // Set this to true if you're using a BSD $config['bsd_md5'] = false; + // Set this to true if you're having problems with image duplicated error and bsd_md5 doesn't help. + $config['php_md5'] = false; + // Number of posts in a "View Last X Posts" page $config['noko50_count'] = 50; // Number of posts a thread needs before it gets a "View Last X Posts" page. diff --git a/post.php b/post.php index 223ddd45..21929bfa 100644 --- a/post.php +++ b/post.php @@ -568,7 +568,7 @@ if (isset($_POST['delete'])) { $md5cmd = $config['bsd_md5'] ? 'md5 -r' : 'md5sum'; - if ($output = shell_exec_error("cat $filenames | $md5cmd")) { + if (!$config['php_md5'] && $output = shell_exec_error("cat $filenames | $md5cmd")) { $explodedvar = explode(' ', $output); $hash = $explodedvar[0]; $post['filehash'] = $hash; -- cgit v1.3 From aa0d606651a6dc0de4a9b430d89825245a65b15e Mon Sep 17 00:00:00 2001 From: yeltsew7 Date: Sun, 15 Feb 2015 21:23:26 -0500 Subject: Add in E Z board locking --- inc/config.php | 3 +++ 1 file changed, 3 insertions(+) (limited to 'inc/config.php') diff --git a/inc/config.php b/inc/config.php index 016b7f77..edbe7b2a 100644 --- a/inc/config.php +++ b/inc/config.php @@ -286,6 +286,9 @@ // Public and private key pair from https://www.google.com/recaptcha/admin/create $config['recaptcha_public'] = '6LcXTcUSAAAAAKBxyFWIt2SO8jwx4W7wcSMRoN3f'; $config['recaptcha_private'] = '6LcXTcUSAAAAAOGVbVdhmEM1_SyRF4xTKe8jbzf_'; + + // Ability to lock a board for normal users and still allow mods to post. Could also be useful for making an archive board + $config['board_locked'] = false; /* * Custom filters detect certain posts and reject/ban accordingly. They are made up of a condition and an -- cgit v1.3 From bdb6001f3f7e93e0b9655c0491bbef6f1df8a5fa Mon Sep 17 00:00:00 2001 From: czaks Date: Tue, 10 Mar 2015 12:48:59 +0100 Subject: support for slugified links; may introduce a few bugs --- inc/config.php | 7 +- inc/display.php | 4 +- inc/functions.php | 92 +++++++++++++++++++++++-- inc/lib/Twig/Extensions/Extension/Tinyboard.php | 3 +- inc/mod/pages.php | 18 ++--- install.php | 6 +- mod.php | 5 ++ post.php | 19 +++-- templates/main.js | 1 + templates/mod/debug/recent_posts.html | 2 +- templates/mod/search_results.html | 4 +- templates/post_reply.html | 4 +- templates/post_thread.html | 10 +-- templates/posts.sql | 1 + templates/themes/catalog/theme.php | 2 +- templates/themes/recent/theme.php | 4 +- templates/themes/sitemap/sitemap.xml | 4 +- templates/themes/sitemap/theme.php | 2 +- 18 files changed, 145 insertions(+), 43 deletions(-) (limited to 'inc/config.php') diff --git a/inc/config.php b/inc/config.php index edbe7b2a..ac4acaa4 100644 --- a/inc/config.php +++ b/inc/config.php @@ -566,6 +566,9 @@ // Allow dice rolling: an email field of the form "dice XdY+/-Z" will result in X Y-sided dice rolled and summed, // with the modifier Z added, with the result displayed at the top of the post body. $config['allow_roll'] = false; + + // Use semantic URLs for threads, like /b/res/12345/daily-programming-thread.html + $config['slugify'] = false; /* * ==================== @@ -1118,8 +1121,10 @@ // Location of files. $config['file_index'] = 'index.html'; - $config['file_page'] = '%d.html'; + $config['file_page'] = '%d.html'; // NB: page is both an index page and a thread $config['file_page50'] = '%d+50.html'; + $config['file_page_slug'] = '%d-%s.html'; + $config['file_page50_slug'] = '%d-%s+50.html'; $config['file_mod'] = 'mod.php'; $config['file_post'] = 'post.php'; $config['file_script'] = 'main.js'; diff --git a/inc/display.php b/inc/display.php index 1a78e19b..65525ab9 100644 --- a/inc/display.php +++ b/inc/display.php @@ -383,7 +383,7 @@ class Post { public function link($pre = '', $page = false) { global $config, $board; - return $this->root . $board['dir'] . $config['dir']['res'] . sprintf(($page ? $page : $config['file_page']), $this->thread) . '#' . $pre . $this->id; + return $this->root . $board['dir'] . $config['dir']['res'] . link_for((array)$this, $page == '50') . '#' . $pre . $this->id; } public function build($index=false) { @@ -438,7 +438,7 @@ class Thread { public function link($pre = '', $page = false) { global $config, $board; - return $this->root . $board['dir'] . $config['dir']['res'] . sprintf(($page ? $page : $config['file_page']), $this->id) . '#' . $pre . $this->id; + return $this->root . $board['dir'] . $config['dir']['res'] . link_for((array)$this, $page == '50') . '#' . $pre . $this->id; } public function add(Post $post) { $this->posts[] = $post; diff --git a/inc/functions.php b/inc/functions.php index 25362a62..79d06f5c 100755 --- a/inc/functions.php +++ b/inc/functions.php @@ -150,7 +150,9 @@ function loadConfig() { preg_quote($config['dir']['res'], '/') . '(' . str_replace('%d', '\d+', preg_quote($config['file_page'], '/')) . '|' . - str_replace('%d', '\d+', preg_quote($config['file_page50'], '/')) . + str_replace('%d', '\d+', preg_quote($config['file_page50'], '/')) . '|' . + str_replace(array('%d', '%s'), array('\d+', '[a-z0-9-]+'), preg_quote($config['file_page_slug'], '/')) . '|' . + str_replace(array('%d', '%s'), array('\d+', '[a-z0-9-]+'), preg_quote($config['file_page50_slug'], '/')) . ')' . '|' . preg_quote($config['file_mod'], '/') . '\?\/.+' . @@ -912,7 +914,7 @@ function insertFloodPost(array $post) { function post(array $post) { global $pdo, $board; - $query = prepare(sprintf("INSERT INTO ``posts_%s`` VALUES ( NULL, :thread, :subject, :email, :name, :trip, :capcode, :body, :body_nomarkup, :time, :time, :files, :num_files, :filehash, :password, :ip, :sticky, :locked, 0, :embed)", $board['uri'])); + $query = prepare(sprintf("INSERT INTO ``posts_%s`` VALUES ( NULL, :thread, :subject, :email, :name, :trip, :capcode, :body, :body_nomarkup, :time, :time, :files, :num_files, :filehash, :password, :ip, :sticky, :locked, 0, :embed, :slug)", $board['uri'])); // Basic stuff if (!empty($post['subject'])) { @@ -981,6 +983,10 @@ function post(array $post) { $query->bindValue(':filehash', null, PDO::PARAM_NULL); } + if ($post['op']) { + $query->bindValue(':slug', slugify($post)); + } + if (!$query->execute()) { undoImage($post); error(db_error($query)); @@ -1094,8 +1100,8 @@ function deletePost($id, $error_if_doesnt_exist=true, $rebuild_after=true) { if (!$post['thread']) { // Delete thread HTML page - file_unlink($board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $post['id'])); - file_unlink($board['dir'] . $config['dir']['res'] . sprintf($config['file_page50'], $post['id'])); + file_unlink($board['dir'] . $config['dir']['res'] . link_for($post) ); + file_unlink($board['dir'] . $config['dir']['res'] . link_for($post, true) ); // noko50 file_unlink($board['dir'] . $config['dir']['res'] . sprintf('%d.json', $post['id'])); $antispam_query = prepare('DELETE FROM ``antispam`` WHERE `board` = :board AND `thread` = :thread'); @@ -2067,12 +2073,12 @@ function buildThread($id, $return = false, $mod = false) { if ($return) { return $body; } else { - $noko50fn = $board['dir'] . $config['dir']['res'] . sprintf($config['file_page50'], $id); + $noko50fn = $board['dir'] . $config['dir']['res'] . link_for($thread, true); if ($hasnoko50 || file_exists($noko50fn)) { buildThread50($id, $return, $mod, $thread, $antibot); } - file_write($board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $id), $body); + file_write($board['dir'] . $config['dir']['res'] . link_for($thread), $body); } } @@ -2152,7 +2158,7 @@ function buildThread50($id, $return = false, $mod = false, $thread = null, $anti if ($return) { return $body; } else { - file_write($board['dir'] . $config['dir']['res'] . sprintf($config['file_page50'], $id), $body); + file_write($board['dir'] . $config['dir']['res'] . link_for($thread, true), $body); } } @@ -2421,3 +2427,75 @@ function diceRoller($post) { } } } + +function slugify($post) { + $slug = ""; + + if (isset($post['thread']) && $post['thread']) + $slug = $post['thread']; + elseif (isset ($post['body_nomarkup']) && $post['body_nomarkup']) + $slug = $post['body_nomarkup']; + elseif (isset ($post['body']) && $post['body']) + $slug = strip_html($post['body']); + + // Fix UTF-8 first + $slug = mb_convert_encoding($slug, "UTF-8", "UTF-8"); + + // Transliterate local characters like ü, I wonder how would it work for weird alphabets :^) + $slug = iconv("UTF-8", "ASCII//TRANSLIT//IGNORE", $slug); + + // Downcase everything + $slug = strtolower($slug); + + // Strip bad characters, alphanumerics should suffice + $slug = preg_replace('/[^a-zA-Z0-9]/', '-', $slug); + + // Replace multiple dashes with single ones + $slug = preg_replace('/-+/', '-', $slug); + + // Strip dashes at the beginning and at the end + $slug = preg_replace('/^-|-$/', '', $slug); + + // Slug should be 200 characters long, at max + $slug = substr($slug, 0, 200); + + // Slug is now ready + return $slug; +} + +function link_for($post, $page50 = false, $foreignlink = false, $thread = false) { + global $config, $board; + + $post = (array)$post; + + // Where do we need to look for OP? + $b = $foreignlink ? $foreignlink : $board; + + $id = (isset($post['thread']) && $post['thread']) ? $post['thread'] : $post['id']; + + $slug = false; + + if ($config['slugify'] && isset($post['thread']) && $post['thread']) { + if (!$thread) { + // Oh fuck, we'd better optimize it ASAP + + $query = prepare(sprintf("SELECT `slug` FROM ``posts_%s`` WHERE `id` = :id", $board['uri'])); + $query->bindValue(':id', $id, PDO::PARAM_INT); + $query->execute() or error(db_error($query)); + + $thread = $query->fetch(PDO::FETCH_ASSOC); + } + $slug = $thread['slug']; + } + elseif ($config['slugify']) { + $slug = $post['slug']; + } + + + if ( $page50 && $slug) $tpl = $config['file_page50_slug']; + else if (!$page50 && $slug) $tpl = $config['file_page_slug']; + else if ( $page50 && !$slug) $tpl = $config['file_page50']; + else if (!$page50 && !$slug) $tpl = $config['file_page']; + + return sprintf($tpl, $id, $slug); +} diff --git a/inc/lib/Twig/Extensions/Extension/Tinyboard.php b/inc/lib/Twig/Extensions/Extension/Tinyboard.php index 81276147..028db438 100644 --- a/inc/lib/Twig/Extensions/Extension/Tinyboard.php +++ b/inc/lib/Twig/Extensions/Extension/Tinyboard.php @@ -45,7 +45,8 @@ class Twig_Extensions_Extension_Tinyboard extends Twig_Extension new Twig_SimpleFunction('hiddenInputsHash', 'hiddenInputsHash'), new Twig_SimpleFunction('ratio', 'twig_ratio_function'), new Twig_SimpleFunction('secure_link_confirm', 'twig_secure_link_confirm'), - new Twig_SimpleFunction('secure_link', 'twig_secure_link') + new Twig_SimpleFunction('secure_link', 'twig_secure_link'), + new Twig_SimpleFunction('link_for', 'link_for') ); } diff --git a/inc/mod/pages.php b/inc/mod/pages.php index c7722763..79d1bf51 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -1161,7 +1161,7 @@ function mod_move_reply($originBoard, $postID) { $post = $query->fetch(PDO::FETCH_ASSOC); // redirect - header('Location: ?/' . sprintf($config['board_path'], $board['uri']) . $config['dir']['res'] . sprintf($config['file_page'], $post['thread'] ? $post['thread'] : $newID) . '#' . $newID, true, $config['redirect_http']); + header('Location: ?/' . sprintf($config['board_path'], $board['uri']) . $config['dir']['res'] . link_for($post) . '#' . $newID, true, $config['redirect_http']); } else { @@ -1322,6 +1322,8 @@ function mod_move($originBoard, $postID) { // trigger themes rebuildThemes('post', $targetBoard); + $newboard = $board; + // return to original board openBoard($originBoard); @@ -1332,7 +1334,7 @@ function mod_move($originBoard, $postID) { $query->execute() or error(db_error($query)); // leave a reply, linking to the new thread - $post = array( + $spost = array( 'mod' => true, 'subject' => '', 'email' => '', @@ -1346,23 +1348,23 @@ function mod_move($originBoard, $postID) { 'op' => false ); - $post['body'] = $post['body_nomarkup'] = sprintf($config['mod']['shadow_mesage'], '>>>/' . $targetBoard . '/' . $newID); + $spost['body'] = $spost['body_nomarkup'] = sprintf($config['mod']['shadow_mesage'], '>>>/' . $targetBoard . '/' . $newID); - markup($post['body']); + markup($spost['body']); - $botID = post($post); + $botID = post($spost); buildThread($postID); buildIndex(); - header('Location: ?/' . sprintf($config['board_path'], $originBoard) . $config['dir']['res'] .sprintf($config['file_page'], $postID) . + header('Location: ?/' . sprintf($config['board_path'], $originBoard) . $config['dir']['res'] . link_for($post, false, $newboard) . '#' . $botID, true, $config['redirect_http']); } else { deletePost($postID); buildIndex(); openBoard($targetBoard); - header('Location: ?/' . sprintf($config['board_path'], $board['uri']) . $config['dir']['res'] . sprintf($config['file_page'], $newID), true, $config['redirect_http']); + header('Location: ?/' . sprintf($config['board_path'], $board['uri']) . $config['dir']['res'] . link_for($post, false, $newboard), true, $config['redirect_http']); } } @@ -1494,7 +1496,7 @@ function mod_edit_post($board, $edit_raw_html, $postID) { rebuildThemes('post', $board); - header('Location: ?/' . sprintf($config['board_path'], $board) . $config['dir']['res'] . sprintf($config['file_page'], $post['thread'] ? $post['thread'] : $postID) . '#' . $postID, true, $config['redirect_http']); + header('Location: ?/' . sprintf($config['board_path'], $board) . $config['dir']['res'] . link_for($post) . '#' . $postID, true, $config['redirect_http']); } else { if ($config['minify_html']) { $post['body_nomarkup'] = str_replace("\n", ' ', utf8tohtml($post['body_nomarkup'])); diff --git a/install.php b/install.php index 2e050eee..95caf8ec 100644 --- a/install.php +++ b/install.php @@ -1,7 +1,7 @@ vichan upgrade path. query("CREATE TABLE IF NOT EXISTS ``search_queries`` ( `ip` varchar(39) NOT NULL, `time` int(11) NOT NULL, `query` text NOT NULL) ENGINE=MyISAM DEFAULT CHARSET=utf8;") or error(db_error()); diff --git a/mod.php b/mod.php index 384eec88..e06d5db6 100644 --- a/mod.php +++ b/mod.php @@ -105,6 +105,11 @@ $pages = array( str_replace('%d', '(\d+)', preg_quote($config['file_page50'], '!')) => 'view_thread50', '/(\%b)/' . preg_quote($config['dir']['res'], '!') . str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) => 'view_thread', + + '/(\%b)/' . preg_quote($config['dir']['res'], '!') . + str_replace(array('%d','%s'), array('(\d+)', '[a-z0-9-]+'), preg_quote($config['file_page50_slug'], '!')) => 'view_thread50', + '/(\%b)/' . preg_quote($config['dir']['res'], '!') . + str_replace(array('%d','%s'), array('(\d+)', '[a-z0-9-]+'), preg_quote($config['file_page_slug'], '!')) => 'view_thread', ); diff --git a/post.php b/post.php index d33c8150..93592590 100644 --- a/post.php +++ b/post.php @@ -85,7 +85,7 @@ if (isset($_POST['delete'])) { } _syslog(LOG_INFO, 'Deleted post: ' . - '/' . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $post['thread'] ? $post['thread'] : $id) . ($post['thread'] ? '#' . $id : '') + '/' . $board['dir'] . $config['dir']['res'] . link_for($post) . ($post['thread'] ? '#' . $id : '') ); } } @@ -142,7 +142,7 @@ if (isset($_POST['delete'])) { if ($config['syslog']) _syslog(LOG_INFO, 'Reported post: ' . - '/' . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $thread ? $thread : $id) . ($thread ? '#' . $id : '') . + '/' . $board['dir'] . $config['dir']['res'] . link_for($post) . ($thread ? '#' . $id : '') . ' for "' . $reason . '"' ); $query = prepare("INSERT INTO ``reports`` VALUES (NULL, :time, :ip, :board, :post, :reason)"); @@ -250,7 +250,7 @@ if (isset($_POST['delete'])) { //Check if thread exists if (!$post['op']) { - $query = prepare(sprintf("SELECT `sticky`,`locked`,`sage` FROM ``posts_%s`` WHERE `id` = :id AND `thread` IS NULL LIMIT 1", $board['uri'])); + $query = prepare(sprintf("SELECT `sticky`,`locked`,`sage`,`slug` FROM ``posts_%s`` WHERE `id` = :id AND `thread` IS NULL LIMIT 1", $board['uri'])); $query->bindValue(':id', $post['thread'], PDO::PARAM_INT); $query->execute() or error(db_error()); @@ -259,6 +259,9 @@ if (isset($_POST['delete'])) { error($config['error']['nonexistant']); } } + else { + $thread = false; + } // Check for an embed field @@ -782,6 +785,7 @@ if (isset($_POST['delete'])) { $post = (object)$post; $post->files = array_map(function($a) { return (object)$a; }, $post->files); + $error = event('post', $post); $post->files = array_map(function($a) { return (array)$a; }, $post->files); @@ -845,19 +849,20 @@ if (isset($_POST['delete'])) { if ($noko) { $redirect = $root . $board['dir'] . $config['dir']['res'] . - sprintf($config['file_page'], $post['op'] ? $id:$post['thread']) . (!$post['op'] ? '#' . $id : ''); + link_for($post, false, false, $thread) . (!$post['op'] ? '#' . $id : ''); if (!$post['op'] && isset($_SERVER['HTTP_REFERER'])) { $regex = array( 'board' => str_replace('%s', '(\w{1,8})', preg_quote($config['board_path'], '/')), 'page' => str_replace('%d', '(\d+)', preg_quote($config['file_page'], '/')), - 'page50' => str_replace('%d', '(\d+)', preg_quote($config['file_page50'], '/')), + 'page50' => '(' . str_replace('%d', '(\d+)', preg_quote($config['file_page50'], '/')) . '|' . + str_replace(array('%d', '%s'), array('(\d+)', '[a-z0-9-]+'), preg_quote($config['file_page50_slug'], '/')) . ')', 'res' => preg_quote($config['dir']['res'], '/'), ); if (preg_match('/\/' . $regex['board'] . $regex['res'] . $regex['page50'] . '([?&].*)?$/', $_SERVER['HTTP_REFERER'])) { $redirect = $root . $board['dir'] . $config['dir']['res'] . - sprintf($config['file_page50'], $post['op'] ? $id:$post['thread']) . (!$post['op'] ? '#' . $id : ''); + link_for($post, true, false, $thread) . (!$post['op'] ? '#' . $id : ''); } } } else { @@ -867,7 +872,7 @@ if (isset($_POST['delete'])) { if ($config['syslog']) _syslog(LOG_INFO, 'New post: /' . $board['dir'] . $config['dir']['res'] . - sprintf($config['file_page'], $post['op'] ? $id : $post['thread']) . (!$post['op'] ? '#' . $id : '')); + link_for($post) . (!$post['op'] ? '#' . $id : '')); if (!$post['mod']) header('X-Associated-Content: "' . $redirect . '"'); diff --git a/templates/main.js b/templates/main.js index ead852fe..e948fd82 100644 --- a/templates/main.js +++ b/templates/main.js @@ -146,6 +146,7 @@ function changeStyle(styleName, link) { {% endraw %} {% if config.stylesheets_board %} {# This is such an unacceptable mess. There needs to be an easier way. #} + {# Needs fix for slugify #} var matches = document.URL.match(/\/(\w+)\/($|{{ config.dir.res|replace({'/': '\\/'}) }}{{ config.file_page|replace({'%d': '\\d+', '.': '\\.'}) }}|{{ config.file_index|replace({'.': '\\.'}) }}|{{ config.file_page|replace({'%d': '\\d+', '.': '\\.'}) }})/); {% raw %} if (matches) { diff --git a/templates/mod/debug/recent_posts.html b/templates/mod/debug/recent_posts.html index e4eb4f3a..ce4cffc4 100644 --- a/templates/mod/debug/recent_posts.html +++ b/templates/mod/debug/recent_posts.html @@ -63,7 +63,7 @@ {% else %} {% set thread = post.id %} {% endif %} - + {{ post.id }} diff --git a/templates/mod/search_results.html b/templates/mod/search_results.html index 0d3c2a10..186ee5db 100644 --- a/templates/mod/search_results.html +++ b/templates/mod/search_results.html @@ -195,7 +195,7 @@ {% else %} {% set thread = post.id %} {% endif %} - + {{ post.id }} @@ -265,4 +265,4 @@ [{{ i + 1 }}] {% endfor %}

-{% endif %} \ No newline at end of file +{% endif %} diff --git a/templates/post_reply.html b/templates/post_reply.html index e7343230..451ff1b9 100644 --- a/templates/post_reply.html +++ b/templates/post_reply.html @@ -12,8 +12,8 @@ {% include 'post/time.html' %} {% include 'post/poster_id.html' %}  - No. - {{ post.id }} + No. + {{ post.id }}

{% include 'post/fileinfo.html' %} {% include 'post/post_controls.html' %} diff --git a/templates/post_thread.html b/templates/post_thread.html index 08b4c4c1..61146491 100644 --- a/templates/post_thread.html +++ b/templates/post_thread.html @@ -15,8 +15,8 @@ {% include 'post/time.html' %} {% include 'post/poster_id.html' %}  - No. - {{ post.id }} + No. + {{ post.id }} {% if post.sticky %} {% if config.font_awesome %} @@ -39,14 +39,14 @@ {% endif %} {% endif %} {% if index %} - [{% trans %}Reply{% endtrans %}] + [{% trans %}Reply{% endtrans %}] {% endif %} {% if isnoko50 %} - [{% trans %}View All{% endtrans %}] + [{% trans %}View All{% endtrans %}] {% endif %} {% if hasnoko50 and not isnoko50 %} {% set lastcount = config.noko50_count %} - [{% trans %}Last 1 Post{% plural lastcount %}Last {{ count }} Posts{% endtrans %}] + [{% trans %}Last 1 Post{% plural lastcount %}Last {{ count }} Posts{% endtrans %}] {% endif %} {% include 'post/post_controls.html' %}

diff --git a/templates/posts.sql b/templates/posts.sql index 9a47c6ad..6b2249ef 100644 --- a/templates/posts.sql +++ b/templates/posts.sql @@ -19,6 +19,7 @@ CREATE TABLE IF NOT EXISTS ``posts_{{ board }}`` ( `locked` int(1) NOT NULL, `sage` int(1) NOT NULL, `embed` text, + `slug` varchar(256) DEFAULT NULL, UNIQUE KEY `id` (`id`), KEY `thread_id` (`thread`,`id`), KEY `filehash` (`filehash`(40)), diff --git a/templates/themes/catalog/theme.php b/templates/themes/catalog/theme.php index 9ba2d27a..b3b7caf7 100644 --- a/templates/themes/catalog/theme.php +++ b/templates/themes/catalog/theme.php @@ -42,7 +42,7 @@ $board_name, $board_name, $board_name, $board_name, $board_name)) or error(db_error()); while ($post = $query->fetch(PDO::FETCH_ASSOC)) { - $post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], ($post['thread'] ? $post['thread'] : $post['id'])); + $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)) { diff --git a/templates/themes/recent/theme.php b/templates/themes/recent/theme.php index b1153477..2ea6a7b9 100644 --- a/templates/themes/recent/theme.php +++ b/templates/themes/recent/theme.php @@ -62,7 +62,7 @@ // board settings won't be available in the template file, so generate links now $post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] - . sprintf($config['file_page'], ($post['thread'] ? $post['thread'] : $post['id'])) . '#' . $post['id']; + . link_for($post) . '#' . $post['id']; if ($files) { if ($files[0]->thumb == 'spoiler') { @@ -92,7 +92,7 @@ while ($post = $query->fetch(PDO::FETCH_ASSOC)) { openBoard($post['board']); - $post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], ($post['thread'] ? $post['thread'] : $post['id'])) . '#' . $post['id']; + $post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . link_for($post) . '#' . $post['id']; if ($post['body'] != "") $post['snippet'] = pm_snippet($post['body'], 30); else diff --git a/templates/themes/sitemap/sitemap.xml b/templates/themes/sitemap/sitemap.xml index 733da607..95dfdd26 100644 --- a/templates/themes/sitemap/sitemap.xml +++ b/templates/themes/sitemap/sitemap.xml @@ -9,11 +9,11 @@ {% for board, thread_list in threads %} {% for thread in thread_list %} - {{ settings.url ~ (config.board_path | format(board)) ~ config.dir.res ~ (config.file_page | format(thread.thread_id)) }} + {{ settings.url ~ (config.board_path | format(board)) ~ config.dir.res ~ link_for(thread) }} {{ thread.lastmod | date('%Y-%m-%dT%H:%M:%S') }}{{ timezone() }} {{ settings.changefreq }} {% endfor %} {% endfor %} -{% endfilter %} \ No newline at end of file +{% endfilter %} diff --git a/templates/themes/sitemap/theme.php b/templates/themes/sitemap/theme.php index 3e048dd5..1cebcdb6 100644 --- a/templates/themes/sitemap/theme.php +++ b/templates/themes/sitemap/theme.php @@ -26,7 +26,7 @@ $threads = array(); foreach ($boards as $board) { - $query = query(sprintf("SELECT `id` AS `thread_id`, (SELECT `time` FROM ``posts_%s`` WHERE `thread` = `thread_id` OR `id` = `thread_id` ORDER BY `time` DESC LIMIT 1) AS `lastmod` FROM ``posts_%s`` WHERE `thread` IS NULL", $board, $board)) or error(db_error()); + $query = query(sprintf("SELECT `id`, `slug`, (SELECT `time` FROM ``posts_%s`` WHERE `thread` = `thread_id` OR `id` = `thread_id` ORDER BY `time` DESC LIMIT 1) AS `lastmod` FROM ``posts_%s`` WHERE `thread` IS NULL", $board, $board)) or error(db_error()); $threads[$board] = $query->fetchAll(PDO::FETCH_ASSOC); } -- cgit v1.3 From 10a82199656aa5a9f5b81afda1a2f3512f46efe2 Mon Sep 17 00:00:00 2001 From: Marcin Łabanowski Date: Thu, 12 Mar 2015 00:00:59 +0100 Subject: enable a `basic` cache by default; notify me if it breaks your chan --- inc/config.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'inc/config.php') diff --git a/inc/config.php b/inc/config.php index ac4acaa4..42e1c32b 100644 --- a/inc/config.php +++ b/inc/config.php @@ -115,7 +115,7 @@ * http://tinyboard.org/docs/index.php?p=Config/Cache */ - $config['cache']['enabled'] = false; + $config['cache']['enabled'] = 'php'; // $config['cache']['enabled'] = 'xcache'; // $config['cache']['enabled'] = 'apc'; // $config['cache']['enabled'] = 'memcached'; @@ -570,6 +570,9 @@ // Use semantic URLs for threads, like /b/res/12345/daily-programming-thread.html $config['slugify'] = false; + // Max size for slugs + $config['slug_max_size'] = 80; + /* * ==================== * Ban settings -- cgit v1.3 From 10f93d0d4367ade293c7a8733989cedcd7ca791a Mon Sep 17 00:00:00 2001 From: czaks Date: Tue, 24 Mar 2015 05:19:25 +0100 Subject: implement a protection against transparent proxies --- inc/config.php | 6 ++++++ inc/functions.php | 34 ++++++++++++++++++++++------------ post.php | 7 ++++++- 3 files changed, 34 insertions(+), 13 deletions(-) (limited to 'inc/config.php') diff --git a/inc/config.php b/inc/config.php index 42e1c32b..0ba1952b 100644 --- a/inc/config.php +++ b/inc/config.php @@ -290,6 +290,12 @@ // Ability to lock a board for normal users and still allow mods to post. Could also be useful for making an archive board $config['board_locked'] = false; + // If poster's proxy supplies X-Forwarded-For header, check if poster's real IP is banned. + $config['proxy_check'] = false; + + // If poster's proxy supplies X-Forwarded-For header, save it for further inspection and/or filtering. + $config['proxy_save'] = false; + /* * Custom filters detect certain posts and reject/ban accordingly. They are made up of a condition and an * action (for when ALL conditions are met). As every single post has to be put through each filter, diff --git a/inc/functions.php b/inc/functions.php index ca918e0a..0f70d447 100755 --- a/inc/functions.php +++ b/inc/functions.php @@ -810,12 +810,29 @@ function checkBan($board = false) { if (event('check-ban', $board)) return true; - $bans = Bans::find($_SERVER['REMOTE_ADDR'], $board, $config['show_modname']); + $ips = array(); + + $ips[] = $_SERVER['REMOTE_ADDR']; + + if ($config['proxy_check'] && isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { + $ips = array_merge($ips, explode(", ", $_SERVER['HTTP_X_FORWARDED_FOR'])); + } + + foreach ($ips as $ip) { + $bans = Bans::find($_SERVER['REMOTE_ADDR'], $board, $config['show_modname']); - foreach ($bans as &$ban) { - if ($ban['expires'] && $ban['expires'] < time()) { - Bans::delete($ban['id']); - if ($config['require_ban_view'] && !$ban['seen']) { + foreach ($bans as &$ban) { + if ($ban['expires'] && $ban['expires'] < time()) { + Bans::delete($ban['id']); + if ($config['require_ban_view'] && !$ban['seen']) { + if (!isset($_POST['json_response'])) { + displayBan($ban); + } else { + header('Content-Type: text/json'); + die(json_encode(array('error' => true, 'banned' => true))); + } + } + } else { if (!isset($_POST['json_response'])) { displayBan($ban); } else { @@ -823,13 +840,6 @@ function checkBan($board = false) { die(json_encode(array('error' => true, 'banned' => true))); } } - } else { - if (!isset($_POST['json_response'])) { - displayBan($ban); - } else { - header('Content-Type: text/json'); - die(json_encode(array('error' => true, 'banned' => true))); - } } } diff --git a/post.php b/post.php index 87795aa0..100c3efb 100644 --- a/post.php +++ b/post.php @@ -516,7 +516,7 @@ if (isset($_POST['delete'])) { "\n".geoip\geoip_country_name_by_addr_v6($gi, ipv4to6($_SERVER['REMOTE_ADDR'])).""; } } - + if ($config['user_flag'] && isset($_POST['user_flag'])) if (!empty($_POST['user_flag']) ){ @@ -530,6 +530,11 @@ if (isset($_POST['delete'])) { $post['body'] .= "\n" . strtolower($user_flag) . "" . "\n" . $flag_alt . ""; } + + if ($config['proxy_save'] && isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { + $proxy = preg_replace("/[^0-9a-fA-F.,: ]/", '', $_SERVER['HTTP_X_FORWARDED_FOR']); + $post['body'] .= "\n".$proxy.""; + } if (mysql_version() >= 50503) { $post['body_nomarkup'] = $post['body']; // Assume we're using the utf8mb4 charset -- cgit v1.3 From e4e01e45733488a756f457f0681dc90b28f6fa1b Mon Sep 17 00:00:00 2001 From: czaks Date: Wed, 1 Apr 2015 17:16:30 +0200 Subject: smart build: define configuration variables --- inc/config.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'inc/config.php') diff --git a/inc/config.php b/inc/config.php index 0ba1952b..be1bb8e1 100644 --- a/inc/config.php +++ b/inc/config.php @@ -1181,9 +1181,20 @@ // Website favicon. // $config['url_favicon'] = '/favicon.gif'; - // EXPERIMENTAL: Try not to build pages when we shouldn't have to. + // Try not to build pages when we shouldn't have to. $config['try_smarter'] = true; + // EXPERIMENTAL: Defer static HTML building to a moment, when a given file is actually accessed. + // Warning: This option won't run out of the box. You need to tell your webserver, that a file + // for serving 403 and 404 pages is /smart_build.php. Also, you need to turn off indexes. + $config['smart_build'] = false; + + // Smart build related: when a file doesn't exist, where should we redirect? + $config['page_404'] = '/404.html'; + + // Smart build related: extra entrypoints. + $config['smart_build_entrypoints'] = array(); + /* * ==================== * Mod settings -- cgit v1.3 From dc2928a14dcd29bf8502b6a9dc1357ad0e624251 Mon Sep 17 00:00:00 2001 From: czaks Date: Sun, 5 Apr 2015 18:48:53 +0200 Subject: cache_config preliminary release --- inc/config.php | 5 ++++ inc/functions.php | 71 +++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 61 insertions(+), 15 deletions(-) (limited to 'inc/config.php') diff --git a/inc/config.php b/inc/config.php index be1bb8e1..3a63054c 100644 --- a/inc/config.php +++ b/inc/config.php @@ -137,6 +137,11 @@ // Tinyboard to use. $config['cache']['redis'] = array('localhost', 6379, '', 1); + // EXPERIMENTAL: Should we cache configs? Warning: this changes board behaviour, i'd say, a lot. + // If you have any lambdas/includes present in your config, you should move them to instance-functions.php + // (this file will be explicitly loaded during cache hit, but not during cache miss). + $config['cache_config'] = false; + /* * ==================== * Cookie settings diff --git a/inc/functions.php b/inc/functions.php index fc22e6ce..7b4dde7e 100755 --- a/inc/functions.php +++ b/inc/functions.php @@ -50,15 +50,40 @@ $current_locale = 'en'; function loadConfig() { - global $board, $config, $__ip, $debug, $__version, $microtime_start, $current_locale; + global $board, $config, $__ip, $debug, $__version, $microtime_start, $current_locale, $events; $error = function_exists('error') ? 'error' : 'basic_error_function_because_the_other_isnt_loaded_yet'; - reset_events(); + $boardsuffix = isset($board['uri']) ? $board['uri'] : ''; if (!isset($_SERVER['REMOTE_ADDR'])) $_SERVER['REMOTE_ADDR'] = '0.0.0.0'; + if (file_exists('tmp/cache/cache_config.php')) { + require_once('tmp/cache/cache_config.php'); + } + + + if (isset($config['cache_config']) && + $config['cache_config'] && + $config = Cache::get('config_' . $boardsuffix ) ) { + $events = Cache::get('events_' . $boardsuffix ); + + if (file_exists('inc/instance-functions.php')) { + require_once('inc/instance-functions.php'); + } + + if ($config['locale'] != $current_locale) { + $current_locale = $config['locale']; + init_locale($config['locale'], $error); + } + } + else { + $config = array(); + // We will indent that later. + + reset_events(); + $arrays = array( 'db', 'api', @@ -86,7 +111,6 @@ function loadConfig() { 'dashboard_links' ); - $config = array(); foreach ($arrays as $key) { $config[$key] = array(); } @@ -99,7 +123,7 @@ function loadConfig() { // Those calls are expensive. Unfortunately, our cache system is not initialized at this point. // So, we may store the locale in a tmp/ filesystem. - if (file_exists($fn = 'tmp/cache/locale_' . ( isset($board['uri']) ? $board['uri'] : '' ) ) ) { + if (file_exists($fn = 'tmp/cache/locale_' . $boardsuffix ) ) { $config['locale'] = file_get_contents($fn); } else { @@ -138,8 +162,6 @@ function loadConfig() { init_locale($config['locale'], $error); } - date_default_timezone_set($config['timezone']); - if (!isset($config['global_message'])) $config['global_message'] = false; @@ -219,8 +241,22 @@ function loadConfig() { if (!isset($config['user_flags'])) $config['user_flags'] = array(); + if (!isset($__version)) + $__version = file_exists('.installed') ? trim(file_get_contents('.installed')) : false; + $config['version'] = $__version; + + if ($config['allow_roll']) + event_handler('post', 'diceRoller'); + + if (is_array($config['anonymous'])) + $config['anonymous'] = $config['anonymous'][array_rand($config['anonymous'])]; + + + } // Effectful config processing below: + date_default_timezone_set($config['timezone']); + if ($config['root_file']) { chdir($config['root_file']); } @@ -233,10 +269,6 @@ function loadConfig() { if (preg_match('/^\:\:(ffff\:)?(\d+\.\d+\.\d+\.\d+)$/', $__ip, $m)) $_SERVER['REMOTE_ADDR'] = $m[2]; - if (!isset($__version)) - $__version = file_exists('.installed') ? trim(file_get_contents('.installed')) : false; - $config['version'] = $__version; - if ($config['verbose_errors']) { set_error_handler('verbose_error_handler'); error_reporting(E_ALL); @@ -260,13 +292,22 @@ function loadConfig() { event_handler('post', 'postHandler'); } - if (is_array($config['anonymous'])) - $config['anonymous'] = $config['anonymous'][array_rand($config['anonymous'])]; + event('load-config'); - if ($config['allow_roll']) - event_handler('post', 'diceRoller'); + if ($config['cache_config'] && !isset ($config['cache_config_loaded'])) { + file_put_contents('tmp/cache/cache_config.php', ' Date: Sun, 12 Apr 2015 00:32:58 +0200 Subject: [code] tag support --- inc/config.php | 11 ++++------- inc/functions.php | 27 ++++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 10 deletions(-) (limited to 'inc/config.php') diff --git a/inc/config.php b/inc/config.php index 3a63054c..b7c60125 100644 --- a/inc/config.php +++ b/inc/config.php @@ -624,13 +624,10 @@ $config['markup'][] = array("/\*\*(.+?)\*\*/", "\$1"); $config['markup'][] = array("/^[ |\t]*==(.+?)==[ |\t]*$/m", "\$1"); - // Highlight PHP code wrapped in tags (PHP 5.3+) - // $config['markup'][] = array( - // '/^<code>(.+)<\/code>/ms', - // function($matches) { - // return highlight_string(html_entity_decode($matches[1]), true); - // } - // ); + // Code markup. This should be set to a regular expression, using tags you want to use. Examples: + // "/\[code\](.*?)[\/code]/is" + // "/```([a-z0-9-]{0,20})\n(.*?)\n?```/s" + $config['markup_code'] = false; // Repair markup with HTML Tidy. This may be slower, but it solves nesting mistakes. Tinyboad, at the // time of writing this, can not prevent out-of-order markup tags (eg. "**''test**'') without help from diff --git a/inc/functions.php b/inc/functions.php index a6c85a19..5a52d602 100755 --- a/inc/functions.php +++ b/inc/functions.php @@ -1857,6 +1857,15 @@ function markup(&$body, $track_cites = false) { if (mysql_version() < 50503) $body = mb_encode_numericentity($body, array(0x010000, 0xffffff, 0, 0xffffff), 'UTF-8'); + if ($config['markup_code']) { + $code_markup = array(); + $body = preg_replace_callback($config['markup_code'], function($matches) use (&$code_markup) { + $d = count($code_markup); + $code_markup[] = $matches; + return ""; + }, $body); + } + foreach ($config['markup'] as $markup) { if (is_string($markup[1])) { $body = preg_replace($markup[0], $markup[1], $body); @@ -2054,7 +2063,19 @@ function markup(&$body, $track_cites = false) { $body = preg_replace('/\s+$/', '', $body); $body = preg_replace("/\n/", '
', $body); - + + // Fix code markup + if ($config['markup_code']) { + foreach ($code_markup as $id => $val) { + $code = isset($val[2]) ? $val[2] : $val[1]; + $code_lang = isset($val[2]) ? $val[1] : ""; + + $code = "
".str_replace(array("\n","\t"), array("
","	"), htmlspecialchars($code))."
"; + + $body = str_replace("", $code, $body); + } + } + if ($config['markup_repair_tidy']) { $tidy = new tidy(); $body = str_replace("\t", ' ', $body); @@ -2072,10 +2093,10 @@ function markup(&$body, $track_cites = false) { ), 'utf8'); $body = str_replace("\n", '', $body); } - + // replace tabs with 8 spaces $body = str_replace("\t", ' ', $body); - + return $tracked_cites; } -- cgit v1.3 From 1b16e97f67853e37641dee3ca1e7d9022a786f2b Mon Sep 17 00:00:00 2001 From: czaks Date: Sun, 12 Apr 2015 03:08:40 +0200 Subject: [code] fix regexps --- inc/config.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'inc/config.php') diff --git a/inc/config.php b/inc/config.php index b7c60125..f11ee5f1 100644 --- a/inc/config.php +++ b/inc/config.php @@ -625,8 +625,8 @@ $config['markup'][] = array("/^[ |\t]*==(.+?)==[ |\t]*$/m", "\$1"); // Code markup. This should be set to a regular expression, using tags you want to use. Examples: - // "/\[code\](.*?)[\/code]/is" - // "/```([a-z0-9-]{0,20})\n(.*?)\n?```/s" + // "/\[code\](.*?)\[\/code\]/is" + // "/```([a-z0-9-]{0,20})\n(.*?)\n?```\n?/s" $config['markup_code'] = false; // Repair markup with HTML Tidy. This may be slower, but it solves nesting mistakes. Tinyboad, at the -- cgit v1.3 From 4014682882d0b390dc099d05e6701521e5f64a31 Mon Sep 17 00:00:00 2001 From: Marcin Łabanowski Date: Wed, 22 Apr 2015 05:54:48 +0200 Subject: fileboard support --- inc/config.php | 15 ++++++++++++- inc/display.php | 3 ++- inc/functions.php | 4 ++++ post.php | 17 +++++++++++++-- stylesheets/burichan.css | 2 +- stylesheets/caffe.css | 2 +- stylesheets/confraria.css | 8 +++---- stylesheets/dark.css | 10 ++++----- stylesheets/dark_roach.css | 24 ++++++++++----------- stylesheets/favela.css | 4 ++-- stylesheets/ferus.css | 10 ++++----- stylesheets/futaba+vichan.css | 4 ++-- stylesheets/futaba-light.css | 4 ++-- stylesheets/futaba.css | 4 ++-- stylesheets/gentoochan.css | 4 ++-- stylesheets/jungle.css | 4 ++-- stylesheets/luna.css | 22 +++++++++---------- stylesheets/miku.css | 8 +++---- stylesheets/nigrachan.css | 8 +++---- stylesheets/notsuba.css | 8 +++---- stylesheets/novo_jungle.css | 6 +++--- stylesheets/piwnichan.css | 4 ++-- stylesheets/ricechan.css | 2 +- stylesheets/style.css | 37 +++++++++++++++++++------------ stylesheets/szalet.css | 4 ++-- stylesheets/terminal2.css | 10 ++++----- stylesheets/testorange.css | 2 +- stylesheets/v8ch.css | 2 +- stylesheets/wasabi.css | 18 ++++++++-------- stylesheets/yotsuba.css | 4 ++-- templates/fileboard.html | 15 +++++++++++++ templates/post_form.html | 12 +++++++++++ templates/post_thread_fileboard.html | 42 ++++++++++++++++++++++++++++++++++++ 33 files changed, 216 insertions(+), 107 deletions(-) create mode 100644 templates/fileboard.html create mode 100644 templates/post_thread_fileboard.html (limited to 'inc/config.php') diff --git a/inc/config.php b/inc/config.php index f11ee5f1..32308bd4 100644 --- a/inc/config.php +++ b/inc/config.php @@ -282,7 +282,8 @@ 'file_url', 'json_response', 'user_flag', - 'no_country' + 'no_country', + 'tag' ); // Enable reCaptcha to make spam even harder. Rarely necessary. @@ -735,6 +736,11 @@ $config['allowed_ext'][] = 'png'; // $config['allowed_ext'][] = 'svg'; + // Allowed extensions for OP. Inherits from the above setting if set to false. Otherwise, it overrides both allowed_ext and + // allowed_ext_files (filetypes for downloadable files should be set in allowed_ext_files as well). This setting is useful + // for creating fileboards. + $config['allowed_ext_op'] = false; + // Allowed additional file extensions (not images; downloadable files). // $config['allowed_ext_files'][] = 'txt'; // $config['allowed_ext_files'][] = 'zip'; @@ -1518,6 +1524,13 @@ // Allow OP to remove arbitrary posts in his thread $config['user_moderation'] = false; + // File board. Like 4chan /f/ + $config['file_board'] = false; + + // Thread tags. Set to false to disable + // Example: array('A' => 'Chinese cartoons', 'M' => 'Music', 'P' => 'Pornography'); + $config['allowed_tags'] = false; + /* * ==================== * Public post search diff --git a/inc/display.php b/inc/display.php index 65525ab9..e7fb9320 100644 --- a/inc/display.php +++ b/inc/display.php @@ -453,7 +453,8 @@ class Thread { event('show-thread', $this); - $built = Element('post_thread.html', array('config' => $config, 'board' => $board, 'post' => &$this, 'index' => $index, 'hasnoko50' => $hasnoko50, 'isnoko50' => $isnoko50, 'mod' => $this->mod)); + $file = ($index && $config['file_board']) ? 'post_thread_fileboard.html' : 'post_thread.html'; + $built = Element($file, array('config' => $config, 'board' => $board, 'post' => &$this, 'index' => $index, 'hasnoko50' => $hasnoko50, 'isnoko50' => $isnoko50, 'mod' => $this->mod)); return $built; } diff --git a/inc/functions.php b/inc/functions.php index 5a52d602..aa91133f 100755 --- a/inc/functions.php +++ b/inc/functions.php @@ -1358,6 +1358,10 @@ function index($page, $mod=false) { $body .= $thread->build(true); } + if ($config['file_board']) { + $body = Element('fileboard.html', array('body' => $body, 'mod' => $mod)); + } + return array( 'board' => $board, 'body' => $body, diff --git a/post.php b/post.php index 2b903b1c..5081845f 100644 --- a/post.php +++ b/post.php @@ -312,7 +312,12 @@ if (isset($_POST['delete'])) { $url_without_params = $post['file_url']; $post['extension'] = strtolower(mb_substr($url_without_params, mb_strrpos($url_without_params, '.') + 1)); - if (!in_array($post['extension'], $config['allowed_ext']) && !in_array($post['extension'], $config['allowed_ext_files'])) + + if ($post['op'] && $config['allowed_ext_op']) { + if (!in_array($post['extension'], $config['allowed_ext_op'])) + error($config['error']['unknownext']); + } + else if (!in_array($post['extension'], $config['allowed_ext']) && !in_array($post['extension'], $config['allowed_ext_files'])) error($config['error']['unknownext']); $post['file_tmp'] = tempnam($config['tmp'], 'url'); @@ -536,6 +541,10 @@ if (isset($_POST['delete'])) { "\n" . $flag_alt . ""; } + if ($config['allowed_tags'] && $_POST['op'] && isset($_POST['tag']) && isset($config['allowed_tags'][$_POST['tag']])) { + $post['body'] .= "\n" . $_POST['tag'] . ""; + } + if ($config['proxy_save'] && isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $proxy = preg_replace("/[^0-9a-fA-F.,: ]/", '', $_SERVER['HTTP_X_FORWARDED_FOR']); $post['body'] .= "\n".$proxy.""; @@ -565,7 +574,11 @@ if (isset($_POST['delete'])) { if ($post['has_file']) { $fnarray = array(); foreach ($post['files'] as $key => &$file) { - if (!in_array($file['extension'], $config['allowed_ext']) && !in_array($file['extension'], $config['allowed_ext_files'])) + if ($post['op'] && $config['allowed_ext_op']) { + if (!in_array($file['extension'], $config['allowed_ext_op'])) + error($config['error']['unknownext']); + } + elseif (!in_array($file['extension'], $config['allowed_ext']) && !in_array($file['extension'], $config['allowed_ext_files'])) error($config['error']['unknownext']); $file['is_an_image'] = !in_array($file['extension'], $config['allowed_ext_files']); diff --git a/stylesheets/burichan.css b/stylesheets/burichan.css index f1bbd8e6..6b1de235 100644 --- a/stylesheets/burichan.css +++ b/stylesheets/burichan.css @@ -36,7 +36,7 @@ div.banner { font-weight: normal; } -p.intro span.name { +.intro span.name { font-family: serif; font-size: 12px; } diff --git a/stylesheets/caffe.css b/stylesheets/caffe.css index aee4d5ab..7ba7bd1c 100644 --- a/stylesheets/caffe.css +++ b/stylesheets/caffe.css @@ -353,7 +353,7 @@ width: 100%; #attention_bar:hover { background-color: rgba(88, 53, 41, 0.3); } -p.intro a.email span.name { +.intro a.email span.name { color: #8e6152; } a.post_no:hover { diff --git a/stylesheets/confraria.css b/stylesheets/confraria.css index 8769c6bb..3b60aaa6 100644 --- a/stylesheets/confraria.css +++ b/stylesheets/confraria.css @@ -55,11 +55,11 @@ form table tr th { padding: 0px 5px; } -p.intro span.name { +.intro span.name { color: #C5C8C6; } -p.intro span.subject { +.intro span.subject { color: #CC1105; font-weight: bold; } @@ -90,11 +90,11 @@ div.post.reply.highlighted { background: #4A4C4F; } -p.intro a.email span.name { +.intro a.email span.name { color: rgb(129, 162, 190); } -p.intro a.email:hover span.name { +.intro a.email:hover span.name { color: rgb(95, 137, 172); } diff --git a/stylesheets/dark.css b/stylesheets/dark.css index beb12364..e21b264e 100644 --- a/stylesheets/dark.css +++ b/stylesheets/dark.css @@ -23,7 +23,7 @@ div.title, h1 { div.title p { font-size: 10px; } -a:link, a:visited, p.intro a.email span.name { +a:link, a:visited, .intro a.email span.name { color: #CCCCCC; text-decoration: none; font-family: sans-serif; @@ -61,21 +61,21 @@ div.post.reply div.body a:link, div.post.reply div.body a:visited { div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover { color: #32DD72; } -p.intro span.subject { +.intro span.subject { font-size: 12px; font-family: sans-serif; color: #446655; font-weight: 800; } -p.intro span.name { +.intro span.name { color: #32DD72; font-weight: 800; } -p.intro a.capcode, p.intro a.nametag { +.intro a.capcode, p.intro a.nametag { color: magenta; margin-left: 0; } -p.intro a.email, p.intro a.email span.name, p.intro a.email:hover, p.intro a.email:hover span.name { +.intro a.email, p.intro a.email span.name, p.intro a.email:hover, p.intro a.email:hover span.name { color: #32ddaf; } input[type="text"], textarea, select { diff --git a/stylesheets/dark_roach.css b/stylesheets/dark_roach.css index 7d123c6d..89e050d4 100644 --- a/stylesheets/dark_roach.css +++ b/stylesheets/dark_roach.css @@ -20,7 +20,7 @@ a, a:visited { text-decoration: none; color: #9999CC; } -a:hover, p.intro a.post_no:hover { +a:hover, .intro a.post_no:hover { color: #996699 } a.post_no { @@ -28,19 +28,19 @@ a.post_no { margin: 0; padding: 0; } -p.intro a.post_no { +.intro a.post_no { color: inherit; } -p.intro a.post_no, p.intro a.email { +.intro a.post_no, p.intro a.email { margin: 0; } -p.intro a.email span.name { +.intro a.email span.name { color: #666699; } -p.intro a.email:hover span.name { +.intro a.email:hover span.name { color: #663366; } -p.intro label { +.intro label { display: inline; } h2 { @@ -163,7 +163,7 @@ div.post.op { div.post.op hr { border-color: #000000; } -p.intro { +.intro { margin: 0.5em 0; padding: 0; padding-bottom: 0.2em; @@ -172,19 +172,19 @@ input.delete { float: left; margin: 1px 6px 0 0; } -p.intro span.subject { +.intro span.subject { color: #336699; font-weight: bold; } -p.intro span.name { +.intro span.name { color: #336600; font-weight: bold; } -p.intro span.capcode, p.intro a.capcode, p.intro a.nametag { +.intro span.capcode, p.intro a.capcode, p.intro a.nametag { color: #CC0000; margin-left: 0; } -p.intro a { +.intro a { margin-left: 8px; } div.delete { @@ -456,7 +456,7 @@ table.mod.config-editor input[type="text"] { background-color: #333333; opacity: 0.8; } -p.intro.thread-hidden { +.intro.thread-hidden { margin: 0px; padding: 0px; } diff --git a/stylesheets/favela.css b/stylesheets/favela.css index 6c9f6d58..52d24c76 100644 --- a/stylesheets/favela.css +++ b/stylesheets/favela.css @@ -46,7 +46,7 @@ form table tr th { color: #FFF; } -p.intro span.name { +.intro span.name { font-family: serif; } @@ -81,7 +81,7 @@ div[id^="thread_"].highlighted { background: #B5FFDD; } -p.intro a.email span.name { +.intro a.email span.name { color: #345456; } diff --git a/stylesheets/ferus.css b/stylesheets/ferus.css index f84d86ca..2517d3b0 100644 --- a/stylesheets/ferus.css +++ b/stylesheets/ferus.css @@ -16,7 +16,7 @@ div.title, h1 { div.title p { font-size: 13px; } -a:link, a:visited, p.intro a.email span.name { +a:link, a:visited, .intro a.email span.name { color: #16C816; text-decoration: underline; font-family: monospace; @@ -51,21 +51,21 @@ div.post.reply div.body a:link, div.post.reply div.body a:visited { div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover { color: #00FF00; } -p.intro span.subject { +.intro span.subject { font-size: 12px; font-family: monospace; color: #446655; font-weight: 800; } -p.intro span.name { +.intro span.name { color: #008200; font-weight: 900; } -p.intro a.capcode, p.intro a.nametag { +.intro a.capcode, p.intro a.nametag { color: magenta; margin-left: 0; } -p.intro a.email, p.intro a.email span.name, p.intro a.email:hover, p.intro a.email:hover span.name { +.intro a.email, p.intro a.email span.name, p.intro a.email:hover, p.intro a.email:hover span.name { color: #00CC64; font-family: monospace; } diff --git a/stylesheets/futaba+vichan.css b/stylesheets/futaba+vichan.css index f00dc9b7..16dff61b 100644 --- a/stylesheets/futaba+vichan.css +++ b/stylesheets/futaba+vichan.css @@ -15,7 +15,7 @@ div.title p { div.pages { font-size: 13px !important; } -a:link, a:visited, p.intro a.email span.name { +a:link, a:visited, .intro a.email span.name { color: #0000ff; font-size: inherit; text-decoration: inherit; @@ -41,7 +41,7 @@ div.post.reply.highlighted { div.post.reply div.body a { color: navy; } -p.intro span.subject { +.intro span.subject { color: #d00; } form table tr th { diff --git a/stylesheets/futaba-light.css b/stylesheets/futaba-light.css index fc67709f..19166adf 100644 --- a/stylesheets/futaba-light.css +++ b/stylesheets/futaba-light.css @@ -15,7 +15,7 @@ div.title p { div.pages { font-size: 13px !important; } -a:link, a:visited, p.intro a.email span.name { +a:link, a:visited, .intro a.email span.name { color: #A32615; font-size: inherit; text-decoration: inherit; @@ -42,7 +42,7 @@ div.post.reply.highlighted { div.post.reply div.body a { color: rgb(190, 79, 43); } -p.intro span.subject { +.intro span.subject { color: #AA4848; } form table tr th { diff --git a/stylesheets/futaba.css b/stylesheets/futaba.css index 02c38351..2b4fc1d2 100644 --- a/stylesheets/futaba.css +++ b/stylesheets/futaba.css @@ -10,7 +10,7 @@ div.title h1 { div.title p { font-size: 10px; } -a:link, a:visited, p.intro a.email span.name { +a:link, a:visited, .intro a.email span.name { color: #0000ff; } a:link:hover { @@ -30,7 +30,7 @@ div.post.reply.highlighted { div.post.reply div.body a { color: navy; } -p.intro span.subject { +.intro span.subject { color: #d00; } form table tr th { diff --git a/stylesheets/gentoochan.css b/stylesheets/gentoochan.css index b5075136..ae7ef2f3 100644 --- a/stylesheets/gentoochan.css +++ b/stylesheets/gentoochan.css @@ -2,7 +2,7 @@ body { background: #0E0E0E url(data:image/gif;base64,R0lGODlhGAAMAKEEAOXl5ebm5vDw8PHx8SH+EUNyZWF0ZWQgd2l0aCBHSU1QACwAAAAAGAAMAAACRpQiY6cLa146MyY1EJQKjG81lNGRUPOIkgMJHtquBgIO7xwvpbrpduUSuXq8ntEC0bBEylYitdDAdM1ViaobkgKgZwyDLAAAOw==) repeat 0 0!important; color: #000; } -a:link, a:visited, p.intro a.email span.name { +a:link, a:visited, .intro a.email span.name { -webkit-transition: all ease-in 0.3s; -moz-transition: all ease-in 0.3s; color: rgba(0, 0, 0, 0.6); @@ -33,7 +33,7 @@ div.post.reply.highlighted { div.post.reply p.body a { color: navy; } -p.intro span.subject { +.intro span.subject { color: #000; } form table tr th { diff --git a/stylesheets/jungle.css b/stylesheets/jungle.css index 1765b3a9..86cb13b8 100644 --- a/stylesheets/jungle.css +++ b/stylesheets/jungle.css @@ -66,7 +66,7 @@ box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.35); div.post.reply div.body a { color: #00E; } -p.intro span.subject { +.intro span.subject { color: #d00; } form table tr th { @@ -118,7 +118,7 @@ table.modlog tr th { background: #EA8; } -p.intro span.name { +.intro span.name { color: maroon; font-weight: 600; } diff --git a/stylesheets/luna.css b/stylesheets/luna.css index 7439f5ca..e2fd6528 100644 --- a/stylesheets/luna.css +++ b/stylesheets/luna.css @@ -22,7 +22,7 @@ a, a:selected { text-decoration: bold; color: #ffffff; } -a:hover, p.intro a.post_no:hover { +a:hover, .intro a.post_no:hover { color: #ffffff; } a.post_no { @@ -30,19 +30,19 @@ a.post_no { margin: 0; padding: 0; } -p.intro a.post_no { +.intro a.post_no { color: inherit; } -p.intro a.post_no, p.intro a.email { +.intro a.post_no, p.intro a.email { margin: 0; } -p.intro a.email span.name { +.intro a.email span.name { color: #0091ff; } -p.intro a.email:hover span.name { +.intro a.email:hover span.name { color: #ffffff; } -p.intro label { +.intro label { display: inline; } h2 { @@ -165,7 +165,7 @@ div.post.op { div.post.op hr { border-color: #040934; } -p.intro { +.intro { margin: 0.5em 0; padding: 0; padding-bottom: 0.2em; @@ -174,19 +174,19 @@ input.delete { float: left; margin: 1px 6px 0 0; } -p.intro span.subject { +.intro span.subject { color: #CCCCEE; font-weight: bold; } -p.intro span.name { +.intro span.name { color: #BBBBDD; font-weight: bold; } -p.intro span.capcode, p.intro a.capcode, p.intro a.nametag { +.intro span.capcode, p.intro a.capcode, p.intro a.nametag { color: #CCCCEE; margin-left: 0; } -p.intro a { +.intro a { margin-left: 8px; } div.delete { diff --git a/stylesheets/miku.css b/stylesheets/miku.css index 84e67933..7a8fb87e 100644 --- a/stylesheets/miku.css +++ b/stylesheets/miku.css @@ -19,11 +19,11 @@ a.post_no { color: #000033; } -p.intro a.email span.name { +.intro a.email span.name { color: #0093AB; } -p.intro a.email:hover span.name { +.intro a.email:hover span.name { color: #DD0000; } @@ -43,12 +43,12 @@ div.post.op hr { border-color: #B7C9D5; } -p.intro span.subject { +.intro span.subject { color: #117743; font-weight: 800; } -p.intro span.name { +.intro span.name { color: #117743; font-weight: 800; } diff --git a/stylesheets/nigrachan.css b/stylesheets/nigrachan.css index 6d0a94fa..28ab3eb3 100644 --- a/stylesheets/nigrachan.css +++ b/stylesheets/nigrachan.css @@ -52,7 +52,7 @@ input[type="text"], input[type="password"], textarea, input[type="submit"], inpu border: 1px solid #202020; } -p.intro span.name { +.intro span.name { font-size: 11pt; color: #505050; font-weight: bold; @@ -88,16 +88,16 @@ div.post.reply.highlighted { background: #111111; } -p.intro a.email span.name { +.intro a.email span.name { color: #FFFFFF; } -p.intro a.email:hover span.name { +.intro a.email:hover span.name { color: #A0A0A0; text-decoration: underline; } -p.intro span.subject { +.intro span.subject { color: #606060; } diff --git a/stylesheets/notsuba.css b/stylesheets/notsuba.css index ef9e1057..8ecb6b21 100644 --- a/stylesheets/notsuba.css +++ b/stylesheets/notsuba.css @@ -20,11 +20,11 @@ a.post_no { color: #000033; } -p.intro a.email span.name { +.intro a.email span.name { color: #608673; } -p.intro a.email:hover span.name { +.intro a.email:hover span.name { color: #DD0000; } @@ -44,12 +44,12 @@ div.post.op hr { border-color: #608673; } -p.intro span.subject { +.intro span.subject { color: #8a2e2e; font-weight: 800; } -p.intro span.name { +.intro span.name { color: #117743; font-weight: 800; } diff --git a/stylesheets/novo_jungle.css b/stylesheets/novo_jungle.css index 70501d0a..8c313723 100644 --- a/stylesheets/novo_jungle.css +++ b/stylesheets/novo_jungle.css @@ -65,7 +65,7 @@ form[name="postcontrols"] { margin: 20px auto; } -p.intro span.name { +.intro span.name { color: #800000; font-weight: 800; } @@ -104,11 +104,11 @@ div.post.reply.highlighted { background-image: url('img/jungle_td_dark.png');; } -p.intro a.email span.name { +.intro a.email span.name { color: #0000EE; } -p.intro a.email:hover span.name { +.intro a.email:hover span.name { color: #00990B; } diff --git a/stylesheets/piwnichan.css b/stylesheets/piwnichan.css index 2c1ea49a..7780226e 100644 --- a/stylesheets/piwnichan.css +++ b/stylesheets/piwnichan.css @@ -41,7 +41,7 @@ a.email span.name { color: #5A8C99 !important; } -p.intro span.capcode, p.intro a.capcode, p.intro a.nametag { +.intro span.capcode, p.intro a.capcode, p.intro a.nametag { color: #6E0877; } @@ -157,7 +157,7 @@ div.banner, .replymode, .catalogmode { font-weight:800; } -p.intro span.subject { +.intro span.subject { color: #4D2C80; font-weight: bold; } diff --git a/stylesheets/ricechan.css b/stylesheets/ricechan.css index 79b6d145..f01fc9bf 100644 --- a/stylesheets/ricechan.css +++ b/stylesheets/ricechan.css @@ -190,7 +190,7 @@ blockquote { .de-refmap { color: #4C505E !important; } -p.intro a.email span.name { +.intro a.email span.name { text-decoration: underline; } .quote { diff --git a/stylesheets/style.css b/stylesheets/style.css index 80b124f8..5ae23cd6 100644 --- a/stylesheets/style.css +++ b/stylesheets/style.css @@ -13,7 +13,7 @@ a,a:visited { color: #34345C; } -a:hover,p.intro a.post_no:hover { +a:hover,.intro a.post_no:hover { color: #ff0000; } @@ -23,27 +23,27 @@ a.post_no { padding: 0; } -p.intro a.post_no { +.intro a.post_no { color: inherit; } -p.intro a.post_no,p.intro a.email,p.intro a.post_anchor { +.intro a.post_no,p.intro a.email,p.intro a.post_anchor { margin: 0; } -p.intro a.email span.name { +.intro a.email span.name { color: #34345C; } -p.intro a.email:hover span.name { +.intro a.email:hover span.name { color: #ff0000; } -p.intro label { +.intro label { display: inline; } -p.intro time,p.intro a.ip-link,p.intro a.capcode { +.intro time,p.intro a.ip-link,p.intro a.capcode { direction: ltr; unicode-bidi: embed; } @@ -219,7 +219,7 @@ div.post.op hr { border-color: #D9BFB7; } -p.intro { +.intro { margin: 0.5em 0; padding: 0; padding-bottom: 0.2em; @@ -230,22 +230,22 @@ input.delete { margin: 1px 6px 0 0; } -p.intro span.subject { +.intro span.subject { color: #0F0C5D; font-weight: bold; } -p.intro span.name { +.intro span.name { color: #117743; font-weight: bold; } -p.intro span.capcode,p.intro a.capcode,p.intro a.nametag { +.intro span.capcode,p.intro a.capcode,p.intro a.nametag { color: #F00000; margin-left: 0; } -p.intro a { +.intro a { margin-left: 8px; } @@ -604,7 +604,7 @@ table.mod.config-editor input[type="text"] { background-color: rgba(100%,100%,100%,0.2); } -p.intro.thread-hidden { +.intro.thread-hidden { margin: 0; padding: 0; } @@ -931,7 +931,7 @@ span.pln { @media screen and (min-width: 768px) { - p.intro { + .intro { clear: none; } @@ -1051,3 +1051,12 @@ span.pln { margin-left: 10px; margin-right: 10px; } + +/* Fileboard */ +table.fileboard th, table.fileboard td { + padding: 2px; + text-align: center; +} +table.fileboard .intro a { + margin-left: 0px; +} diff --git a/stylesheets/szalet.css b/stylesheets/szalet.css index e4deb8ee..77a216a6 100644 --- a/stylesheets/szalet.css +++ b/stylesheets/szalet.css @@ -20,7 +20,7 @@ background-repeat: repeat; background-color: #200000; } -p.intro span.capcode, p.intro a.capcode, p.intro a.nametag { +.intro span.capcode, p.intro a.capcode, p.intro a.nametag { color: #26899C; } @@ -154,7 +154,7 @@ div.banner, .replymode, .catalogmode { font-weight:800; } -p.intro span.subject { +.intro span.subject { color: #771018; font-weight: bold; } diff --git a/stylesheets/terminal2.css b/stylesheets/terminal2.css index f7463553..a951bc16 100644 --- a/stylesheets/terminal2.css +++ b/stylesheets/terminal2.css @@ -16,7 +16,7 @@ div.title, h1 { div.title p { font-size: 10px; } -a:link, a:visited, p.intro a.email span.name { +a:link, a:visited, .intro a.email span.name { color: #00FF00; text-decoration: underline; font-family: sans-serif; @@ -50,21 +50,21 @@ div.post.reply div.body a:link, div.post.reply div.body a:visited { div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover { color: #00FF00; } -p.intro span.subject { +.intro span.subject { font-size: 12px; font-family: sans-serif; color: #446655; font-weight: 800; } -p.intro span.name { +.intro span.name { color: #00FF00; font-weight: 800; } -p.intro a.capcode, p.intro a.nametag { +.intro a.capcode, p.intro a.nametag { color: #00FF00; margin-left: 0; } -p.intro a.email, p.intro a.email span.name, p.intro a.email:hover, p.intro a.email:hover span.name { +.intro a.email, p.intro a.email span.name, p.intro a.email:hover, p.intro a.email:hover span.name { color: #00FF00; } input[type="text"], textarea, select { diff --git a/stylesheets/testorange.css b/stylesheets/testorange.css index cd2161b6..44ebd697 100644 --- a/stylesheets/testorange.css +++ b/stylesheets/testorange.css @@ -202,7 +202,7 @@ div.boardlist.bottom { background-color: rgba(0%, 0%, 0%, 0.45); } -p.intro span.subject { +.intro span.subject { color:#ee8100; } diff --git a/stylesheets/v8ch.css b/stylesheets/v8ch.css index bd8e68ab..eafed531 100644 --- a/stylesheets/v8ch.css +++ b/stylesheets/v8ch.css @@ -136,7 +136,7 @@ form table tr th{ background: #fec !important; } -p.intro.thread-hidden{ +.intro.thread-hidden{ padding-bottom: 1em !important; } diff --git a/stylesheets/wasabi.css b/stylesheets/wasabi.css index f898d731..87a81bdd 100644 --- a/stylesheets/wasabi.css +++ b/stylesheets/wasabi.css @@ -27,16 +27,16 @@ a.post_no { margin: 0; padding: 0; } -p.intro a.post_no, p.intro a.email { +.intro a.post_no, p.intro a.email { margin: 0; } -p.intro a.email span.name { +.intro a.email span.name { color: #34345C; } -p.intro a.email:hover span.name { +.intro a.email:hover span.name { color: #ff0000; } -p.intro label { +.intro label { display: inline; } h2 { @@ -155,7 +155,7 @@ div.post.op { div.post.op hr { border-color: #D9BFB7; } -p.intro { +.intro { margin: 0.5em 0; padding: 0; padding-bottom: 0.2em; @@ -164,19 +164,19 @@ input.delete { float: left; margin: 1px 6px 0 0; } -p.intro span.subject { +.intro span.subject { color: #0F0C5D; font-weight: bold; } -p.intro span.name { +.intro span.name { color: #117743; font-weight: bold; } -p.intro a.capcode, p.intro a.nametag { +.intro a.capcode, p.intro a.nametag { color: #F00000; margin-left: 0; } -p.intro a { +.intro a { margin-left: 8px; } div.delete { diff --git a/stylesheets/yotsuba.css b/stylesheets/yotsuba.css index 8997b696..5324d1a7 100644 --- a/stylesheets/yotsuba.css +++ b/stylesheets/yotsuba.css @@ -2,7 +2,7 @@ body { background: #ffe url('img/fade-yotsuba.png') repeat-x 50% 0%; color: #800000; } -a:link, a:visited, p.intro a.email span.name { +a:link, a:visited, .intro a.email span.name { color: #0000ff; } a:link:hover { @@ -22,7 +22,7 @@ div.post.reply.highlighted { div.post.reply div.body a { color: navy; } -p.intro span.subject { +.intro span.subject { color: #d00; } form table tr th { diff --git a/templates/fileboard.html b/templates/fileboard.html new file mode 100644 index 00000000..a970cecb --- /dev/null +++ b/templates/fileboard.html @@ -0,0 +1,15 @@ + + + + {{ body }} +
  + {% trans %}No.{% endtrans %} + {% trans %}Name{% endtrans %} + {% trans %}File{% endtrans %} + {% trans %}Tag{% endtrans %} + {% trans %}Subject{% endtrans %} + {% trans %}Size{% endtrans %} + {% trans %}Date{% endtrans %} + {% trans %}Replies{% endtrans %} +   +
diff --git a/templates/post_form.html b/templates/post_form.html index d2e644b3..ea3ac765 100644 --- a/templates/post_form.html +++ b/templates/post_form.html @@ -92,6 +92,18 @@ {% endif %} + {% if config.allowed_tags and not id %} + + {% trans %}Tag{% endtrans %} + + + + + {% endif %} {% trans %}File{% endtrans %} diff --git a/templates/post_thread_fileboard.html b/templates/post_thread_fileboard.html new file mode 100644 index 00000000..983bfe17 --- /dev/null +++ b/templates/post_thread_fileboard.html @@ -0,0 +1,42 @@ +{% filter remove_whitespace %} +{# tabs and new lines will be ignored #} + +{# we are intentionally breaking the thread_ID convention: the jses need to handle this case differently #} + + + +{{ post.id }} +{% include 'post/name.html' %} + {% include 'post/flag.html' %} +[{{ post.files[0].filename|e|bidi_cleanup }}] +{% if post.modifiers['tag'] %}[{{ post.modifiers['tag'] }}]{% endif %} +{% include 'post/subject.html' %} + {% if post.sticky %} + {% if config.font_awesome %} + + {% else %} + Sticky + {% endif %} + {% endif %} + {% if post.locked %} + {% if config.font_awesome %} + + {% else %} + Locked + {% endif %} + {% endif %} + {% if post.bumplocked and (config.mod.view_bumplock < 0 or (post.mod and post.mod|hasPermission(config.mod.view_bumplock, board.uri))) %} + {% if config.font_awesome %} + + {% else %} + Bumplocked + {% endif %} + {% endif %} +{{ post.files[0].size|filesize }} +{% include 'post/time.html' %} +{{ post.omitted }} +{% include 'post/post_controls.html' %} + [{% trans %}Reply{% endtrans %}] + + +{% endfilter %} -- cgit v1.3