mirror of
https://github.com/vichan-devel/vichan.git
synced 2025-02-17 11:28:41 +01:00
- IMPORTANT: Now EXPLICITLY defines $post['time'] as PHP time() instead of relying on database NOW().
- Increased memory management in all of my recent work. - board-search.php Fetches activity from board_stats and now includes timestamp as a search option. - boards.php Correctly fetches board activity and formats numbers. - inc/functions.php Completely reworked activity fetching. - inc/functions Wrote updateStatisticsForPost() which streams new posts in statistics. - post.php Writes into updateStatisticsForPost() for streaming new posts. - Added styling for tags (in progress work). - tools/migrate_board_stats.php Now correcty defines author_ip_count. Signed-off-by: 8n-tech <8n-tech@users.noreply.github.com>
This commit is contained in:
parent
316e681bbd
commit
ecfe072a4f
@ -26,6 +26,7 @@ $search = array(
|
||||
'lang' => false,
|
||||
'nsfw' => true,
|
||||
'tags' => false,
|
||||
'time' => ( (int)( time() / 3600 ) * 3600 ) - 3600,
|
||||
'title' => false,
|
||||
);
|
||||
|
||||
@ -43,6 +44,12 @@ if (isset( $_GET['lang'] ) && $_GET['lang'] != "" && isset($languages[$search['l
|
||||
if (isset( $_GET['tags'] ) && $_GET['tags'] != "") {
|
||||
$search['tags'] = $_GET['tags'];
|
||||
}
|
||||
|
||||
// What time range?
|
||||
if (isset( $_GET['time'] ) && is_numeric( $_GET['time'] ) ) {
|
||||
$search['time'] = ( (int)( $_GET['time'] / 3600 ) * 3600 );
|
||||
}
|
||||
|
||||
// Include what in the uri / title / subtitle?
|
||||
if (isset( $_GET['title'] ) && $_GET['title'] != "") {
|
||||
$search['title'] = $_GET['title'];
|
||||
@ -80,6 +87,8 @@ foreach ($boards as $board) {
|
||||
$response['boards'][ $board['uri'] ] = $board;
|
||||
}
|
||||
|
||||
unset( $boards );
|
||||
|
||||
|
||||
/* Tag Fetching */
|
||||
// (We have do this even if we're not filtering by tags so that we know what each board's tags are)
|
||||
@ -103,16 +112,33 @@ foreach ($response['boards'] as $boardUri => &$board) {
|
||||
}
|
||||
}
|
||||
|
||||
unset( $boardTags );
|
||||
|
||||
|
||||
/* Activity Fetching */
|
||||
$boardActivity = fetchBoardActivity( array_keys( $response['boards'] ) );
|
||||
$boardActivity = fetchBoardActivity( array_keys( $response['boards'] ), $search['time'], true );
|
||||
$response['tags'] = array();
|
||||
|
||||
// Loop through each board and record activity to it.
|
||||
// We will also be weighing and building a tag list.
|
||||
foreach ($response['boards'] as $boardUri => &$board) {
|
||||
$board['active'] = (int) $boardActivity['active'][ $boardUri ];
|
||||
$board['pph'] = (int) $boardActivity['average'][ $boardUri ];
|
||||
$board['active'] = 0;
|
||||
$board['pph'] = 0;
|
||||
|
||||
if (isset($boardActivity['active'][ $boardUri ])) {
|
||||
$board['active'] = (int) $boardActivity['active'][ $boardUri ];
|
||||
}
|
||||
if (isset($boardActivity['average'][ $boardUri ])) {
|
||||
$precision = 4 - strlen( $boardActivity['average'][ $boardUri ] );
|
||||
|
||||
if( $precision < 0 ) {
|
||||
$precision = 0;
|
||||
}
|
||||
|
||||
$board['pph'] = round( $boardActivity['average'][ $boardUri ], 2 );
|
||||
|
||||
unset( $precision );
|
||||
}
|
||||
|
||||
if (isset($board['tags']) && count($board['tags']) > 0) {
|
||||
foreach ($board['tags'] as $tag) {
|
||||
@ -126,6 +152,8 @@ foreach ($response['boards'] as $boardUri => &$board) {
|
||||
}
|
||||
}
|
||||
|
||||
unset( $boardActivity );
|
||||
|
||||
// Sort boards by their popularity, then by their total posts.
|
||||
$boardActivityValues = array();
|
||||
$boardTotalPostsValues = array();
|
||||
@ -152,6 +180,9 @@ if (count($response['tags']) > 0) {
|
||||
}
|
||||
|
||||
|
||||
/* Include our interpreted search terms. */
|
||||
$response['search'] = $search;
|
||||
|
||||
/* (Please) Respond */
|
||||
if (!$Included) {
|
||||
$json = json_encode( $response );
|
||||
|
27
boards.php
27
boards.php
@ -1,9 +1,10 @@
|
||||
<?php
|
||||
|
||||
include "inc/functions.php"; // October 23, 2013
|
||||
include "inc/functions.php";
|
||||
include "inc/countries.php";
|
||||
|
||||
$admin = isset($mod["type"]) && $mod["type"]<=30;
|
||||
$admin = isset($mod["type"]) && $mod["type"]<=30;
|
||||
$founding_date = "October 23, 2013";
|
||||
|
||||
if (php_sapi_name() == 'fpm-fcgi' && !$admin) {
|
||||
error('Cannot be run directly.');
|
||||
@ -23,25 +24,16 @@ if (count($searchJson)) {
|
||||
}
|
||||
}
|
||||
|
||||
/* $query = prepare(sprintf("
|
||||
SELECT IFNULL(MAX(id),0) max,
|
||||
(SELECT COUNT(*) FROM ``posts_%s`` WHERE FROM_UNIXTIME(time) > DATE_SUB(NOW(), INTERVAL 1 HOUR)) pph,
|
||||
(SELECT COUNT(DISTINCT ip) FROM ``posts_%s`` WHERE FROM_UNIXTIME(time) > DATE_SUB(NOW(), INTERVAL 3 DAY)) uniq_ip
|
||||
FROM ``posts_%s``
|
||||
", $board['uri'], $board['uri'], $board['uri'], $board['uri'], $board['uri']));
|
||||
$query->execute() or error(db_error($query));
|
||||
$r = $query->fetch(PDO::FETCH_ASSOC); */
|
||||
|
||||
$boardQuery = prepare("SELECT COUNT(1) AS 'boards_total', COUNT(indexed) AS 'boards_public' FROM ``boards``");
|
||||
$boardQuery = prepare("SELECT COUNT(1) AS 'boards_total', SUM(indexed) AS 'boards_public', SUM(posts_total) AS 'posts_total' FROM ``boards``");
|
||||
$boardQuery->execute() or error(db_error($tagQuery));
|
||||
$boardResult = $boardQuery->fetchAll(PDO::FETCH_ASSOC)[0];
|
||||
|
||||
$boards_total = $boardResult['boards_total'];
|
||||
$boards_public = $boardResult['boards_public'];
|
||||
$boards_hidden = $boardResult['boards_total'] - $boardResult['boards_public'];
|
||||
$boards_total = number_format( $boardResult['boards_total'], 0 );
|
||||
$boards_public = number_format( $boardResult['boards_public'], 0 );
|
||||
$boards_hidden = number_format( $boardResult['boards_total'] - $boardResult['boards_public'], 0 );
|
||||
|
||||
$posts_hour = 0;
|
||||
$posts_total = 0;
|
||||
$posts_hour = number_format( fetchBoardActivity(), 0 );
|
||||
$posts_total = number_format( $boardResult['posts_total'], 0 );
|
||||
|
||||
/* Create and distribute page */
|
||||
$boardsHTML = Element("8chan/boards-table.html", array(
|
||||
@ -66,6 +58,7 @@ $searchHTML = Element("8chan/boards-search.html", array(
|
||||
"posts_hour" => $posts_hour,
|
||||
"posts_total" => $posts_total,
|
||||
|
||||
"founding_date" => $founding_date,
|
||||
"page_updated" => date('r'),
|
||||
"uptime" => shell_exec('uptime -p'),
|
||||
|
||||
|
@ -833,18 +833,65 @@ function loadBoardConfig( $uri ) {
|
||||
return $config;
|
||||
}
|
||||
|
||||
function fetchBoardActivity( $uris ) {
|
||||
function fetchBoardActivity( array $uris = array(), $forTime = false, $detailed = false ) {
|
||||
global $config;
|
||||
|
||||
$boardActivity = array();
|
||||
//$uris = "\"" . implode( (array) $uris, "\",\"" ) . "\"";
|
||||
// Set our search time for now if we didn't pass one.
|
||||
if (!is_integer($forTime)) {
|
||||
$forTime = time();
|
||||
}
|
||||
// Get the last hour for this timestamp.
|
||||
$forHour = ( (int)( $forTime / 3600 ) * 3600 ) - 3600;
|
||||
|
||||
foreach ($uris as $uri) {
|
||||
$random = 0;//rand( -1000, 1000 );
|
||||
if( $random < 0 ) $random = 0;
|
||||
$boardActivity = array(
|
||||
'active' => array(),
|
||||
'average' => array(),
|
||||
);
|
||||
|
||||
// Query for stats for these boards.
|
||||
if (count($uris)) {
|
||||
$uriSearch = "`stat_uri` IN (\"" . implode( (array) $uris, "\",\"" ) . "\") AND ";
|
||||
}
|
||||
else {
|
||||
$uriSearch = "";
|
||||
}
|
||||
|
||||
if ($detailed === true) {
|
||||
$bsQuery = prepare("SELECT `stat_uri`, `post_count`, `author_ip_array` FROM ``board_stats`` WHERE {$uriSearch} ( `stat_hour` <= :hour AND `stat_hour` >= :hoursago )");
|
||||
$bsQuery->bindValue(':hour', $forHour, PDO::PARAM_INT);
|
||||
$bsQuery->bindValue(':hoursago', $forHour - ( 3600 * 72 ), PDO::PARAM_INT);
|
||||
$bsQuery->execute() or error(db_error($bsQuery));
|
||||
$bsResult = $bsQuery->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$boardActivity['active'][ $uri ] = $random;
|
||||
$boardActivity['average'][ $uri ] = ($random * 72) / 72;
|
||||
|
||||
// Format the results.
|
||||
foreach ($bsResult as $bsRow) {
|
||||
if (!isset($boardActivity['active'][$bsRow['stat_uri']])) {
|
||||
$boardActivity['active'][$bsRow['stat_uri']] = unserialize( $bsRow['author_ip_array'] );
|
||||
$boardActivity['average'][$bsRow['stat_uri']] = $bsRow['post_count'];
|
||||
}
|
||||
else {
|
||||
$boardActivity['active'][$bsRow['stat_uri']] = array_merge( $boardActivity['active'][$bsRow['stat_uri']], unserialize( $bsRow['author_ip_array'] ) );
|
||||
$boardActivity['average'][$bsRow['stat_uri']] = $bsRow['post_count'];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($boardActivity['active'] as &$activity) {
|
||||
$activity = count( array_unique( $activity ) );
|
||||
}
|
||||
foreach ($boardActivity['average'] as &$activity) {
|
||||
$activity /= 72;
|
||||
}
|
||||
}
|
||||
// Simple return.
|
||||
else {
|
||||
$bsQuery = prepare("SELECT SUM(`post_count`) AS `post_count` FROM ``board_stats`` WHERE {$uriSearch} ( `stat_hour` <= :hour AND `stat_hour` >= :hoursago )");
|
||||
$bsQuery->bindValue(':hour', $forHour, PDO::PARAM_INT);
|
||||
$bsQuery->bindValue(':hoursago', $forHour - ( 3600 * 72 ), PDO::PARAM_INT);
|
||||
$bsQuery->execute() or error(db_error($bsQuery));
|
||||
$bsResult = $bsQuery->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$boardActivity = $bsResult[0]['post_count'];
|
||||
}
|
||||
|
||||
return $boardActivity;
|
||||
@ -854,7 +901,7 @@ function fetchBoardTags( $uris ) {
|
||||
global $config;
|
||||
|
||||
$boardTags = array();
|
||||
$uris = "\"{$config['db']['prefix']}" . implode( (array) $uris, "\",\"" ) . "\"";
|
||||
$uris = "\"" . implode( (array) $uris, "\",\"" ) . "\"";
|
||||
|
||||
$tagQuery = prepare("SELECT * FROM ``board_tags`` WHERE `uri` IN ({$uris})");
|
||||
$tagQuery->execute() or error(db_error($tagQuery));
|
||||
@ -1090,70 +1137,70 @@ 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, :cycle, 0, :embed, NULL)", $board['uri']));
|
||||
|
||||
|
||||
// Basic stuff
|
||||
if (!empty($post['subject'])) {
|
||||
$query->bindValue(':subject', $post['subject']);
|
||||
} else {
|
||||
$query->bindValue(':subject', null, PDO::PARAM_NULL);
|
||||
}
|
||||
|
||||
|
||||
if (!empty($post['email'])) {
|
||||
$query->bindValue(':email', $post['email']);
|
||||
} else {
|
||||
$query->bindValue(':email', null, PDO::PARAM_NULL);
|
||||
}
|
||||
|
||||
|
||||
if (!empty($post['trip'])) {
|
||||
$query->bindValue(':trip', $post['trip']);
|
||||
} else {
|
||||
$query->bindValue(':trip', null, PDO::PARAM_NULL);
|
||||
}
|
||||
|
||||
|
||||
$query->bindValue(':name', $post['name']);
|
||||
$query->bindValue(':body', $post['body']);
|
||||
$query->bindValue(':body_nomarkup', $post['body_nomarkup']);
|
||||
$query->bindValue(':time', isset($post['time']) ? $post['time'] : time(), PDO::PARAM_INT);
|
||||
$query->bindValue(':password', $post['password']);
|
||||
$query->bindValue(':password', $post['password']);
|
||||
$query->bindValue(':ip', isset($post['ip']) ? $post['ip'] : $_SERVER['REMOTE_ADDR']);
|
||||
|
||||
|
||||
if ($post['op'] && $post['mod'] && isset($post['sticky']) && $post['sticky']) {
|
||||
$query->bindValue(':sticky', true, PDO::PARAM_INT);
|
||||
} else {
|
||||
$query->bindValue(':sticky', false, PDO::PARAM_INT);
|
||||
}
|
||||
|
||||
|
||||
if ($post['op'] && $post['mod'] && isset($post['locked']) && $post['locked']) {
|
||||
$query->bindValue(':locked', true, PDO::PARAM_INT);
|
||||
} else {
|
||||
$query->bindValue(':locked', false, PDO::PARAM_INT);
|
||||
}
|
||||
|
||||
|
||||
if ($post['op'] && $post['mod'] && isset($post['cycle']) && $post['cycle']) {
|
||||
$query->bindValue(':cycle', true, PDO::PARAM_INT);
|
||||
} else {
|
||||
$query->bindValue(':cycle', false, PDO::PARAM_INT);
|
||||
}
|
||||
|
||||
|
||||
if ($post['mod'] && isset($post['capcode']) && $post['capcode']) {
|
||||
$query->bindValue(':capcode', $post['capcode'], PDO::PARAM_INT);
|
||||
} else {
|
||||
$query->bindValue(':capcode', null, PDO::PARAM_NULL);
|
||||
}
|
||||
|
||||
|
||||
if (!empty($post['embed'])) {
|
||||
$query->bindValue(':embed', $post['embed']);
|
||||
} else {
|
||||
$query->bindValue(':embed', null, PDO::PARAM_NULL);
|
||||
}
|
||||
|
||||
|
||||
if ($post['op']) {
|
||||
// No parent thread, image
|
||||
$query->bindValue(':thread', null, PDO::PARAM_NULL);
|
||||
} else {
|
||||
$query->bindValue(':thread', $post['thread'], PDO::PARAM_INT);
|
||||
}
|
||||
|
||||
|
||||
if ($post['has_file']) {
|
||||
$query->bindValue(':files', json_encode($post['files']));
|
||||
$query->bindValue(':num_files', $post['num_files']);
|
||||
@ -1163,12 +1210,12 @@ function post(array $post) {
|
||||
$query->bindValue(':num_files', 0);
|
||||
$query->bindValue(':filehash', null, PDO::PARAM_NULL);
|
||||
}
|
||||
|
||||
|
||||
if (!$query->execute()) {
|
||||
undoImage($post);
|
||||
error(db_error($query));
|
||||
}
|
||||
|
||||
|
||||
return $pdo->lastInsertId();
|
||||
}
|
||||
|
||||
@ -1462,6 +1509,65 @@ function index($page, $mod=false) {
|
||||
);
|
||||
}
|
||||
|
||||
// Handle statistic tracking for a new post.
|
||||
function updateStatisticsForPost( $post, $new = true ) {
|
||||
$postIp = isset($post['ip']) ? $post['ip'] : $_SERVER['REMOTE_ADDR'];
|
||||
$postUri = $post['board'];
|
||||
$postTime = (int)( $post['time'] / 3600 ) * 3600;
|
||||
|
||||
$bsQuery = prepare("SELECT * FROM ``board_stats`` WHERE `stat_uri` = :uri AND `stat_hour` = :hour");
|
||||
$bsQuery->bindValue(':uri', $postUri);
|
||||
$bsQuery->bindValue(':hour', $postTime, PDO::PARAM_INT);
|
||||
$bsQuery->execute() or error(db_error($bsQuery));
|
||||
$bsResult = $bsQuery->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// Flesh out the new stats row.
|
||||
$boardStats = array();
|
||||
|
||||
// If we already have a row, we're going to be adding this post to it.
|
||||
if (count($bsResult)) {
|
||||
$boardStats = $bsResult[0];
|
||||
$boardStats['stat_uri'] = $postUri;
|
||||
$boardStats['stat_hour'] = $postTime;
|
||||
$boardStats['post_id_array'] = unserialize( $boardStats['post_id_array'] );
|
||||
$boardStats['author_ip_array'] = unserialize( $boardStats['author_ip_array'] );
|
||||
|
||||
++$boardStats['post_count'];
|
||||
$boardStats['post_id_array'][] = (int) $post['id'];
|
||||
$boardStats['author_ip_array'][] = less_ip( $postIp );
|
||||
$boardStats['author_ip_array'] = array_unique( $boardStats['author_ip_array'] );
|
||||
}
|
||||
// If this a new row, we're building the stat to only reflect this first post.
|
||||
else {
|
||||
$boardStats['stat_uri'] = $postUri;
|
||||
$boardStats['stat_hour'] = $postTime;
|
||||
$boardStats['post_count'] = 1;
|
||||
$boardStats['post_id_array'] = array( (int) $post['id'] );
|
||||
$boardStats['author_ip_count'] = 1;
|
||||
$boardStats['author_ip_array'] = array( less_ip( $postIp ) );
|
||||
}
|
||||
|
||||
// Cleanly serialize our array for insertion.
|
||||
$boardStats['post_id_array'] = str_replace( "\"", "\\\"", serialize( $boardStats['post_id_array'] ) );
|
||||
$boardStats['author_ip_array'] = str_replace( "\"", "\\\"", serialize( $boardStats['author_ip_array'] ) );
|
||||
|
||||
|
||||
// Insert this data into our statistics table.
|
||||
$statsInsert = "VALUES(\"{$boardStats['stat_uri']}\", \"{$boardStats['stat_hour']}\", \"{$boardStats['post_count']}\", \"{$boardStats['post_id_array']}\", \"{$boardStats['author_ip_count']}\", \"{$boardStats['author_ip_array']}\" )";
|
||||
|
||||
$postStatQuery = prepare(
|
||||
"REPLACE INTO ``board_stats`` (stat_uri, stat_hour, post_count, post_id_array, author_ip_count, author_ip_array) {$statsInsert}"
|
||||
);
|
||||
$postStatQuery->execute() or error(db_error($postStatQuery));
|
||||
|
||||
// Update the posts_total tracker on the board.
|
||||
if ($new) {
|
||||
query("UPDATE ``boards`` SET `posts_total`=`posts_total`+1 WHERE `uri`=\"{$postUri}\"");
|
||||
}
|
||||
|
||||
return $boardStats;
|
||||
}
|
||||
|
||||
function getPageButtons($pages, $mod=false) {
|
||||
global $config, $board;
|
||||
|
||||
|
47
post.php
47
post.php
@ -209,11 +209,16 @@ if (isset($_POST['delete'])) {
|
||||
}
|
||||
}
|
||||
elseif (isset($_POST['post'])) {
|
||||
if (!isset($_POST['body'], $_POST['board']))
|
||||
if (!isset($_POST['body'], $_POST['board'])) {
|
||||
error($config['error']['bot']);
|
||||
|
||||
$post = array('board' => $_POST['board'], 'files' => array());
|
||||
|
||||
}
|
||||
|
||||
$post = array(
|
||||
'board' => $_POST['board'],
|
||||
'files' => array(),
|
||||
'time' => time(), // Timezone independent UNIX timecode.
|
||||
);
|
||||
|
||||
// Check if board exists
|
||||
if (!openBoard($post['board']))
|
||||
error($config['error']['noboard']);
|
||||
@ -228,7 +233,7 @@ elseif (isset($_POST['post'])) {
|
||||
$_POST['subject'] = '';
|
||||
|
||||
if (!isset($_POST['password']))
|
||||
$_POST['password'] = '';
|
||||
$_POST['password'] = '';
|
||||
|
||||
if (isset($_POST['thread'])) {
|
||||
$post['op'] = false;
|
||||
@ -708,7 +713,7 @@ elseif (isset($_POST['post'])) {
|
||||
do_filters($post);
|
||||
}
|
||||
|
||||
if ($post['has_file']) {
|
||||
if ($post['has_file']) {
|
||||
foreach ($post['files'] as $key => &$file) {
|
||||
if ($file['is_an_image'] && $config['ie_mime_type_detection'] !== false) {
|
||||
// Check IE MIME type detection XSS exploit
|
||||
@ -906,10 +911,15 @@ elseif (isset($_POST['post'])) {
|
||||
$post['files'] = $post['files'];
|
||||
$post['num_files'] = sizeof($post['files']);
|
||||
|
||||
// Commit the post to the database.
|
||||
$post['id'] = $id = post($post);
|
||||
|
||||
insertFloodPost($post);
|
||||
|
||||
|
||||
// Update statistics for this board.
|
||||
updateStatisticsForPost( $post );
|
||||
|
||||
|
||||
// Handle cyclical threads
|
||||
if (!$post['op'] && isset($thread['cycle']) && $thread['cycle']) {
|
||||
// Query is a bit weird due to "This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'" (MariaDB Ver 15.1 Distrib 10.0.17-MariaDB, for Linux (x86_64))
|
||||
@ -1005,17 +1015,20 @@ elseif (isset($_POST['post'])) {
|
||||
event('post-after', $post);
|
||||
|
||||
buildIndex();
|
||||
|
||||
// We are already done, let's continue our heavy-lifting work in the background (if we run off FastCGI)
|
||||
if (function_exists('fastcgi_finish_request'))
|
||||
@fastcgi_finish_request();
|
||||
|
||||
if ($post['op'])
|
||||
rebuildThemes('post-thread', $board['uri']);
|
||||
else
|
||||
rebuildThemes('post', $board['uri']);
|
||||
|
||||
} elseif (isset($_POST['appeal'])) {
|
||||
// We are already done, let's continue our heavy-lifting work in the background (if we run off FastCGI)
|
||||
if (function_exists('fastcgi_finish_request')) {
|
||||
@fastcgi_finish_request();
|
||||
}
|
||||
|
||||
if ($post['op']) {
|
||||
rebuildThemes('post-thread', $board['uri']);
|
||||
}
|
||||
else {
|
||||
rebuildThemes('post', $board['uri']);
|
||||
}
|
||||
}
|
||||
elseif (isset($_POST['appeal'])) {
|
||||
if (!isset($_POST['ban_id']))
|
||||
error($config['error']['bot']);
|
||||
|
||||
|
@ -1363,15 +1363,19 @@ table.board-list-table .board-title {
|
||||
}
|
||||
table.board-list-table .board-pph {
|
||||
width: 55px;
|
||||
padding: 4px;
|
||||
}
|
||||
table.board-list-table .board-max {
|
||||
width: 90px;
|
||||
padding: 4px;
|
||||
}
|
||||
table.board-list-table .board-unique {
|
||||
width: 100px;
|
||||
padding: 4px;
|
||||
}
|
||||
table.board-list-table .board-tags {
|
||||
width: auto;
|
||||
padding: 0 15px 0 4px;
|
||||
}
|
||||
|
||||
table.board-list-table div.board-cell {
|
||||
@ -1435,4 +1439,14 @@ li.tag-item {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0 0.6em 0 0;
|
||||
}
|
||||
a.tag-link {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
li.tag-item a.tag-link {
|
||||
}
|
||||
td.board-tags a.tag-link {
|
||||
display: inline-block;
|
||||
margin: 0 0.4em 0 0;
|
||||
}
|
@ -72,6 +72,8 @@
|
||||
</thead>
|
||||
|
||||
<tbody class="board-list-tbody">{{html_boards}}</tbody>
|
||||
|
||||
<tfoot class="board-list-loading loading"></tfoot>
|
||||
</table>
|
||||
</section>
|
||||
</div>
|
||||
|
@ -6,6 +6,6 @@
|
||||
<td class="board-pph"><div class="board-cell">{{board['pph']}}</td>
|
||||
<td class="board-max"><div class="board-cell">{{board['posts_total']}}</td>
|
||||
<td class="board-unique"><div class="board-cell">{{board['active']}}</td>
|
||||
<td class="board-tags"><div class="board-cell">{% for tag in board.tags %}<span class="board-tag">{{ tag }}</span> {% endfor %}</div></td>
|
||||
<td class="board-tags"><div class="board-cell">{% for tag in board.tags %}<a class="tag-link" href="#">{{ tag }}</a>{% endfor %}</div></td>
|
||||
</tr>
|
||||
{% endfor %}
|
@ -1,36 +1,80 @@
|
||||
<div class="boardlist">
|
||||
<p>{% trans %}There are currently <strong>{{n_boards}}</strong> boards + <strong>{{hidden_boards_total}}</strong> unindexed boards = <strong>{{t_boards}}</strong> 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 %}</p>
|
||||
<main id="boardlist">
|
||||
<section class="description box col col-12">
|
||||
<h2 class="box-title">Global Statistics</h2>
|
||||
<p class="box-content">{% trans %}There are currently <strong>{{boards_public}}</strong> public boards, <strong>{{boards_total}}</strong> total. Site-wide, {{posts_hour}} posts have been made in the last hour, with {{posts_total}} being made on all active boards since {{founding_date}}.{% endtrans %}</p>
|
||||
{% if uptime %}<p class="box-content">{{uptime}} without interruption</p>{% endif %}
|
||||
<p class="box-content">This page last updated {{page_updated}}.</p>
|
||||
</section>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>L</th>
|
||||
<th>{% trans %}Board{% endtrans %}</th>
|
||||
<th>{% trans %}Board title{% endtrans %}</th>
|
||||
<th>{% trans %}Posts in last hour{% endtrans %}</th>
|
||||
<th>{% trans %}Total posts{% endtrans %}</th>
|
||||
<th>{% trans %}Unique IPs{% endtrans %}</th>
|
||||
<th>{% trans %}Created{% endtrans %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="loading">
|
||||
|
||||
</tbody>
|
||||
<tbody>
|
||||
{% for board in boards %}
|
||||
<tr>
|
||||
<td>{{ board.img|raw }}</td>
|
||||
<td><a href='/{{board['uri']}}/'>/{{board['uri']}}/</a>{{lock|raw}}</td>
|
||||
<td>{{ board['title'] }}</td>
|
||||
<td>{{board['pph']}}</td>
|
||||
<td style='text-align:right'>{{board['max']}}</td>
|
||||
<td style='text-align:right'>{{board['uniq_ip']}}</td>
|
||||
<td>{{board['time']}} ({{board['ago']}} ago)</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p><em>Page last updated: {{last_update}}</em></p>
|
||||
<p>{{uptime_p}} without interruption</p>
|
||||
</div>
|
||||
<div class="board-list">
|
||||
<aside class="search-container col col-2">
|
||||
<form id="search-form" class="box" method="post" target="/board-search.php">
|
||||
<h2 class="box-title">Search</h2>
|
||||
|
||||
<div class="board-search box-content">
|
||||
<label class="search-item search-sfw">
|
||||
<input type="checkbox" id="search-sfw-input" name="sfw" checked="checked" /> NSFW boards
|
||||
</label>
|
||||
|
||||
<div class="search-item search-title">
|
||||
<input type="text" id="search-title-input" name="title" placeholder="Search titles..." />
|
||||
</div>
|
||||
|
||||
<div class="search-item search-lang">
|
||||
<select id="search-lang-input" name="lang">
|
||||
<optgroup label="Popular">
|
||||
<option>All languages</option>
|
||||
<option>English</option>
|
||||
<option>Spanish</option>
|
||||
</optgroup>
|
||||
<optgroup label="All">
|
||||
<option>Chinese</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="search-item search-tag">
|
||||
<input type="text" id="search-tag-input" name="tag" placeholder="Search tags..." />
|
||||
</div>
|
||||
|
||||
<div class="search-item search-submit">
|
||||
<button id="search-submit">Search</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="tag-list box-content">
|
||||
<li class="tag-item">
|
||||
<a class="tag-link" href="#">{{html_tags}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</form>
|
||||
</aside>
|
||||
|
||||
<section class="board-list col col-10">
|
||||
<table class="board-list-table">
|
||||
<colgroup>
|
||||
<col class="board-meta" />
|
||||
<col class="board-uri" />
|
||||
<col class="board-title" />
|
||||
<col class="board-pph" />
|
||||
<col class="board-max" />
|
||||
<col class="board-unique" />
|
||||
<col class="board-tags" />
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="board-meta" data-column="meta"></th>
|
||||
<th class="board-uri" data-column="uri">{% trans %}Board{% endtrans %}</th>
|
||||
<th class="board-title" data-column="title">{% trans %}Title{% endtrans %}</th>
|
||||
<th class="board-pph" data-column="pph" title="Posts per hour">{% trans %}PPH{% endtrans %}</th>
|
||||
<th class="board-max" data-column="max">{% trans %}Total posts{% endtrans %}</th>
|
||||
<th class="board-unique" data-column="unique" title="Unique IPs to post in the last 72 hours">{% trans %}Active users{% endtrans %}</th>
|
||||
<th class="board-tags" data-column="tags">{% trans %}Tags{% endtrans %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody class="board-list-tbody">{{html_boards}}</tbody>
|
||||
</table>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
@ -79,11 +79,10 @@ foreach ($boards as $board) {
|
||||
|
||||
// Add to ip array.
|
||||
if (!isset($postDatum['author_ip_array'])) {
|
||||
$postDatum['author_ip_array'][ less_ip( $post['ip'] ) ] = 1;
|
||||
$postDatum['author_ip_array'] = array();
|
||||
}
|
||||
|
||||
// Count ip array.
|
||||
$postDatum['author_ip_count'] = count( $postDatum['post_id_array'] );
|
||||
$postDatum['author_ip_array'][ less_ip( $post['ip'] ) ] = 1;
|
||||
|
||||
unset( $postHourTime );
|
||||
}
|
||||
@ -93,7 +92,8 @@ foreach ($boards as $board) {
|
||||
$postDatum = &$postHour[ $postHourTime ];
|
||||
|
||||
// Serialize arrays for TEXT insert.
|
||||
$postDatum['post_id_array' ] = str_replace( "\"", "\\\"", serialize( $postDatum['post_id_array'] ) );
|
||||
$postDatum['post_id_array'] = str_replace( "\"", "\\\"", serialize( $postDatum['post_id_array'] ) );
|
||||
$postDatum['author_ip_count'] = count( array_keys( $postDatum['author_ip_array'] ) );
|
||||
$postDatum['author_ip_array'] = str_replace( "\"", "\\\"", serialize( array_keys( $postDatum['author_ip_array'] ) ) );
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user