using the new uploader

This commit is contained in:
green-ponies (jgen) 2012-01-08 13:36:39 -05:00
commit 57da47c93a
48 changed files with 850 additions and 200 deletions

View File

@ -30,9 +30,12 @@ DefaultType image/jpeg
<IfModule mod_expires.c> <IfModule mod_expires.c>
ExpiresActive On ExpiresActive On
ExpiresDefault "access plus 1 month" <FilesMatch "([0-9a-f]{32}|\.(gif|jpe?g|png|css|js))$">
ExpiresByType text/html "now" Header set Cache-Control "public, max-age=2629743"
ExpiresByType text/plain "now" ExpiresDefault "access plus 1 month"
</FilesMatch>
#ExpiresByType text/html "now"
#ExpiresByType text/plain "now"
</IfModule> </IfModule>
<ifmodule mod_deflate.c> <ifmodule mod_deflate.c>

View File

@ -32,12 +32,36 @@ class AdminPageTheme extends Themelet {
</form> </form>
"; ";
$page->add_block(new Block("Misc Admin Tools", $html)); $page->add_block(new Block("Misc Admin Tools", $html));
/* First check
Requires you to click the checkbox to enable the delete by query form */
$dbqcheck = "
if(document.getElementById(&quot;dbqcheck&quot;).checked == false){
document.getElementById(&quot;dbqtags&quot;).disabled = true;
document.getElementById(&quot;dbqsubmit&quot;).disabled = true;
}else{
document.getElementById(&quot;dbqtags&quot;).disabled = false;
document.getElementById(&quot;dbqsubmit&quot;).disabled = false;
}";
/* Second check
Requires you to confirm the deletion by clicking ok. */
$html = " $html = "
".make_form(make_link("admin_utils"))." <script type='text/javascript'>
function checkform(){
if(confirm('Are you sure you wish to delete all images using these tags?')){
return true;
}else{
return false;
}
}
</script>"
.make_form(make_link("admin_utils"),"post",false,false,"return checkform()")."
<input type='checkbox' id='dbqcheck' name='action' onclick='$dbqcheck'>
<input type='hidden' name='action' value='delete by query'> <input type='hidden' name='action' value='delete by query'>
<input type='text' name='query'> <input type='text' id='dbqtags' disabled='true' name='query'>
<input type='submit' value='Go'> <input type='submit' id='dbqsubmit' disabled='true' value='Go'>
</form> </form>
"; ";
$page->add_block(new Block("Delete by Query", $html)); $page->add_block(new Block("Delete by Query", $html));

View File

@ -7,7 +7,6 @@
class FlashFileHandler extends DataHandlerExtension { class FlashFileHandler extends DataHandlerExtension {
protected function create_thumb($hash) { protected function create_thumb($hash) {
// FIXME: scale image, as not all boards use 192x192
copy("ext/handle_flash/thumb.jpg", warehouse_path("thumbs", $hash)); copy("ext/handle_flash/thumb.jpg", warehouse_path("thumbs", $hash));
} }

View File

@ -7,7 +7,6 @@
class MP3FileHandler extends DataHandlerExtension { class MP3FileHandler extends DataHandlerExtension {
protected function create_thumb($hash) { protected function create_thumb($hash) {
// FIXME: scale image, as not all boards use 192x192
copy("ext/handle_mp3/thumb.jpg", warehouse_path("thumbs", $hash)); copy("ext/handle_mp3/thumb.jpg", warehouse_path("thumbs", $hash));
} }

View File

@ -40,7 +40,6 @@ class SVGFileHandler implements Extension {
// exec("convert images/{$ha}/{$hash}[0] -geometry {$w}x{$h} -quality {$q} jpg:thumbs/{$ha}/{$hash}"); // exec("convert images/{$ha}/{$hash}[0] -geometry {$w}x{$h} -quality {$q} jpg:thumbs/{$ha}/{$hash}");
// } // }
// else { // else {
// FIXME: scale image, as not all boards use 192x192
copy("ext/handle_svg/thumb.jpg", warehouse_path("thumbs", $hash)); copy("ext/handle_svg/thumb.jpg", warehouse_path("thumbs", $hash));
// } // }
} }

View File

@ -7,6 +7,7 @@ class HomeTheme extends Themelet {
<html> <html>
<head> <head>
<title>$sitename</title> <title>$sitename</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<link rel='stylesheet' href='$data_href/themes/$theme_name/style.css' type='text/css'> <link rel='stylesheet' href='$data_href/themes/$theme_name/style.css' type='text/css'>
</head> </head>
<style> <style>
@ -46,7 +47,7 @@ EOD
$counter_html $counter_html
<div class='space' id='foot'> <div class='space' id='foot'>
<small><small> <small><small>
<a href='$contact_link'>Contact</a> &ndash; Serving $num_comma posts &ndash; <a href='mailto:$contact_link'>Contact</a> &ndash; Serving $num_comma posts &ndash;
Running <a href='http://code.shishnet.org/shimmie2/'>Shimmie</a> Running <a href='http://code.shishnet.org/shimmie2/'>Shimmie</a>
</small></small> </small></small>
</div> </div>

View File

@ -35,9 +35,6 @@ class NumericScore implements Extension {
if($event instanceof DisplayingImageEvent) { if($event instanceof DisplayingImageEvent) {
if(!$user->is_anonymous()) { if(!$user->is_anonymous()) {
$html = $this->theme->get_voter_html($event->image); $html = $this->theme->get_voter_html($event->image);
if($user->is_admin()) {
$html .= "<p><a href='/numeric_score_votes/{$event->image->id}'>See All Votes</a>";
}
$page->add_block(new Block("Image Score", $html, "left", 20)); $page->add_block(new Block("Image Score", $html, "left", 20));
} }
} }

View File

@ -37,6 +37,8 @@ class NumericScoreTheme extends Themelet {
<input type='hidden' name='image_id' value='$i_image_id'> <input type='hidden' name='image_id' value='$i_image_id'>
<input type='submit' value='Remove All Votes'> <input type='submit' value='Remove All Votes'>
</form> </form>
<p><a href='".make_link("numeric_score_votes/$i_image_id")."'>See All Votes</a>
"; ";
} }
return $html; return $html;

View File

@ -87,16 +87,13 @@ class TagEditCloud implements Extension {
if ((gettype($image) == 'object') && (isset($image->tag_array)) && ($itags=$image->tag_array)) $itags=array_fill_keys(array_values($itags),true); if ((gettype($image) == 'object') && (isset($image->tag_array)) && ($itags=$image->tag_array)) $itags=array_fill_keys(array_values($itags),true);
$result = $database->execute(" SELECT tag, FLOOR(LOG(2.7, LOG(2.7, count - ? + 1)+1)*1.5*100)/100 AS scaled, count $tag_data = $database->get_all(" SELECT tag, FLOOR(LOG(2.7, LOG(2.7, count - ? + 1)+1)*1.5*100)/100 AS scaled, count
FROM tags WHERE count >= ? ORDER BY ". FROM tags WHERE count >= ? ORDER BY ".
(!$alphasort ? "count DESC":"tag"). (!$alphasort ? "count DESC":"tag").
" limit $maxcount", " limit $maxcount",
array($tags_min,$tags_min) array($tags_min,$tags_min)
); );
$tag_data = $result->GetArray();
$counter=1; $counter=1;
foreach($tag_data as $row) { foreach($tag_data as $row) {
if((!$alphasort)&&($counter==$defcount)) $cloud .= "<div id=\"tagcloud_extra\" style=\"display: none;\">"; if((!$alphasort)&&($counter==$defcount)) $cloud .= "<div id=\"tagcloud_extra\" style=\"display: none;\">";

View File

@ -75,6 +75,7 @@ class MySQL extends DBEngine {
$data = str_replace("SCORE_DATETIME", "DATETIME", $data); $data = str_replace("SCORE_DATETIME", "DATETIME", $data);
$data = str_replace("SCORE_NOW", "\"1970-01-01\"", $data); $data = str_replace("SCORE_NOW", "\"1970-01-01\"", $data);
$data = str_replace("SCORE_STRNORM", "", $data); $data = str_replace("SCORE_STRNORM", "", $data);
$data = str_replace("SCORE_ILIKE", "LIKE", $data);
return $data; return $data;
} }
@ -96,6 +97,7 @@ class PostgreSQL extends DBEngine {
$data = str_replace("SCORE_DATETIME", "TIMESTAMP", $data); $data = str_replace("SCORE_DATETIME", "TIMESTAMP", $data);
$data = str_replace("SCORE_NOW", "current_time", $data); $data = str_replace("SCORE_NOW", "current_time", $data);
$data = str_replace("SCORE_STRNORM", "lower", $data); $data = str_replace("SCORE_STRNORM", "lower", $data);
$data = str_replace("SCORE_ILIKE", "ILIKE", $data);
return $data; return $data;
} }
@ -142,6 +144,7 @@ class SQLite extends DBEngine {
$data = str_replace("SCORE_BOOL", "CHAR(1)", $data); $data = str_replace("SCORE_BOOL", "CHAR(1)", $data);
$data = str_replace("SCORE_NOW", "\"1970-01-01\"", $data); $data = str_replace("SCORE_NOW", "\"1970-01-01\"", $data);
$data = str_replace("SCORE_STRNORM", "", $data); $data = str_replace("SCORE_STRNORM", "", $data);
$data = str_replace("SCORE_ILIKE", "LIKE", $data);
$cols = array(); $cols = array();
$extras = ""; $extras = "";
foreach(explode(",", $data) as $bit) { foreach(explode(",", $data) as $bit) {

View File

@ -177,6 +177,19 @@ abstract class DataHandlerExtension implements Extension {
$iae = new ImageAdditionEvent($event->user, $image); $iae = new ImageAdditionEvent($event->user, $image);
send_event($iae); send_event($iae);
$event->image_id = $iae->image->id; $event->image_id = $iae->image->id;
// Rating Stuff.
if(!empty($event->metadata['rating'])){
global $user;
$rating = $event->metadata['rating'];
send_event(new RatingSetEvent($image, $user, $rating));
}
// Locked Stuff.
if(!empty($event->metadata['locked'])){
$locked = $event->metadata['locked'];
send_event(new LockSetEvent($image, !empty($locked)));
}
} }
} }

View File

@ -500,9 +500,12 @@ class Image {
$tmpl = str_replace('$filename', $_escape($base_fname), $tmpl); $tmpl = str_replace('$filename', $_escape($base_fname), $tmpl);
$tmpl = str_replace('$title', $_escape($config->get_string("title")), $tmpl); $tmpl = str_replace('$title', $_escape($config->get_string("title")), $tmpl);
$plte = new ParseLinkTemplateEvent($tmpl, $this); // nothing seems to use this, sending the event out to 50 exts is a lot of overhead
send_event($plte); if(!SPEED_HAX) {
$tmpl = $plte->link; $plte = new ParseLinkTemplateEvent($tmpl, $this);
send_event($plte);
$tmpl = $plte->link;
}
return $tmpl; return $tmpl;
} }
@ -972,7 +975,8 @@ function move_upload_to_archive($event) {
$target = warehouse_path("images", $event->hash); $target = warehouse_path("images", $event->hash);
if(!file_exists(dirname($target))) mkdir(dirname($target), 0755, true); if(!file_exists(dirname($target))) mkdir(dirname($target), 0755, true);
if(!@copy($event->tmpname, $target)) { if(!@copy($event->tmpname, $target)) {
throw new UploadException("Failed to copy file from uploads ({$event->tmpname}) to archive ($target)"); $errors = error_get_last(); // note: requires php 5.2
throw new UploadException("Failed to copy file from uploads ({$event->tmpname}) to archive ($target): {$errors['type']} / {$errors['message']}");
return false; return false;
} }
return true; return true;

View File

@ -183,7 +183,7 @@ class Page {
* Display the page according to the mode and data given * Display the page according to the mode and data given
*/ */
public function display() { public function display() {
global $page; global $page, $user;
header("Content-type: ".$this->type); header("Content-type: ".$this->type);
header("X-Powered-By: SCore-".SCORE_VERSION); header("X-Powered-By: SCore-".SCORE_VERSION);
@ -196,7 +196,22 @@ class Page {
switch($this->mode) { switch($this->mode) {
case "page": case "page":
header("Cache-control: no-cache"); header("Vary: Cookie, Accept-Encoding");
if(CACHE_HTTP) {
if($user->is_anonymous() && $_SERVER["REQUEST_METHOD"] == "GET") {
header("Cache-control: public, max-age=600");
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 600) . ' GMT');
}
else {
#header("Cache-control: private, max-age=0");
header("Cache-control: no-cache");
header('Expires: ' . gmdate('D, d M Y H:i:s', time() - 600) . ' GMT');
}
}
else {
header("Cache-control: no-cache");
header('Expires: ' . gmdate('D, d M Y H:i:s', time() - 600) . ' GMT');
}
usort($this->blocks, "blockcmp"); usort($this->blocks, "blockcmp");
$this->add_auto_html_headers(); $this->add_auto_html_headers();
$layout = new Layout(); $layout = new Layout();

View File

@ -47,6 +47,25 @@ function sql_escape($input) {
return $database->db->Quote($input); return $database->db->Quote($input);
} }
/**
* Turn all manner of HTML / INI / JS / DB booleans into a PHP one
*
* @retval boolean
*/
function bool_escape($input) {
$input = strtolower($input);
return (
$input == "y" ||
$input == "yes" ||
$input == "t" ||
$input == "true" ||
$input == "on" ||
$input == 1 ||
$input == true
);
}
/** /**
* Some functions require a callback function for escaping, * Some functions require a callback function for escaping,
* but we might not want to alter the data * but we might not want to alter the data
@ -110,34 +129,9 @@ function to_shorthand_int($int) {
* @retval string * @retval string
*/ */
function autodate($date, $html=true) { function autodate($date, $html=true) {
global $config; $cpu = date('c', strtotime($date));
$hum = date('F j, Y', strtotime($date));
$format = $config->get_string('autodate_format', "F j, Y"); return ($html ? "<time datetime='$cpu'>$hum</time>" : $hum);
$seconds = time() - strtotime($date);
$ago = seconds_to_time($seconds) . " ago";
$on = "on " . date($format, strtotime($date));
if($config->get_bool('use_autodate', true)) {
return ($html ? "<span title='$on'>$ago</span>" : $ago);
}
else {
return $on;
}
}
/**
* Turn a number of seconds into a vague human timespan, eg 142 -> "2 minutes"
*
* @retval string
*/
function seconds_to_time($seconds) {
if($seconds<60) return $seconds . " second" . plural($seconds); $seconds = round($seconds/60);
if($seconds<60) return $seconds . " minute" . plural($seconds); $seconds = round($seconds/60);
if($seconds<24) return $seconds . " hour" . plural($seconds); $seconds = round($seconds/24);
if($seconds<7) return $seconds . " day" . plural($seconds); $seconds = round($seconds/7);
if($seconds<4) return $seconds . " week" . plural($seconds); $seconds = round($seconds/4);
if($seconds<12) return $seconds . " month" . plural($seconds); $seconds = round($seconds/12);
return $seconds . " year" . plural($seconds);
} }
@ -178,7 +172,7 @@ function make_link($page=null, $query=null) {
if(is_null($page)) $page = $config->get_string('main_page'); if(is_null($page)) $page = $config->get_string('main_page');
if($config->get_bool('nice_urls', false)) { if(FORCE_NICE_URLS || $config->get_bool('nice_urls', false)) {
#$full = "http://" . $_SERVER["SERVER_NAME"] . $_SERVER["PHP_SELF"]; #$full = "http://" . $_SERVER["SERVER_NAME"] . $_SERVER["PHP_SELF"];
$full = $_SERVER["PHP_SELF"]; $full = $_SERVER["PHP_SELF"];
$base = str_replace("/index.php", "", $full); $base = str_replace("/index.php", "", $full);
@ -203,6 +197,48 @@ function make_link($page=null, $query=null) {
} }
} }
/**
* Take the current URL and modify some paramaters
*
* @retval string
*/
function modify_current_url($changes) {
return modify_url($_SERVER['QUERY_STRING'], $changes);
}
function modify_url($url, $changes) {
// SHIT: PHP is officially the worst web API ever because it does not
// have a built-in function to do this.
// SHIT: parse_str is magically retarded; not only is it a useless name, it also
// didn't return the parsed array, preferring to overwrite global variables with
// whatever data the user supplied. Thankfully, 4.0.3 added an extra option to
// give it an array to use...
$params = array();
parse_str($url, $params);
if(isset($changes['q'])) {
$base = $changes['q'];
unset($changes['q']);
}
else {
$base = $_GET['q'];
}
if(isset($params['q'])) {
unset($params['q']);
}
foreach($changes as $k => $v) {
if(is_null($v) and isset($params[$k])) unset($params[$k]);
$params[$k] = $v;
}
return make_link($base, http_build_query($params));
}
/** /**
* Turn a relative link into an absolute one, including hostname * Turn a relative link into an absolute one, including hostname
* *
@ -222,13 +258,16 @@ function make_http($link) {
* *
* @retval string * @retval string
*/ */
function make_form($target, $method="POST", $multipart=False, $form_id="") { function make_form($target, $method="POST", $multipart=False, $form_id="", $onsubmit="") {
global $user; global $user;
$auth = $user->get_auth_html(); $auth = $user->get_auth_html();
$extra = empty($form_id) ? '' : " id='$form_id'"; $extra = empty($form_id) ? '' : " id='$form_id'";
if($multipart) { if($multipart) {
$extra .= " enctype='multipart/form-data'"; $extra .= " enctype='multipart/form-data'";
} }
if($onsubmit) {
$extra .= " onsubmit='$onsubmit'";
}
return "<form action='$target' method='$method'$extra>$auth"; return "<form action='$target' method='$method'$extra>$auth";
} }
@ -253,8 +292,8 @@ function captcha_get_html() {
if(DEBUG && ip_in_range($_SERVER['REMOTE_ADDR'], "127.0.0.0/8")) return ""; if(DEBUG && ip_in_range($_SERVER['REMOTE_ADDR'], "127.0.0.0/8")) return "";
$captcha = ""; $captcha = "";
if($user->is_anonymous() && $config->get_bool("use_captchas")) { if($user->is_anonymous() && $config->get_bool("comment_captcha")) {
$rpk = $config->get_string("api_recaptcha_pubkey"); $rpk = $config->get_string("api_recaptcha_privkey");
if(!empty($rpk)) { if(!empty($rpk)) {
$captcha = recaptcha_get_html($rpk); $captcha = recaptcha_get_html($rpk);
} }
@ -274,8 +313,8 @@ function captcha_check() {
if(DEBUG && ip_in_range($_SERVER['REMOTE_ADDR'], "127.0.0.0/8")) return true; if(DEBUG && ip_in_range($_SERVER['REMOTE_ADDR'], "127.0.0.0/8")) return true;
if($user->is_anonymous() && $config->get_bool("use_captchas")) { if($user->is_anonymous() && $config->get_bool("comment_captcha")) {
$rpk = $config->get_string('api_recaptcha_privkey'); $rpk = $config->get_string('api_recaptcha_pubkey');
if(!empty($rpk)) { if(!empty($rpk)) {
$resp = recaptcha_check_answer( $resp = recaptcha_check_answer(
$rpk, $rpk,
@ -504,7 +543,12 @@ function format_text($string) {
function warehouse_path($base, $hash, $create=true) { function warehouse_path($base, $hash, $create=true) {
$ab = substr($hash, 0, 2); $ab = substr($hash, 0, 2);
$cd = substr($hash, 2, 2); $cd = substr($hash, 2, 2);
$pa = "$base/$ab/$hash"; if(WH_SPLITS == 2) {
$pa = "$base/$ab/$cd/$hash";
}
else {
$pa = "$base/$ab/$hash";
}
if($create && !file_exists(dirname($pa))) mkdir(dirname($pa), 0755, true); if($create && !file_exists(dirname($pa))) mkdir(dirname($pa), 0755, true);
return $pa; return $pa;
} }

View File

@ -171,6 +171,10 @@ class CommentList extends SimpleExtension {
$i_comment_count = Comment::count_comments_by_user($event->display_user); $i_comment_count = Comment::count_comments_by_user($event->display_user);
$h_comment_rate = sprintf("%.1f", ($i_comment_count / $i_days_old)); $h_comment_rate = sprintf("%.1f", ($i_comment_count / $i_days_old));
$event->add_stats("Comments made: $i_comment_count, $h_comment_rate per day"); $event->add_stats("Comments made: $i_comment_count, $h_comment_rate per day");
global $user;
$recent = $this->get_user_recent_comments($event->display_user->id, 10);
$this->theme->display_user_comments($recent);
} }
public function onDisplayingImage(DisplayingImageEvent $event) { public function onDisplayingImage(DisplayingImageEvent $event) {
@ -312,6 +316,28 @@ class CommentList extends SimpleExtension {
return $comments; return $comments;
} }
private function get_user_recent_comments($user_id, $count) {
global $config;
global $database;
$rows = $database->get_all("
SELECT
users.id as user_id, users.name as user_name, users.email as user_email,
comments.comment as comment, comments.id as comment_id,
comments.image_id as image_id, comments.owner_ip as poster_ip,
comments.posted as posted
FROM comments
LEFT JOIN users ON comments.owner_id=users.id
WHERE users.id = :user_id
ORDER BY comments.id DESC
LIMIT :limit
", array("user_id"=>$user_id, "limit"=>$count));
$comments = array();
foreach($rows as $row) {
$comments[] = new Comment($row);
}
return $comments;
}
private function get_comments($image_id) { private function get_comments($image_id) {
global $config; global $config;
global $database; global $database;

View File

@ -114,11 +114,32 @@ class CommentListTheme extends Themelet {
} }
/**
* Show comments made by a user
*/
public function display_user_comments($comments) {
global $page;
$html = "";
foreach($comments as $comment) {
$html .= $this->comment_to_html($comment, true);
}
$page->add_block(new Block("Comments", $html, "left", 70));
}
protected function comment_to_html($comment, $trim=false) { protected function comment_to_html($comment, $trim=false) {
global $user; global $user;
$tfe = new TextFormattingEvent($comment->comment); $tfe = new TextFormattingEvent($comment->comment);
send_event($tfe);
// sending this event to all ~50 exts has a lot of overhead
if(SPEED_HAX) {
$bb = new BBCode();
$bb->receive_event($tfe);
}
else {
send_event($tfe);
}
$i_uid = int_escape($comment->owner_id); $i_uid = int_escape($comment->owner_id);
$h_name = html_escape($comment->owner_name); $h_name = html_escape($comment->owner_name);
@ -158,6 +179,7 @@ class CommentListTheme extends Themelet {
return " return "
<a name='$i_comment_id'></a> <a name='$i_comment_id'></a>
<div class='$oe comment'> <div class='$oe comment'>
<!--<span class='timeago' style='float: right;'>$h_timestamp</span>-->
$h_userlink: $h_comment $h_userlink: $h_comment
$h_dellink $h_dellink
</div> </div>

View File

@ -94,8 +94,8 @@ class PixelFileHandler extends DataHandlerExtension {
if($size[1] > $size[0]*5) $size[1] = $size[0]*5; if($size[1] > $size[0]*5) $size[1] = $size[0]*5;
// running the call with cmd.exe requires quoting for our paths // running the call with cmd.exe requires quoting for our paths
$format = '"%s" "%s[0]" -crop %ux%u +repage -flatten -strip -thumbnail %ux%u jpg:"%s"'; $format = '"%s" "%s[0]" -crop %ux%u +repage -flatten -strip -thumbnail %ux%u -quality %u jpg:"%s"';
$cmd = sprintf($format, $convert, $inname, $size[0], $size[1], $w, $h, $outname); $cmd = sprintf($format, $convert, $inname, $size[0], $size[1], $w, $h, $q, $outname);
$cmd = str_replace("\"convert\"", "convert", $cmd); // quotes are only needed if the path to convert contains a space; some other times, quotes break things, see github bug #27 $cmd = str_replace("\"convert\"", "convert", $cmd); // quotes are only needed if the path to convert contains a space; some other times, quotes break things, see github bug #27
exec($cmd, $output, $ret); exec($cmd, $output, $ret);

View File

@ -169,10 +169,8 @@ class Setup extends SimpleExtension {
$config->set_default_string("main_page", "post/list"); $config->set_default_string("main_page", "post/list");
$config->set_default_string("base_href", "./index.php?q="); $config->set_default_string("base_href", "./index.php?q=");
$config->set_default_string("theme", "default"); $config->set_default_string("theme", "default");
$config->set_default_bool("use_autodate", true);
$config->set_default_bool("word_wrap", true); $config->set_default_bool("word_wrap", true);
$config->set_default_bool("use_captchas", false); $config->set_default_bool("comment_captcha", false);
$config->set_default_string("autodate_format", "F j, Y");
// Automatic caching is disabled by default // Automatic caching is disabled by default
$config->set_default_string("autocache_location", "data/cache"); $config->set_default_string("autocache_location", "data/cache");
$config->set_default_bool("autocache_css", false); $config->set_default_bool("autocache_css", false);

View File

@ -15,9 +15,11 @@ class TagList implements Extension {
if($event instanceof InitExtEvent) { if($event instanceof InitExtEvent) {
$config->set_default_int("tag_list_length", 15); $config->set_default_int("tag_list_length", 15);
$config->set_default_int("popular_tag_list_length", 15);
$config->set_default_int("tags_min", 3); $config->set_default_int("tags_min", 3);
$config->set_default_string("info_link", 'http://en.wikipedia.org/wiki/$tag'); $config->set_default_string("info_link", 'http://en.wikipedia.org/wiki/$tag');
$config->set_default_string("tag_list_image_type", 'related'); $config->set_default_string("tag_list_image_type", 'related');
$config->set_default_bool("tag_list_pages", false);
} }
if(($event instanceof PageRequestEvent) && $event->page_matches("tags")) { if(($event instanceof PageRequestEvent) && $event->page_matches("tags")) {
@ -82,10 +84,12 @@ class TagList implements Extension {
if($event instanceof SetupBuildingEvent) { if($event instanceof SetupBuildingEvent) {
$sb = new SetupBlock("Tag Map Options"); $sb = new SetupBlock("Tag Map Options");
$sb->add_int_option("tags_min", "Only show tags used at least "); $sb->add_label(" times"); $sb->add_int_option("tags_min", "Only show tags used at least "); $sb->add_label(" times");
$sb->add_bool_option("tag_list_pages", "<br>Paged tag lists: ");
$event->panel->add_block($sb); $event->panel->add_block($sb);
$sb = new SetupBlock("Popular / Related Tag List"); $sb = new SetupBlock("Popular / Related Tag List");
$sb->add_int_option("tag_list_length", "Show top "); $sb->add_label(" tags"); $sb->add_int_option("tag_list_length", "Show top "); $sb->add_label(" related tags");
$sb->add_int_option("popular_tag_list_length", "<br>Show top "); $sb->add_label(" popular tags");
$sb->add_text_option("info_link", "<br>Tag info link: "); $sb->add_text_option("info_link", "<br>Tag info link: ");
$sb->add_choice_option("tag_list_image_type", array( $sb->add_choice_option("tag_list_image_type", array(
"Image's tags only" => "tags", "Image's tags only" => "tags",
@ -111,6 +115,43 @@ class TagList implements Extension {
return $config->get_int('tags_min'); return $config->get_int('tags_min');
} }
} }
private function get_starts_with() {
global $config;
if(isset($_GET['starts_with'])) {
return $_GET['starts_with'] . "%";
}
else {
if($config->get_bool("tag_list_pages")) {
return "a%";
}
else {
return "%";
}
}
}
private function build_az() {
global $database;
$tags_min = $this->get_tags_min();
$tag_data = $database->get_col($database->engine->scoreql_to_sql("
SELECT DISTINCT
SCORE_STRNORM(substr(tag, 1, 1))
FROM tags
WHERE count >= :tags_min
ORDER BY SCORE_STRNORM(substr(tag, 1, 1))
"), array("tags_min"=>$tags_min));
$html = "";
foreach($tag_data as $a) {
$html .= " <a href='".modify_current_url(array("starts_with"=>$a))."'>$a</a>";
}
$html .= "<p><hr>";
return $html;
}
// }}} // }}}
// maps {{{ // maps {{{
private function build_navigation() { private function build_navigation() {
@ -119,28 +160,31 @@ class TagList implements Extension {
$h_alphabetic = "<a href='".make_link("tags/alphabetic")."'>Alphabetic</a>"; $h_alphabetic = "<a href='".make_link("tags/alphabetic")."'>Alphabetic</a>";
$h_popularity = "<a href='".make_link("tags/popularity")."'>Popularity</a>"; $h_popularity = "<a href='".make_link("tags/popularity")."'>Popularity</a>";
$h_cats = "<a href='".make_link("tags/categories")."'>Categories</a>"; $h_cats = "<a href='".make_link("tags/categories")."'>Categories</a>";
$h_all = "<a href='?mincount=1'>Show All</a>"; $h_all = "<a href='".modify_current_url(array("mincount"=>1))."'>Show All</a>";
return "$h_index<br>&nbsp;<br>$h_map<br>$h_alphabetic<br>$h_popularity<br>$h_cats<br>&nbsp;<br>$h_all"; return "$h_index<br>&nbsp;<br>$h_map<br>$h_alphabetic<br>$h_popularity<br>$h_cats<br>&nbsp;<br>$h_all";
} }
private function build_tag_map() { private function build_tag_map() {
global $database; global $config, $database;
$tags_min = $this->get_tags_min(); $tags_min = $this->get_tags_min();
if(file_exists("data/tag_map_$tags_min.html")) { $starts_with = $this->get_starts_with();
return file_get_contents("data/tag_map_$tags_min.html"); $cache_key = "data/tag_cloud-" . md5("tc" . $tags_min . $starts_with) . ".html";
} if(file_exists($cache_key)) {return file_get_contents($cache_key);}
$tag_data = $database->get_all(" // SHIT: PDO/pgsql has problems using the same named param twice -_-;;
$tag_data = $database->get_all($database->engine->scoreql_to_sql("
SELECT SELECT
tag, tag,
FLOOR(LOG(2.7, LOG(2.7, count - :tags_min + 1)+1)*1.5*100)/100 AS scaled FLOOR(LOG(2.7, LOG(2.7, count - :tags_min2 + 1)+1)*1.5*100)/100 AS scaled
FROM tags FROM tags
WHERE count >= :tags_min WHERE count >= :tags_min
ORDER BY tag AND tag SCORE_ILIKE :starts_with
", array("tags_min"=>$tags_min)); ORDER BY SCORE_STRNORM(tag)
"), array("tags_min"=>$tags_min, "tags_min2"=>$tags_min, "starts_with"=>$starts_with));
$html = ""; $html = "";
if($config->get_bool("tag_list_pages")) $html .= $this->build_az();
foreach($tag_data as $row) { foreach($tag_data as $row) {
$h_tag = html_escape($row['tag']); $h_tag = html_escape($row['tag']);
$size = sprintf("%.2f", (float)$row['scaled']); $size = sprintf("%.2f", (float)$row['scaled']);
@ -150,36 +194,43 @@ class TagList implements Extension {
$html .= "&nbsp;<a style='font-size: ${size}em' href='$link'>$h_tag_no_underscores</a>&nbsp;\n"; $html .= "&nbsp;<a style='font-size: ${size}em' href='$link'>$h_tag_no_underscores</a>&nbsp;\n";
} }
// file_put_contents("data/tag_map_$tags_min.html", $html); if(SPEED_HAX) {file_put_contents($cache_key, $html);}
return $html; return $html;
} }
private function build_tag_alphabetic() { private function build_tag_alphabetic() {
global $database; global $config, $database;
$tags_min = $this->get_tags_min(); $tags_min = $this->get_tags_min();
if(file_exists("data/tag_alpha_$tags_min.html")) { $starts_with = $this->get_starts_with();
return file_get_contents("data/tag_alpha_$tags_min.html"); $cache_key = "data/tag_alpha-" . md5("ta" . $tags_min . $starts_with) . ".html";
} if(file_exists($cache_key)) {return file_get_contents($cache_key);}
$tag_data = $database->get_all( $tag_data = $database->get_all($database->engine->scoreql_to_sql("
"SELECT tag,count FROM tags WHERE count >= :tags_min ORDER BY tag", SELECT tag, count
array("tags_min"=>$tags_min)); FROM tags
WHERE count >= :tags_min
AND tag SCORE_ILIKE :starts_with
ORDER BY SCORE_STRNORM(tag)
"), array("tags_min"=>$tags_min, "starts_with"=>$starts_with));
$html = ""; $html = "";
if($config->get_bool("tag_list_pages")) $html .= $this->build_az();
$lastLetter = ""; $lastLetter = "";
foreach($tag_data as $row) { foreach($tag_data as $row) {
$h_tag = html_escape($row['tag']); $h_tag = html_escape($row['tag']);
$count = $row['count']; $count = $row['count'];
if($lastLetter != strtolower(substr($h_tag, 0, 1))) { if($lastLetter != strtolower(substr($h_tag, 0, count($starts_with)+1))) {
$lastLetter = strtolower(substr($h_tag, 0, 1)); $lastLetter = strtolower(substr($h_tag, 0, count($starts_with)+1));
$html .= "<p>$lastLetter<br>"; $html .= "<p>$lastLetter<br>";
} }
$link = $this->tag_link($row['tag']); $link = $this->tag_link($row['tag']);
$html .= "<a href='$link'>$h_tag&nbsp;($count)</a>\n"; $html .= "<a href='$link'>$h_tag&nbsp;($count)</a>\n";
} }
// file_put_contents("data/tag_alpha_$tags_min.html", $html); if(SPEED_HAX) {file_put_contents($cache_key, $html);}
return $html; return $html;
} }
@ -187,13 +238,15 @@ class TagList implements Extension {
global $database; global $database;
$tags_min = $this->get_tags_min(); $tags_min = $this->get_tags_min();
if(file_exists("data/tag_popul_$tags_min.html")) { $cache_key = "data/tag_popul-" . md5("tp" . $tags_min) . ".html";
return file_get_contents("data/tag_popul_$tags_min.html"); if(file_exists($cache_key)) {return file_get_contents($cache_key);}
}
$tag_data = $database->get_all( $tag_data = $database->get_all("
"SELECT tag,count,FLOOR(LOG(count)) AS scaled FROM tags WHERE count >= :tags_min ORDER BY count DESC, tag ASC", SELECT tag, count, FLOOR(LOG(count)) AS scaled
array("tags_min"=>$tags_min)); FROM tags
WHERE count >= :tags_min
ORDER BY count DESC, tag ASC
", array("tags_min"=>$tags_min));
$html = "Results grouped by log<sub>e</sub>(n)"; $html = "Results grouped by log<sub>e</sub>(n)";
$lastLog = ""; $lastLog = "";
@ -209,7 +262,8 @@ class TagList implements Extension {
$html .= "<a href='$link'>$h_tag&nbsp;($count)</a>\n"; $html .= "<a href='$link'>$h_tag&nbsp;($count)</a>\n";
} }
// file_put_contents("data/tag_popul_$tags_min.html", $html); if(SPEED_HAX) {file_put_contents($cache_key, $html);}
return $html; return $html;
} }
@ -301,9 +355,9 @@ class TagList implements Extension {
FROM tags FROM tags
WHERE count > 0 WHERE count > 0
ORDER BY count DESC ORDER BY count DESC
LIMIT :tag_list_length LIMIT :popular_tag_list_length
"; ";
$args = array("tag_list_length"=>$config->get_int('tag_list_length')); $args = array("popular_tag_list_length"=>$config->get_int('popular_tag_list_length'));
$tags = $database->get_all($query, $args); $tags = $database->get_all($query, $args);
$database->cache->set("popular_tags", $tags, 600); $database->cache->set("popular_tags", $tags, 600);

View File

@ -52,8 +52,12 @@ class TagListTheme extends Themelet {
$html .= " <span class='tag_count'>$count</span>"; $html .= " <span class='tag_count'>$count</span>";
} }
} }
$page->add_block(new Block("Related", $html, "left")); if($config->get_string('tag_list_image_type')=="tags"){
$page->add_block(new Block("Tags", $html, "left", 10));}
else{
$page->add_block(new Block("Related Tags", $html, "left", 10));
}
} }

View File

@ -173,6 +173,7 @@ class Upload implements Extension {
if(!empty($_GET['tags']) && $_GET['tags'] != "null") { if(!empty($_GET['tags']) && $_GET['tags'] != "null") {
$tags = Tag::explode($_GET['tags']); $tags = Tag::explode($_GET['tags']);
} }
$ok = $this->try_transload($url, $tags, $url); $ok = $this->try_transload($url, $tags, $url);
$this->theme->display_upload_status($page, $ok); $this->theme->display_upload_status($page, $ok);
} }
@ -301,10 +302,30 @@ class Upload implements Extension {
private function try_transload($url, $tags, $source, $replace='') { private function try_transload($url, $tags, $source, $replace='') {
global $page; global $page;
global $config; global $config;
global $user;
$ok = true; $ok = true;
if(empty($source)) $source = $url; //Allows external source to be set.
if(!empty($_GET['source'])){
$source = $_GET['source'];
}else{
$source = $url;
}
// Checks if user is admin > check if you want locked.
if($user->is_admin()){
$locked = bool_escape($_GET['locked']);
}
// Checks if url contains rating, also checks if the rating extension is enabled.
if($config->get_string("transload_engine", "none") != "none" && file_exists("ext/rating") && !empty($_GET['rating'])) {
// Rating event will validate that this is s/q/e/u
$rating = strtolower($_GET['rating']);
$rating = $rating[0];
}else{
$rating = "";
}
// PHP falls back to system default if /tmp fails, can't we just // PHP falls back to system default if /tmp fails, can't we just
// use the system default to start with? :-/ // use the system default to start with? :-/
@ -365,6 +386,16 @@ class Upload implements Extension {
$metadata['tags'] = $tags; $metadata['tags'] = $tags;
$metadata['source'] = $source; $metadata['source'] = $source;
/* check for locked > adds to metadata if it has */
if(!empty($locked)){
$metadata['locked'] = $locked ? "on" : "";
}
/* check for rating > adds to metadata if it has */
if(!empty($rating)){
$metadata['rating'] = $rating;
}
/* check if we have been given an image ID to replace */ /* check if we have been given an image ID to replace */
if (!empty($replace)) { if (!empty($replace)) {
$metadata['replace'] = $replace; $metadata['replace'] = $replace;

BIN
ext/upload/minus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

BIN
ext/upload/plus.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 B

View File

@ -1,4 +1,14 @@
/* Only need to change the file/url inputs */
#large_upload_form INPUT { #large_upload_form INPUT.wid {
width: 100%; width: 100%;
} }
#radio_button {
width: auto;
}
#wrapper {
opacity : 0.4;
filter: alpha(opacity=40); // msie
}
/* This is needed since the theme style.css forcibly sets vertical align to "top". */
TABLE.vert TD, TABLE.vert TH {vertical-align: middle;}

View File

@ -12,22 +12,58 @@ class UploadTheme extends Themelet {
public function display_page(Page $page) { public function display_page(Page $page) {
global $config; global $config;
$tl_enabled = ($config->get_string("transload_engine", "none") != "none"); $tl_enabled = ($config->get_string("transload_engine", "none") != "none");
// Uploader 2.0!
$upload_list = ""; $upload_list = "";
for($i=0; $i<$config->get_int('upload_count'); $i++) { for($i=0; $i<$config->get_int('upload_count'); $i++) {
$n = $i + 1; $a=$i+1;
$width = $tl_enabled ? "35%" : "80%"; $s=$i-1;
$upload_list .= " if(!$i==0){
<tr> $upload_list .="<tr id='row$i' style='display:none'>";
<td width='50'>File $n</td> }else{
<td width='250'><input id='data$i' name='data$i' type='file'></td> $upload_list .= "<tr id='row$i'>";
"; }
if($tl_enabled) { $upload_list .= "<td width='15'>";
$upload_list .= "
<td width='50'>URL $n</td> if($i==0){
<td width='250'><input id='url$i' name='url$i' type='text'></td> $upload_list .= "<div id='hide$i'><img id='wrapper' src='ext/upload/minus.png' />" .
"; "<a href='#' onclick='javascript:document.getElementById(&quot;row$a&quot;).style.display = &quot;&quot;;document.getElementById(&quot;hide$i&quot;).style.display = &quot;none&quot;;document.getElementById(&quot;hide$a&quot;).style.display = &quot;&quot;;'>".
} "<img src='ext/upload/plus.png'></a></div></td>";
}else{
$upload_list .="<div id='hide$i'>
<a href='#' onclick='javascript:document.getElementById(&quot;row$i&quot;).style.display = &quot;none&quot;;".
"document.getElementById(&quot;hide$i&quot;).style.display = &quot;none&quot;;".
"document.getElementById(&quot;hide$s&quot;).style.display = &quot;&quot;;".
"document.getElementById(&quot;data$i&quot;).value = &quot;&quot;;".
"document.getElementById(&quot;url$i&quot;).value = &quot;&quot;;'>".
"<img src='ext/upload/minus.png' /></a>";
if($a==$config->get_int('upload_count')){
$upload_list .="<img id='wrapper' src='ext/upload/plus.png' />";
}else{
$upload_list .=
"<a href='#' onclick='javascript:document.getElementById(&quot;row$a&quot;).style.display = &quot;&quot;;".
"document.getElementById(&quot;hide$i&quot;).style.display = &quot;none&quot;;".
"document.getElementById(&quot;hide$a&quot;).style.display = &quot;&quot;;'>".
"<img src='ext/upload/plus.png' /></a>";
}
$upload_list .= "</div></td>";
}
$upload_list .=
"<td width='60'><form><input id='radio_buttona' type='radio' name='method' value='file' checked='checked' onclick='javascript:document.getElementById(&quot;url$i&quot;).style.display = &quot;none&quot;;document.getElementById(&quot;url$i&quot;).value = &quot;&quot;;document.getElementById(&quot;data$i&quot;).style.display = &quot;&quot;' /> File<br>";
if($tl_enabled) {
$upload_list .=
"<input id='radio_buttonb' type='radio' name='method' value='url' onclick='javascript:document.getElementById(&quot;data$i&quot;).style.display = &quot;none&quot;;document.getElementById(&quot;data$i&quot;).value = &quot;&quot;;document.getElementById(&quot;url$i&quot;).style.display = &quot;&quot;' /> URL</ br></td></form>
<td><input id='data$i' name='data$i' class='wid' type='file'><input id='url$i' name='url$i' class='wid' type='text' style='display:none'></td>
";
}
else {
$upload_list .= "</form></td>
<td width='250'><input id='data$i' name='data$i' class='wid' type='file'></td>
";
}
$upload_list .= " $upload_list .= "
</tr> </tr>
"; ";
@ -51,30 +87,60 @@ class UploadTheme extends Themelet {
}); });
</script> </script>
".make_form(make_link("upload"), "POST", $multipart=True)." ".make_form(make_link("upload"), "POST", $multipart=True)."
<table id='large_upload_form'> <table id='large_upload_form' class='vert'>
$upload_list $upload_list
<tr><td>Tags</td><td colspan='3'><input id='tag_box' name='tags' type='text'></td></tr> <tr><td></td><td>Tags<td colspan='3'><input id='tag_box' name='tags' type='text'></td></tr>
<tr><td>Source</td><td colspan='3'><input name='source' type='text'></td></tr> <tr><td></td><td>Source</td><td colspan='3'><input name='source' type='text'></td></tr>
<tr><td colspan='4'><input id='uploadbutton' type='submit' value='Post'></td></tr> <tr><td colspan='4'><input id='uploadbutton' type='submit' value='Post'></td></tr>
</table> </table>
</form> </form>
<small>(Max file size is $max_kb)</small> <small>(Max file size is $max_kb)</small>
"; ";
if($tl_enabled) { if($tl_enabled) {
$link = make_http(make_link("upload")); $link = make_http(make_link("upload"));
$home = make_http(make_link());
$title = $config->get_string('title');
if($config->get_bool('nice_urls')){ if($config->get_bool('nice_urls')){
$delimiter = '?'; $delimiter = '?';
} else { } else {
$delimiter = '&amp;'; $delimiter = '&amp;';
} }
{
$js='javascript:(function(){if(typeof window=="undefined"||!window.location||window.location.href=="about:blank"){window.location="'. $home .'";}else if(typeof document=="undefined"||!document.body){window.location="'. $home .'?url="+encodeURIComponent(window.location.href);} else if(window.location.href.match("\/\/'. $_SERVER["HTTP_HOST"] .'.*")){alert("You are already at '. $title .'!");} else{var tags=prompt("Please enter tags","tagme");if(tags!=""&&tags!=null){var link="'. $link . $delimiter .'url="+location.href+"&tags="+tags;var w=window.open(link,"_blank");}}})();'; $title = "Upload to " . $config->get_string('title');
$html .= '<p><a href="javascript:location.href=&quot;' .
$html .= '<p><a href=\''.$js.'\'>Upload to '.$title.'</a> (Drag & drop onto your bookmarks toolbar, then click when looking at an image)'; $link . $delimiter . 'url=&quot;+location.href+&quot;&amp;tags=&quot;+prompt(&quot;enter tags&quot;)">' .
$title . '</a> (Drag & drop onto your bookmarks toolbar, then click when looking at an image)';
}
{
/* Danbooru > Shimmie Bookmarklet.
This "should" work on any site running danbooru, unless for some odd reason they switched around the id's or aren't using post/list.
Most likely this will stop working when Danbooru updates to v2, all depends if they switch the ids or not >_>.
Clicking the link on a danbooru image page should give you something along the lines of:
'http://www.website.com/shimmie/upload?url="http://sonohara.donmai.us/data/crazylongurl.jpg&tags="too many tags"&rating="s"&source="http://danbooru.donmai.us/post/show/012345/"'
TODO: Possibly make the entire/most of the script into a .js file, and just make the bookmarklet load it on click (Something like that?)
*/
$title = "Danbooru to " . $config->get_string('title');
$html .= '<p><a href="javascript:'.
/* This should stop the bookmarklet being insanely long...not that it's already huge or anything. */
'var ste=&quot;'. $link . $delimiter .'url=&quot;;var tag=document.getElementById(&quot;post_tags&quot;).value;var rtg=document.documentElement.innerHTML.match(&quot;<li>Rating: (.*)<\/li>&quot;);var srx=&quot;http://&quot; + document.location.hostname+document.location.href.match(&quot;\/post\/show\/.*\/&quot;);' .
//The default confirm sucks, mainly due to being unable to change the text in the Ok/Cancel box (Yes/No would be better.)
'if (confirm(&quot;OK = Use Current tags.\nCancel = Use new tags.&quot;)==true){' . //Just incase some people don't want the insane amount of tags danbooru has.
//The flash check is kind of picky, although it should work on "most" images..there will be either some old or extremely new ones that lack the flash tag.
'if(tag.search(/\bflash\b/)==-1){'.
'location.href=ste+document.getElementById(&quot;highres&quot;).href+&quot;&amp;tags=&quot;+tag+&quot;&amp;rating=&quot;+rtg[1]+&quot;&amp;source=&quot;+srx;}'.
'else{'.
'location.href=ste+document.getElementsByName(&quot;movie&quot;)[0].value+&quot;&amp;tags=&quot;+tag+&quot;&amp;rating=&quot;+rtg[1]+&quot;&amp;source=&quot;+srx;}'.
//The following is more or less the same as above, instead using the tags on danbooru, should load a prompt box instead.
'}else{'.
'var p=prompt(&quot;Enter Tags&quot;,&quot;&quot;);'.
'if(tag.search(/\bflash\b/)==-1){'.
'location.href=ste+document.getElementById(&quot;highres&quot;).href+&quot;&amp;tags=&quot;+p+&quot;&amp;rating=&quot;+rtg[1]+&quot;&amp;source=&quot;+srx;}' .
'else{'.
'location.href=ste+document.getElementsByName(&quot;movie&quot;)[0].value+&quot;&amp;tags=&quot;+p+&quot;&amp;rating=&quot;+rtg[1]+&quot;&amp;source=&quot;+srx;}'.
'}">' .
$title . '</a> (As above, Click on a Danbooru-run image page. (This also grabs the tags/rating/source!))';
}
} }
$page->set_title("Upload"); $page->set_title("Upload");
@ -89,21 +155,18 @@ class UploadTheme extends Themelet {
$tl_enabled = ($config->get_string("transload_engine", "none") != "none"); $tl_enabled = ($config->get_string("transload_engine", "none") != "none");
$upload_list = ''; $upload_list = '';
$width = $tl_enabled ? "35%" : "80%";
$upload_list .= " $upload_list .= "
<tr> <tr>
<td width='50'>File</td> <td width='60'><form><input id='radio_buttona' type='radio' name='method' value='file' checked='checked' onclick='javascript:document.getElementById(&quot;url0&quot;).style.display = &quot;none&quot;;document.getElementById(&quot;url0&quot;).value = &quot;&quot;;document.getElementById(&quot;data0&quot;).style.display = &quot;&quot;' /> File<br>";
<td width='250'><input id='data0' name='data0' type='file'></td> if($tl_enabled) {
</tr> $upload_list .="
"; <input id='radio_buttonb' type='radio' name='method' value='url' onclick='javascript:document.getElementById(&quot;data0&quot;).style.display = &quot;none&quot;;document.getElementById(&quot;data0&quot;).value = &quot;&quot;;document.getElementById(&quot;url0&quot;).style.display = &quot;&quot;' /> URL</ br></td></form>
if($tl_enabled) { <td><input id='data0' name='data0' class='wid' type='file'><input id='url0' name='url0' class='wid' type='text' style='display:none'></td>
$upload_list .= " ";
<tr> } else {
<td width='50'>URL</td> $upload_list .= "</form></td>
<td width='250'><input id='url0' name='url0' type='text'></td> ";
</tr> }
";
}
$max_size = $config->get_int('upload_size'); $max_size = $config->get_int('upload_size');
$max_kb = to_shorthand_int($max_size); $max_kb = to_shorthand_int($max_size);
@ -117,7 +180,7 @@ class UploadTheme extends Themelet {
.$thumbnail."<br>" .$thumbnail."<br>"
.make_form(make_link("upload/replace/".$image_id), "POST", $multipart=True)." .make_form(make_link("upload/replace/".$image_id), "POST", $multipart=True)."
<input type='hidden' name='image_id' value='$image_id'> <input type='hidden' name='image_id' value='$image_id'>
<table id='large_upload_form'> <table id='large_upload_form' class='vert'>
$upload_list $upload_list
<tr><td>Source</td><td colspan='3'><input name='source' type='text'></td></tr> <tr><td>Source</td><td colspan='3'><input name='source' type='text'></td></tr>
<tr><td colspan='4'><input id='uploadbutton' type='submit' value='Post'></td></tr> <tr><td colspan='4'><input id='uploadbutton' type='submit' value='Post'></td></tr>
@ -187,4 +250,4 @@ class UploadTheme extends Themelet {
"; ";
} }
} }
?> ?>

View File

@ -79,6 +79,11 @@ class UserPage extends SimpleExtension {
} }
else if($event->get_arg(0) == "logout") { else if($event->get_arg(0) == "logout") {
set_prefixed_cookie("session", "", time()+60*60*24*$config->get_int('login_memory'), "/"); set_prefixed_cookie("session", "", time()+60*60*24*$config->get_int('login_memory'), "/");
if(CACHE_HTTP) {
# to keep as few versions of content as possible,
# make cookies all-or-nothing
set_prefixed_cookie("user", "", time()+60*60*24*$config->get_int('login_memory'), "/");
}
log_info("user", "Logged out"); log_info("user", "Logged out");
$page->set_mode("redirect"); $page->set_mode("redirect");
$page->set_redirect(make_link()); $page->set_redirect(make_link());
@ -161,8 +166,8 @@ class UserPage extends SimpleExtension {
public function onUserPageBuilding(Event $event) { public function onUserPageBuilding(Event $event) {
global $page, $user, $config; global $page, $user, $config;
$h_join_date = html_escape($event->display_user->join_date); $h_join_date = autodate($event->display_user->join_date);
$event->add_stats("Join date: $h_join_date", 10); $event->add_stats("Joined: $h_join_date", 10);
$av = $event->display_user->get_avatar_html(); $av = $event->display_user->get_avatar_html();
if($av) $event->add_stats($av, 0); if($av) $event->add_stats($av, 0);
@ -228,6 +233,8 @@ class UserPage extends SimpleExtension {
} }
public function onSearchTermParse(Event $event) { public function onSearchTermParse(Event $event) {
global $user;
$matches = array(); $matches = array();
if(preg_match("/^(poster|user)=(.*)$/i", $event->term, $matches)) { if(preg_match("/^(poster|user)=(.*)$/i", $event->term, $matches)) {
$user = User::by_name($matches[2]); $user = User::by_name($matches[2]);
@ -243,6 +250,10 @@ class UserPage extends SimpleExtension {
$user_id = int_escape($matches[2]); $user_id = int_escape($matches[2]);
$event->add_querylet(new Querylet("images.owner_id = $user_id")); $event->add_querylet(new Querylet("images.owner_id = $user_id"));
} }
else if($user->is_admin() && preg_match("/^(poster|user)_ip=([0-9\.]+)$/i", $event->term, $matches)) {
$user_ip = $matches[2]; // FIXME: ip_escape?
$event->add_querylet(new Querylet("images.owner_ip = '$user_ip'"));
}
} }
// }}} // }}}
// Things done *with* the user {{{ // Things done *with* the user {{{

View File

@ -94,7 +94,7 @@ class ViewImageTheme extends Themelet {
$html .= " ($h_ip)"; $html .= " ($h_ip)";
} }
if(!is_null($image->source)) { if(!is_null($image->source)) {
if(substr($image->source, 0, 7) == "http://") { if(substr($image->source, 0, 7) == "http://" || substr($image->source, 0, 8) == "https://") {
$html .= " (<a href='$h_source'>source</a>)"; $html .= " (<a href='$h_source'>source</a>)";
} }
else { else {

View File

@ -50,22 +50,26 @@
* Each of these can be imported at the start of a function with eg "global $page, $user;" * Each of these can be imported at the start of a function with eg "global $page, $user;"
*/ */
// set up and purify the environment
define("DEBUG", true);
define("COVERAGE", true);
define("CONTEXT", false);
define("CACHE_MEMCACHE", false);
define("CACHE_DIR", false);
define("VERSION", 'trunk');
define("SCORE_VERSION", 's2hack/'.VERSION);
define("COOKIE_PREFIX", 'shm');
if(empty($database_dsn) && !file_exists("config.php")) { if(empty($database_dsn) && !file_exists("config.php")) {
header("Location: install.php"); header("Location: install.php");
exit; exit;
} }
require_once "config.php"; require_once "config.php";
// set up and purify the environment
define("DEBUG", false);
define("COVERAGE", false);
define("CONTEXT", false);
define("CACHE_MEMCACHE", false);
define("CACHE_DIR", false);
define("CACHE_HTTP", false);
define("VERSION", 'trunk');
define("SCORE_VERSION", 's2hack/'.VERSION);
define("COOKIE_PREFIX", 'shm');
define("SPEED_HAX", false);
define("FORCE_NICE_URLS", false);
define("WH_SPLITS", 1);
require_once "core/util.inc.php"; require_once "core/util.inc.php";
require_once "lib/context.php"; require_once "lib/context.php";
if(CONTEXT) { if(CONTEXT) {

146
lib/jquery.timeago.js Normal file
View File

@ -0,0 +1,146 @@
/**
* Timeago is a jQuery plugin that makes it easy to support automatically
* updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago").
*
* @name timeago
* @version 0.10.0
* @requires jQuery v1.2.3+
* @author Ryan McGeary
* @license MIT License - http://www.opensource.org/licenses/mit-license.php
*
* For usage and examples, visit:
* http://timeago.yarp.com/
*
* Copyright (c) 2008-2011, Ryan McGeary (ryanonjavascript -[at]- mcgeary [*dot*] org)
*/
(function($) {
$.timeago = function(timestamp) {
if (timestamp instanceof Date) {
return inWords(timestamp);
} else if (typeof timestamp === "string") {
return inWords($.timeago.parse(timestamp));
} else {
return inWords($.timeago.datetime(timestamp));
}
};
var $t = $.timeago;
$.extend($.timeago, {
settings: {
refreshMillis: 60000,
allowFuture: false,
strings: {
prefixAgo: null,
prefixFromNow: null,
suffixAgo: "ago",
suffixFromNow: "from now",
seconds: "less than a minute",
minute: "about a minute",
minutes: "%d minutes",
hour: "about an hour",
hours: "about %d hours",
day: "a day",
days: "%d days",
month: "about a month",
months: "%d months",
year: "about a year",
years: "%d years",
numbers: []
}
},
inWords: function(distanceMillis) {
var $l = this.settings.strings;
var prefix = $l.prefixAgo;
var suffix = $l.suffixAgo;
if (this.settings.allowFuture) {
if (distanceMillis < 0) {
prefix = $l.prefixFromNow;
suffix = $l.suffixFromNow;
}
}
var seconds = Math.abs(distanceMillis) / 1000;
var minutes = seconds / 60;
var hours = minutes / 60;
var days = hours / 24;
var years = days / 365;
function substitute(stringOrFunction, number) {
var string = $.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction;
var value = ($l.numbers && $l.numbers[number]) || number;
return string.replace(/%d/i, value);
}
var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) ||
seconds < 90 && substitute($l.minute, 1) ||
minutes < 45 && substitute($l.minutes, Math.round(minutes)) ||
minutes < 90 && substitute($l.hour, 1) ||
hours < 24 && substitute($l.hours, Math.round(hours)) ||
hours < 48 && substitute($l.day, 1) ||
days < 30 && substitute($l.days, Math.floor(days)) ||
days < 60 && substitute($l.month, 1) ||
days < 365 && substitute($l.months, Math.floor(days / 30)) ||
years < 2 && substitute($l.year, 1) ||
substitute($l.years, Math.floor(years));
return $.trim([prefix, words, suffix].join(" "));
},
parse: function(iso8601) {
var s = $.trim(iso8601);
s = s.replace(/\.\d\d\d+/,""); // remove milliseconds
s = s.replace(/-/,"/").replace(/-/,"/");
s = s.replace(/T/," ").replace(/Z/," UTC");
s = s.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400
return new Date(s);
},
datetime: function(elem) {
// jQuery's `is()` doesn't play well with HTML5 in IE
var isTime = $(elem).get(0).tagName.toLowerCase() === "time"; // $(elem).is("time");
var iso8601 = isTime ? $(elem).attr("datetime") : $(elem).attr("title");
return $t.parse(iso8601);
}
});
$.fn.timeago = function() {
var self = this;
self.each(refresh);
var $s = $t.settings;
if ($s.refreshMillis > 0) {
setInterval(function() { self.each(refresh); }, $s.refreshMillis);
}
return self;
};
function refresh() {
var data = prepareData(this);
if (!isNaN(data.datetime)) {
$(this).text(inWords(data.datetime));
}
return this;
}
function prepareData(element) {
element = $(element);
if (!element.data("timeago")) {
element.data("timeago", { datetime: $t.datetime(element) });
var text = $.trim(element.text());
if (text.length > 0) {
element.attr("title", text);
}
}
return element.data("timeago");
}
function inWords(date) {
return $t.inWords(distance(date));
}
function distance(date) {
return (new Date().getTime() - date.getTime());
}
// fix for IE6 suckage
document.createElement("abbr");
document.createElement("time");
}(jQuery));

View File

@ -4,7 +4,7 @@
* - Documentation and latest version * - Documentation and latest version
* http://recaptcha.net/plugins/php/ * http://recaptcha.net/plugins/php/
* - Get a reCAPTCHA API Key * - Get a reCAPTCHA API Key
* http://recaptcha.net/api/getkey * https://www.google.com/recaptcha/admin/create
* - Discussion group * - Discussion group
* http://groups.google.com/group/recaptcha * http://groups.google.com/group/recaptcha
* *
@ -35,9 +35,9 @@
/** /**
* The reCAPTCHA server URL's * The reCAPTCHA server URL's
*/ */
define("RECAPTCHA_API_SERVER", "http://api.recaptcha.net"); define("RECAPTCHA_API_SERVER", "http://www.google.com/recaptcha/api");
define("RECAPTCHA_API_SECURE_SERVER", "https://api-secure.recaptcha.net"); define("RECAPTCHA_API_SECURE_SERVER", "https://www.google.com/recaptcha/api");
define("RECAPTCHA_VERIFY_SERVER", "api-verify.recaptcha.net"); define("RECAPTCHA_VERIFY_SERVER", "www.google.com");
/** /**
* Encodes the given data into a query string format * Encodes the given data into a query string format
@ -106,7 +106,7 @@ function _recaptcha_http_post($host, $path, $data, $port = 80) {
function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false) function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false)
{ {
if ($pubkey == null || $pubkey == '') { if ($pubkey == null || $pubkey == '') {
die ("To use reCAPTCHA you must get an API key from <a href='http://recaptcha.net/api/getkey'>http://recaptcha.net/api/getkey</a>"); die ("To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>");
} }
if ($use_ssl) { if ($use_ssl) {
@ -152,7 +152,7 @@ class ReCaptchaResponse {
function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $extra_params = array()) function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $extra_params = array())
{ {
if ($privkey == null || $privkey == '') { if ($privkey == null || $privkey == '') {
die ("To use reCAPTCHA you must get an API key from <a href='http://recaptcha.net/api/getkey'>http://recaptcha.net/api/getkey</a>"); die ("To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>");
} }
if ($remoteip == null || $remoteip == '') { if ($remoteip == null || $remoteip == '') {
@ -169,7 +169,7 @@ function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $ex
return $recaptcha_response; return $recaptcha_response;
} }
$response = _recaptcha_http_post (RECAPTCHA_VERIFY_SERVER, "/verify", $response = _recaptcha_http_post (RECAPTCHA_VERIFY_SERVER, "/recaptcha/api/verify",
array ( array (
'privatekey' => $privkey, 'privatekey' => $privkey,
'remoteip' => $remoteip, 'remoteip' => $remoteip,
@ -200,7 +200,7 @@ function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $ex
* @param string $appname The name of your application * @param string $appname The name of your application
*/ */
function recaptcha_get_signup_url ($domain = null, $appname = null) { function recaptcha_get_signup_url ($domain = null, $appname = null) {
return "http://recaptcha.net/api/getkey?" . _recaptcha_qsencode (array ('domain' => $domain, 'app' => $appname)); return "https://www.google.com/recaptcha/admin/create?" . _recaptcha_qsencode (array ('domains' => $domain, 'app' => $appname));
} }
function _recaptcha_aes_pad($val) { function _recaptcha_aes_pad($val) {
@ -230,14 +230,14 @@ function _recaptcha_mailhide_urlbase64 ($x) {
function recaptcha_mailhide_url($pubkey, $privkey, $email) { function recaptcha_mailhide_url($pubkey, $privkey, $email) {
if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null) { if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null) {
die ("To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " . die ("To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " .
"you can do so at <a href='http://mailhide.recaptcha.net/apikey'>http://mailhide.recaptcha.net/apikey</a>"); "you can do so at <a href='http://www.google.com/recaptcha/mailhide/apikey'>http://www.google.com/recaptcha/mailhide/apikey</a>");
} }
$ky = pack('H*', $privkey); $ky = pack('H*', $privkey);
$cryptmail = _recaptcha_aes_encrypt ($email, $ky); $cryptmail = _recaptcha_aes_encrypt ($email, $ky);
return "http://mailhide.recaptcha.net/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ($cryptmail); return "http://www.google.com/recaptcha/mailhide/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ($cryptmail);
} }
/** /**
@ -262,7 +262,7 @@ function _recaptcha_mailhide_email_parts ($email) {
* Gets html to display an email address given a public an private key. * Gets html to display an email address given a public an private key.
* to get a key, go to: * to get a key, go to:
* *
* http://mailhide.recaptcha.net/apikey * http://www.google.com/recaptcha/mailhide/apikey
*/ */
function recaptcha_mailhide_html($pubkey, $privkey, $email) { function recaptcha_mailhide_html($pubkey, $privkey, $email) {
$emailparts = _recaptcha_mailhide_email_parts ($email); $emailparts = _recaptcha_mailhide_email_parts ($email);

View File

@ -26,6 +26,7 @@ $(document).ready(function() {
$confirm.dialog('open'); $confirm.dialog('open');
}); });
$("time").timeago();
}); });
var defaultTexts = new Array(); var defaultTexts = new Array();

View File

@ -88,7 +88,7 @@ class Layout {
$debug = get_debug_info(); $debug = get_debug_info();
$contact = empty($contact_link) ? "" : "<br><a href='$contact_link'>Contact</a>"; $contact = empty($contact_link) ? "" : "<br><a href='mailto:$contact_link'>Contact</a>";
if(empty($this->subheading)) { if(empty($this->subheading)) {
$subheading = ""; $subheading = "";
@ -219,7 +219,7 @@ $header_html
<em> <em>
Images &copy; their respective owners, Images &copy; their respective owners,
<a href="http://code.shishnet.org/shimmie2/">Shimmie</a> &copy; <a href="http://code.shishnet.org/shimmie2/">Shimmie</a> &copy;
<a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2011, <a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2012,
based on the Danbooru concept. based on the Danbooru concept.
$debug $debug
$contact $contact

View File

@ -18,9 +18,33 @@ class Themelet {
public function build_thumb_html(Image $image, $query=null) { public function build_thumb_html(Image $image, $query=null) {
global $config; global $config;
$h_view_link = make_link("post/view/{$image->id}", $query); $h_view_link = make_link("post/view/{$image->id}", $query);
$h_tip = html_escape($image->get_tooltip());
$h_thumb_link = $image->get_thumb_link(); $h_thumb_link = $image->get_thumb_link();
$tsize = get_thumbnail_size($image->width, $image->height);
// Removes the size tag if the file is an mp3
if($image->ext == 'mp3'){
$iitip = $image->get_tooltip();
$mp3tip = array("0x0");
$h_tip = str_replace($mp3tip, " ", $iitip);
// Makes it work with a variation of the default tooltips (I.E $tags // $filesize // $size)
$justincase = array(" //", "// ", " //", "// ", " ");
if(strstr($h_tip, " ")){
$h_tip = html_escape(str_replace($justincase, "", $h_tip));
}else{
$h_tip = html_escape($h_tip);
}
}else{
$h_tip = html_escape($image->get_tooltip());
}
// If file is flash or svg then sets thumbnail to max size.
if($image->ext == 'swf' || $image->ext == 'svg'){
$tsize = get_thumbnail_size($config->get_int('thumb_width'), $config->get_int('thumb_height')); }
else{
$tsize = get_thumbnail_size($image->width, $image->height); }
return "<a href='$h_view_link'><img title='$h_tip' alt='$h_tip' ". return "<a href='$h_view_link'><img title='$h_tip' alt='$h_tip' ".
"width='{$tsize[0]}' height='{$tsize[1]}' src='$h_thumb_link' /></a>"; "width='{$tsize[0]}' height='{$tsize[1]}' src='$h_thumb_link' /></a>";
} }

View File

@ -6,7 +6,7 @@ class CustomViewImageTheme extends ViewImageTheme {
$page->set_title("Image {$image->id}: ".html_escape($image->get_tag_list())); $page->set_title("Image {$image->id}: ".html_escape($image->get_tag_list()));
$page->set_heading(html_escape($image->get_tag_list())); $page->set_heading(html_escape($image->get_tag_list()));
$page->add_block(new Block("Navigation", $this->build_navigation($image), "left", 0)); $page->add_block(new Block("Navigation", $this->build_navigation($image), "left", 0));
$page->add_block(new Block("Statistics", $this->build_stats($image), "left", 10)); $page->add_block(new Block("Statistics", $this->build_stats($image), "left", 15));
$page->add_block(new Block(null, $this->build_image_editor($image, $editor_parts), "main", 10)); $page->add_block(new Block(null, $this->build_image_editor($image, $editor_parts), "main", 10));
$page->add_block(new Block(null, $this->build_pin($image), "main", 11)); $page->add_block(new Block(null, $this->build_pin($image), "main", 11));
} }

View File

@ -42,7 +42,7 @@ class Layout {
$debug = get_debug_info(); $debug = get_debug_info();
$contact = empty($contact_link) ? "" : "<br><a href='$contact_link'>Contact</a>"; $contact = empty($contact_link) ? "" : "<br><a href='mailto:$contact_link'>Contact</a>";
$wrapper = ""; $wrapper = "";
if(strlen($page->heading) > 100) { if(strlen($page->heading) > 100) {
@ -71,7 +71,7 @@ $header_html
<div id="footer"> <div id="footer">
Images &copy; their respective owners, Images &copy; their respective owners,
<a href="http://code.shishnet.org/shimmie2/">Shimmie</a> &copy; <a href="http://code.shishnet.org/shimmie2/">Shimmie</a> &copy;
<a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2011, <a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2012,
based on the Danbooru concept. based on the Danbooru concept.
$debug $debug
$contact $contact

View File

@ -128,6 +128,10 @@ UL {
.comment { .comment {
text-align: left; text-align: left;
} }
.comment .timeago {
float: right;
font-size: 75%;
}
.more:after { .more:after {
content: " >>>"; content: " >>>";

View File

@ -31,9 +31,33 @@ class Themelet {
global $config; global $config;
$i_id = int_escape($image->id); $i_id = int_escape($image->id);
$h_view_link = make_link("post/view/$i_id", $query); $h_view_link = make_link("post/view/$i_id", $query);
$h_tip = html_escape($image->get_tooltip());
$h_thumb_link = $image->get_thumb_link(); $h_thumb_link = $image->get_thumb_link();
$tsize = get_thumbnail_size($image->width, $image->height);
// Removes the size tag if the file is an mp3
if($image->ext == 'mp3'){
$iitip = $image->get_tooltip();
$mp3tip = array("0x0");
$h_tip = str_replace($mp3tip, " ", $iitip);
// Makes it work with a variation of the default tooltips (I.E $tags // $filesize // $size)
$justincase = array(" //", "// ", " //", "// ", " ");
if(strstr($h_tip, " ")){
$h_tip = html_escape(str_replace($justincase, "", $h_tip));
}else{
$h_tip = html_escape($h_tip);
}
}else{
$h_tip = html_escape($image->get_tooltip());
}
// If file is flash or svg then sets thumbnail to max size.
if($image->ext == 'swf' || $image->ext == 'svg'){
$tsize = get_thumbnail_size($config->get_int('thumb_width'), $config->get_int('thumb_height')); }
else{
$tsize = get_thumbnail_size($image->width, $image->height); }
return " return "
<!-- cancel border --> <!-- cancel border -->
<div class='thumbblock'> <div class='thumbblock'>

View File

@ -42,7 +42,7 @@ class Layout {
$debug = get_debug_info(); $debug = get_debug_info();
$contact = empty($contact_link) ? "" : "<br><a href='$contact_link'>Contact</a>"; $contact = empty($contact_link) ? "" : "<br><a href='mailto:$contact_link'>Contact</a>";
$subheading = empty($page->subheading) ? "" : "<div id='subtitle'>{$page->subheading}</div>"; $subheading = empty($page->subheading) ? "" : "<div id='subtitle'>{$page->subheading}</div>";
$wrapper = ""; $wrapper = "";
@ -71,7 +71,7 @@ $header_html
<div id="footer"> <div id="footer">
Images &copy; their respective owners, Images &copy; their respective owners,
<a href="http://code.shishnet.org/shimmie2/">Shimmie</a> &copy; <a href="http://code.shishnet.org/shimmie2/">Shimmie</a> &copy;
<a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2011, <a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2012,
based on the Danbooru concept. based on the Danbooru concept.
$debug $debug
$contact $contact

View File

@ -31,9 +31,33 @@ class Themelet {
global $config; global $config;
$i_id = int_escape($image->id); $i_id = int_escape($image->id);
$h_view_link = make_link("post/view/$i_id", $query); $h_view_link = make_link("post/view/$i_id", $query);
$h_tip = html_escape($image->get_tooltip());
$h_thumb_link = $image->get_thumb_link(); $h_thumb_link = $image->get_thumb_link();
$tsize = get_thumbnail_size($image->width, $image->height);
// Removes the size tag if the file is an mp3
if($image->ext == 'mp3'){
$iitip = $image->get_tooltip();
$mp3tip = array("0x0");
$h_tip = str_replace($mp3tip, " ", $iitip);
// Makes it work with a variation of the default tooltips (I.E $tags // $filesize // $size)
$justincase = array(" //", "// ", " //", "// ", " ");
if(strstr($h_tip, " ")){
$h_tip = html_escape(str_replace($justincase, "", $h_tip));
}else{
$h_tip = html_escape($h_tip);
}
}else{
$h_tip = html_escape($image->get_tooltip());
}
// If file is flash or svg then sets thumbnail to max size.
if($image->ext == 'swf' || $image->ext == 'svg'){
$tsize = get_thumbnail_size($config->get_int('thumb_width'), $config->get_int('thumb_height')); }
else{
$tsize = get_thumbnail_size($image->width, $image->height); }
return " return "
<div class='thumbblock'> <div class='thumbblock'>
<div class='rr thumb'> <div class='rr thumb'>

View File

@ -37,7 +37,7 @@ class Layout {
$debug = get_debug_info(); $debug = get_debug_info();
$contact = empty($contact_link) ? "" : "<br><a href='$contact_link'>Contact</a>"; $contact = empty($contact_link) ? "" : "<br><a href='mailto:$contact_link'>Contact</a>";
if(empty($page->subheading)) { if(empty($page->subheading)) {
$subheading = ""; $subheading = "";
@ -79,7 +79,7 @@ $header_html
<hr> <hr>
Images &copy; their respective owners, Images &copy; their respective owners,
<a href="http://code.shishnet.org/shimmie2/">Shimmie</a> &copy; <a href="http://code.shishnet.org/shimmie2/">Shimmie</a> &copy;
<a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2011, <a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2012,
based on the Danbooru concept. based on the Danbooru concept.
<br>Futaba theme based on 4chan's layout and CSS :3 <br>Futaba theme based on 4chan's layout and CSS :3
$debug $debug

View File

@ -19,9 +19,33 @@ class Themelet {
public function build_thumb_html(Image $image, $query=null) { public function build_thumb_html(Image $image, $query=null) {
global $config; global $config;
$h_view_link = make_link("post/view/{$image->id}", $query); $h_view_link = make_link("post/view/{$image->id}", $query);
$h_tip = html_escape($image->get_tooltip());
$h_thumb_link = $image->get_thumb_link(); $h_thumb_link = $image->get_thumb_link();
$tsize = get_thumbnail_size($image->width, $image->height);
// Removes the size tag if the file is an mp3
if($image->ext == 'mp3'){
$iitip = $image->get_tooltip();
$mp3tip = array("0x0");
$h_tip = str_replace($mp3tip, " ", $iitip);
// Makes it work with a variation of the default tooltips (I.E $tags // $filesize // $size)
$justincase = array(" //", "// ", " //", "// ", " ");
if(strstr($h_tip, " ")){
$h_tip = html_escape(str_replace($justincase, "", $h_tip));
}else{
$h_tip = html_escape($h_tip);
}
}else{
$h_tip = html_escape($image->get_tooltip());
}
// If file is flash or svg then sets thumbnail to max size.
if($image->ext == 'swf' || $image->ext == 'svg'){
$tsize = get_thumbnail_size($config->get_int('thumb_width'), $config->get_int('thumb_height')); }
else{
$tsize = get_thumbnail_size($image->width, $image->height); }
return "<a class='thumb' href='$h_view_link'><img title='$h_tip' alt='$h_tip' ". return "<a class='thumb' href='$h_view_link'><img title='$h_tip' alt='$h_tip' ".
"width='{$tsize[0]}' height='{$tsize[1]}' src='$h_thumb_link' /></a>"; "width='{$tsize[0]}' height='{$tsize[1]}' src='$h_thumb_link' /></a>";
} }

View File

@ -138,7 +138,7 @@ class Layout {
$debug = get_debug_info(); $debug = get_debug_info();
$contact = empty($contact_link) ? "" : "<br><a href='$contact_link'>Contact</a>"; $contact = empty($contact_link) ? "" : "<br><a href='mailto:$contact_link'>Contact</a>";
$subheading = empty($page->subheading) ? "" : "<div id='subtitle'>{$page->subheading}</div>"; $subheading = empty($page->subheading) ? "" : "<div id='subtitle'>{$page->subheading}</div>";
$wrapper = ""; $wrapper = "";
@ -176,7 +176,7 @@ class Layout {
<div id="footer"> <div id="footer">
Images &copy; their respective owners, Images &copy; their respective owners,
<a href="http://code.shishnet.org/shimmie2/">Shimmie</a> &copy; <a href="http://code.shishnet.org/shimmie2/">Shimmie</a> &copy;
<a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2011, <a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2012,
based on the Danbooru concept.<br /> based on the Danbooru concept.<br />
Lite Theme by <a href="http://seemslegit.com">Zach</a> Lite Theme by <a href="http://seemslegit.com">Zach</a>
$debug $debug

View File

@ -31,17 +31,41 @@ class Themelet {
global $config; global $config;
$i_id = int_escape($image->id); $i_id = int_escape($image->id);
$h_view_link = make_link("post/view/$i_id", $query); $h_view_link = make_link("post/view/$i_id", $query);
$h_tip = html_escape($image->get_tooltip());
$h_thumb_link = $image->get_thumb_link(); $h_thumb_link = $image->get_thumb_link();
$tsize = get_thumbnail_size($image->width, $image->height);
// Removes the size tag if the file is an mp3
if($image->ext == 'mp3'){
$iitip = $image->get_tooltip();
$mp3tip = array("0x0");
$h_tip = str_replace($mp3tip, " ", $iitip);
// Makes it work with a variation of the default tooltips (I.E $tags // $filesize // $size)
$justincase = array(" //", "// ", " //", "// ", " ");
if(strstr($h_tip, " ")){
$h_tip = html_escape(str_replace($justincase, "", $h_tip));
}else{
$h_tip = html_escape($h_tip);
}
}else{
$h_tip = html_escape($image->get_tooltip());
}
// If file is flash or svg then sets thumbnail to max size.
if($image->ext == 'swf' || $image->ext == 'svg'){
$tsize = get_thumbnail_size($config->get_int('thumb_width'), $config->get_int('thumb_height')); }
else{
$tsize = get_thumbnail_size($image->width, $image->height); }
return " return "
<div class='thumbblock'> <center><div class='thumbblock'>
<a href='$h_view_link' style='position: relative; display: block; height: {$tsize[1]}px; width: {$tsize[0]}px;'> <a href='$h_view_link' style='position: relative; display: block; height: {$tsize[1]}px; width: {$tsize[0]}px;'>
<img id='thumb_$i_id' title='$h_tip' alt='$h_tip' class='highlighted' style='height: {$tsize[1]}px; width: {$tsize[0]}px;' src='$h_thumb_link'> <img id='thumb_$i_id' title='$h_tip' alt='$h_tip' class='highlighted' style='height: {$tsize[1]}px; width: {$tsize[0]}px;' src='$h_thumb_link'>
</a> </a>
</div> </div></center>
"; ";
} }

View File

@ -3,10 +3,16 @@
class CustomViewImageTheme extends ViewImageTheme { class CustomViewImageTheme extends ViewImageTheme {
public function display_page($image, $editor_parts) { public function display_page($image, $editor_parts) {
global $page; global $page;
$metatags = str_replace(" ", ", ", html_escape($image->get_tag_list()));
$page->set_title("Image {$image->id}: ".html_escape($image->get_tag_list())); $page->set_title("Image {$image->id}: ".html_escape($image->get_tag_list()));
$page->set_heading(html_escape($image->get_tag_list())); $page->set_heading(html_escape($image->get_tag_list()));
$page->add_html_header("<meta name=\"keywords\" content=\"$metatags\">");
$page->add_html_header("<meta property=\"og:title\" content=\"$metatags\">");
$page->add_html_header("<meta property=\"og:type\" content=\"article\">");
$page->add_html_header("<meta property=\"og:image\" content=\"".make_http($image->get_thumb_link())."\">");
$page->add_html_header("<meta property=\"og:url\" content=\"".make_http(make_link("post/view/{$image->id}"))."\">");
$page->add_block(new Block("Navigation", $this->build_navigation($image), "left", 0)); $page->add_block(new Block("Navigation", $this->build_navigation($image), "left", 0));
$page->add_block(new Block("Statistics", $this->build_stats($image), "left", 10)); $page->add_block(new Block("Statistics", $this->build_stats($image), "left", 15));
$page->add_block(new Block(null, $this->build_image_editor($image, $editor_parts), "main", 10)); $page->add_block(new Block(null, $this->build_image_editor($image, $editor_parts), "main", 10));
$page->add_block(new Block(null, $this->build_pin($image), "main", 11)); $page->add_block(new Block(null, $this->build_pin($image), "main", 11));
} }

View File

@ -37,7 +37,7 @@ class Layout {
$debug = get_debug_info(); $debug = get_debug_info();
$contact = empty($contact_link) ? "" : "<br><a href='$contact_link'>Contact</a>"; $contact = empty($contact_link) ? "" : "<br><a href='mailto:$contact_link'>Contact</a>";
$subheading = empty($page->subheading) ? "" : "<div id='subtitle'>{$page->subheading}</div>"; $subheading = empty($page->subheading) ? "" : "<div id='subtitle'>{$page->subheading}</div>";
$wrapper = ""; $wrapper = "";
@ -69,7 +69,7 @@ $header_html
<hr> <hr>
Images &copy; their respective owners, Images &copy; their respective owners,
<a href="http://code.shishnet.org/shimmie2/">Shimmie</a> &copy; <a href="http://code.shishnet.org/shimmie2/">Shimmie</a> &copy;
<a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2011, <a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2012,
based on the Danbooru concept. based on the Danbooru concept.
$debug $debug
$contact $contact

View File

@ -29,9 +29,33 @@ class Themelet {
global $config; global $config;
$i_id = int_escape($image->id); $i_id = int_escape($image->id);
$h_view_link = make_link("post/view/$i_id", $query); $h_view_link = make_link("post/view/$i_id", $query);
$h_tip = html_escape($image->get_tooltip());
$h_thumb_link = $image->get_thumb_link(); $h_thumb_link = $image->get_thumb_link();
$tsize = get_thumbnail_size($image->width, $image->height);
// Removes the size tag if the file is an mp3
if($image->ext == 'mp3'){
$iitip = $image->get_tooltip();
$mp3tip = array("0x0");
$h_tip = str_replace($mp3tip, " ", $iitip);
// Makes it work with a variation of the default tooltips (I.E $tags // $filesize // $size)
$justincase = array(" //", "// ", " //", "// ", " ");
if(strstr($h_tip, " ")){
$h_tip = html_escape(str_replace($justincase, "", $h_tip));
}else{
$h_tip = html_escape($h_tip);
}
}else{
$h_tip = html_escape($image->get_tooltip());
}
// If file is flash or svg then sets thumbnail to max size.
if($image->ext == 'swf' || $image->ext == 'svg'){
$tsize = get_thumbnail_size($config->get_int('thumb_width'), $config->get_int('thumb_height')); }
else{
$tsize = get_thumbnail_size($image->width, $image->height); }
return "<a class='thumb' href='$h_view_link'><img id='$i_id' title='$h_tip' alt='$h_tip' ". return "<a class='thumb' href='$h_view_link'><img id='$i_id' title='$h_tip' alt='$h_tip' ".
"width='{$tsize[0]}' height='{$tsize[1]}' src='$h_thumb_link' /></a>"; "width='{$tsize[0]}' height='{$tsize[1]}' src='$h_thumb_link' /></a>";
} }

View File

@ -10,7 +10,9 @@ class Layout {
global $config; global $config;
$theme_name = $config->get_string('theme', 'default'); $theme_name = $config->get_string('theme', 'default');
$site_name = $config->get_string('title');
$data_href = get_base_href(); $data_href = get_base_href();
$main_page = $config->get_string('main_page');
$contact_link = $config->get_string('contact_link'); $contact_link = $config->get_string('contact_link');
$header_html = ""; $header_html = "";
@ -45,7 +47,7 @@ class Layout {
$debug = get_debug_info(); $debug = get_debug_info();
$contact = empty($contact_link) ? "" : "<br><a href='$contact_link'>Contact</a>"; $contact = empty($contact_link) ? "" : "<br><a href='mailto:$contact_link'>Contact</a>";
$subheading = empty($page->subheading) ? "" : "<div id='subtitle'>{$page->subheading}</div>"; $subheading = empty($page->subheading) ? "" : "<div id='subtitle'>{$page->subheading}</div>";
$wrapper = ""; $wrapper = "";
@ -67,7 +69,7 @@ $header_html
<table id="header" class="bgtop" width="100%" height="113px"> <table id="header" class="bgtop" width="100%" height="113px">
<tr> <tr>
<td><center> <td><center>
<h1><a href="/">{$page->heading}</a></h1> <h1><a href="$data_href/$main_page">{$site_name}</a></h1>
<p>[Navigation links go here] <p>[Navigation links go here]
</center></td> </center></td>
$head_block_html $head_block_html
@ -83,7 +85,7 @@ $header_html
<div id="footer"> <div id="footer">
Images &copy; their respective owners, Images &copy; their respective owners,
<a href="http://code.shishnet.org/shimmie2/">Shimmie</a> &copy; <a href="http://code.shishnet.org/shimmie2/">Shimmie</a> &copy;
<a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2011, <a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2012,
based on the Danbooru concept. based on the Danbooru concept.
$debug $debug
$contact $contact

View File

@ -31,10 +31,34 @@ class Themelet {
global $config; global $config;
$i_id = int_escape($image->id); $i_id = int_escape($image->id);
$h_view_link = make_link("post/view/$i_id", $query); $h_view_link = make_link("post/view/$i_id", $query);
$h_tip = html_escape($image->get_tooltip());
$h_image_link = $image->get_image_link(); $h_image_link = $image->get_image_link();
$h_thumb_link = $image->get_thumb_link(); $h_thumb_link = $image->get_thumb_link();
$tsize = get_thumbnail_size($image->width, $image->height);
// Removes the size tag if the file is an mp3
if($image->ext == 'mp3'){
$iitip = $image->get_tooltip();
$mp3tip = array("0x0");
$h_tip = str_replace($mp3tip, " ", $iitip);
// Makes it work with a variation of the default tooltips (I.E $tags // $filesize // $size)
$justincase = array(" //", "// ", " //", "// ", " ");
if(strstr($h_tip, " ")){
$h_tip = html_escape(str_replace($justincase, "", $h_tip));
}else{
$h_tip = html_escape($h_tip);
}
}else{
$h_tip = html_escape($image->get_tooltip());
}
// If file is flash or svg then sets thumbnail to max size.
if($image->ext == 'swf' || $image->ext == 'svg'){
$tsize = get_thumbnail_size($config->get_int('thumb_width'), $config->get_int('thumb_height')); }
else{
$tsize = get_thumbnail_size($image->width, $image->height); }
return " return "
<div class='thumbblock'> <div class='thumbblock'>
<div class='rr thumb'> <div class='rr thumb'>