333 lines
7.3 KiB
PHP
333 lines
7.3 KiB
PHP
<?php
|
|
|
|
die();
|
|
|
|
$mysql_suppress_err = false;
|
|
ini_set('display_errors', 1);
|
|
error_reporting(E_ALL);
|
|
|
|
require_once 'lib/db.php';
|
|
|
|
define('IN_APP', true);
|
|
|
|
class StaffLog {
|
|
private
|
|
// NSFW boards for preview styling
|
|
$nsfwBoards = array(
|
|
'b' => true,
|
|
'aco' => true,
|
|
'd' => true,
|
|
'e' => true,
|
|
'gif' => true,
|
|
'h' => true,
|
|
'hc' => true,
|
|
'hm' => true,
|
|
'hr' => true,
|
|
'pol' => true,
|
|
'r' => true,
|
|
'r9k' => true,
|
|
's4s' => true,
|
|
's' => true,
|
|
'soc' => true,
|
|
't' => true,
|
|
'u' => true,
|
|
'wg' => true,
|
|
'y' => true,
|
|
'i' => true,
|
|
'ic' => true,
|
|
'f' => true
|
|
),
|
|
|
|
// Forced anon boards
|
|
$forcedAnonBoards = array(
|
|
'b' => true,
|
|
'soc' => true,
|
|
),
|
|
|
|
// Maximum number of entries to display
|
|
$limit = 25,
|
|
|
|
// Just in case
|
|
$hard_limit = 250,
|
|
|
|
// Fetch bans from X hours ago
|
|
$interval = 3,
|
|
|
|
// Where to output the file
|
|
$outpath = '/www/4chan.org/web/www/bans.html',
|
|
|
|
// HTML template root
|
|
$template_root = '/www/4chan.org/web/www/views/';
|
|
|
|
/**
|
|
* Salt for thumbnail hashing
|
|
*/
|
|
private function getSalt() {
|
|
return file_get_contents('/www/keys/legacy.salt');
|
|
}
|
|
|
|
/**
|
|
* "Days/Hours/Minutes ago"
|
|
*/
|
|
private function getPreciseDuration($delta) {
|
|
if ($delta < 1) {
|
|
return 'moments';
|
|
}
|
|
|
|
if ($delta < 60) {
|
|
return $delta . ' seconds';
|
|
}
|
|
|
|
if ($delta < 3600) {
|
|
$count = floor($delta / 60);
|
|
|
|
if ($count > 1) {
|
|
return $count . ' minutes';
|
|
}
|
|
else {
|
|
return 'one minute';
|
|
}
|
|
}
|
|
|
|
if ($delta < 86400) {
|
|
$count = floor($delta / 3600);
|
|
|
|
if ($count > 1) {
|
|
$head = $count . ' hours';
|
|
}
|
|
else {
|
|
$head = 'one hour';
|
|
}
|
|
|
|
$tail = floor($delta / 60 - $count * 60);
|
|
|
|
if ($tail > 1) {
|
|
$head .= ' and ' . $tail . ' minutes';
|
|
}
|
|
|
|
return $head;
|
|
}
|
|
|
|
$count = floor($delta / 86400);
|
|
|
|
if ($count > 1) {
|
|
$head = $count . ' days';
|
|
}
|
|
else {
|
|
$head = 'one day';
|
|
}
|
|
|
|
$tail = floor($delta / 3600 - $count * 24);
|
|
|
|
if ($tail > 1) {
|
|
$head .= ' and ' . $tail . ' hours';
|
|
}
|
|
|
|
return $head;
|
|
}
|
|
|
|
/**
|
|
* Show unstyled error message and exit
|
|
*/
|
|
private function error($message) {
|
|
die($message);
|
|
}
|
|
|
|
/**
|
|
* Render HTML
|
|
*/
|
|
private function renderHTML($view) {
|
|
ob_start();
|
|
include($this->template_root . $view . '.tpl.php');
|
|
//file_put_contents($this->outpath, ob_get_contents());
|
|
ob_end_flush();
|
|
}
|
|
|
|
/**
|
|
* Fetches all public templates from the database (is_public = 1)
|
|
*/
|
|
private function getTemplates() {
|
|
$all_templates = array();
|
|
|
|
$result = mysql_global_call('SELECT SQL_NO_CACHE no, name, days FROM ban_templates WHERE is_public = 1');
|
|
|
|
if (!mysql_num_rows($result)) {
|
|
$this->error("Couldn't get ban templates");
|
|
}
|
|
|
|
while ($tpl = mysql_fetch_assoc($result)) {
|
|
$all_templates[$tpl['no']] = array(
|
|
'name' => preg_replace('/ \[[^\]]+\]$/i', '', $tpl['name'])
|
|
);
|
|
|
|
$days = (int)$tpl['days'];
|
|
|
|
if ($days > 1) {
|
|
$length = $tpl['days'] . ' days';
|
|
}
|
|
else if ($days < 0) {
|
|
$length = 'Permanent';
|
|
}
|
|
else if ($days == 1) {
|
|
$length = $tpl['days'] . ' day';
|
|
}
|
|
else {
|
|
$length = 'n/a';
|
|
}
|
|
|
|
$all_templates[$tpl['no']]['length'] = $length;
|
|
}
|
|
|
|
return $all_templates;
|
|
}
|
|
|
|
/**
|
|
* Main
|
|
*/
|
|
public function run() {
|
|
mysql_global_connect();
|
|
|
|
$this->entries = array();
|
|
$this->previews = array();
|
|
|
|
// Get templates
|
|
$this->templates = $this->getTemplates();
|
|
|
|
//print_r($this->templates);
|
|
|
|
$tpl_list = implode(',', array_keys($this->templates));
|
|
|
|
$salt = $this->getSalt();
|
|
|
|
// Get bans
|
|
$query = <<<SQL
|
|
SELECT SQL_NO_CACHE no, global, template_id, board, post_num, post_json as post,
|
|
template_id as ban_template, reason,
|
|
UNIX_TIMESTAMP(now) as time,
|
|
UNIX_TIMESTAMP(length) as ban_end
|
|
FROM banned_users
|
|
WHERE template_id IN($tpl_list)
|
|
AND active = 1
|
|
AND post_json != ''
|
|
AND board != 'test'
|
|
AND board != 'j'
|
|
AND length != '0'
|
|
AND now >= DATE_SUB(NOW(), INTERVAL {$this->interval} HOUR)
|
|
ORDER BY now DESC
|
|
LIMIT {$this->hard_limit}
|
|
SQL;
|
|
|
|
$result = mysql_global_call($query);
|
|
|
|
$entries = array();
|
|
|
|
while ($entry = mysql_fetch_assoc($result)) {
|
|
$entries[] = $entry;
|
|
}
|
|
|
|
if (count($entries) < $this->limit) {
|
|
$keys = array_keys($entries);
|
|
}
|
|
else {
|
|
$keys = array_rand($entries, $this->limit);
|
|
}
|
|
|
|
$id = 0;
|
|
|
|
foreach ($keys as $key) {
|
|
$entry = $entries[$key];
|
|
|
|
$entry['id'] = $id;
|
|
$entry['time'] = (int)$entry['time'];
|
|
|
|
$reasons = explode('<>', $entry['reason']);
|
|
$entry['public_reason'] = $reasons[0];
|
|
|
|
if ($entry['ban_end'] && ((int)$entry['ban_end'] - (int)$entry['time'] < 1)) {
|
|
$entry['type'] = 'Warn';
|
|
}
|
|
else {
|
|
$entry['type'] = 'Ban';
|
|
}
|
|
|
|
$post = json_decode($entry['post'], true);
|
|
|
|
$entry['is_op'] = !$post['resto'];
|
|
|
|
$entry['preview_id'] = $entry['board'] . '-' . $id;
|
|
|
|
$preview = array(
|
|
'board' => $entry['board'],
|
|
'now' => $post['now'],
|
|
'name' => $names[0],
|
|
'trip' => $names[1],
|
|
'com' => $post['com'],
|
|
'time' => $post['time']
|
|
);
|
|
|
|
if ($this->forcedAnonBoards[$entry['board']]) {
|
|
$preview['name'] = 'Anonymous';
|
|
unset($preview['trip']);
|
|
}
|
|
else {
|
|
$names = explode('</span> <span class="postertrip">', $post['name']);
|
|
|
|
$preview['name'] = $names[0];
|
|
|
|
if ($names[1]) {
|
|
$preview['trip'] = $names[1];
|
|
}
|
|
|
|
if ($post['email'] !== '') {
|
|
$preview['email'] = $post['email'];
|
|
}
|
|
}
|
|
|
|
if (strpos($post['sub'], 'SPOILER<>') === 0) {
|
|
$preview['sub'] = substr($post['sub'], 9);
|
|
$preview['spoiler'] = 1;
|
|
} else {
|
|
if ($entry['board'] == 'f') {
|
|
$preview['sub'] = preg_replace('/^\d+\|/', '', $post['sub']);
|
|
}
|
|
else {
|
|
$preview['sub'] = $post['sub'];
|
|
}
|
|
}
|
|
|
|
if (isset($this->nsfwBoards[$entry['board']])) {
|
|
$preview['nsfw'] = true;
|
|
}
|
|
|
|
if ($post['ext']) {
|
|
$preview['thumb'] = sha1($entry['board'] . $post['no'] . $salt);
|
|
$preview['ext'] = $post['ext'];
|
|
$preview['w'] = $post['w'];
|
|
$preview['h'] = $post['h'];
|
|
$preview['tn_w'] = $post['tn_w'];
|
|
$preview['tn_h'] = $post['tn_h'];
|
|
$preview['md5'] = $post['md5'];
|
|
$preview['fsize'] = $post['fsize'];
|
|
$preview['filename'] = $post['filename'];
|
|
$preview['md5'] = $post['md5'];
|
|
$preview['tim'] = $post['tim'];
|
|
}
|
|
else if ($post['filedeleted']) {
|
|
$preview['filedeleted'] = 1;
|
|
}
|
|
|
|
$this->previews[$entry['preview_id']] = $preview;
|
|
|
|
$this->entries[] = $entry;
|
|
|
|
++$id;
|
|
}
|
|
|
|
$this->previews = json_encode($this->previews);
|
|
|
|
$this->renderHTML('bans');
|
|
}
|
|
}
|
|
|
|
$ctrl = new StaffLog();
|
|
$ctrl->run();
|