From 12a480ed8b612e7f804e5e49890b3b8a0405e257 Mon Sep 17 00:00:00 2001 From: "green-ponies (jgen)" Date: Thu, 3 Nov 2011 16:55:04 -0400 Subject: [PATCH 001/120] Fixed small bug with transloading images. (If clean_urls were not enabled) --- ext/upload/theme.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ext/upload/theme.php b/ext/upload/theme.php index f26905c0..a86d6f58 100644 --- a/ext/upload/theme.php +++ b/ext/upload/theme.php @@ -64,8 +64,15 @@ class UploadTheme extends Themelet { if($tl_enabled) { $link = make_http(make_link("upload")); $title = "Upload to " . $config->get_string('title'); + + if($config->get_bool('nice_urls')){ + $delimiter = '?'; + } else { + $delimiter = '&'; + } + $html .= '

' . + $link . $delimiter . 'url="+location.href+"&tags="+prompt("enter tags")">' . $title . ' (Drag & drop onto your bookmarks toolbar, then click when looking at an image)'; } From 7bfe30e0c5bea1ca12e5ae699d848c84336a1de2 Mon Sep 17 00:00:00 2001 From: "green-ponies (jgen)" Date: Fri, 4 Nov 2011 01:00:45 -0400 Subject: [PATCH 002/120] Patch for displaying error message when disk full. --- ext/upload/main.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ext/upload/main.php b/ext/upload/main.php index 167bce07..75c48583 100644 --- a/ext/upload/main.php +++ b/ext/upload/main.php @@ -178,7 +178,9 @@ class Upload implements Extension { } else { - if(!$is_full) { + if ($is_full) { + $this->theme->display_full($page); + } else { $this->theme->display_page($page); } } From db59cb14af5e8af56a4a33f0b3a333e32c0e8092 Mon Sep 17 00:00:00 2001 From: "green-ponies (jgen)" Date: Sun, 8 Jan 2012 13:23:03 -0500 Subject: [PATCH 003/120] Working on Reverting Changes by specific IP. --- contrib/tag_history/main.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/contrib/tag_history/main.php b/contrib/tag_history/main.php index fc0f43e6..ce2b9249 100644 --- a/contrib/tag_history/main.php +++ b/contrib/tag_history/main.php @@ -126,6 +126,7 @@ class Tag_History implements Extension { // there is no history entry with that id so either the image was deleted // while the user was viewing the history, someone is playing with form // variables or we have messed up in code somewhere. + /* calling die() is probably not a good idea, we should throw an Exception */ die("Error: No tag history with specified id was found."); } @@ -179,6 +180,30 @@ class Tag_History implements Extension { return ($row ? $row : array()); } + /* This doesn't actually get _ALL_ IPs as it limits to 1000. */ + public function get_all_user_ips() + { + global $database; + $row = $database->get_all(" + SELECT DISTINCT user_ip + FROM tag_histories + ORDER BY tag_histories.user_ip DESC + LIMIT 1000"); + return ($row ? $row : array()); + } + + public function process_revert_all_changes_by_ip($ip) + { + global $database; + /* + +SELECT * FROM `tag_histories` WHERE image_id IN +( select image_id from `tag_histories` where user_ip="216.240.14.185" and date_set >= 2011-10-23) +ORDER BY image_id, date_set + + */ + } + /* * this function is called when an image has been deleted */ From f93b86261eac078599d7773ea913f388d80f9d26 Mon Sep 17 00:00:00 2001 From: "green-ponies (jgen)" Date: Sun, 8 Jan 2012 13:23:39 -0500 Subject: [PATCH 004/120] Small feature for uploading using a bookmark. --- ext/upload/theme.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ext/upload/theme.php b/ext/upload/theme.php index a86d6f58..0c5b0686 100644 --- a/ext/upload/theme.php +++ b/ext/upload/theme.php @@ -63,7 +63,8 @@ class UploadTheme extends Themelet { if($tl_enabled) { $link = make_http(make_link("upload")); - $title = "Upload to " . $config->get_string('title'); + $home = make_http(make_link()); + $title = $config->get_string('title'); if($config->get_bool('nice_urls')){ $delimiter = '?'; @@ -71,9 +72,9 @@ class UploadTheme extends Themelet { $delimiter = '&'; } - $html .= '

' . - $title . ' (Drag & drop onto your bookmarks toolbar, then click when looking at an image)'; + $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");}}})();'; + + $html .= '

Upload to '.$title.' (Drag & drop onto your bookmarks toolbar, then click when looking at an image)'; } $page->set_title("Upload"); From dcf96456f1bbf15a982717baf088f4a6309fb8ab Mon Sep 17 00:00:00 2001 From: "green-ponies (jgen)" Date: Sun, 8 Jan 2012 16:50:35 -0500 Subject: [PATCH 005/120] Fixed issue with Cancelling Transloads. Also added some features to the Bookmarklet. --- ext/upload/theme.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/ext/upload/theme.php b/ext/upload/theme.php index fae6501f..4d701eea 100644 --- a/ext/upload/theme.php +++ b/ext/upload/theme.php @@ -98,17 +98,18 @@ class UploadTheme extends Themelet { "; if($tl_enabled) { - $link = make_http(make_link("upload")); + $link = make_http(make_link("upload")); + $main_page = make_http(make_link()); + $title = $config->get_string('title'); + if($config->get_bool('nice_urls')){ $delimiter = '?'; } else { $delimiter = '&'; } - { - $title = "Upload to " . $config->get_string('title'); - $html .= '

' . - $title . ' (Drag & drop onto your bookmarks toolbar, then click when looking at an image)'; + { + $js='javascript:(function(){if(typeof window=="undefined"||!window.location||window.location.href=="about:blank"){window.location="'. $main_page .'";}else if(typeof document=="undefined"||!document.body){window.location="'. $main_page .'?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");}}})();'; + $html .= '

Upload to '.$title.' (Drag & drop onto your bookmarks toolbar, then click when looking at an image)'; } { /* Danbooru > Shimmie Bookmarklet. From f7fc253075c999bdd182c9bdc781003b37c20e02 Mon Sep 17 00:00:00 2001 From: "green-ponies (jgen)" Date: Sun, 8 Jan 2012 22:18:17 -0500 Subject: [PATCH 006/120] Display message if no comments. --- ext/comment/theme.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ext/comment/theme.php b/ext/comment/theme.php index 264cd67b..3e2f9138 100644 --- a/ext/comment/theme.php +++ b/ext/comment/theme.php @@ -123,6 +123,9 @@ class CommentListTheme extends Themelet { foreach($comments as $comment) { $html .= $this->comment_to_html($comment, true); } + if(empty($html)) { + $html = '

No comments by this user.

'; + } $page->add_block(new Block("Comments", $html, "left", 70)); } From 0b03f91f1c37d87b68049b5d94cf889d6c745ca7 Mon Sep 17 00:00:00 2001 From: "green-ponies (jgen)" Date: Mon, 9 Jan 2012 20:45:30 -0500 Subject: [PATCH 007/120] Fixed the new upload form. Changed it over to use jQuery since shimmie has that already. Works with FF, Chrome, and IE 7 now. --- ext/upload/theme.php | 110 +++++++++++++++++++++++++++---------------- 1 file changed, 69 insertions(+), 41 deletions(-) diff --git a/ext/upload/theme.php b/ext/upload/theme.php index 4d701eea..1b13bf9e 100644 --- a/ext/upload/theme.php +++ b/ext/upload/theme.php @@ -15,59 +15,87 @@ class UploadTheme extends Themelet { // Uploader 2.0! $upload_list = ""; - for($i=0; $i<$config->get_int('upload_count'); $i++) { + for($i=0; $i<$config->get_int('upload_count'); $i++) + { $a=$i+1; $s=$i-1; + if(!$i==0){ $upload_list .=""; }else{ $upload_list .= ""; - } - $upload_list .= ""; - - if($i==0){ - $upload_list .= "
" . - "". - "
"; - }else{ - $upload_list .="
- ". - ""; - if($a==$config->get_int('upload_count')){ - $upload_list .=""; - }else{ - $upload_list .= - "". - ""; - } - $upload_list .= "
"; - } + } + + $upload_list .= ""; + if($i==0){ + $js = 'javascript:$(function() { + $("#row'.$a.'").show(); + $("#hide'.$i.'").hide(); + $("#hide'.$a.'").show();});'; + + $upload_list .= "
" . + "". + "
"; + } else { + $js = 'javascript:$(function() { + $("#row'.$i.'").hide(); + $("#hide'.$i.'").hide(); + $("#hide'.$s.'").show(); + $("#data'.$i.'").val(""); + $("#url'.$i.'").val(""); + });'; + + $upload_list .="
+ ". + ""; + + if($a==$config->get_int('upload_count')){ + $upload_list .=""; + }else{ + $js1 = 'javascript:$(function() { + $("#row'.$a.'").show(); + $("#hide'.$i.'").hide(); + $("#hide'.$a.'").show(); });'; + $upload_list .= - "
File
"; - if($tl_enabled) { - $upload_list .= - " URL
+ "". + ""; + } + $upload_list .= "
"; + } - - "; - } - else { - $upload_list .= " - - "; - } + $js2 = 'javascript:$(function() { + $("#url'.$i.'").show(); + $("#url'.$i.'").val(""); + $("#data'.$i.'").show(); });'; + + $upload_list .= + " File
"; + + if($tl_enabled) { + $js = 'javascript:$(function() { + $("#data'.$i.'").hide(); + $("#data'.$i.'").val(""); + $("#url'.$i.'").show(); });'; + + $upload_list .= + " URL + + + + "; + } else { + $upload_list .= " + + "; + } $upload_list .= " "; } + $max_size = $config->get_int('upload_size'); $max_kb = to_shorthand_int($max_size); $html = " @@ -86,7 +114,7 @@ class UploadTheme extends Themelet { }); }); - ".make_form(make_link("upload"), "POST", $multipart=True)." + ".make_form(make_link("upload"), "POST", $multipart=True, 'file_upload')." $upload_list @@ -109,7 +137,7 @@ class UploadTheme extends Themelet { } { $js='javascript:(function(){if(typeof window=="undefined"||!window.location||window.location.href=="about:blank"){window.location="'. $main_page .'";}else if(typeof document=="undefined"||!document.body){window.location="'. $main_page .'?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");}}})();'; - $html .= '

Upload to '.$title.' (Drag & drop onto your bookmarks toolbar, then click when looking at an image)'; + $html .= '

Upload to '.$title.' (Drag & drop onto your bookmarks toolbar, then click when looking at an image)'; } { /* Danbooru > Shimmie Bookmarklet. From 9f8a49483fc8411d63528d0ff97a2018e8b34bd1 Mon Sep 17 00:00:00 2001 From: Thasan Date: Thu, 12 Jan 2012 03:54:27 +0200 Subject: [PATCH 008/120] check if thumbnail already exists before regenerating it, way to force regen. --- contrib/regen_thumb/main.php | 2 +- core/extension.class.php | 7 ++++++- ext/handle_pixel/main.php | 9 +++++++++ ext/image/main.php | 3 ++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/contrib/regen_thumb/main.php b/contrib/regen_thumb/main.php index 23aac9a6..cf3e2eb6 100644 --- a/contrib/regen_thumb/main.php +++ b/contrib/regen_thumb/main.php @@ -18,7 +18,7 @@ class RegenThumb extends SimpleExtension { if($event->page_matches("regen_thumb") && $user->is_admin() && isset($_POST['image_id'])) { $image = Image::by_id(int_escape($_POST['image_id'])); - send_event(new ThumbnailGenerationEvent($image->hash, $image->ext)); + send_event(new ThumbnailGenerationEvent($image->hash, $image->ext, true)); $this->theme->display_results($page, $image); } } diff --git a/core/extension.class.php b/core/extension.class.php index d9cd0a18..ccd287d2 100644 --- a/core/extension.class.php +++ b/core/extension.class.php @@ -194,7 +194,12 @@ abstract class DataHandlerExtension implements Extension { } if(($event instanceof ThumbnailGenerationEvent) && $this->supported_ext($event->type)) { - $this->create_thumb($event->hash); + if (method_exists($this, 'create_thumb_force') && $event->force == true) { + $this->create_thumb_force($event->hash); + } + else { + $this->create_thumb($event->hash); + } } if(($event instanceof DisplayingImageEvent) && $this->supported_ext($event->image->ext)) { diff --git a/ext/handle_pixel/main.php b/ext/handle_pixel/main.php index 4cea671f..1fcd6d3b 100644 --- a/ext/handle_pixel/main.php +++ b/ext/handle_pixel/main.php @@ -48,6 +48,15 @@ class PixelFileHandler extends DataHandlerExtension { } protected function create_thumb($hash) { + $outname = warehouse_path("thumbs", $hash); + if(file_exists($outname)) { + return true; + } + return $this->create_thumb_force($hash); + } + + protected function create_thumb_force($hash) { + echo "x"; $inname = warehouse_path("images", $hash); $outname = warehouse_path("thumbs", $hash); global $config; diff --git a/ext/image/main.php b/ext/image/main.php index a42c7916..931f6f8c 100644 --- a/ext/image/main.php +++ b/ext/image/main.php @@ -97,9 +97,10 @@ class ThumbnailGenerationEvent extends Event { * @param $hash The unique hash of the image * @param $type The type of the image */ - public function ThumbnailGenerationEvent($hash, $type) { + public function ThumbnailGenerationEvent($hash, $type, $force=false) { $this->hash = $hash; $this->type = $type; + $this->force = $force; } } From cd34879cf1e5007bfc1908303bc54368277ea8e2 Mon Sep 17 00:00:00 2001 From: Thasan Date: Thu, 12 Jan 2012 03:59:58 +0200 Subject: [PATCH 009/120] oops, forgot debug code --- ext/handle_pixel/main.php | 1 - 1 file changed, 1 deletion(-) diff --git a/ext/handle_pixel/main.php b/ext/handle_pixel/main.php index 1fcd6d3b..2e4cd734 100644 --- a/ext/handle_pixel/main.php +++ b/ext/handle_pixel/main.php @@ -56,7 +56,6 @@ class PixelFileHandler extends DataHandlerExtension { } protected function create_thumb_force($hash) { - echo "x"; $inname = warehouse_path("images", $hash); $outname = warehouse_path("thumbs", $hash); global $config; From aa452bf8eb3737ad0469283e6a3a66732abaa923 Mon Sep 17 00:00:00 2001 From: Thasan Date: Sat, 14 Jan 2012 11:15:13 +0200 Subject: [PATCH 010/120] Added $force to vars --- ext/image/main.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/image/main.php b/ext/image/main.php index 931f6f8c..d4daf7a0 100644 --- a/ext/image/main.php +++ b/ext/image/main.php @@ -89,8 +89,8 @@ class ImageReplaceException extends SCoreException { * Request a thumbnail be made for an image object. */ class ThumbnailGenerationEvent extends Event { - var $hash, $type; - + var $hash, $type, $force; + /** * Request a thumbnail be made for an image object * From 342600cb405acf3bb0d01816b87fe008cb0cfc7a Mon Sep 17 00:00:00 2001 From: "green-ponies (jgen)" Date: Sun, 15 Jan 2012 12:02:54 -0500 Subject: [PATCH 011/120] This code is not used in the master branch. Moved into separate branch 'revert_by_ip'. --- contrib/tag_history/main.php | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/contrib/tag_history/main.php b/contrib/tag_history/main.php index ce2b9249..dfe15c5b 100644 --- a/contrib/tag_history/main.php +++ b/contrib/tag_history/main.php @@ -180,30 +180,6 @@ class Tag_History implements Extension { return ($row ? $row : array()); } - /* This doesn't actually get _ALL_ IPs as it limits to 1000. */ - public function get_all_user_ips() - { - global $database; - $row = $database->get_all(" - SELECT DISTINCT user_ip - FROM tag_histories - ORDER BY tag_histories.user_ip DESC - LIMIT 1000"); - return ($row ? $row : array()); - } - - public function process_revert_all_changes_by_ip($ip) - { - global $database; - /* - -SELECT * FROM `tag_histories` WHERE image_id IN -( select image_id from `tag_histories` where user_ip="216.240.14.185" and date_set >= 2011-10-23) -ORDER BY image_id, date_set - - */ - } - /* * this function is called when an image has been deleted */ From 6d88e3f4d87aafe2d4e8ec7a74ebc09bc77be1b6 Mon Sep 17 00:00:00 2001 From: Shish Date: Mon, 16 Jan 2012 01:35:36 +0000 Subject: [PATCH 012/120] twitter feed ext --- contrib/twitter_soc/main.php | 23 ++++ contrib/twitter_soc/script.js | 239 ++++++++++++++++++++++++++++++++++ contrib/twitter_soc/style.css | 44 +++++++ contrib/twitter_soc/test.php | 29 +++++ contrib/twitter_soc/theme.php | 25 ++++ 5 files changed, 360 insertions(+) create mode 100644 contrib/twitter_soc/main.php create mode 100644 contrib/twitter_soc/script.js create mode 100644 contrib/twitter_soc/style.css create mode 100644 contrib/twitter_soc/test.php create mode 100644 contrib/twitter_soc/theme.php diff --git a/contrib/twitter_soc/main.php b/contrib/twitter_soc/main.php new file mode 100644 index 00000000..04d42c48 --- /dev/null +++ b/contrib/twitter_soc/main.php @@ -0,0 +1,23 @@ + + * License: GPLv2 + * Description: Show a twitter feed with the Sea of Clouds script + */ + +class TwitterSoc extends SimpleExtension { + public function onPostListBuilding($event) { + global $config, $page; + if(strlen($config->get_string("twitter_soc_username")) > 0) { + $this->theme->display_feed($page, $config->get_string("twitter_soc_username")); + } + } + + public function onSetupBuilding($event) { + $sb = new SetupBlock("Tweet!"); + $sb->add_text_option("twitter_soc_username", "Username "); + $event->panel->add_block($sb); + } +} +?> diff --git a/contrib/twitter_soc/script.js b/contrib/twitter_soc/script.js new file mode 100644 index 00000000..f4dc0f0a --- /dev/null +++ b/contrib/twitter_soc/script.js @@ -0,0 +1,239 @@ +// jquery.tweet.js - See http://tweet.seaofclouds.com/ or https://github.com/seaofclouds/tweet for more info +// Copyright (c) 2008-2011 Todd Matthews & Steve Purcell +(function($) { +console.log("Loading tweet"); + $.fn.tweet = function(o){ + var s = $.extend({ + username: null, // [string or array] required unless using the 'query' option; one or more twitter screen names (use 'list' option for multiple names, where possible) + list: null, // [string] optional name of list belonging to username + favorites: false, // [boolean] display the user's favorites instead of his tweets + query: null, // [string] optional search query (see also: http://search.twitter.com/operators) + avatar_size: null, // [integer] height and width of avatar if displayed (48px max) + count: 3, // [integer] how many tweets to display? + fetch: null, // [integer] how many tweets to fetch via the API (set this higher than 'count' if using the 'filter' option) + page: 1, // [integer] which page of results to fetch (if count != fetch, you'll get unexpected results) + retweets: true, // [boolean] whether to fetch (official) retweets (not supported in all display modes) + intro_text: null, // [string] do you want text BEFORE your your tweets? + outro_text: null, // [string] do you want text AFTER your tweets? + join_text: null, // [string] optional text in between date and tweet, try setting to "auto" + auto_join_text_default: "i said,", // [string] auto text for non verb: "i said" bullocks + auto_join_text_ed: "i", // [string] auto text for past tense: "i" surfed + auto_join_text_ing: "i am", // [string] auto tense for present tense: "i was" surfing + auto_join_text_reply: "i replied to", // [string] auto tense for replies: "i replied to" @someone "with" + auto_join_text_url: "i was looking at", // [string] auto tense for urls: "i was looking at" http:... + loading_text: null, // [string] optional loading text, displayed while tweets load + refresh_interval: null , // [integer] optional number of seconds after which to reload tweets + twitter_url: "twitter.com", // [string] custom twitter url, if any (apigee, etc.) + twitter_api_url: "api.twitter.com", // [string] custom twitter api url, if any (apigee, etc.) + twitter_search_url: "search.twitter.com", // [string] custom twitter search url, if any (apigee, etc.) + template: "{avatar}{time}{join}{text}", // [string or function] template used to construct each tweet

  • - see code for available vars + comparator: function(tweet1, tweet2) { // [function] comparator used to sort tweets (see Array.sort) + return tweet2["tweet_time"] - tweet1["tweet_time"]; + }, + filter: function(tweet) { // [function] whether or not to include a particular tweet (be sure to also set 'fetch') + return true; + } + }, o); + + // See http://daringfireball.net/2010/07/improved_regex_for_matching_urls + var url_regexp = /\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/gi; + + // Expand values inside simple string templates with {placeholders} + function t(template, info) { + if (typeof template === "string") { + var result = template; + for(var key in info) { + var val = info[key]; + result = result.replace(new RegExp('{'+key+'}','g'), val === null ? '' : val); + } + return result; + } else return template(info); + } + // Export the t function for use when passing a function as the 'template' option + $.extend({tweet: {t: t}}); + + function replacer (regex, replacement) { + return function() { + var returning = []; + this.each(function() { + returning.push(this.replace(regex, replacement)); + }); + return $(returning); + }; + } + + function escapeHTML(s) { + return s.replace(//g,"^>"); + } + + $.fn.extend({ + linkUser: replacer(/(^|[\W])@(\w+)/gi, "$1@$2"), + // Support various latin1 (\u00**) and arabic (\u06**) alphanumeric chars + linkHash: replacer(/(?:^| )[\#]+([\w\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u00ff\u0600-\u06ff]+)/gi, + ' #$1'), + capAwesome: replacer(/\b(awesome)\b/gi, '$1'), + capEpic: replacer(/\b(epic)\b/gi, '$1'), + makeHeart: replacer(/(<)+[3]/gi, "") + }); + + function linkURLs(text, entities) { + return text.replace(url_regexp, function(match) { + var url = (/^[a-z]+:/i).test(match) ? match : "http://"+match; + var text = match; + for(var i = 0; i < entities.length; ++i) { + var entity = entities[i]; + if (entity.url == url && entity.expanded_url) { + url = entity.expanded_url; + text = entity.display_url; + break; + } + } + return ""+escapeHTML(text)+""; + }); + } + + function parse_date(date_str) { + // The non-search twitter APIs return inconsistently-formatted dates, which Date.parse + // cannot handle in IE. We therefore perform the following transformation: + // "Wed Apr 29 08:53:31 +0000 2009" => "Wed, Apr 29 2009 08:53:31 +0000" + return Date.parse(date_str.replace(/^([a-z]{3})( [a-z]{3} \d\d?)(.*)( \d{4})$/i, '$1,$2$4$3')); + } + + function relative_time(date) { + var relative_to = (arguments.length > 1) ? arguments[1] : new Date(); + var delta = parseInt((relative_to.getTime() - date) / 1000, 10); + var r = ''; + if (delta < 1) { + r = 'just now'; + } else if (delta < 60) { + r = delta + ' seconds ago'; + } else if(delta < 120) { + r = 'a minute ago'; + } else if(delta < (45*60)) { + r = (parseInt(delta / 60, 10)).toString() + ' minutes ago'; + } else if(delta < (2*60*60)) { + r = 'an hour ago'; + } else if(delta < (24*60*60)) { + r = '' + (parseInt(delta / 3600, 10)).toString() + ' hours ago'; + } else if(delta < (48*60*60)) { + r = 'a day ago'; + } else { + r = (parseInt(delta / 86400, 10)).toString() + ' days ago'; + } + return 'about ' + r; + } + + function build_auto_join_text(text) { + if (text.match(/^(@([A-Za-z0-9-_]+)) .*/i)) { + return s.auto_join_text_reply; + } else if (text.match(url_regexp)) { + return s.auto_join_text_url; + } else if (text.match(/^((\w+ed)|just) .*/im)) { + return s.auto_join_text_ed; + } else if (text.match(/^(\w*ing) .*/i)) { + return s.auto_join_text_ing; + } else { + return s.auto_join_text_default; + } + } + + function build_api_url() { + var proto = ('https:' == document.location.protocol ? 'https:' : 'http:'); + var count = (s.fetch === null) ? s.count : s.fetch; + var common_params = '&include_entities=1&callback=?'; + if (s.list) { + return proto+"//"+s.twitter_api_url+"/1/"+s.username[0]+"/lists/"+s.list+"/statuses.json?page="+s.page+"&per_page="+count+common_params; + } else if (s.favorites) { + return proto+"//"+s.twitter_api_url+"/favorites/"+s.username[0]+".json?page="+s.page+"&count="+count+common_params; + } else if (s.query === null && s.username.length == 1) { + return proto+'//'+s.twitter_api_url+'/1/statuses/user_timeline.json?screen_name='+s.username[0]+'&count='+count+(s.retweets ? '&include_rts=1' : '')+'&page='+s.page+common_params; + } else { + var query = (s.query || 'from:'+s.username.join(' OR from:')); + return proto+'//'+s.twitter_search_url+'/search.json?&q='+encodeURIComponent(query)+'&rpp='+count+'&page='+s.page+common_params; + } + } + + function extract_avatar_url(item, secure) { + if (secure) { + return ('user' in item) ? + item.user.profile_image_url_https : + extract_avatar_url(item, false). + replace(/^http:\/\/[a-z0-9]{1,3}\.twimg\.com\//, "https://s3.amazonaws.com/twitter_production/"); + } else { + return item.profile_image_url || item.user.profile_image_url; + } + } + + // Convert twitter API objects into data available for + // constructing each tweet
  • using a template + function extract_template_data(item){ + var o = {}; + o.item = item; + o.source = item.source; + o.screen_name = item.from_user || item.user.screen_name; + o.avatar_size = s.avatar_size; + o.avatar_url = extract_avatar_url(item, (document.location.protocol === 'https:')); + o.retweet = typeof(item.retweeted_status) != 'undefined'; + o.tweet_time = parse_date(item.created_at); + o.join_text = s.join_text == "auto" ? build_auto_join_text(item.text) : s.join_text; + o.tweet_id = item.id_str; + o.twitter_base = "http://"+s.twitter_url+"/"; + o.user_url = o.twitter_base+o.screen_name; + o.tweet_url = o.user_url+"/status/"+o.tweet_id; + o.reply_url = o.twitter_base+"intent/tweet?in_reply_to="+o.tweet_id; + o.retweet_url = o.twitter_base+"intent/retweet?tweet_id="+o.tweet_id; + o.favorite_url = o.twitter_base+"intent/favorite?tweet_id="+o.tweet_id; + o.retweeted_screen_name = o.retweet && item.retweeted_status.user.screen_name; + o.tweet_relative_time = relative_time(o.tweet_time); + o.entities = item.entities ? (item.entities.urls || []).concat(item.entities.media || []) : []; + o.tweet_raw_text = o.retweet ? ('RT @'+o.retweeted_screen_name+' '+item.retweeted_status.text) : item.text; // avoid '...' in long retweets + o.tweet_text = $([linkURLs(o.tweet_raw_text, o.entities)]).linkUser().linkHash()[0]; + o.tweet_text_fancy = $([o.tweet_text]).makeHeart().capAwesome().capEpic()[0]; + + // Default spans, and pre-formatted blocks for common layouts + o.user = t('{screen_name}', o); + o.join = s.join_text ? t(' {join_text} ', o) : ' '; + o.avatar = o.avatar_size ? + t('{screen_name}\'s avatar', o) : ''; + o.time = t('{tweet_relative_time}', o); + o.text = t('{tweet_text_fancy}', o); + o.reply_action = t('reply', o); + o.retweet_action = t('retweet', o); + o.favorite_action = t('favorite', o); + return o; + } + + return this.each(function(i, widget){ + var list = $('
      '); + var intro = '

      '+s.intro_text+'

      '; + var outro = '

      '+s.outro_text+'

      '; + var loading = $('

      '+s.loading_text+'

      '); + + if(s.username && typeof(s.username) == "string"){ + s.username = [s.username]; + } + + $(widget).bind("tweet:load", function(){ + if (s.loading_text) $(widget).empty().append(loading); + $.getJSON(build_api_url(), function(data){ + $(widget).empty().append(list); + if (s.intro_text) list.before(intro); + list.empty(); + + var tweets = $.map(data.results || data, extract_template_data); + tweets = $.grep(tweets, s.filter).sort(s.comparator).slice(0, s.count); + list.append($.map(tweets, function(o) { return "
    • " + t(s.template, o) + "
    • "; }).join('')). + children('li:first').addClass('tweet_first').end(). + children('li:odd').addClass('tweet_even').end(). + children('li:even').addClass('tweet_odd'); + + if (s.outro_text) list.after(outro); + $(widget).trigger("loaded").trigger((tweets.length === 0 ? "empty" : "full")); + if (s.refresh_interval) { + window.setTimeout(function() { $(widget).trigger("tweet:load"); }, 1000 * s.refresh_interval); + } + }); + }).trigger("tweet:load"); + }); + }; +})(jQuery); diff --git a/contrib/twitter_soc/style.css b/contrib/twitter_soc/style.css new file mode 100644 index 00000000..06adfd42 --- /dev/null +++ b/contrib/twitter_soc/style.css @@ -0,0 +1,44 @@ +.tweet, +.query { + font: 120% Georgia, serif; + color: #085258; +} + + .tweet_list { + -webkit-border-radius: 0.5em; + -moz-border-radius: 0.5em; + border-radius: 0.5em; + list-style: none; + margin: 0; + padding: 0; + overflow-y: hidden; + /*background-color: #8ADEE2;*/ + } + + .tweet_list .awesome, + .tweet_list .epic { + text-transform: uppercase; + } + + .tweet_list li { + overflow-y: auto; + overflow-x: hidden; + padding: 0.5em; + list-style-type: none; + } + + .tweet_list li a { + color: #0C717A; + } + + .tweet_list .tweet_even { + /*background-color: #91E5E7;*/ + } + + .tweet_list .tweet_avatar { + padding-right: .5em; float: left; + } + + .tweet_list .tweet_avatar img { + vertical-align: middle; + } diff --git a/contrib/twitter_soc/test.php b/contrib/twitter_soc/test.php new file mode 100644 index 00000000..e11bd6a2 --- /dev/null +++ b/contrib/twitter_soc/test.php @@ -0,0 +1,29 @@ +log_in_as_admin(); + + $this->get_page("setup"); + $this->set_field("_config_twitter_soc_username", "shish2k"); + $this->click("Save Settings"); + + /* + $this->get_page("post/list"); + $this->assert_text("Note"); + $this->assert_text("kittens"); + */ + + $this->get_page("setup"); + $this->set_field("_config_twitter_soc_username", ""); + $this->click("Save Settings"); + + /* + $this->get_page("post/list"); + $this->assert_no_text("Note"); + $this->assert_no_text("kittens"); + */ + + $this->log_out(); + } +} +?> diff --git a/contrib/twitter_soc/theme.php b/contrib/twitter_soc/theme.php new file mode 100644 index 00000000..be5c68fe --- /dev/null +++ b/contrib/twitter_soc/theme.php @@ -0,0 +1,25 @@ +add_block(new Block("Tweets", ' +
      +

      Follow us on Twitter + + ', "left", 25)); + } +} +?> From 5b9c8b736dda9098609b1106dfc247f6767b3af3 Mon Sep 17 00:00:00 2001 From: Shish Date: Mon, 16 Jan 2012 01:50:44 +0000 Subject: [PATCH 013/120] remove debug --- contrib/twitter_soc/script.js | 1 - 1 file changed, 1 deletion(-) diff --git a/contrib/twitter_soc/script.js b/contrib/twitter_soc/script.js index f4dc0f0a..06457f3a 100644 --- a/contrib/twitter_soc/script.js +++ b/contrib/twitter_soc/script.js @@ -1,7 +1,6 @@ // jquery.tweet.js - See http://tweet.seaofclouds.com/ or https://github.com/seaofclouds/tweet for more info // Copyright (c) 2008-2011 Todd Matthews & Steve Purcell (function($) { -console.log("Loading tweet"); $.fn.tweet = function(o){ var s = $.extend({ username: null, // [string or array] required unless using the 'query' option; one or more twitter screen names (use 'list' option for multiple names, where possible) From 9bde42d452fb3198b674f3769b9bf52b0cf3a53f Mon Sep 17 00:00:00 2001 From: Shish Date: Mon, 16 Jan 2012 02:53:38 +0000 Subject: [PATCH 014/120] consistent hashing for multiple data mirrors --- core/imageboard.pack.php | 22 ++++ lib/flexihash.php | 269 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 291 insertions(+) create mode 100644 lib/flexihash.php diff --git a/core/imageboard.pack.php b/core/imageboard.pack.php index 5f110f07..dfc0565f 100644 --- a/core/imageboard.pack.php +++ b/core/imageboard.pack.php @@ -24,6 +24,8 @@ \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ $tag_n = 0; // temp hack +$_flexihash = null; +$_fh_last_opts = null; /** * An object representing an entry in the images table. As of 2.2, this no @@ -507,6 +509,26 @@ class Image { $tmpl = $plte->link; } + global $_flexihash, $_fh_last_opts; + $matches = array(); + if(preg_match("/(.*){(.*)}(.*)/", $tmpl, &$matches)) { + $pre = $matches[1]; + $opts = $matches[2]; + $post = $matches[3]; + + if($opts != $_fh_last_opts) { + $_fh_last_opts = $opts; + require_once("lib/flexihash.php"); + $_flexihash = new Flexihash(); + foreach(explode(",", $opts) as $opt) { + $_flexihash->addTarget($opt); + } + } + + $choice = $_flexihash->lookup($pre.$post); + $tmpl = $pre.$choice.$post; + } + return $tmpl; } diff --git a/lib/flexihash.php b/lib/flexihash.php new file mode 100644 index 00000000..f9d25db5 --- /dev/null +++ b/lib/flexihash.php @@ -0,0 +1,269 @@ + target, ... } + */ + private $_positionToTarget = array(); + + /** + * Internal map of targets to lists of positions that target is hashed to. + * @var array { target => [ position, position, ... ], ... } + */ + private $_targetToPositions = array(); + + /** + * Whether the internal map of positions to targets is already sorted. + * @var boolean + */ + private $_positionToTargetSorted = false; + + /** + * Constructor + * @param object $hasher Flexihash_Hasher + * @param int $replicas Amount of positions to hash each target to. + */ + public function __construct(Flexihash_Hasher $hasher = null, $replicas = null) + { + $this->_hasher = $hasher ? $hasher : new Flexihash_Crc32Hasher(); + if (!empty($replicas)) $this->_replicas = $replicas; + } + + /** + * Add a target. + * @param string $target + * @param float $weight + * @chainable + */ + public function addTarget($target, $weight=1) + { + if (isset($this->_targetToPositions[$target])) + { + throw new Flexihash_Exception("Target '$target' already exists."); + } + + $this->_targetToPositions[$target] = array(); + + // hash the target into multiple positions + for ($i = 0; $i < round($this->_replicas*$weight); $i++) + { + $position = $this->_hasher->hash($target . $i); + $this->_positionToTarget[$position] = $target; // lookup + $this->_targetToPositions[$target] []= $position; // target removal + } + + $this->_positionToTargetSorted = false; + $this->_targetCount++; + + return $this; + } + + /** + * Add a list of targets. + * @param array $targets + * @param float $weight + * @chainable + */ + public function addTargets($targets, $weight=1) + { + foreach ($targets as $target) + { + $this->addTarget($target,$weight); + } + + return $this; + } + + /** + * Remove a target. + * @param string $target + * @chainable + */ + public function removeTarget($target) + { + if (!isset($this->_targetToPositions[$target])) + { + throw new Flexihash_Exception("Target '$target' does not exist."); + } + + foreach ($this->_targetToPositions[$target] as $position) + { + unset($this->_positionToTarget[$position]); + } + + unset($this->_targetToPositions[$target]); + + $this->_targetCount--; + + return $this; + } + + /** + * A list of all potential targets + * @return array + */ + public function getAllTargets() + { + return array_keys($this->_targetToPositions); + } + + /** + * Looks up the target for the given resource. + * @param string $resource + * @return string + */ + public function lookup($resource) + { + $targets = $this->lookupList($resource, 1); + if (empty($targets)) throw new Flexihash_Exception('No targets exist'); + return $targets[0]; + } + + /** + * Get a list of targets for the resource, in order of precedence. + * Up to $requestedCount targets are returned, less if there are fewer in total. + * + * @param string $resource + * @param int $requestedCount The length of the list to return + * @return array List of targets + */ + public function lookupList($resource, $requestedCount) + { + if (!$requestedCount) + throw new Flexihash_Exception('Invalid count requested'); + + // handle no targets + if (empty($this->_positionToTarget)) + return array(); + + // optimize single target + if ($this->_targetCount == 1) + return array_unique(array_values($this->_positionToTarget)); + + // hash resource to a position + $resourcePosition = $this->_hasher->hash($resource); + + $results = array(); + $collect = false; + + $this->_sortPositionTargets(); + + // search values above the resourcePosition + foreach ($this->_positionToTarget as $key => $value) + { + // start collecting targets after passing resource position + if (!$collect && $key > $resourcePosition) + { + $collect = true; + } + + // only collect the first instance of any target + if ($collect && !in_array($value, $results)) + { + $results []= $value; + } + + // return when enough results, or list exhausted + if (count($results) == $requestedCount || count($results) == $this->_targetCount) + { + return $results; + } + } + + // loop to start - search values below the resourcePosition + foreach ($this->_positionToTarget as $key => $value) + { + if (!in_array($value, $results)) + { + $results []= $value; + } + + // return when enough results, or list exhausted + if (count($results) == $requestedCount || count($results) == $this->_targetCount) + { + return $results; + } + } + + // return results after iterating through both "parts" + return $results; + } + + public function __toString() + { + return sprintf( + '%s{targets:[%s]}', + get_class($this), + implode(',', $this->getAllTargets()) + ); + } + + // ---------------------------------------- + // private methods + + /** + * Sorts the internal mapping (positions to targets) by position + */ + private function _sortPositionTargets() + { + // sort by key (position) if not already + if (!$this->_positionToTargetSorted) + { + ksort($this->_positionToTarget, SORT_REGULAR); + $this->_positionToTargetSorted = true; + } + } + +} + From 8f56b9ae2ca4765616738aef966eafbdad0bca36 Mon Sep 17 00:00:00 2001 From: Shish Date: Mon, 16 Jan 2012 19:58:03 +0000 Subject: [PATCH 015/120] argh php, syntax that used to be required is now deprecated... --- core/imageboard.pack.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/imageboard.pack.php b/core/imageboard.pack.php index dfc0565f..428a4484 100644 --- a/core/imageboard.pack.php +++ b/core/imageboard.pack.php @@ -511,7 +511,7 @@ class Image { global $_flexihash, $_fh_last_opts; $matches = array(); - if(preg_match("/(.*){(.*)}(.*)/", $tmpl, &$matches)) { + if(preg_match("/(.*){(.*)}(.*)/", $tmpl, $matches)) { $pre = $matches[1]; $opts = $matches[2]; $post = $matches[3]; From fdca5e46620178f0779ad0deb431655c75a02124 Mon Sep 17 00:00:00 2001 From: "green-ponies (jgen)" Date: Fri, 4 Nov 2011 01:00:45 -0400 Subject: [PATCH 016/120] Patch for displaying error message when disk full. --- ext/upload/main.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ext/upload/main.php b/ext/upload/main.php index 0a40076c..ebe48b69 100644 --- a/ext/upload/main.php +++ b/ext/upload/main.php @@ -179,7 +179,9 @@ class Upload implements Extension { } else { - if(!$is_full) { + if ($is_full) { + $this->theme->display_full($page); + } else { $this->theme->display_page($page); } } From d46244f9261a4c6383c3e39a2aa7eefa3c439a11 Mon Sep 17 00:00:00 2001 From: "green-ponies (jgen)" Date: Sun, 8 Jan 2012 22:18:17 -0500 Subject: [PATCH 017/120] Display message if no comments. --- ext/comment/theme.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ext/comment/theme.php b/ext/comment/theme.php index 264cd67b..3e2f9138 100644 --- a/ext/comment/theme.php +++ b/ext/comment/theme.php @@ -123,6 +123,9 @@ class CommentListTheme extends Themelet { foreach($comments as $comment) { $html .= $this->comment_to_html($comment, true); } + if(empty($html)) { + $html = '

      No comments by this user.

      '; + } $page->add_block(new Block("Comments", $html, "left", 70)); } From cc3bda38f0c98dd683db02d0283065ad8361fb44 Mon Sep 17 00:00:00 2001 From: Shish Date: Mon, 16 Jan 2012 20:58:55 +0000 Subject: [PATCH 018/120] attempt to hand-merge jgen's revert by IP vits --- contrib/tag_history/main.php | 134 ++++++++++++++++++++++++++++++++-- contrib/tag_history/theme.php | 69 ++++++++++++++--- core/util.inc.php | 32 ++++++++ 3 files changed, 215 insertions(+), 20 deletions(-) diff --git a/contrib/tag_history/main.php b/contrib/tag_history/main.php index fc0f43e6..3ef706be 100644 --- a/contrib/tag_history/main.php +++ b/contrib/tag_history/main.php @@ -1,8 +1,8 @@ - * Description: Keep a record of tag changes + * Author: Bzchan , modified by jgen + * Description: Keep a record of tag changes, and allows you to revert changes. */ class Tag_History implements Extension { @@ -20,8 +20,44 @@ class Tag_History implements Extension { $this->install(); } } - - if(($event instanceof PageRequestEvent) && $event->page_matches("tag_history")) + + if(($event instanceof AdminBuildingEvent)) + { + if(isset($_POST['revert_ip']) && $user->is_admin() && $user->check_auth_token()) + { + $revert_ip = filter_var($_POST['revert_ip'], FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE); + + if ($revert_ip === false) { + // invalid ip given. + $this->theme->display_admin_block('Invalid IP'); + return; + } + + if (isset($_POST['revert_date']) && !empty($_POST['revert_date'])) { + if (isValidDate($_POST['revert_date'])){ + $revert_date = addslashes($_POST['revert_date']); // addslashes is really unnecessary since we just checked if valid, but better safe. + } else { + $this->theme->display_admin_block('Invalid Date'); + return; + } + } else { + $revert_date = null; + } + + set_time_limit(0); // reverting changes can take a long time, disable php's timelimit if possible. + + // Call the revert function. + $this->process_revert_all_changes_by_ip($revert_ip, $revert_date); + // output results + $this->theme->display_revert_ip_results(); + } + else + { + $this->theme->display_admin_block(); // add a block to the admin panel + } + } + + if (($event instanceof PageRequestEvent) && ($event->page_matches("tag_history"))) { if($event->get_arg(0) == "revert") { @@ -40,6 +76,7 @@ class Tag_History implements Extension { $this->theme->display_global_page($page, $this->get_global_tag_history()); } } + if(($event instanceof DisplayingImageEvent)) { // handle displaying a link on the view page @@ -107,7 +144,7 @@ class Tag_History implements Extension { { global $page; // check for the nothing case - if($revert_id=="nothing") + if(empty($revert_id) || $revert_id=="nothing") { // tried to set it too the same thing so ignore it (might be a bot) // go back to the index page with you @@ -121,7 +158,7 @@ class Tag_History implements Extension { // lets get this revert id assuming it exists $result = $this->get_tag_history_from_revert($revert_id); - if($result==null) + if(empty($result)) { // there is no history entry with that id so either the image was deleted // while the user was viewing the history, someone is playing with form @@ -134,13 +171,43 @@ class Tag_History implements Extension { $stored_image_id = $result['image_id']; $stored_tags = $result['tags']; - log_debug("tag_history", "Reverting tags of $stored_image_id to [$stored_tags]"); + log_debug("tag_history", 'Reverting tags of Image #'.$stored_image_id.' to ['.$stored_tags.']'); // all should be ok so we can revert by firing the SetUserTags event. send_event(new TagSetEvent(Image::by_id($stored_image_id), $stored_tags)); // all should be done now so redirect the user back to the image $page->set_mode("redirect"); - $page->set_redirect(make_link("post/view/$stored_image_id")); + $page->set_redirect(make_link('post/view/'.$stored_image_id)); + } + + /* + * This function is used by process_revert_all_changes_by_ip() + * to just revert an image's tag history. + */ + private function process_revert_request_only($revert_id) + { + if(empty($revert_id)) { + return; + } + $id = (int) $revert_id; + $result = $this->get_tag_history_from_revert($id); + + if(empty($result)) { + // there is no history entry with that id so either the image was deleted + // while the user was viewing the history, or something messed up + /* calling die() is probably not a good idea, we should throw an Exception */ + die('Error: No tag history with specified id ('.$id.') was found in the database.'."\n\n". + 'Perhaps the image was deleted while processing this request.'); + } + + // lets get the values out of the result + $stored_result_id = $result['id']; + $stored_image_id = $result['image_id']; + $stored_tags = $result['tags']; + + log_debug("tag_history", 'Reverting tags of Image #'.$stored_image_id.' to ['.$stored_tags.']'); + // all should be ok so we can revert by firing the SetUserTags event. + send_event(new TagSetEvent(Image::by_id($stored_image_id), $stored_tags)); } public function get_tag_history_from_revert($revert_id) @@ -179,6 +246,56 @@ class Tag_History implements Extension { return ($row ? $row : array()); } + /* + * This function attempts to revert all changes by a given IP within an (optional) timeframe. + */ + public function process_revert_all_changes_by_ip($ip, $date=null) + { + global $database; + $date_select = ''; + + if (!empty($date)) { + $date_select = 'and date_set >= '.$date; + } else { + $date = 'forever'; + } + + log_info("tag_history", 'Attempting to revert edits by ip='.$ip.' (from '.$date.' to now).'); + + // Get all the images that the given IP has changed tags on (within the timeframe) that were last editied by the given IP + $result = $database->get_all(' + SELECT t1.image_id FROM tag_histories t1 LEFT JOIN tag_histories t2 + ON (t1.image_id = t2.image_id AND t1.date_set < t2.date_set) + WHERE t2.image_id IS NULL AND t1.user_ip="'.$ip.'" AND t1.image_id IN + ( select image_id from `tag_histories` where user_ip="'.$ip.'" '.$date_select.') + ORDER BY t1.image_id;'); + + if (empty($result)) { + log_info("tag_history", 'Nothing to revert! for ip='.$ip.' (from '.$date.' to now).'); + $this->theme->add_status('Nothing to Revert','Nothing to revert for ip='.$ip.' (from '.$date.' to now)'); + return; // nothing to do. + } + + for ($i = 0 ; $i < count($result) ; $i++) + { + $image_id = (int) $result[$i]['image_id']; + + // Get the first tag history that was done before the given IP edit + $row = $database->get_row(' + SELECT id,tags FROM `tag_histories` WHERE image_id="'.$image_id.'" AND user_ip!="'.$ip.'" '.$date_select.' ORDER BY date_set DESC LIMIT 1'); + + if (empty($row)) { + // we can not revert this image based on the date restriction. + // Output a message perhaps? + } else { + $id = (int) $row['id']; + $this->process_revert_request_only($id); + $this->theme->add_status('Reverted Change','Reverted Image #'.$image_id.' to Tag History #'.$id.' ('.$row['tags'].')'); + } + } + log_info("tag_history", 'Reverted '.count($result).' edits by ip='.$ip.' (from '.$date.' to now).'); + } + /* * this function is called when an image has been deleted */ @@ -207,6 +324,7 @@ class Tag_History implements Extension { // if the image has no history, make one with the old tags $entries = $database->get_one("SELECT COUNT(*) FROM tag_histories WHERE image_id = ?", array($image->id)); if($entries == 0){ + /* these two queries could probably be combined */ $database->execute(" INSERT INTO tag_histories(image_id, tags, user_id, user_ip, date_set) VALUES (?, ?, ?, ?, now())", diff --git a/contrib/tag_history/theme.php b/contrib/tag_history/theme.php index 46ed3564..842ed8bd 100644 --- a/contrib/tag_history/theme.php +++ b/contrib/tag_history/theme.php @@ -1,6 +1,12 @@ , modified by jgen + */ class Tag_HistoryTheme extends Themelet { + var $messages = array(); + public function display_history_page(Page $page, $image_id, $history) { global $user; $start_string = " @@ -22,11 +28,12 @@ class Tag_HistoryTheme extends Themelet { $setter .= " / " . $fields['user_ip']; } $selected = ($n == 2) ? " checked" : ""; - $history_list .= " + $history_list .= '
    • - - -
    • \n"; + + + + '; } $end_string = " @@ -37,8 +44,8 @@ class Tag_HistoryTheme extends Themelet { "; $history_html = $start_string . $history_list . $end_string; - $page->set_title("Image $image_id Tag History"); - $page->set_heading("Tag History: $image_id"); + $page->set_title('Image '.$image_id.' Tag History'); + $page->set_heading('Tag History: '.$image_id); $page->add_block(new NavBlock()); $page->add_block(new Block("Tag History", $history_html, "main", 10)); } @@ -68,13 +75,13 @@ class Tag_HistoryTheme extends Themelet { if($user->is_admin()) { $setter .= " / " . $fields['user_ip']; } - $history_list .= " + $history_list .= '
    • - - $image_id: - $current_tags (Set by $setter) + + '.$image_id.': + '.$current_tags.' (Set by '.$setter.')
    • - "; + '; } $history_html = $start_string . $history_list . $end_string; @@ -85,8 +92,46 @@ class Tag_HistoryTheme extends Themelet { } public function display_history_link(Page $page, $image_id) { - $link = "Tag History\n"; + $link = 'Tag History'; $page->add_block(new Block(null, $link, "main", 5)); } + + /* + * Add a section to the admin page. + */ + public function display_admin_block($validation_msg='') { + global $page; + + if (!empty($validation_msg)) { + $validation_msg = '
      '. $validation_msg .''; + } + + $html = ' + Revert tag changes/edit by a specific IP address.
      + You can restrict the time frame to revert these edits as well. +
      (Date format: 2011-10-23) + '.$validation_msg.' + +

      '.make_form(make_link("admin/revert_ip"),'POST',false,'revert_ip_form')." + IP Address:
      + Date range:

      + +
      + "; + $page->add_block(new Block("Revert By IP", $html)); + } + + /* + * Show a standard page for results to be put into + */ + public function display_revert_ip_results() { + global $page; + $html = implode($this->messages, "\n"); + $page->add_block(new Block("Revert by IP", $html)); + } + + public function add_status($title, $body) { + $this->messages[] = '

      '. $title .'
      '. $body .'

      '; + } } ?> diff --git a/core/util.inc.php b/core/util.inc.php index 25e020f9..97146d25 100644 --- a/core/util.inc.php +++ b/core/util.inc.php @@ -134,6 +134,38 @@ function autodate($date, $html=true) { return ($html ? "" : $hum); } +/** + * Check if a given string is a valid date-time. ( Format: yyyy-mm-dd hh:mm:ss ) + * + * @retval boolean + */ +function isValidDateTime($dateTime) +{ + if (preg_match("/^(\d{4})-(\d{2})-(\d{2}) ([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/", $dateTime, $matches)) { + if (checkdate($matches[2], $matches[3], $matches[1])) { + return true; + } + } + + return false; +} + +/** + * Check if a given string is a valid date. ( Format: yyyy-mm-dd ) + * + * @retval boolean + */ +function isValidDate($date) +{ + if (preg_match("/^(\d{4})-(\d{2})-(\d{2})$/", $date, $matches)) { + // checkdate wants (month, day, year) + if (checkdate($matches[2], $matches[3], $matches[1])) { + return true; + } + } + + return false; +} /** * Return a pluraliser if necessary From 46960eed48a1551b938298544c0ed90bc8f8ebee Mon Sep 17 00:00:00 2001 From: "green-ponies (jgen)" Date: Mon, 16 Jan 2012 16:06:05 -0500 Subject: [PATCH 019/120] Fix for Notes missing js files. --- contrib/notes/theme.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/contrib/notes/theme.php b/contrib/notes/theme.php index 08c4f815..5bbf506e 100644 --- a/contrib/notes/theme.php +++ b/contrib/notes/theme.php @@ -56,7 +56,11 @@ class NotesTheme extends Themelet { } // check action POST on form - public function display_note_system(Page $page, $image_id, $recovered_notes, $adminOptions) { + public function display_note_system(Page $page, $image_id, $recovered_notes, $adminOptions) + { + $page->add_html_header("", 100); + $page->add_html_header("", 101); + $html = " - ".make_form(make_link("upload"), "POST", $multipart=True)." + ".make_form(make_link("upload"), "POST", $multipart=True, 'file_upload')."
  • Tags
    $upload_list @@ -98,17 +126,18 @@ class UploadTheme extends Themelet { "; if($tl_enabled) { - $link = make_http(make_link("upload")); + $link = make_http(make_link("upload")); + $main_page = make_http(make_link()); + $title = $config->get_string('title'); + if($config->get_bool('nice_urls')){ $delimiter = '?'; } else { $delimiter = '&'; } - { - $title = "Upload to " . $config->get_string('title'); - $html .= '

    ' . - $title . ' (Drag & drop onto your bookmarks toolbar, then click when looking at an image)'; + { + $js='javascript:(function(){if(typeof window=="undefined"||!window.location||window.location.href=="about:blank"){window.location="'. $main_page .'";}else if(typeof document=="undefined"||!document.body){window.location="'. $main_page .'?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");}}})();'; + $html .= '

    Upload to '.$title.' (Drag & drop onto your bookmarks toolbar, then click when looking at an image)'; } { /* Danbooru > Shimmie Bookmarklet. From ce303d4fe37df766745acb4b852cbdaab012c24c Mon Sep 17 00:00:00 2001 From: "green-ponies (jgen)" Date: Mon, 16 Jan 2012 16:11:53 -0500 Subject: [PATCH 021/120] Needs to have the get_base_href() first. --- contrib/notes/theme.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contrib/notes/theme.php b/contrib/notes/theme.php index 5bbf506e..4d0e1d3e 100644 --- a/contrib/notes/theme.php +++ b/contrib/notes/theme.php @@ -58,8 +58,9 @@ class NotesTheme extends Themelet { // check action POST on form public function display_note_system(Page $page, $image_id, $recovered_notes, $adminOptions) { - $page->add_html_header("", 100); - $page->add_html_header("", 101); + $data_href = get_base_href(); + $page->add_html_header("", 100); + $page->add_html_header("", 101); $html = " @@ -153,6 +180,14 @@ class Layout { $main_block_html = "

    $main_block_html
    "; } + // This is required for the holiday feature. + if(empty($csssheet)){ + $csssheet = ""; + } + if(empty($banner)){ + $holiday = ""; + } + print << @@ -160,10 +195,12 @@ class Layout { {$page->title} + $csssheet $header_html + $banner $menu $custom_sublinks From 77597001609df7cf640e76ed7ee79edf38d39f47 Mon Sep 17 00:00:00 2001 From: Daku Date: Tue, 17 Jan 2012 03:58:28 +0000 Subject: [PATCH 025/120] fixes tag_edit__locked/locked errors --- ext/upload/main.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/upload/main.php b/ext/upload/main.php index ebe48b69..2620ac34 100644 --- a/ext/upload/main.php +++ b/ext/upload/main.php @@ -314,7 +314,7 @@ class Upload implements Extension { } // Checks if user is admin > check if you want locked. - if($user->is_admin()){ + if($user->is_admin() && !empty($_GET['locked'])){ $locked = bool_escape($_GET['locked']); } From fcb8307f58d18e72960d315e2220cd1569625907 Mon Sep 17 00:00:00 2001 From: Daku Date: Tue, 17 Jan 2012 04:03:32 +0000 Subject: [PATCH 026/120] Booru bookmarklet now works with shimmie sites + is now loaded via .js script on the site. --- ext/upload/bookmarklet.js | 42 +++++++++++++++++++++++++++++++++++++++ ext/upload/theme.php | 35 ++++++++------------------------ 2 files changed, 50 insertions(+), 27 deletions(-) create mode 100644 ext/upload/bookmarklet.js diff --git a/ext/upload/bookmarklet.js b/ext/upload/bookmarklet.js new file mode 100644 index 00000000..b32b8009 --- /dev/null +++ b/ext/upload/bookmarklet.js @@ -0,0 +1,42 @@ +/* Imageboard to Shimmie */ +// This should work with "most" sites running Danbooru/Gelbooru/Shimmie +// Danbooru +if(document.getElementById("post_tags") !== null){ + var tag=document.getElementById("post_tags").value; + var rtg=document.documentElement.innerHTML.match("
  • Rating: (.*)<\/li>")[1]; + var srx="http://" + document.location.hostname + document.location.href.match("\/post\/show\/[0-9]+\/"); + if(tag.search(/\bflash\b/)==-1){ + location.href=ste+document.getElementById("highres").href+"&tags="+tag+"&rating="+rtg[1]+"&source="+srx; + }else{ + location.href=ste+document.getElementsByName("movie")[0].value+"&tags="+tag+"&rating="+rtg[1]+"&source="+srx; + } +} +/* Shimmie +Shimmie doesn't seem to have any way to grab tags via id unless you have the ability to edit tags. +Have to go the round about way of checking the title for tags. +This crazy way of checking "should" work with older releases though (Seems to work with 2009~ ver) */ +else if(document.getElementsByTagName("title")[0].innerHTML.search("Image [0-9.-]+\: ")==0){ + var tag=document.getElementsByTagName("title")[0].innerHTML.match("Image [0-9.-]+\: (.*)")[1]; + //TODO: Make rating show in statistics. + var srx="http://" + document.location.hostname + document.location.href.match("\/post\/view\/[0-9]+"); + /*TODO: Figure out regex for shortening file link. + I.E http://blah.net/_images/1234abcd/everysingletag.png > http://blah.net/_images/1234abcd.png + .match("WEBSITE.NET\/_images\/[A-Za-z0-9]+", "(\\.[a-z][a-z]+)")*/ + if(tag.search(/\bflash\b/)==-1){ + location.href=ste+document.getElementById("main_image").src+"&tags="+tag+"&source="+srx; + }else{ + location.href=ste+document.location.hostname+document.getElementsByName("movie")[0].value+"&tags="+tag+"&source="+srx; + } +}/* +// Gelbooru +else if(document.getElementById("tags") !== null){ + //Gelbooru has an annoying anti-hotlinking thing which doesn't seem to like the bookmarklet... + //So if someone can figure out how to bypass the hotlinking, please update the code :< + var ste="http://localhost/shimmie_trunk/upload?url="; + var tag=document.getElementById("tags").value; + var rtg=document.documentElement.innerHTML.match("
  • Rating: (.*)<\/li>")[1]; + var srx="http://" + document.location.hostname + document.location.href.match("\/index\.php\\?page=post&s=view&id=.*"); //Gelbooru has really ugly urls.. + var gmi=document.getElementById("image").src.match(".*img[0-9]+\.gelbooru\.com\/\/images\/[0-9]+\/[a-z0-9]+\.[a-z0-9]+")[0]; + //Since Gelbooru does not allow flash, no need to search for flash tag. + location.href=ste+gmi+"&tags="+tag+"&rating="+rtg[1]+"&source="+srx'; +}*/ diff --git a/ext/upload/theme.php b/ext/upload/theme.php index 1b13bf9e..6f83a0b2 100644 --- a/ext/upload/theme.php +++ b/ext/upload/theme.php @@ -140,34 +140,15 @@ class UploadTheme extends Themelet { $html .= '

    Upload to '.$title.' (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?) + /* Imageboard > Shimmie Bookmarklet + This is more or less, an upgraded version of the "Danbooru>Shimmie" bookmarklet. + At the moment this works with Shimmie & Danbooru. + It would also work with Gelbooru but unless someone can figure out how to bypass their hotlinking..meh. + The bookmarklet is now also loaded via the .js file in this folder. */ - $title = "Danbooru to " . $config->get_string('title'); - $html .= '

    ' . - $title . ' (As above, Click on a Danbooru-run image page. (This also grabs the tags/rating/source!))'; - + $title = "Booru to " . $config->get_string('title'); + $html .= '

    '. + $title . ' (Click when looking at an image page. Works on sites running Shimmie or Danbooru. (This also grabs the tags/rating/source!))'; } } From 9f5465c0e5480b1a8904e13e5ebbd26b7c541540 Mon Sep 17 00:00:00 2001 From: Daku Date: Tue, 17 Jan 2012 04:28:45 +0000 Subject: [PATCH 027/120] Bookmarklet now asks if you want to use current/new tags again. --- ext/upload/bookmarklet.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ext/upload/bookmarklet.js b/ext/upload/bookmarklet.js index b32b8009..6cde44fa 100644 --- a/ext/upload/bookmarklet.js +++ b/ext/upload/bookmarklet.js @@ -1,8 +1,10 @@ /* Imageboard to Shimmie */ // This should work with "most" sites running Danbooru/Gelbooru/Shimmie + +if (confirm("OK = Use Current tags.\nCancel = Use new tags.")==true){}else{var tag=prompt("Enter Tags","");var chk=1;}; // Danbooru if(document.getElementById("post_tags") !== null){ - var tag=document.getElementById("post_tags").value; + if (typeof tag !=="ftp://ftp." && chk !==1){var tag=document.getElementById("post_tags").value;} var rtg=document.documentElement.innerHTML.match("

  • Rating: (.*)<\/li>")[1]; var srx="http://" + document.location.hostname + document.location.href.match("\/post\/show\/[0-9]+\/"); if(tag.search(/\bflash\b/)==-1){ @@ -16,7 +18,7 @@ Shimmie doesn't seem to have any way to grab tags via id unless you have the abi Have to go the round about way of checking the title for tags. This crazy way of checking "should" work with older releases though (Seems to work with 2009~ ver) */ else if(document.getElementsByTagName("title")[0].innerHTML.search("Image [0-9.-]+\: ")==0){ - var tag=document.getElementsByTagName("title")[0].innerHTML.match("Image [0-9.-]+\: (.*)")[1]; + if (typeof tag !=="ftp://ftp." && chk !==1){var tag=document.getElementsByTagName("title")[0].innerHTML.match("Image [0-9.-]+\: (.*)")[1];} //TODO: Make rating show in statistics. var srx="http://" + document.location.hostname + document.location.href.match("\/post\/view\/[0-9]+"); /*TODO: Figure out regex for shortening file link. @@ -32,8 +34,7 @@ else if(document.getElementsByTagName("title")[0].innerHTML.search("Image [0-9.- else if(document.getElementById("tags") !== null){ //Gelbooru has an annoying anti-hotlinking thing which doesn't seem to like the bookmarklet... //So if someone can figure out how to bypass the hotlinking, please update the code :< - var ste="http://localhost/shimmie_trunk/upload?url="; - var tag=document.getElementById("tags").value; + if (typeof tag !=="ftp://ftp." && chk !==1){var tag=document.getElementById("tags").value;} var rtg=document.documentElement.innerHTML.match("
  • Rating: (.*)<\/li>")[1]; var srx="http://" + document.location.hostname + document.location.href.match("\/index\.php\\?page=post&s=view&id=.*"); //Gelbooru has really ugly urls.. var gmi=document.getElementById("image").src.match(".*img[0-9]+\.gelbooru\.com\/\/images\/[0-9]+\/[a-z0-9]+\.[a-z0-9]+")[0]; From 433197e1871e405fe71983ae1a0e541dc53e2181 Mon Sep 17 00:00:00 2001 From: Daku Date: Tue, 17 Jan 2012 04:57:14 +0000 Subject: [PATCH 028/120] Bookmarklet seems to work fine with Gelbooru now... --- ext/upload/bookmarklet.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ext/upload/bookmarklet.js b/ext/upload/bookmarklet.js index 6cde44fa..5ca4cca0 100644 --- a/ext/upload/bookmarklet.js +++ b/ext/upload/bookmarklet.js @@ -29,15 +29,15 @@ else if(document.getElementsByTagName("title")[0].innerHTML.search("Image [0-9.- }else{ location.href=ste+document.location.hostname+document.getElementsByName("movie")[0].value+"&tags="+tag+"&source="+srx; } -}/* +} // Gelbooru else if(document.getElementById("tags") !== null){ //Gelbooru has an annoying anti-hotlinking thing which doesn't seem to like the bookmarklet... - //So if someone can figure out how to bypass the hotlinking, please update the code :< if (typeof tag !=="ftp://ftp." && chk !==1){var tag=document.getElementById("tags").value;} var rtg=document.documentElement.innerHTML.match("
  • Rating: (.*)<\/li>")[1]; - var srx="http://" + document.location.hostname + document.location.href.match("\/index\.php\\?page=post&s=view&id=.*"); //Gelbooru has really ugly urls.. + //Can't seem to grab source due to url containing a & + //var srx="http://" + document.location.hostname + document.location.href.match("\/index\.php?page=post&s=view\\&id=.*"); var gmi=document.getElementById("image").src.match(".*img[0-9]+\.gelbooru\.com\/\/images\/[0-9]+\/[a-z0-9]+\.[a-z0-9]+")[0]; //Since Gelbooru does not allow flash, no need to search for flash tag. - location.href=ste+gmi+"&tags="+tag+"&rating="+rtg[1]+"&source="+srx'; -}*/ + location.href=ste+gmi+"&tags="+tag+"&rating="+rtg[1];//+"&source="+srx; +} From a45c09b2b6967df5608926b8816e25c54e6aa96e Mon Sep 17 00:00:00 2001 From: Daku Date: Tue, 17 Jan 2012 07:57:58 +0000 Subject: [PATCH 029/120] Bookmarklet now checks if ext is supported/filesize is lower than limit before attempting to upload. --- ext/upload/bookmarklet.js | 45 +++++++++++++++++++++++++++++---------- ext/upload/theme.php | 10 +++++++-- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/ext/upload/bookmarklet.js b/ext/upload/bookmarklet.js index 5ca4cca0..05646134 100644 --- a/ext/upload/bookmarklet.js +++ b/ext/upload/bookmarklet.js @@ -1,16 +1,31 @@ /* Imageboard to Shimmie */ // This should work with "most" sites running Danbooru/Gelbooru/Shimmie +var maxsze = (maxsze.match("(?:\.*[0-9])")) * 1024; //This assumes we are only working with MB. +var toobig = "The file you are trying to upload is too big to upload!"; +var notsup = "The file you are trying to upload is not supported!"; + if (confirm("OK = Use Current tags.\nCancel = Use new tags.")==true){}else{var tag=prompt("Enter Tags","");var chk=1;}; + // Danbooru if(document.getElementById("post_tags") !== null){ if (typeof tag !=="ftp://ftp." && chk !==1){var tag=document.getElementById("post_tags").value;} - var rtg=document.documentElement.innerHTML.match("
  • Rating: (.*)<\/li>")[1]; + var rtg=document.getElementById("stats").innerHTML.match("
  • Rating: (.*)<\/li>")[1]; var srx="http://" + document.location.hostname + document.location.href.match("\/post\/show\/[0-9]+\/"); + var filesze=document.getElementById("stats").innerHTML.match("[0-9] \\(((?:\.*[0-9])) ([a-zA-Z]+)"); + if(filesze[2] == "MB"){var filesze = filesze[1] * 1024;}else{var filesze = filesze[2].match("[0-9]+");} if(tag.search(/\bflash\b/)==-1){ - location.href=ste+document.getElementById("highres").href+"&tags="+tag+"&rating="+rtg[1]+"&source="+srx; + if(supext.search(document.getElementById("highres").href.match("http\:\/\/.*\\.([a-z0-9]+)")[1]) !== -1){ + if(filesze <= maxsze){ + location.href=ste+document.getElementById("highres").href+"&tags="+tag+"&rating="+rtg[1]+"&source="+srx; + }else{alert(toobig);} + }else{alert(notsup);} }else{ - location.href=ste+document.getElementsByName("movie")[0].value+"&tags="+tag+"&rating="+rtg[1]+"&source="+srx; + if(supext.search(document.getElementById("highres").href.match("http\:\/\/.*\\.([a-z0-9]+)")[1]) !== -1){ + if(filesze <= maxsze){ + location.href=ste+document.getElementsByName("movie")[0].value+"&tags="+tag+"&rating="+rtg[1]+"&source="+srx; + }else{alert(toobig);} + }else{alert(notsup);} } } /* Shimmie @@ -21,23 +36,31 @@ else if(document.getElementsByTagName("title")[0].innerHTML.search("Image [0-9.- if (typeof tag !=="ftp://ftp." && chk !==1){var tag=document.getElementsByTagName("title")[0].innerHTML.match("Image [0-9.-]+\: (.*)")[1];} //TODO: Make rating show in statistics. var srx="http://" + document.location.hostname + document.location.href.match("\/post\/view\/[0-9]+"); - /*TODO: Figure out regex for shortening file link. - I.E http://blah.net/_images/1234abcd/everysingletag.png > http://blah.net/_images/1234abcd.png - .match("WEBSITE.NET\/_images\/[A-Za-z0-9]+", "(\\.[a-z][a-z]+)")*/ + /*TODO: Figure out regex for shortening file link. I.E http://blah.net/_images/1234abcd/everysingletag.png > http://blah.net/_images/1234abcd.png*/ + /*TODO: Make file size show on all themes (Only seems to show in lite/Danbooru themes.)*/ if(tag.search(/\bflash\b/)==-1){ - location.href=ste+document.getElementById("main_image").src+"&tags="+tag+"&source="+srx; + var img = document.getElementById("main_image").src; + if(supext.search(img.match(".*\\.([a-z0-9]+)")[1]) !== -1){ + location.href=ste+img+"&tags="+tag+"&source="+srx; + }else{alert(notsup);} }else{ - location.href=ste+document.location.hostname+document.getElementsByName("movie")[0].value+"&tags="+tag+"&source="+srx; + var mov = document.location.hostname+document.getElementsByName("movie")[0].value; + if(supext.search(mov.match(".*\\.([a-z0-9]+)")[1]) !== -1){ + location.href=ste+mov+"&tags="+tag+"&source="+srx; + }else{alert(notsup);} } } // Gelbooru else if(document.getElementById("tags") !== null){ - //Gelbooru has an annoying anti-hotlinking thing which doesn't seem to like the bookmarklet... + //Gelbooru has an annoying anti-hotlinking thing which doesn't seem to like the bookmarklet. if (typeof tag !=="ftp://ftp." && chk !==1){var tag=document.getElementById("tags").value;} - var rtg=document.documentElement.innerHTML.match("
  • Rating: (.*)<\/li>")[1]; + var rtg=document.getElementById("stats").innerHTML.match("
  • Rating: (.*)<\/li>")[1]; //Can't seem to grab source due to url containing a & //var srx="http://" + document.location.hostname + document.location.href.match("\/index\.php?page=post&s=view\\&id=.*"); var gmi=document.getElementById("image").src.match(".*img[0-9]+\.gelbooru\.com\/\/images\/[0-9]+\/[a-z0-9]+\.[a-z0-9]+")[0]; //Since Gelbooru does not allow flash, no need to search for flash tag. - location.href=ste+gmi+"&tags="+tag+"&rating="+rtg[1];//+"&source="+srx; + //Gelbooru doesn't show file size in statistics either... + if(supext.search(gmi.match("http\:\/\/.*\\.([a-z0-9]+)")[1]) !== -1){ + location.href=ste+gmi+"&tags="+tag+"&rating="+rtg[1];//+"&source="+srx; + }else{alert(notsup);} } diff --git a/ext/upload/theme.php b/ext/upload/theme.php index 6f83a0b2..ecdc64a5 100644 --- a/ext/upload/theme.php +++ b/ext/upload/theme.php @@ -146,9 +146,15 @@ class UploadTheme extends Themelet { It would also work with Gelbooru but unless someone can figure out how to bypass their hotlinking..meh. The bookmarklet is now also loaded via the .js file in this folder. */ + //Bookmarklet checks if shimmie supports ext. If not, won't upload to site/shows alert saying not supported. + $supported_ext = "jpg jpeg gif png"; + if(file_exists("ext/handle_flash")){$supported_ext .= " swf";} + if(file_exists("ext/handle_ico")){$supported_ext .= " ico ani cur";} + if(file_exists("ext/handle_mp3")){$supported_ext .= " mp3";} + if(file_exists("ext/handle_svg")){$supported_ext .= " svg";} $title = "Booru to " . $config->get_string('title'); - $html .= '

    '. - $title . ' (Click when looking at an image page. Works on sites running Shimmie or Danbooru. (This also grabs the tags/rating/source!))'; + $html .= '

    '. + $title . ' (Click when looking at an image page. Works on sites running Shimmie/Danbooru/Gelbooru. (This also grabs the tags/rating/source!))'; } } From a336944b11d1da0cf874e5b24ee42ebbf71e503f Mon Sep 17 00:00:00 2001 From: Daku Date: Tue, 17 Jan 2012 10:56:52 +0000 Subject: [PATCH 030/120] uploader fixes --- ext/upload/theme.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ext/upload/theme.php b/ext/upload/theme.php index ecdc64a5..fc6d5f59 100644 --- a/ext/upload/theme.php +++ b/ext/upload/theme.php @@ -34,7 +34,7 @@ class UploadTheme extends Themelet { $("#hide'.$i.'").hide(); $("#hide'.$a.'").show();});'; - $upload_list .= "

    " . + $upload_list .= "
    " . "". "
    "; } else { @@ -51,7 +51,7 @@ class UploadTheme extends Themelet { ""; if($a==$config->get_int('upload_count')){ - $upload_list .=""; + $upload_list .=""; }else{ $js1 = 'javascript:$(function() { $("#row'.$a.'").show(); @@ -66,12 +66,12 @@ class UploadTheme extends Themelet { } $js2 = 'javascript:$(function() { - $("#url'.$i.'").show(); + $("#url'.$i.'").hide(); $("#url'.$i.'").val(""); $("#data'.$i.'").show(); });'; $upload_list .= - "
  • + " URL
    Tags
    File
    "; + "
    File
    "; if($tl_enabled) { $js = 'javascript:$(function() { @@ -80,7 +80,7 @@ class UploadTheme extends Themelet { $("#url'.$i.'").show(); });'; $upload_list .= - " URL
    From 940b95c9e6f6d090a12fa611e21f0332589c1e7d Mon Sep 17 00:00:00 2001 From: Shish Date: Tue, 17 Jan 2012 15:33:42 +0000 Subject: [PATCH 031/120] searching for image hash bans --- contrib/image_hash_ban/main.php | 23 +++++++++++++++++++++-- contrib/image_hash_ban/theme.php | 11 ++++++++++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/contrib/image_hash_ban/main.php b/contrib/image_hash_ban/main.php index 1c36fd9c..a99fe7c7 100644 --- a/contrib/image_hash_ban/main.php +++ b/contrib/image_hash_ban/main.php @@ -128,11 +128,30 @@ class ImageBan extends SimpleExtension { // DB funness public function get_image_hash_bans($page, $size=100) { + global $database; + // FIXME: many $size_i = int_escape($size); $offset_i = int_escape($page-1)*$size_i; - global $database; - $bans = $database->get_all("SELECT * FROM image_bans ORDER BY id DESC LIMIT $size_i OFFSET $offset_i"); + $where = array("(1=1)"); + $args = array(); + if(!empty($_GET['hash'])) { + $where[] = 'hash = ?'; + $args[] = $_GET['hash']; + } + if(!empty($_GET['reason'])) { + $where[] = 'reason SCORE_ILIKE ?'; + $args[] = "%".$_GET['reason']."%"; + } + $where = implode(" AND ", $where); + $bans = $database->get_all($database->engine->scoreql_to_sql(" + SELECT * + FROM image_bans + WHERE $where + ORDER BY id DESC + LIMIT $size_i + OFFSET $offset_i + "), $args); if($bans) {return $bans;} else {return array();} } diff --git a/contrib/image_hash_ban/theme.php b/contrib/image_hash_ban/theme.php index 1e858c79..d4649921 100644 --- a/contrib/image_hash_ban/theme.php +++ b/contrib/image_hash_ban/theme.php @@ -45,7 +45,16 @@ class ImageBanTheme extends Themelet { }); - + + + + + + + + + + $h_bans ".make_form(make_link("image_hash_ban/add"))." From e46c22a228bd074a0289cbd207f89d9abd1cfa52 Mon Sep 17 00:00:00 2001 From: Shish Date: Tue, 17 Jan 2012 15:47:58 +0000 Subject: [PATCH 032/120] weighted CDN targets --- core/imageboard.pack.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/core/imageboard.pack.php b/core/imageboard.pack.php index 428a4484..70e0d9fb 100644 --- a/core/imageboard.pack.php +++ b/core/imageboard.pack.php @@ -521,7 +521,18 @@ class Image { require_once("lib/flexihash.php"); $_flexihash = new Flexihash(); foreach(explode(",", $opts) as $opt) { - $_flexihash->addTarget($opt); + $parts = explode("=", $opt); + $opt_val = ""; + $opt_weight = 0; + if(count($parts) == 2) { + $opt_val = $parts[0]; + $opt_weight = $parts[1]; + } + elseif(count($parts) == 1) { + $opt_val = $parts[0]; + $opt_weight = 1; + } + $_flexihash->addTarget($opt_val, $opt_weight); } } From 46776bf853812a7dddba60de4e0f1b0ecd641d1b Mon Sep 17 00:00:00 2001 From: NaGeL Date: Tue, 17 Jan 2012 22:43:16 +0100 Subject: [PATCH 033/120] added author= search tag. --- contrib/artists/main.php | 92 +++++++++++++++++++++++++++++++++------- 1 file changed, 76 insertions(+), 16 deletions(-) diff --git a/contrib/artists/main.php b/contrib/artists/main.php index e4a5a803..cb11b40d 100644 --- a/contrib/artists/main.php +++ b/contrib/artists/main.php @@ -43,6 +43,14 @@ class Artists implements Extension { if ($event instanceof PageRequestEvent) $this->handle_commands($event); + + if($event instanceof SearchTermParseEvent) { + $matches = array(); + if(preg_match("/^author=(.*)$/", $event->term, $matches)) { + $char = $matches[1]; + $event->add_querylet(new Querylet("Author = :author_char", array("author_char"=>$char))); + } + } } public function try_install() { @@ -130,7 +138,10 @@ class Artists implements Extension { } $database->execute("UPDATE images SET author = ? WHERE id = ?" - , array($artistName, $event->image->id)); + , array( + $artistName + , $event->image->id + )); } public function handle_commands($event) { @@ -457,7 +468,9 @@ class Artists implements Extension { global $database; $result = $database->get_one("SELECT COUNT(1) FROM artist_alias WHERE artist_id = ? AND alias = ?", array( - $artistID, $alias)); + $artistID + , $alias + )); return ($result != 0); } @@ -617,7 +630,12 @@ class Artists implements Extension { global $database; $database->execute("UPDATE artists SET name = ?, notes = ?, updated = now(), user_id = ? WHERE id = ? " - , array( $name, $notes, $userID, $artistID )); + , array( + $name + , $notes + , $userID + , $artistID + )); // ALIAS MATCHING SECTION $i = 0; @@ -708,7 +726,11 @@ class Artists implements Extension { global $database; $database->execute("UPDATE artist_alias SET alias = ?, updated = now(), user_id = ? WHERE id = ? " - , array( $alias, $userID, $aliasID )); + , array( + $alias + , $userID + , $aliasID + )); } private function update_url() @@ -733,7 +755,11 @@ class Artists implements Extension { global $database; $database->execute("UPDATE artist_urls SET url = ?, updated = now(), user_id = ? WHERE id = ?" - , array( $url, $userID, $urlID )); + , array( + $url + , $userID + , $urlID + )); } private function update_member() @@ -759,7 +785,11 @@ class Artists implements Extension { global $database; $database->execute("UPDATE artist_members SET name = ?, updated = now(), user_id = ? WHERE id = ?" - , array( $memberName, $userID, $memberID )); + , array( + $memberName + , $userID + , $memberID + )); } /* @@ -831,7 +861,11 @@ class Artists implements Extension { (user_id, name, notes, created, updated) VALUES (?, ?, ?, now(), now())", - array( $user->id, $name, $notes )); + array( + $user->id + , $name + , $notes + )); $result = $database->get_row("SELECT LAST_INSERT_ID() AS artistID", array()); @@ -845,7 +879,9 @@ class Artists implements Extension { global $database; $result = $database->get_one("SELECT COUNT(1) FROM artists WHERE name = ?" - , array($name)); + , array( + $name + )); return ($result != 0); } @@ -909,7 +945,9 @@ class Artists implements Extension { private function get_artist_id($name){ global $database; $artistID = $database->get_row("SELECT id FROM artists WHERE name = ?" - , array( $name )); + , array( + $name + )); return $artistID['id']; } @@ -918,7 +956,9 @@ class Artists implements Extension { global $database; $artistID = $database->get_row("SELECT artist_id FROM artist_alias WHERE alias = ?" - , array( $alias )); + , array( + $alias + )); return $artistID["artist_id"]; } @@ -932,7 +972,9 @@ class Artists implements Extension { global $database; $database->execute("DELETE FROM artists WHERE id = ? " - , array( $artistID )); + , array( + $artistID + )); } @@ -1056,7 +1098,11 @@ class Artists implements Extension { global $database; $database->execute("INSERT INTO artist_urls (artist_id, created, updated, url, user_id) VALUES (?, now(), now(), ?, ?)" - , array( $artistID, $url, $userID )); + , array( + $artistID + , $url + , $userID + )); } private function add_alias() @@ -1086,7 +1132,11 @@ class Artists implements Extension { global $database; $database->execute("INSERT INTO artist_alias (artist_id, created, updated, alias, user_id) VALUES (?, now(), now(), ?, ?)" - , array( $artistID, $alias, $userID )); + , array( + $artistID + , $alias + , $userID + )); } private function add_members() @@ -1115,7 +1165,11 @@ class Artists implements Extension { global $database; $database->execute("INSERT INTO artist_members (artist_id, name, created, updated, user_id) VALUES (?, ?, now(), now(), ?)" - , array( $artistID, $member, $userID )); + , array( + $artistID + , $member + , $userID + )); } private function member_exists($artistID, $member) @@ -1125,7 +1179,10 @@ class Artists implements Extension { global $database; $result = $database->get_one("SELECT COUNT(1) FROM artist_members WHERE artist_id = ? AND name = ?" - , array( $artistID, $member )); + , array( + $artistID + , $member + )); return ($result != 0); } @@ -1136,7 +1193,10 @@ class Artists implements Extension { global $database; $result = $database->get_one("SELECT COUNT(1) FROM artist_urls WHERE artist_id = ? AND url = ?" - , array( $artistID, $url )); + , array( + $artistID + , $url + )); return ($result != 0); } From 3c6217fa4cb16517c06cd51d086450aa3a3ecf9b Mon Sep 17 00:00:00 2001 From: NaGeL Date: Tue, 17 Jan 2012 22:45:24 +0100 Subject: [PATCH 034/120] added [align=(left|center|right)] BBcode which aligns text naturally. --- ext/bbcode/main.php | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/bbcode/main.php b/ext/bbcode/main.php index bddda8c5..328d9dba 100644 --- a/ext/bbcode/main.php +++ b/ext/bbcode/main.php @@ -63,6 +63,7 @@ class BBCode extends FormatterExtension { $text = preg_replace("/\[li\](.*?)\[\/li\]/s", "
  • \\1
  • ", $text); $text = preg_replace("#\[\*\]#s", "
  • ", $text); $text = preg_replace("#
    <(li|ul|ol|/ul|/ol)>#s", "<\\1>", $text); + $text = preg_replace("#\[align=(left|center|right)\](.*?)\[\/align\]#s", "
    \\2
    ", $text); $text = $this->filter_spoiler($text); $text = $this->insert_code($text); return $text; From bdf274074c0f8bd8e52847c1170c4c14e9dc33b4 Mon Sep 17 00:00:00 2001 From: Shish Date: Wed, 18 Jan 2012 03:13:27 +0000 Subject: [PATCH 035/120] some people like heading to the image after an image that isn't there (mostly robots with old URLs) --- ext/view/main.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/ext/view/main.php b/ext/view/main.php index fc495cbc..56105a8e 100644 --- a/ext/view/main.php +++ b/ext/view/main.php @@ -87,6 +87,10 @@ class ViewImage extends SimpleExtension { } $image = Image::by_id($image_id); + if(is_null($image)) { + $this->theme->display_error($page, "Image not found", "Couldn't find image $image_id"); + } + if($event->page_matches("post/next")) { $image = $image->get_next($search_terms); } @@ -94,13 +98,12 @@ class ViewImage extends SimpleExtension { $image = $image->get_prev($search_terms); } - if(!is_null($image)) { - $page->set_mode("redirect"); - $page->set_redirect(make_link("post/view/{$image->id}", $query)); - } - else { + if(is_null($image)) { $this->theme->display_error($page, "Image not found", "No more images"); } + + $page->set_mode("redirect"); + $page->set_redirect(make_link("post/view/{$image->id}", $query)); } if($event->page_matches("post/view")) { From b52651c5582d1445248983ee57bf0908ebddaf4f Mon Sep 17 00:00:00 2001 From: NaGeL Date: Tue, 17 Jan 2012 22:45:24 +0100 Subject: [PATCH 036/120] added [align=(left|center|right)] BBcode which aligns text naturally. --- ext/bbcode/main.php | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/bbcode/main.php b/ext/bbcode/main.php index bddda8c5..328d9dba 100644 --- a/ext/bbcode/main.php +++ b/ext/bbcode/main.php @@ -63,6 +63,7 @@ class BBCode extends FormatterExtension { $text = preg_replace("/\[li\](.*?)\[\/li\]/s", "
  • \\1
  • ", $text); $text = preg_replace("#\[\*\]#s", "
  • ", $text); $text = preg_replace("#
    <(li|ul|ol|/ul|/ol)>#s", "<\\1>", $text); + $text = preg_replace("#\[align=(left|center|right)\](.*?)\[\/align\]#s", "
    \\2
    ", $text); $text = $this->filter_spoiler($text); $text = $this->insert_code($text); return $text; From b1d1d71093066a7b55eea622fc96328d36b1a88c Mon Sep 17 00:00:00 2001 From: Shish Date: Wed, 18 Jan 2012 17:53:52 +0000 Subject: [PATCH 037/120] author search from nagel --- contrib/artists/main.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/contrib/artists/main.php b/contrib/artists/main.php index e4a5a803..c86a8e10 100644 --- a/contrib/artists/main.php +++ b/contrib/artists/main.php @@ -43,6 +43,14 @@ class Artists implements Extension { if ($event instanceof PageRequestEvent) $this->handle_commands($event); + + if ($event instanceof SearchTermParseEvent) { + $matches = array(); + if(preg_match("/^author=(.*)$/", $event->term, $matches)) { + $char = $matches[1]; + $event->add_querylet(new Querylet("Author = :author_char", array("author_char"=>$char))); + } + } } public function try_install() { From 760810723286e04bd96defd5d90e6beae64992f2 Mon Sep 17 00:00:00 2001 From: Shish Date: Thu, 19 Jan 2012 15:20:32 +0000 Subject: [PATCH 038/120] lib/askismet expects the referrer to either be set manually, or exist; if it doesn't exist we need to set it manually --- ext/comment/main.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ext/comment/main.php b/ext/comment/main.php index 6e165d03..0c54ad06 100644 --- a/ext/comment/main.php +++ b/ext/comment/main.php @@ -405,6 +405,13 @@ class CommentList extends SimpleExtension { 'permalink' => '', ); + # akismet breaks if there's no referrer in the environment; so if there + # isn't, supply one manually + if(!isset($_SERVER['HTTP_REFERER'])) { + $comment['referrer'] = ''; + log_warning("comment", "User '{$user->name}' commented with no referrer: $text"); + } + $akismet = new Akismet( $_SERVER['SERVER_NAME'], $config->get_string('comment_wordpress_key'), From b8bdbd3533fb917d7ee27fceb97d90bbc9b4986f Mon Sep 17 00:00:00 2001 From: Shish Date: Thu, 19 Jan 2012 15:23:44 +0000 Subject: [PATCH 039/120] after detecting an error, don't carry on processing the bad data... --- ext/view/main.php | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/view/main.php b/ext/view/main.php index 56105a8e..01df30ee 100644 --- a/ext/view/main.php +++ b/ext/view/main.php @@ -89,6 +89,7 @@ class ViewImage extends SimpleExtension { $image = Image::by_id($image_id); if(is_null($image)) { $this->theme->display_error($page, "Image not found", "Couldn't find image $image_id"); + return; } if($event->page_matches("post/next")) { From 520fb08652d674d6d6d98194813567ea3f23a48d Mon Sep 17 00:00:00 2001 From: NaGeL Date: Thu, 19 Jan 2012 16:28:16 +0100 Subject: [PATCH 040/120] just gitignore update --- .gitignore | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.gitignore b/.gitignore index b1d70c05..72316d3d 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,12 @@ ext/upload_cmd ext/wiki ext/word_filter ext/zoom + +/ext/resize/main.php +/ext/resize/style.css +/ext/resize/theme.php +/ext/twitter_soc/main.php +/ext/twitter_soc/script.js +/ext/twitter_soc/style.css +/ext/twitter_soc/test.php +/ext/twitter_soc/theme.php \ No newline at end of file From 8ba22d8fbcf1434fbef81d21cec6bdecc2e5aae1 Mon Sep 17 00:00:00 2001 From: Shish Date: Thu, 19 Jan 2012 15:28:55 +0000 Subject: [PATCH 041/120] same for user-agent --- ext/comment/main.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ext/comment/main.php b/ext/comment/main.php index 0c54ad06..6f082a76 100644 --- a/ext/comment/main.php +++ b/ext/comment/main.php @@ -408,9 +408,13 @@ class CommentList extends SimpleExtension { # akismet breaks if there's no referrer in the environment; so if there # isn't, supply one manually if(!isset($_SERVER['HTTP_REFERER'])) { - $comment['referrer'] = ''; + $comment['referrer'] = 'none'; log_warning("comment", "User '{$user->name}' commented with no referrer: $text"); } + if(!isset($_SERVER['HTTP_USER_AGENT'])) { + $comment['user_agent'] = 'none'; + log_warning("comment", "User '{$user->name}' commented with no user-agent: $text"); + } $akismet = new Akismet( $_SERVER['SERVER_NAME'], From 557a82e7bec36d741063f288eb548efe9073d915 Mon Sep 17 00:00:00 2001 From: NaGeL Date: Thu, 19 Jan 2012 16:43:20 +0100 Subject: [PATCH 042/120] Fixed linking bug in admin_user/list page. --- ext/user/theme.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/user/theme.php b/ext/user/theme.php index 5f1491e1..b503d9f6 100644 --- a/ext/user/theme.php +++ b/ext/user/theme.php @@ -17,7 +17,7 @@ class UserPageTheme extends Themelet { $html .= "
  • "; foreach($users as $duser) { $html .= ""; - $html .= ""; + $html .= ""; $html .= ""; } $html .= "
    HashReasonAction
    HashReasonAction
    Name
    ".html_escape($duser->name)."".html_escape($duser->name)."
    "; From 8eaaa6a7ca49aafae7ed3f4b868f3fd8cfcc06a9 Mon Sep 17 00:00:00 2001 From: NaGeL Date: Thu, 19 Jan 2012 18:23:43 +0100 Subject: [PATCH 043/120] Added user deletion. User is deleted from database the Comments are deleted too, unknown reason for me Noting else is deleted so far. --- ext/user/main.php | 29 +++++++++++++++++++++++++++++ ext/user/theme.php | 5 +++++ 2 files changed, 34 insertions(+) diff --git a/ext/user/main.php b/ext/user/main.php index fc0da212..0f1e8027 100644 --- a/ext/user/main.php +++ b/ext/user/main.php @@ -144,6 +144,9 @@ class UserPage extends SimpleExtension { // join (select owner_id,count(*) as comment_count from comments group by owner_id) as _comments on _comments.owner_id=users.id; $this->theme->display_user_list($page, User::by_list(0), $user); } + else if($event->get_arg(0) == "delete_user") { + $this->delete_user($page); + } } if(($event instanceof PageRequestEvent) && $event->page_matches("user")) { @@ -463,6 +466,32 @@ class UserPage extends SimpleExtension { ORDER BY most_recent DESC", array("id"=>$duser->id)); return $rows; } + + private function delete_user($page) { + global $user; + global $config; + global $database; + + $page->set_title("Error"); + $page->set_heading("Error"); + $page->add_block(new NavBlock()); + + if (!$user->is_admin()) { + $page->add_block(new Block("Not Admin", "Only admins can delete accounts")); + } + else if(!isset($_POST['id']) || !is_numeric($_POST['id'])) { + $page->add_block(new Block("No ID Specified", + "You need to specify the account number to edit")); + } + else{ + $database->execute("DELETE FROM users + WHERE id = :id" + , array("id"=>$_POST['id'])); + } + $page->set_mode("redirect"); + $page->set_redirect(make_link("post/list")); + } + // }}} } add_event_listener(new UserPage()); diff --git a/ext/user/theme.php b/ext/user/theme.php index b503d9f6..424099f4 100644 --- a/ext/user/theme.php +++ b/ext/user/theme.php @@ -181,6 +181,11 @@ class UserPageTheme extends Themelet { "; + $html .=" +

    ".make_form(make_link("user_admin/delete_user"))." + + + "; } return $html; } From 36e443e07d360f777c2848122645db8b30873e66 Mon Sep 17 00:00:00 2001 From: Shish Date: Fri, 20 Jan 2012 03:12:48 +0000 Subject: [PATCH 044/120] the algorithm for listing old comments pages is *really* inefficient; the first few pages are quick, page 100 can take a few seconds to generate... rule34 has over 100,000 pages of comments. Limit to the first few pages for now, as I don't know anyone who even goes past the front page. --- ext/comment/main.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/ext/comment/main.php b/ext/comment/main.php index 6f082a76..c71ebc2a 100644 --- a/ext/comment/main.php +++ b/ext/comment/main.php @@ -146,7 +146,18 @@ class CommentList extends SimpleExtension { } } else if($event->get_arg(0) == "list") { - $this->build_page($event->get_arg(1)); + $page_num = int_escape($event->get_arg(1)); + if($page_num <= 5) { + $this->build_page($page_num); + } + else { + header("HTTP/1.0 403 Blocked"); + $this->theme->display_error($page, + "This page is history~", + "Only the first 5 pages of comments are visible ". + "- 99% of the traffic to older pages was bots, and ". + "they were hammering the database o.o"); + } } } } From 18e36f9b31863a18d349a13962d975fc8a6c7a9b Mon Sep 17 00:00:00 2001 From: Shish Date: Fri, 20 Jan 2012 03:15:58 +0000 Subject: [PATCH 045/120] Rather than three levels of configuration, let's have two (define()'d values in config.php for system-level stuff, the web-editable config table for user-level stuff). Basically switches database_dsn from a global variable to a defined constant. --- README.txt | 6 +++--- core/database.class.php | 13 +++++-------- core/util.inc.php | 2 +- index.php | 29 +++++++++++++++++------------ install.php | 6 ++++-- 5 files changed, 30 insertions(+), 26 deletions(-) diff --git a/README.txt b/README.txt index 97d8955a..622d90a9 100644 --- a/README.txt +++ b/README.txt @@ -40,10 +40,10 @@ Installation Upgrade from 2.3.X ~~~~~~~~~~~~~~~~~~ The database connection setting in config.php has changed; now using -PDO DSN format [1] rather than ADODB URI [2] +PDO DSN format rather than ADODB URI: - [1] :user=;password=;host=;dbname= - [2] ://:@/ + OLD: $database_dsn = "://:@/"; + NEW: define("DATABASE_DSN", ":user=;password=;host=;dbname="); The rest should be automatic, just unzip into a clean folder and copy across config.php, images and thumbs folders from the old version. This diff --git a/core/database.class.php b/core/database.class.php index 53ed4b4d..64123180 100644 --- a/core/database.class.php +++ b/core/database.class.php @@ -274,8 +274,6 @@ class Database { * stored in config.php in the root shimmie folder */ public function Database() { - global $database_dsn, $cache_dsn; - # FIXME: detect ADODB URI, automatically translate PDO DSN /* @@ -285,10 +283,10 @@ class Database { * http://stackoverflow.com/questions/237367 */ $matches = array(); $db_user=null; $db_pass=null; - if(preg_match("/user=([^;]*)/", $database_dsn, $matches)) $db_user=$matches[1]; - if(preg_match("/password=([^;]*)/", $database_dsn, $matches)) $db_pass=$matches[1]; + if(preg_match("/user=([^;]*)/", DATABASE_DSN, $matches)) $db_user=$matches[1]; + if(preg_match("/password=([^;]*)/", DATABASE_DSN, $matches)) $db_pass=$matches[1]; - $this->db = new PDO($database_dsn, $db_user, $db_pass); + $this->db = new PDO(DATABASE_DSN, $db_user, $db_pass); $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $db_proto = $this->db->getAttribute(PDO::ATTR_DRIVER_NAME); @@ -305,9 +303,8 @@ class Database { die("Unknown PDO driver: $db_proto"); } - if(isset($cache_dsn) && !empty($cache_dsn)) { - $matches = array(); - preg_match("#(memcache|apc)://(.*)#", $cache_dsn, $matches); + $matches = array(); + if(CACHE_DSN && preg_match("#(memcache|apc)://(.*)#", CACHE_DSN, $matches)) { if($matches[1] == "memcache") { $this->cache = new MemcacheCache($matches[2]); } diff --git a/core/util.inc.php b/core/util.inc.php index 97146d25..21343497 100644 --- a/core/util.inc.php +++ b/core/util.inc.php @@ -204,7 +204,7 @@ function make_link($page=null, $query=null) { if(is_null($page)) $page = $config->get_string('main_page'); - if(FORCE_NICE_URLS || $config->get_bool('nice_urls', false)) { + if(NICE_URLS || $config->get_bool('nice_urls', false)) { #$full = "http://" . $_SERVER["SERVER_NAME"] . $_SERVER["PHP_SELF"]; $full = $_SERVER["PHP_SELF"]; $base = str_replace("/index.php", "", $full); diff --git a/index.php b/index.php index 63c3b52c..29cbecca 100644 --- a/index.php +++ b/index.php @@ -57,18 +57,23 @@ if(empty($database_dsn) && !file_exists("config.php")) { require_once "config.php"; // set up and purify the environment -if(!defined("DEBUG")) define("DEBUG", false); -if(!defined("COVERAGE")) define("COVERAGE", false); -if(!defined("CONTEXT")) define("CONTEXT", false); -if(!defined("CACHE_MEMCACHE")) define("CACHE_MEMCACHE", false); -if(!defined("CACHE_DIR")) define("CACHE_DIR", false); -if(!defined("CACHE_HTTP")) define("CACHE_HTTP", false); -if(!defined("VERSION")) define("VERSION", 'trunk'); -if(!defined("SCORE_VERSION")) define("SCORE_VERSION", 's2hack/'.VERSION); -if(!defined("COOKIE_PREFIX")) define("COOKIE_PREFIX", 'shm'); -if(!defined("SPEED_HAX")) define("SPEED_HAX", false); -if(!defined("FORCE_NICE_URLS")) define("FORCE_NICE_URLS", false); -if(!defined("WH_SPLITS")) define("WH_SPLITS", 1); +function _d($name, $value) { + if(!defined($name)) define($name, $value); +} +_d("DATABASE_DSN", null); // string PDO database connection details +_d("CACHE_DSN", null); // string cache connection details +_d("DEBUG", false); // boolean print various debugging details +_d("COVERAGE", false); // boolean activate xdebug coverage monitor +_d("CONTEXT", null); // string file to log performance data into +_d("CACHE_MEMCACHE", false); // boolean store complete rendered pages in memcache +_d("CACHE_DIR", false); // boolean store complete rendered pages on disk +_d("CACHE_HTTP", false); // boolean output explicit HTTP caching headers +_d("COOKIE_PREFIX", 'shm'); // string if you run multiple galleries with non-shared logins, give them different prefixes +_d("SPEED_HAX", false); // boolean do some questionable things in the name of performance +_d("NICE_URLS", false); // boolean force niceurl mode +_d("WH_SPLITS", 1); // int how many levels of subfolders to put in the warehouse +_d("VERSION", 'trunk'); // string shimmie version +_d("SCORE_VERSION", 's2hack/'.VERSION); // string SCore version require_once "core/util.inc.php"; require_once "lib/context.php"; diff --git a/install.php b/install.php index 83a1f2f3..e5f2e5cc 100755 --- a/install.php +++ b/install.php @@ -52,7 +52,7 @@ if(is_readable("config.php")) {

    Shimmie Repair Console

    "; + $file_content = "<"+"?php\n"+ + "define('DATABASE_DSN', '$database_dsn');\n"+ + "?"+">"; if(is_writable("./") && file_put_contents("config.php", $file_content)) { assert(file_exists("config.php")); From 49e7bfa1b229546b4ee480e52e120c9b62199695 Mon Sep 17 00:00:00 2001 From: Shish Date: Fri, 20 Jan 2012 03:29:29 +0000 Subject: [PATCH 046/120] tidy up some ancient base_href / data_href messes; base_href as a config variable is no longer used --- contrib/browser_search/main.php | 1 - contrib/forum/theme.php | 2 -- contrib/home/main.php | 10 ++++------ contrib/home/theme.php | 4 ++-- contrib/rss_comments/main.php | 2 +- contrib/rss_images/main.php | 2 +- contrib/tagger/theme.php | 2 +- core/util.inc.php | 5 ++++- ext/setup/main.php | 1 - 9 files changed, 13 insertions(+), 16 deletions(-) diff --git a/contrib/browser_search/main.php b/contrib/browser_search/main.php index 0b458a64..fc113121 100755 --- a/contrib/browser_search/main.php +++ b/contrib/browser_search/main.php @@ -36,7 +36,6 @@ class BrowserSearch implements Extension { // First, we need to build all the variables we'll need $search_title = $config->get_string('title'); - //$search_form_url = $config->get_string('base_href'); //make_link('post/list'); $search_form_url = make_link('post/list/{searchTerms}'); $suggenton_url = make_link('browser_search/')."{searchTerms}"; $icon_b64 = base64_encode(file_get_contents("favicon.ico")); diff --git a/contrib/forum/theme.php b/contrib/forum/theme.php index ea460b47..40b015d9 100644 --- a/contrib/forum/theme.php +++ b/contrib/forum/theme.php @@ -83,8 +83,6 @@ class ForumTheme extends Themelet { global $config, $page/*, $user*/; $theme_name = $config->get_string('theme'); - $data_href = $config->get_string('base_href'); - $base_href = $config->get_string('base_href'); $html = ""; $n = 0; diff --git a/contrib/home/main.php b/contrib/home/main.php index f46c6238..b6172016 100644 --- a/contrib/home/main.php +++ b/contrib/home/main.php @@ -28,14 +28,13 @@ class Home extends SimpleExtension { public function onPageRequest(PageRequestEvent $event) { global $config, $page; if($event->page_matches("home")) { - $base_href = $config->get_string('base_href'); - $data_href = get_base_href(); + $base_href = get_base_href(); $sitename = $config->get_string('title'); $theme_name = $config->get_string('theme'); $body = $this->get_body(); - $this->theme->display_page($page, $sitename, $data_href, $theme_name, $body); + $this->theme->display_page($page, $sitename, $base_href, $theme_name, $body); } } @@ -58,8 +57,7 @@ class Home extends SimpleExtension { // returns just the contents of the body global $database; global $config; - $base_href = $config->get_string('base_href'); - $data_href = get_base_href(); + $base_href = get_base_href(); $sitename = $config->get_string('title'); $contact_link = $config->get_string('contact_link'); $counter_dir = $config->get_string('home_counter', 'default'); @@ -71,7 +69,7 @@ class Home extends SimpleExtension { $counter_text = ""; for($n=0; $nset_mode("data"); $page->set_data(<< $sitename - +