From 8cb95ceb98b8dc1ed18b1217793d12659cdee26b Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Tue, 25 Oct 2011 16:17:44 +0100
Subject: [PATCH 01/60] also allow https sources

---
 ext/view/theme.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ext/view/theme.php b/ext/view/theme.php
index b9cb5cf8..59f6b730 100644
--- a/ext/view/theme.php
+++ b/ext/view/theme.php
@@ -94,7 +94,7 @@ class ViewImageTheme extends Themelet {
 			$html .= " ($h_ip)";
 		}
 		if(!is_null($image->source)) {
-			if(substr($image->source, 0, 7) == "http://") {
+			if(substr($image->source, 0, 7) == "http://" || substr($image->source, 0, 8) == "https://") {
 				$html .= " (<a href='$h_source'>source</a>)";
 			}
 			else {

From a89c5943d84d1a2d481f03d17c55696ca1b1847c Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Tue, 8 Nov 2011 11:02:04 +0000
Subject: [PATCH 02/60] error details when the file copy fails

---
 core/imageboard.pack.php | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/core/imageboard.pack.php b/core/imageboard.pack.php
index 249b1b2f..0b2c89b8 100644
--- a/core/imageboard.pack.php
+++ b/core/imageboard.pack.php
@@ -972,7 +972,8 @@ function move_upload_to_archive($event) {
 	$target = warehouse_path("images", $event->hash);
 	if(!file_exists(dirname($target))) mkdir(dirname($target), 0755, true);
 	if(!@copy($event->tmpname, $target)) {
-		throw new UploadException("Failed to copy file from uploads ({$event->tmpname}) to archive ($target)");
+		$errors = error_get_last(); // note: requires php 5.2
+		throw new UploadException("Failed to copy file from uploads ({$event->tmpname}) to archive ($target): {$errors['type']} / {$errors['message']}");
 		return false;
 	}
 	return true;

From c6682b906982128ea776a3a612d88448ed85df85 Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Tue, 8 Nov 2011 11:23:38 +0000
Subject: [PATCH 03/60] make_link for numeric score votes, and put in
 theme.php, fixes issue #50

---
 contrib/numeric_score/main.php  | 3 ---
 contrib/numeric_score/theme.php | 2 ++
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/contrib/numeric_score/main.php b/contrib/numeric_score/main.php
index 3b786e20..0ab462c6 100644
--- a/contrib/numeric_score/main.php
+++ b/contrib/numeric_score/main.php
@@ -35,9 +35,6 @@ class NumericScore implements Extension {
 		if($event instanceof DisplayingImageEvent) {
 			if(!$user->is_anonymous()) {
 				$html = $this->theme->get_voter_html($event->image);
-				if($user->is_admin()) {
-					$html .= "<p><a href='/numeric_score_votes/{$event->image->id}'>See All Votes</a>";
-				}
 				$page->add_block(new Block("Image Score", $html, "left", 20));
 			}
 		}
diff --git a/contrib/numeric_score/theme.php b/contrib/numeric_score/theme.php
index 0d2a1953..eab5b338 100644
--- a/contrib/numeric_score/theme.php
+++ b/contrib/numeric_score/theme.php
@@ -37,6 +37,8 @@ class NumericScoreTheme extends Themelet {
 			<input type='hidden' name='image_id' value='$i_image_id'>
 			<input type='submit' value='Remove All Votes'>
 			</form>
+
+			<p><a href='".make_link("numeric_score_votes/$i_image_id")."'>See All Votes</a>
 			";
 		}
 		return $html;

From ac9e1c73cf5b4dc858c2d4660f04ab350127dc6b Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Sun, 11 Dec 2011 06:13:00 +0000
Subject: [PATCH 04/60] Adding a simple Danbooru>Shimmie bookmarklet.

---
 ext/upload/theme.php | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/ext/upload/theme.php b/ext/upload/theme.php
index f26905c0..adecaaa1 100644
--- a/ext/upload/theme.php
+++ b/ext/upload/theme.php
@@ -68,6 +68,14 @@ class UploadTheme extends Themelet {
 				$link . '?url=&quot;+location.href+&quot;&amp;tags=&quot;+prompt(&quot;enter tags&quot;)">' .
 				$title . '</a> (Drag & drop onto your bookmarks toolbar, then click when looking at an image)';
 		}
+		if($tl_enabled) {
+			$link = make_http(make_link("upload"));
+			$title = "Danbooru to " . $config->get_string('title');
+			$html .= '<p><a href="javascript:if(document.getElementById(&quot;post_old_tags&quot;).value.search(/\bflash\b/)==-1) { location.href=&quot;' .
+				$link . '?url=&quot;+document.getElementById(&quot;highres&quot;).href+&quot;&amp;tags=&quot;+document.getElementById(&quot;post_old_tags&quot;).value } else { location.href=&quot;' .
+				$link . '?url=&quot;+document.getElementsByName(&quot;movie&quot;)[0].value+&quot;&tags=&quot;+document.getElementById(&quot;post_old_tags&quot;).value } ">' .
+				$title . '</a> (As above, Click on a Danbooru-run image page. (This also grabs the tags!))';
+		}
 
 		$page->set_title("Upload");
 		$page->set_heading("Upload");

From 0e4f93a42fbbc1ef70f2c32f52d65d697e774a11 Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Wed, 14 Dec 2011 06:45:35 +0000
Subject: [PATCH 05/60] Added a separate option for popular tags length.

---
 ext/tag_list/main.php | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/ext/tag_list/main.php b/ext/tag_list/main.php
index 3be78be5..71767773 100644
--- a/ext/tag_list/main.php
+++ b/ext/tag_list/main.php
@@ -15,6 +15,7 @@ class TagList implements Extension {
 
 		if($event instanceof InitExtEvent) {
 			$config->set_default_int("tag_list_length", 15);
+			$config->set_default_int("popular_tag_list_length", 15);
 			$config->set_default_int("tags_min", 3);
 			$config->set_default_string("info_link", 'http://en.wikipedia.org/wiki/$tag');
 			$config->set_default_string("tag_list_image_type", 'related');
@@ -85,7 +86,8 @@ class TagList implements Extension {
 			$event->panel->add_block($sb);
 
 			$sb = new SetupBlock("Popular / Related Tag List");
-			$sb->add_int_option("tag_list_length", "Show top "); $sb->add_label(" tags");
+			$sb->add_int_option("tag_list_length", "Show top "); $sb->add_label(" related tags");
+			$sb->add_int_option("popular_tag_list_length", "<br>Show top "); $sb->add_label(" popular tags");
 			$sb->add_text_option("info_link", "<br>Tag info link: ");
 			$sb->add_choice_option("tag_list_image_type", array(
 				"Image's tags only" => "tags",
@@ -301,9 +303,9 @@ class TagList implements Extension {
 				FROM tags
 				WHERE count > 0
 				ORDER BY count DESC
-				LIMIT :tag_list_length
+				LIMIT :popular_tag_list_length
 				";
-			$args = array("tag_list_length"=>$config->get_int('tag_list_length'));
+			$args = array("popular_tag_list_length"=>$config->get_int('popular_tag_list_length'));
 
 			$tags = $database->get_all($query, $args);
 			$database->cache->set("popular_tags", $tags, 600);

From 2b717063eb2ebb6d42b6ee23ae2538b56444379a Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Wed, 14 Dec 2011 07:36:01 +0000
Subject: [PATCH 06/60] Updated the bookmarklet to give you an option to use
 either the your own or the current tags.

---
 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 adecaaa1..863296c2 100644
--- a/ext/upload/theme.php
+++ b/ext/upload/theme.php
@@ -71,12 +71,13 @@ class UploadTheme extends Themelet {
 		if($tl_enabled) {
 			$link = make_http(make_link("upload"));
 			$title = "Danbooru to " . $config->get_string('title');
-			$html .= '<p><a href="javascript:if(document.getElementById(&quot;post_old_tags&quot;).value.search(/\bflash\b/)==-1) { location.href=&quot;' .
-				$link . '?url=&quot;+document.getElementById(&quot;highres&quot;).href+&quot;&amp;tags=&quot;+document.getElementById(&quot;post_old_tags&quot;).value } else { location.href=&quot;' .
-				$link . '?url=&quot;+document.getElementsByName(&quot;movie&quot;)[0].value+&quot;&tags=&quot;+document.getElementById(&quot;post_old_tags&quot;).value } ">' .
+			$html .= '<p><a href="javascript:var img=document.getElementById(&quot;highres&quot;).href;var ste=&quot;' .
+				$link . '?url=&quot;;var tag=document.getElementById(&quot;post_old_tags&quot;).value;if (confirm(&quot;OK = Use Current tags.\nCancel = Use new tags.&quot;)==true)' .
+				'{if(tag.search(/\bflash\b/)==-1){location.href=ste+img+&quot;&amp;tags=&quot;+tag;}else{location.href=ste+document.getElementsByName(&quot;movie&quot;)[0].value' .
+				'+&quot;&amp;tags=&quot;+tag;}}else{var p=prompt(&quot;Enter Tags&quot;,&quot;&quot;);if(tag.search(/\bflash\b/)==-1){location.href=ste+img+&quot;&amp;tags=&quot;+p;}' .
+				'else{location.href=ste+document.getElementsByName(&quot;movie&quot;)[0].value+&quot;&amp;tags=&quot;+p;}}">' .
 				$title . '</a> (As above, Click on a Danbooru-run image page. (This also grabs the tags!))';
 		}
-
 		$page->set_title("Upload");
 		$page->set_heading("Upload");
 		$page->add_block(new NavBlock());

From 583de3fe6a758e4500682add14ec67d235790ff2 Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Wed, 14 Dec 2011 07:53:48 +0000
Subject: [PATCH 07/60] Small update to include the code by green-ponies in
 issue #51.

---
 ext/upload/theme.php | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/ext/upload/theme.php b/ext/upload/theme.php
index 863296c2..9d42098e 100644
--- a/ext/upload/theme.php
+++ b/ext/upload/theme.php
@@ -62,22 +62,31 @@ class UploadTheme extends Themelet {
 		";
 
 		if($tl_enabled) {
-			$link = make_http(make_link("upload"));
+			$link = make_http(make_link("upload"));			
+			if($config->get_bool('nice_urls')){
+				$delimiter = '?';
+			} else {
+				$delimiter = '&amp;';
+			}
+				{
 			$title = "Upload to " . $config->get_string('title');
 			$html .= '<p><a href="javascript:location.href=&quot;' .
-				$link . '?url=&quot;+location.href+&quot;&amp;tags=&quot;+prompt(&quot;enter tags&quot;)">' .
+				$link . $delimiter . 'url=&quot;+location.href+&quot;&amp;tags=&quot;+prompt(&quot;enter tags&quot;)">' .
 				$title . '</a> (Drag & drop onto your bookmarks toolbar, then click when looking at an image)';
-		}
-		if($tl_enabled) {
-			$link = make_http(make_link("upload"));
+			}
+				{
 			$title = "Danbooru to " . $config->get_string('title');
 			$html .= '<p><a href="javascript:var img=document.getElementById(&quot;highres&quot;).href;var ste=&quot;' .
-				$link . '?url=&quot;;var tag=document.getElementById(&quot;post_old_tags&quot;).value;if (confirm(&quot;OK = Use Current tags.\nCancel = Use new tags.&quot;)==true)' .
+				$link . $delimiter . 'url=&quot;;var tag=document.getElementById(&quot;post_old_tags&quot;).value;if (confirm(&quot;OK = Use Current tags.\nCancel = Use new tags.&quot;)==true)' .
 				'{if(tag.search(/\bflash\b/)==-1){location.href=ste+img+&quot;&amp;tags=&quot;+tag;}else{location.href=ste+document.getElementsByName(&quot;movie&quot;)[0].value' .
 				'+&quot;&amp;tags=&quot;+tag;}}else{var p=prompt(&quot;Enter Tags&quot;,&quot;&quot;);if(tag.search(/\bflash\b/)==-1){location.href=ste+img+&quot;&amp;tags=&quot;+p;}' .
 				'else{location.href=ste+document.getElementsByName(&quot;movie&quot;)[0].value+&quot;&amp;tags=&quot;+p;}}">' .
 				$title . '</a> (As above, Click on a Danbooru-run image page. (This also grabs the tags!))';
+
+			}
+				
 		}
+
 		$page->set_title("Upload");
 		$page->set_heading("Upload");
 		$page->add_block(new NavBlock());
@@ -188,4 +197,4 @@ class UploadTheme extends Themelet {
 		";
 	}
 }
-?>
+?>
\ No newline at end of file

From a38327b6d3784b1ee3be41ae1606a4b1e42c4c91 Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Fri, 16 Dec 2011 16:34:23 +0000
Subject: [PATCH 08/60] Made flash thumbnails have a default 192x192
 resolution.

---
 themes/danbooru/themelet.class.php    | 5 ++++-
 themes/default/themelet.class.php     | 5 ++++-
 themes/flat/themelet.class.php        | 5 ++++-
 themes/futaba/themelet.class.php      | 5 ++++-
 themes/lite/themelet.class.php        | 5 ++++-
 themes/old_default/themelet.class.php | 5 ++++-
 themes/warm/themelet.class.php        | 5 ++++-
 7 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/themes/danbooru/themelet.class.php b/themes/danbooru/themelet.class.php
index 2fa978a5..7cd8631c 100644
--- a/themes/danbooru/themelet.class.php
+++ b/themes/danbooru/themelet.class.php
@@ -20,7 +20,10 @@ class Themelet {
 		$h_view_link = make_link("post/view/{$image->id}", $query);
 		$h_tip = html_escape($image->get_tooltip());
 		$h_thumb_link = $image->get_thumb_link();
-		$tsize = get_thumbnail_size($image->width, $image->height);
+		if($image->ext == 'swf'){
+		$tsize = get_thumbnail_size(192, 192); }
+		else{
+		$tsize = get_thumbnail_size($image->width, $image->height); }
 		return "<a href='$h_view_link'><img title='$h_tip' alt='$h_tip' ".
 				"width='{$tsize[0]}' height='{$tsize[1]}' src='$h_thumb_link' /></a>";
 	}
diff --git a/themes/default/themelet.class.php b/themes/default/themelet.class.php
index 159f8881..4fd5e56d 100644
--- a/themes/default/themelet.class.php
+++ b/themes/default/themelet.class.php
@@ -33,7 +33,10 @@ class Themelet {
 		$h_view_link = make_link("post/view/$i_id", $query);
 		$h_tip = html_escape($image->get_tooltip());
 		$h_thumb_link = $image->get_thumb_link();
-		$tsize = get_thumbnail_size($image->width, $image->height);
+		if($image->ext == 'swf'){
+		$tsize = get_thumbnail_size(192, 192); }
+		else{
+		$tsize = get_thumbnail_size($image->width, $image->height); }
 		return "
 			<!-- cancel border -->
 			<div class='thumbblock'>
diff --git a/themes/flat/themelet.class.php b/themes/flat/themelet.class.php
index b79ccc73..5376e6fc 100644
--- a/themes/flat/themelet.class.php
+++ b/themes/flat/themelet.class.php
@@ -33,7 +33,10 @@ class Themelet {
 		$h_view_link = make_link("post/view/$i_id", $query);
 		$h_tip = html_escape($image->get_tooltip());
 		$h_thumb_link = $image->get_thumb_link();
-		$tsize = get_thumbnail_size($image->width, $image->height);
+		if($image->ext == 'swf'){
+		$tsize = get_thumbnail_size(192, 192); }
+		else{
+		$tsize = get_thumbnail_size($image->width, $image->height); }
 		return "
 			<div class='thumbblock'>
 			<div class='rr thumb'>
diff --git a/themes/futaba/themelet.class.php b/themes/futaba/themelet.class.php
index 706f3f1b..c5a902cf 100644
--- a/themes/futaba/themelet.class.php
+++ b/themes/futaba/themelet.class.php
@@ -21,7 +21,10 @@ class Themelet {
 		$h_view_link = make_link("post/view/{$image->id}", $query);
 		$h_tip = html_escape($image->get_tooltip());
 		$h_thumb_link = $image->get_thumb_link();
-		$tsize = get_thumbnail_size($image->width, $image->height);
+		if($image->ext == 'swf'){
+		$tsize = get_thumbnail_size(192, 192); }
+		else{
+		$tsize = get_thumbnail_size($image->width, $image->height); }
 		return "<a class='thumb' href='$h_view_link'><img title='$h_tip' alt='$h_tip' ".
 				"width='{$tsize[0]}' height='{$tsize[1]}' src='$h_thumb_link' /></a>";
 	}
diff --git a/themes/lite/themelet.class.php b/themes/lite/themelet.class.php
index 8d57b147..2714233f 100644
--- a/themes/lite/themelet.class.php
+++ b/themes/lite/themelet.class.php
@@ -33,7 +33,10 @@ class Themelet {
 		$h_view_link = make_link("post/view/$i_id", $query);
 		$h_tip = html_escape($image->get_tooltip());
 		$h_thumb_link = $image->get_thumb_link();
-		$tsize = get_thumbnail_size($image->width, $image->height);
+		if($image->ext == 'swf'){
+		$tsize = get_thumbnail_size(192, 192); }
+		else{
+		$tsize = get_thumbnail_size($image->width, $image->height); }
 		return "
 			<div class='thumbblock'>
 			
diff --git a/themes/old_default/themelet.class.php b/themes/old_default/themelet.class.php
index 41c5cf5e..5b25a843 100644
--- a/themes/old_default/themelet.class.php
+++ b/themes/old_default/themelet.class.php
@@ -31,7 +31,10 @@ class Themelet {
 		$h_view_link = make_link("post/view/$i_id", $query);
 		$h_tip = html_escape($image->get_tooltip());
 		$h_thumb_link = $image->get_thumb_link();
-		$tsize = get_thumbnail_size($image->width, $image->height);
+		if($image->ext == 'swf'){
+		$tsize = get_thumbnail_size(192, 192); }
+		else{
+		$tsize = get_thumbnail_size($image->width, $image->height); }
 		return "<a class='thumb' href='$h_view_link'><img id='$i_id' title='$h_tip' alt='$h_tip' ".
 				"width='{$tsize[0]}' height='{$tsize[1]}' src='$h_thumb_link' /></a>";
 	}
diff --git a/themes/warm/themelet.class.php b/themes/warm/themelet.class.php
index 89f4dcf8..7f90ba8a 100644
--- a/themes/warm/themelet.class.php
+++ b/themes/warm/themelet.class.php
@@ -34,7 +34,10 @@ class Themelet {
 		$h_tip = html_escape($image->get_tooltip());
 		$h_image_link = $image->get_image_link();
 		$h_thumb_link = $image->get_thumb_link();
-		$tsize = get_thumbnail_size($image->width, $image->height);
+		if($image->ext == 'swf'){
+		$tsize = get_thumbnail_size(192, 192); }
+		else{
+		$tsize = get_thumbnail_size($image->width, $image->height); }
 		return "
 			<div class='thumbblock'>
 			<div class='rr thumb'>

From 56931b0eaa80dc07d097b1b9629a3b4b68918942 Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Fri, 16 Dec 2011 18:36:08 +0000
Subject: [PATCH 09/60] Changed the 192x192 default to use the max thumbnail
 size. Made this work with SVG aswell.

---
 themes/danbooru/themelet.class.php    | 4 ++--
 themes/default/themelet.class.php     | 4 ++--
 themes/flat/themelet.class.php        | 4 ++--
 themes/futaba/themelet.class.php      | 4 ++--
 themes/lite/themelet.class.php        | 4 ++--
 themes/old_default/themelet.class.php | 4 ++--
 themes/warm/themelet.class.php        | 4 ++--
 7 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/themes/danbooru/themelet.class.php b/themes/danbooru/themelet.class.php
index 7cd8631c..a848352b 100644
--- a/themes/danbooru/themelet.class.php
+++ b/themes/danbooru/themelet.class.php
@@ -20,8 +20,8 @@ class Themelet {
 		$h_view_link = make_link("post/view/{$image->id}", $query);
 		$h_tip = html_escape($image->get_tooltip());
 		$h_thumb_link = $image->get_thumb_link();
-		if($image->ext == 'swf'){
-		$tsize = get_thumbnail_size(192, 192); }
+		if($image->ext == 'swf' || 'svg'){
+		$tsize = get_thumbnail_size('thumb_width', 'thumb_height'); }
 		else{
 		$tsize = get_thumbnail_size($image->width, $image->height); }
 		return "<a href='$h_view_link'><img title='$h_tip' alt='$h_tip' ".
diff --git a/themes/default/themelet.class.php b/themes/default/themelet.class.php
index 4fd5e56d..d45610b2 100644
--- a/themes/default/themelet.class.php
+++ b/themes/default/themelet.class.php
@@ -33,8 +33,8 @@ class Themelet {
 		$h_view_link = make_link("post/view/$i_id", $query);
 		$h_tip = html_escape($image->get_tooltip());
 		$h_thumb_link = $image->get_thumb_link();
-		if($image->ext == 'swf'){
-		$tsize = get_thumbnail_size(192, 192); }
+		if($image->ext == 'swf' || 'svg'){
+		$tsize = get_thumbnail_size('thumb_width', 'thumb_height'); }
 		else{
 		$tsize = get_thumbnail_size($image->width, $image->height); }
 		return "
diff --git a/themes/flat/themelet.class.php b/themes/flat/themelet.class.php
index 5376e6fc..1724f329 100644
--- a/themes/flat/themelet.class.php
+++ b/themes/flat/themelet.class.php
@@ -33,8 +33,8 @@ class Themelet {
 		$h_view_link = make_link("post/view/$i_id", $query);
 		$h_tip = html_escape($image->get_tooltip());
 		$h_thumb_link = $image->get_thumb_link();
-		if($image->ext == 'swf'){
-		$tsize = get_thumbnail_size(192, 192); }
+		if($image->ext == 'swf' || 'svg'){
+		$tsize = get_thumbnail_size('thumb_width', 'thumb_height'); }
 		else{
 		$tsize = get_thumbnail_size($image->width, $image->height); }
 		return "
diff --git a/themes/futaba/themelet.class.php b/themes/futaba/themelet.class.php
index c5a902cf..5985f2e2 100644
--- a/themes/futaba/themelet.class.php
+++ b/themes/futaba/themelet.class.php
@@ -21,8 +21,8 @@ class Themelet {
 		$h_view_link = make_link("post/view/{$image->id}", $query);
 		$h_tip = html_escape($image->get_tooltip());
 		$h_thumb_link = $image->get_thumb_link();
-		if($image->ext == 'swf'){
-		$tsize = get_thumbnail_size(192, 192); }
+		if($image->ext == 'swf' || 'svg'){
+		$tsize = get_thumbnail_size('thumb_width', 'thumb_height'); }
 		else{
 		$tsize = get_thumbnail_size($image->width, $image->height); }
 		return "<a class='thumb' href='$h_view_link'><img title='$h_tip' alt='$h_tip' ".
diff --git a/themes/lite/themelet.class.php b/themes/lite/themelet.class.php
index 2714233f..d5539d23 100644
--- a/themes/lite/themelet.class.php
+++ b/themes/lite/themelet.class.php
@@ -33,8 +33,8 @@ class Themelet {
 		$h_view_link = make_link("post/view/$i_id", $query);
 		$h_tip = html_escape($image->get_tooltip());
 		$h_thumb_link = $image->get_thumb_link();
-		if($image->ext == 'swf'){
-		$tsize = get_thumbnail_size(192, 192); }
+		if($image->ext == 'swf' || 'svg'){
+		$tsize = get_thumbnail_size('thumb_width', 'thumb_height'); }
 		else{
 		$tsize = get_thumbnail_size($image->width, $image->height); }
 		return "
diff --git a/themes/old_default/themelet.class.php b/themes/old_default/themelet.class.php
index 5b25a843..e7ed8967 100644
--- a/themes/old_default/themelet.class.php
+++ b/themes/old_default/themelet.class.php
@@ -31,8 +31,8 @@ class Themelet {
 		$h_view_link = make_link("post/view/$i_id", $query);
 		$h_tip = html_escape($image->get_tooltip());
 		$h_thumb_link = $image->get_thumb_link();
-		if($image->ext == 'swf'){
-		$tsize = get_thumbnail_size(192, 192); }
+		if($image->ext == 'swf' || 'svg'){
+		$tsize = get_thumbnail_size('thumb_width', 'thumb_height'); }
 		else{
 		$tsize = get_thumbnail_size($image->width, $image->height); }
 		return "<a class='thumb' href='$h_view_link'><img id='$i_id' title='$h_tip' alt='$h_tip' ".
diff --git a/themes/warm/themelet.class.php b/themes/warm/themelet.class.php
index 7f90ba8a..8a3df34a 100644
--- a/themes/warm/themelet.class.php
+++ b/themes/warm/themelet.class.php
@@ -34,8 +34,8 @@ class Themelet {
 		$h_tip = html_escape($image->get_tooltip());
 		$h_image_link = $image->get_image_link();
 		$h_thumb_link = $image->get_thumb_link();
-		if($image->ext == 'swf'){
-		$tsize = get_thumbnail_size(192, 192); }
+		if($image->ext == 'swf' || 'svg'){
+		$tsize = get_thumbnail_size('thumb_width', 'thumb_height'); }
 		else{
 		$tsize = get_thumbnail_size($image->width, $image->height); }
 		return "

From c7852423d42b2536511f03aed1cd437df47e99e7 Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Fri, 16 Dec 2011 21:29:46 +0000
Subject: [PATCH 10/60] Added a feature which removes the size tag from mp3
 tooltips.

---
 themes/danbooru/themelet.class.php    | 25 +++++++++++++++++++++++--
 themes/default/themelet.class.php     | 25 +++++++++++++++++++++++--
 themes/flat/themelet.class.php        | 25 +++++++++++++++++++++++--
 themes/futaba/themelet.class.php      | 25 +++++++++++++++++++++++--
 themes/lite/themelet.class.php        | 25 +++++++++++++++++++++++--
 themes/old_default/themelet.class.php | 25 +++++++++++++++++++++++--
 themes/warm/themelet.class.php        | 25 +++++++++++++++++++++++--
 7 files changed, 161 insertions(+), 14 deletions(-)

diff --git a/themes/danbooru/themelet.class.php b/themes/danbooru/themelet.class.php
index a848352b..9b634942 100644
--- a/themes/danbooru/themelet.class.php
+++ b/themes/danbooru/themelet.class.php
@@ -18,12 +18,33 @@ class Themelet {
 	public function build_thumb_html(Image $image, $query=null) {
 		global $config;
 		$h_view_link = make_link("post/view/{$image->id}", $query);
-		$h_tip = html_escape($image->get_tooltip());
 		$h_thumb_link = $image->get_thumb_link();
-		if($image->ext == 'swf' || 'svg'){
+
+
+		// Removes the size tag if the file is an mp3 
+		if($image->ext == 'mp3'){
+			$iitip = $image->get_tooltip();
+			$mp3tip = array("0x0");
+			$h_tip = str_replace($mp3tip, " ", $iitip);
+		
+			// Makes it work with a variation of the default tooltips (I.E $tags // $filesize // $size)
+			$justincase = array("   //", "//   ", "  //", "//  ", "  ");
+				if(strstr($h_tip, "  ")){
+					$h_tip = html_escape(str_replace($justincase, "", $h_tip));
+				}else{
+				$h_tip = html_escape($h_tip);
+				}
+		}else{
+		$h_tip = html_escape($image->get_tooltip());
+		}
+		
+
+		// If file is flash or svg then sets thumbnail to max size.
+		if($image->ext == 'swf' || $image->ext == 'svg'){
 		$tsize = get_thumbnail_size('thumb_width', 'thumb_height'); }
 		else{
 		$tsize = get_thumbnail_size($image->width, $image->height); }
+
 		return "<a href='$h_view_link'><img title='$h_tip' alt='$h_tip' ".
 				"width='{$tsize[0]}' height='{$tsize[1]}' src='$h_thumb_link' /></a>";
 	}
diff --git a/themes/default/themelet.class.php b/themes/default/themelet.class.php
index d45610b2..e0ee012e 100644
--- a/themes/default/themelet.class.php
+++ b/themes/default/themelet.class.php
@@ -31,12 +31,33 @@ class Themelet {
 		global $config;
 		$i_id = int_escape($image->id);
 		$h_view_link = make_link("post/view/$i_id", $query);
-		$h_tip = html_escape($image->get_tooltip());
 		$h_thumb_link = $image->get_thumb_link();
-		if($image->ext == 'swf' || 'svg'){
+
+
+		// Removes the size tag if the file is an mp3 
+		if($image->ext == 'mp3'){
+			$iitip = $image->get_tooltip();
+			$mp3tip = array("0x0");
+			$h_tip = str_replace($mp3tip, " ", $iitip);
+		
+			// Makes it work with a variation of the default tooltips (I.E $tags // $filesize // $size)
+			$justincase = array("   //", "//   ", "  //", "//  ", "  ");
+				if(strstr($h_tip, "  ")){
+					$h_tip = html_escape(str_replace($justincase, "", $h_tip));
+				}else{
+				$h_tip = html_escape($h_tip);
+				}
+		}else{
+		$h_tip = html_escape($image->get_tooltip());
+		}
+		
+
+		// If file is flash or svg then sets thumbnail to max size.
+		if($image->ext == 'swf' || $image->ext == 'svg'){
 		$tsize = get_thumbnail_size('thumb_width', 'thumb_height'); }
 		else{
 		$tsize = get_thumbnail_size($image->width, $image->height); }
+
 		return "
 			<!-- cancel border -->
 			<div class='thumbblock'>
diff --git a/themes/flat/themelet.class.php b/themes/flat/themelet.class.php
index 1724f329..13e1424b 100644
--- a/themes/flat/themelet.class.php
+++ b/themes/flat/themelet.class.php
@@ -31,12 +31,33 @@ class Themelet {
 		global $config;
 		$i_id = int_escape($image->id);
 		$h_view_link = make_link("post/view/$i_id", $query);
-		$h_tip = html_escape($image->get_tooltip());
 		$h_thumb_link = $image->get_thumb_link();
-		if($image->ext == 'swf' || 'svg'){
+
+
+		// Removes the size tag if the file is an mp3 
+		if($image->ext == 'mp3'){
+			$iitip = $image->get_tooltip();
+			$mp3tip = array("0x0");
+			$h_tip = str_replace($mp3tip, " ", $iitip);
+		
+			// Makes it work with a variation of the default tooltips (I.E $tags // $filesize // $size)
+			$justincase = array("   //", "//   ", "  //", "//  ", "  ");
+				if(strstr($h_tip, "  ")){
+					$h_tip = html_escape(str_replace($justincase, "", $h_tip));
+				}else{
+				$h_tip = html_escape($h_tip);
+				}
+		}else{
+		$h_tip = html_escape($image->get_tooltip());
+		}
+		
+
+		// If file is flash or svg then sets thumbnail to max size.
+		if($image->ext == 'swf' || $image->ext == 'svg'){
 		$tsize = get_thumbnail_size('thumb_width', 'thumb_height'); }
 		else{
 		$tsize = get_thumbnail_size($image->width, $image->height); }
+
 		return "
 			<div class='thumbblock'>
 			<div class='rr thumb'>
diff --git a/themes/futaba/themelet.class.php b/themes/futaba/themelet.class.php
index 5985f2e2..b88fdec6 100644
--- a/themes/futaba/themelet.class.php
+++ b/themes/futaba/themelet.class.php
@@ -19,12 +19,33 @@ class Themelet {
 	public function build_thumb_html(Image $image, $query=null) {
 		global $config;
 		$h_view_link = make_link("post/view/{$image->id}", $query);
-		$h_tip = html_escape($image->get_tooltip());
 		$h_thumb_link = $image->get_thumb_link();
-		if($image->ext == 'swf' || 'svg'){
+
+
+		// Removes the size tag if the file is an mp3 
+		if($image->ext == 'mp3'){
+			$iitip = $image->get_tooltip();
+			$mp3tip = array("0x0");
+			$h_tip = str_replace($mp3tip, " ", $iitip);
+		
+			// Makes it work with a variation of the default tooltips (I.E $tags // $filesize // $size)
+			$justincase = array("   //", "//   ", "  //", "//  ", "  ");
+				if(strstr($h_tip, "  ")){
+					$h_tip = html_escape(str_replace($justincase, "", $h_tip));
+				}else{
+				$h_tip = html_escape($h_tip);
+				}
+		}else{
+		$h_tip = html_escape($image->get_tooltip());
+		}
+		
+
+		// If file is flash or svg then sets thumbnail to max size.
+		if($image->ext == 'swf' || $image->ext == 'svg'){
 		$tsize = get_thumbnail_size('thumb_width', 'thumb_height'); }
 		else{
 		$tsize = get_thumbnail_size($image->width, $image->height); }
+
 		return "<a class='thumb' href='$h_view_link'><img title='$h_tip' alt='$h_tip' ".
 				"width='{$tsize[0]}' height='{$tsize[1]}' src='$h_thumb_link' /></a>";
 	}
diff --git a/themes/lite/themelet.class.php b/themes/lite/themelet.class.php
index d5539d23..ea0297e0 100644
--- a/themes/lite/themelet.class.php
+++ b/themes/lite/themelet.class.php
@@ -31,12 +31,33 @@ class Themelet {
 		global $config;
 		$i_id = int_escape($image->id);
 		$h_view_link = make_link("post/view/$i_id", $query);
-		$h_tip = html_escape($image->get_tooltip());
 		$h_thumb_link = $image->get_thumb_link();
-		if($image->ext == 'swf' || 'svg'){
+
+
+		// Removes the size tag if the file is an mp3 
+		if($image->ext == 'mp3'){
+			$iitip = $image->get_tooltip();
+			$mp3tip = array("0x0");
+			$h_tip = str_replace($mp3tip, " ", $iitip);
+		
+			// Makes it work with a variation of the default tooltips (I.E $tags // $filesize // $size)
+			$justincase = array("   //", "//   ", "  //", "//  ", "  ");
+				if(strstr($h_tip, "  ")){
+					$h_tip = html_escape(str_replace($justincase, "", $h_tip));
+				}else{
+				$h_tip = html_escape($h_tip);
+				}
+		}else{
+		$h_tip = html_escape($image->get_tooltip());
+		}
+		
+
+		// If file is flash or svg then sets thumbnail to max size.
+		if($image->ext == 'swf' || $image->ext == 'svg'){
 		$tsize = get_thumbnail_size('thumb_width', 'thumb_height'); }
 		else{
 		$tsize = get_thumbnail_size($image->width, $image->height); }
+
 		return "
 			<div class='thumbblock'>
 			
diff --git a/themes/old_default/themelet.class.php b/themes/old_default/themelet.class.php
index e7ed8967..35c7dc53 100644
--- a/themes/old_default/themelet.class.php
+++ b/themes/old_default/themelet.class.php
@@ -29,12 +29,33 @@ class Themelet {
 		global $config;
 		$i_id = int_escape($image->id);
 		$h_view_link = make_link("post/view/$i_id", $query);
-		$h_tip = html_escape($image->get_tooltip());
 		$h_thumb_link = $image->get_thumb_link();
-		if($image->ext == 'swf' || 'svg'){
+
+
+		// Removes the size tag if the file is an mp3 
+		if($image->ext == 'mp3'){
+			$iitip = $image->get_tooltip();
+			$mp3tip = array("0x0");
+			$h_tip = str_replace($mp3tip, " ", $iitip);
+		
+			// Makes it work with a variation of the default tooltips (I.E $tags // $filesize // $size)
+			$justincase = array("   //", "//   ", "  //", "//  ", "  ");
+				if(strstr($h_tip, "  ")){
+					$h_tip = html_escape(str_replace($justincase, "", $h_tip));
+				}else{
+				$h_tip = html_escape($h_tip);
+				}
+		}else{
+		$h_tip = html_escape($image->get_tooltip());
+		}
+		
+
+		// If file is flash or svg then sets thumbnail to max size.
+		if($image->ext == 'swf' || $image->ext == 'svg'){
 		$tsize = get_thumbnail_size('thumb_width', 'thumb_height'); }
 		else{
 		$tsize = get_thumbnail_size($image->width, $image->height); }
+
 		return "<a class='thumb' href='$h_view_link'><img id='$i_id' title='$h_tip' alt='$h_tip' ".
 				"width='{$tsize[0]}' height='{$tsize[1]}' src='$h_thumb_link' /></a>";
 	}
diff --git a/themes/warm/themelet.class.php b/themes/warm/themelet.class.php
index 8a3df34a..041274e1 100644
--- a/themes/warm/themelet.class.php
+++ b/themes/warm/themelet.class.php
@@ -31,13 +31,34 @@ class Themelet {
 		global $config;
 		$i_id = int_escape($image->id);
 		$h_view_link = make_link("post/view/$i_id", $query);
-		$h_tip = html_escape($image->get_tooltip());
 		$h_image_link = $image->get_image_link();
 		$h_thumb_link = $image->get_thumb_link();
-		if($image->ext == 'swf' || 'svg'){
+
+
+		// Removes the size tag if the file is an mp3 
+		if($image->ext == 'mp3'){
+			$iitip = $image->get_tooltip();
+			$mp3tip = array("0x0");
+			$h_tip = str_replace($mp3tip, " ", $iitip);
+		
+			// Makes it work with a variation of the default tooltips (I.E $tags // $filesize // $size)
+			$justincase = array("   //", "//   ", "  //", "//  ", "  ");
+				if(strstr($h_tip, "  ")){
+					$h_tip = html_escape(str_replace($justincase, "", $h_tip));
+				}else{
+				$h_tip = html_escape($h_tip);
+				}
+		}else{
+		$h_tip = html_escape($image->get_tooltip());
+		}
+		
+
+		// If file is flash or svg then sets thumbnail to max size.
+		if($image->ext == 'swf' || $image->ext == 'svg'){
 		$tsize = get_thumbnail_size('thumb_width', 'thumb_height'); }
 		else{
 		$tsize = get_thumbnail_size($image->width, $image->height); }
+
 		return "
 			<div class='thumbblock'>
 			<div class='rr thumb'>

From fbe0df29ed0689174fcc5f70dc1d694c305f901e Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Fri, 16 Dec 2011 21:35:30 +0000
Subject: [PATCH 11/60] Fixed scaling with the theme patch.

---
 contrib/handle_flash/main.php | 1 -
 contrib/handle_mp3/main.php   | 1 -
 contrib/handle_svg/main.php   | 1 -
 3 files changed, 3 deletions(-)

diff --git a/contrib/handle_flash/main.php b/contrib/handle_flash/main.php
index f63f988d..8ee32fc0 100644
--- a/contrib/handle_flash/main.php
+++ b/contrib/handle_flash/main.php
@@ -7,7 +7,6 @@
 
 class FlashFileHandler extends DataHandlerExtension {
 	protected function create_thumb($hash) {
-		// FIXME: scale image, as not all boards use 192x192
 		copy("ext/handle_flash/thumb.jpg", warehouse_path("thumbs", $hash));
 	}
 
diff --git a/contrib/handle_mp3/main.php b/contrib/handle_mp3/main.php
index ba02b3c5..76187638 100644
--- a/contrib/handle_mp3/main.php
+++ b/contrib/handle_mp3/main.php
@@ -7,7 +7,6 @@
 
 class MP3FileHandler extends DataHandlerExtension {
 	protected function create_thumb($hash) {
-		// FIXME: scale image, as not all boards use 192x192
 		copy("ext/handle_mp3/thumb.jpg", warehouse_path("thumbs", $hash));
 	}
 
diff --git a/contrib/handle_svg/main.php b/contrib/handle_svg/main.php
index e9e94c25..f028e178 100644
--- a/contrib/handle_svg/main.php
+++ b/contrib/handle_svg/main.php
@@ -40,7 +40,6 @@ class SVGFileHandler implements Extension {
 //				exec("convert images/{$ha}/{$hash}[0] -geometry {$w}x{$h} -quality {$q} jpg:thumbs/{$ha}/{$hash}");
 //			}
 //			else {
-				// FIXME: scale image, as not all boards use 192x192
 				copy("ext/handle_svg/thumb.jpg", warehouse_path("thumbs", $hash));
 //			}
 		}

From c125c4ba927c7ba12921219cc15f89efce48b6de Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Mon, 19 Dec 2011 01:43:46 +0000
Subject: [PATCH 12/60] Making the upload form look a bit nicer.

---
 ext/upload/style.css |  9 +++++++--
 ext/upload/theme.php | 30 ++++++++++++++++++------------
 2 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/ext/upload/style.css b/ext/upload/style.css
index c4b1e63e..1fe3f45d 100644
--- a/ext/upload/style.css
+++ b/ext/upload/style.css
@@ -1,4 +1,9 @@
-
-#large_upload_form INPUT {
+/* Only need to change the file/url inputs */
+#large_upload_form INPUT.wid {
 	width: 100%;
 }
+#radio_button {
+	width: auto;
+}
+/* This is needed since the theme style.css forcibly sets vertical align to "top". */
+TABLE.vert TD, TABLE.vert TH {vertical-align: middle;}
diff --git a/ext/upload/theme.php b/ext/upload/theme.php
index 9d42098e..3575d569 100644
--- a/ext/upload/theme.php
+++ b/ext/upload/theme.php
@@ -12,22 +12,28 @@ class UploadTheme extends Themelet {
 	public function display_page(Page $page) {
 		global $config;
 		$tl_enabled = ($config->get_string("transload_engine", "none") != "none");
-
+		
+		// Uploader 2.0!
 		$upload_list = "";
 		for($i=0; $i<$config->get_int('upload_count'); $i++) {
 			$n = $i + 1;
 			$width = $tl_enabled ? "35%" : "80%";
 			$upload_list .= "
 				<tr>
-					<td width='50'>File $n</td>
-					<td width='250'><input id='data$i' name='data$i' type='file'></td>
-			";
-			if($tl_enabled) {
-				$upload_list .= "
-					<td width='50'>URL $n</td>
-					<td width='250'><input id='url$i' name='url$i' type='text'></td>
-				";
-			}
+					<td width='60'><form><input id='radio_buttona' type='radio' name='method' value='file' checked='checked' onclick='javascript:document.getElementById(&quot;url$i&quot;).style.display = &quot;none&quot;;document.getElementById(&quot;url$i&quot;).value = &quot;&quot;;document.getElementById(&quot;data$i&quot;).style.display = &quot;inline&quot;' /> File<br>";
+				if($tl_enabled) {
+					$upload_list .="
+					<input id='radio_buttonb' type='radio' name='method' value='url' onclick='javascript:document.getElementById(&quot;data$i&quot;).style.display = &quot;none&quot;;document.getElementById(&quot;data$i&quot;).value = &quot;&quot;;document.getElementById(&quot;url$i&quot;).style.display = &quot;inline&quot;' /> URL</ br></td></form>
+					
+					<td><input id='data$i' name='data$i' class='wid' type='file'><input id='url$i' name='url$i' class='wid' type='text' style='display:none'></td>
+					";
+					}
+					else { 
+					$upload_list .= "</form></td>
+					<td width='250'><input id='data$i' name='data$i' class='wid' type='file'></td>
+					";
+					}
+					
 			$upload_list .= "
 				</tr>
 			";
@@ -51,7 +57,7 @@ class UploadTheme extends Themelet {
 			});
 			</script>
 			".make_form(make_link("upload"), "POST", $multipart=True)."
-				<table id='large_upload_form'>
+				<table id='large_upload_form' class='vert'>
 					$upload_list
 					<tr><td>Tags</td><td colspan='3'><input id='tag_box' name='tags' type='text'></td></tr>
 					<tr><td>Source</td><td colspan='3'><input name='source' type='text'></td></tr>
@@ -60,7 +66,7 @@ class UploadTheme extends Themelet {
 			</form>
 			<small>(Max file size is $max_kb)</small>
 		";
-
+		
 		if($tl_enabled) {
 			$link = make_http(make_link("upload"));			
 			if($config->get_bool('nice_urls')){

From dab67ea1bbdcf6fc5c6e5b074547153021d9181c Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Tue, 20 Dec 2011 21:56:07 +0000
Subject: [PATCH 13/60] Updated recaptcha.

---
 lib/recaptchalib.php | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

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

From c37569f3d453d43cb88b289e9d9b27203a1c1a6d Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Wed, 21 Dec 2011 02:28:39 +0000
Subject: [PATCH 14/60] Fixed reCaptcha.

---
 core/util.inc.php  | 8 ++++----
 ext/setup/main.php | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/core/util.inc.php b/core/util.inc.php
index d6ce5354..c1333151 100644
--- a/core/util.inc.php
+++ b/core/util.inc.php
@@ -253,8 +253,8 @@ function captcha_get_html() {
 	if(DEBUG && ip_in_range($_SERVER['REMOTE_ADDR'], "127.0.0.0/8")) return "";
 
 	$captcha = "";
-	if($user->is_anonymous() && $config->get_bool("use_captchas")) {
-		$rpk = $config->get_string("api_recaptcha_pubkey");
+	if($user->is_anonymous() && $config->get_bool("comment_captcha")) {
+		$rpk = $config->get_string("api_recaptcha_privkey");
 		if(!empty($rpk)) {
 			$captcha = recaptcha_get_html($rpk);
 		}
@@ -274,8 +274,8 @@ function captcha_check() {
 
 	if(DEBUG && ip_in_range($_SERVER['REMOTE_ADDR'], "127.0.0.0/8")) return true;
 
-	if($user->is_anonymous() && $config->get_bool("use_captchas")) {
-		$rpk = $config->get_string('api_recaptcha_privkey');
+	if($user->is_anonymous() && $config->get_bool("comment_captcha")) {
+		$rpk = $config->get_string('api_recaptcha_pubkey');
 		if(!empty($rpk)) {
 			$resp = recaptcha_check_answer(
 					$rpk,
diff --git a/ext/setup/main.php b/ext/setup/main.php
index e53061b1..f1885568 100644
--- a/ext/setup/main.php
+++ b/ext/setup/main.php
@@ -171,7 +171,7 @@ class Setup extends SimpleExtension {
 		$config->set_default_string("theme", "default");
 		$config->set_default_bool("use_autodate", true);
 		$config->set_default_bool("word_wrap", true);
-		$config->set_default_bool("use_captchas", false);
+		$config->set_default_bool("comment_captcha", false);
 		$config->set_default_string("autodate_format", "F j, Y");
 		// Automatic caching is disabled by default
 		$config->set_default_string("autocache_location", "data/cache");

From 9a2d694b6a6939ab5245d137de73b77b7f48c404 Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Wed, 21 Dec 2011 02:40:30 +0000
Subject: [PATCH 15/60] Made the replace form look similar to the new upload
 form.

---
 ext/upload/theme.php | 28 ++++++++++++----------------
 1 file changed, 12 insertions(+), 16 deletions(-)

diff --git a/ext/upload/theme.php b/ext/upload/theme.php
index 3575d569..a18adbe5 100644
--- a/ext/upload/theme.php
+++ b/ext/upload/theme.php
@@ -17,7 +17,6 @@ class UploadTheme extends Themelet {
 		$upload_list = "";
 		for($i=0; $i<$config->get_int('upload_count'); $i++) {
 			$n = $i + 1;
-			$width = $tl_enabled ? "35%" : "80%";
 			$upload_list .= "
 				<tr>
 					<td width='60'><form><input id='radio_buttona' type='radio' name='method' value='file' checked='checked' onclick='javascript:document.getElementById(&quot;url$i&quot;).style.display = &quot;none&quot;;document.getElementById(&quot;url$i&quot;).value = &quot;&quot;;document.getElementById(&quot;data$i&quot;).style.display = &quot;inline&quot;' /> File<br>";
@@ -105,21 +104,18 @@ class UploadTheme extends Themelet {
 		$tl_enabled = ($config->get_string("transload_engine", "none") != "none");
 
 		$upload_list = '';
-		$width = $tl_enabled ? "35%" : "80%";
 		$upload_list .= "
-			<tr>
-				<td width='50'>File</td>
-				<td width='250'><input id='data0' name='data0' type='file'></td>
-			</tr>
-		";
-		if($tl_enabled) {
-			$upload_list .= "
-			<tr>
-				<td width='50'>URL</td>
-				<td width='250'><input id='url0' name='url0' type='text'></td>
-			</tr>
-			";
-		}
+				<tr>
+					<td width='60'><form><input id='radio_buttona' type='radio' name='method' value='file' checked='checked' onclick='javascript:document.getElementById(&quot;url0&quot;).style.display = &quot;none&quot;;document.getElementById(&quot;url0&quot;).value = &quot;&quot;;document.getElementById(&quot;data0&quot;).style.display = &quot;inline&quot;' /> File<br>";
+				if($tl_enabled) {
+					$upload_list .="
+					<input id='radio_buttonb' type='radio' name='method' value='url' onclick='javascript:document.getElementById(&quot;data0&quot;).style.display = &quot;none&quot;;document.getElementById(&quot;data0&quot;).value = &quot;&quot;;document.getElementById(&quot;url0&quot;).style.display = &quot;inline&quot;' /> URL</ br></td></form>
+					<td><input id='data0' name='data0' class='wid' type='file'><input id='url0' name='url0' class='wid' type='text' style='display:none'></td>
+					";
+				} else { 
+					$upload_list .= "</form></td>
+					";
+				}
 
 		$max_size = $config->get_int('upload_size');
 		$max_kb = to_shorthand_int($max_size);
@@ -133,7 +129,7 @@ class UploadTheme extends Themelet {
 				.$thumbnail."<br>"
 				.make_form(make_link("upload/replace/".$image_id), "POST", $multipart=True)."
 				<input type='hidden' name='image_id' value='$image_id'>
-				<table id='large_upload_form'>
+				<table id='large_upload_form' class='vert'>
 					$upload_list
 					<tr><td>Source</td><td colspan='3'><input name='source' type='text'></td></tr>
 					<tr><td colspan='4'><input id='uploadbutton' type='submit' value='Post'></td></tr>

From 660f9ca4b06a03e34406b3fcc21fb8626dde89ba Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Wed, 21 Dec 2011 20:52:06 +0000
Subject: [PATCH 16/60] Changed "'thumb_width', 'thumb_height'" >
 "$config->get_int('thumb_width'), $config->get_int('thumb_height')"

---
 themes/danbooru/themelet.class.php    | 2 +-
 themes/default/themelet.class.php     | 2 +-
 themes/flat/themelet.class.php        | 2 +-
 themes/futaba/themelet.class.php      | 2 +-
 themes/lite/themelet.class.php        | 2 +-
 themes/old_default/themelet.class.php | 2 +-
 themes/warm/themelet.class.php        | 2 +-
 7 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/themes/danbooru/themelet.class.php b/themes/danbooru/themelet.class.php
index 9b634942..ed738f7e 100644
--- a/themes/danbooru/themelet.class.php
+++ b/themes/danbooru/themelet.class.php
@@ -41,7 +41,7 @@ class Themelet {
 
 		// If file is flash or svg then sets thumbnail to max size.
 		if($image->ext == 'swf' || $image->ext == 'svg'){
-		$tsize = get_thumbnail_size('thumb_width', 'thumb_height'); }
+		$tsize = get_thumbnail_size($config->get_int('thumb_width'), $config->get_int('thumb_height')); }
 		else{
 		$tsize = get_thumbnail_size($image->width, $image->height); }
 
diff --git a/themes/default/themelet.class.php b/themes/default/themelet.class.php
index e0ee012e..08b4b694 100644
--- a/themes/default/themelet.class.php
+++ b/themes/default/themelet.class.php
@@ -54,7 +54,7 @@ class Themelet {
 
 		// If file is flash or svg then sets thumbnail to max size.
 		if($image->ext == 'swf' || $image->ext == 'svg'){
-		$tsize = get_thumbnail_size('thumb_width', 'thumb_height'); }
+		$tsize = get_thumbnail_size($config->get_int('thumb_width'), $config->get_int('thumb_height')); }
 		else{
 		$tsize = get_thumbnail_size($image->width, $image->height); }
 
diff --git a/themes/flat/themelet.class.php b/themes/flat/themelet.class.php
index 13e1424b..0aaa32b0 100644
--- a/themes/flat/themelet.class.php
+++ b/themes/flat/themelet.class.php
@@ -54,7 +54,7 @@ class Themelet {
 
 		// If file is flash or svg then sets thumbnail to max size.
 		if($image->ext == 'swf' || $image->ext == 'svg'){
-		$tsize = get_thumbnail_size('thumb_width', 'thumb_height'); }
+		$tsize = get_thumbnail_size($config->get_int('thumb_width'), $config->get_int('thumb_height')); }
 		else{
 		$tsize = get_thumbnail_size($image->width, $image->height); }
 
diff --git a/themes/futaba/themelet.class.php b/themes/futaba/themelet.class.php
index b88fdec6..20e7e2fb 100644
--- a/themes/futaba/themelet.class.php
+++ b/themes/futaba/themelet.class.php
@@ -42,7 +42,7 @@ class Themelet {
 
 		// If file is flash or svg then sets thumbnail to max size.
 		if($image->ext == 'swf' || $image->ext == 'svg'){
-		$tsize = get_thumbnail_size('thumb_width', 'thumb_height'); }
+		$tsize = get_thumbnail_size($config->get_int('thumb_width'), $config->get_int('thumb_height')); }
 		else{
 		$tsize = get_thumbnail_size($image->width, $image->height); }
 
diff --git a/themes/lite/themelet.class.php b/themes/lite/themelet.class.php
index ea0297e0..d5b5e479 100644
--- a/themes/lite/themelet.class.php
+++ b/themes/lite/themelet.class.php
@@ -54,7 +54,7 @@ class Themelet {
 
 		// If file is flash or svg then sets thumbnail to max size.
 		if($image->ext == 'swf' || $image->ext == 'svg'){
-		$tsize = get_thumbnail_size('thumb_width', 'thumb_height'); }
+		$tsize = get_thumbnail_size($config->get_int('thumb_width'), $config->get_int('thumb_height')); }
 		else{
 		$tsize = get_thumbnail_size($image->width, $image->height); }
 
diff --git a/themes/old_default/themelet.class.php b/themes/old_default/themelet.class.php
index 35c7dc53..ff48817b 100644
--- a/themes/old_default/themelet.class.php
+++ b/themes/old_default/themelet.class.php
@@ -52,7 +52,7 @@ class Themelet {
 
 		// If file is flash or svg then sets thumbnail to max size.
 		if($image->ext == 'swf' || $image->ext == 'svg'){
-		$tsize = get_thumbnail_size('thumb_width', 'thumb_height'); }
+		$tsize = get_thumbnail_size($config->get_int('thumb_width'), $config->get_int('thumb_height')); }
 		else{
 		$tsize = get_thumbnail_size($image->width, $image->height); }
 
diff --git a/themes/warm/themelet.class.php b/themes/warm/themelet.class.php
index 041274e1..38170d2e 100644
--- a/themes/warm/themelet.class.php
+++ b/themes/warm/themelet.class.php
@@ -55,7 +55,7 @@ class Themelet {
 
 		// If file is flash or svg then sets thumbnail to max size.
 		if($image->ext == 'swf' || $image->ext == 'svg'){
-		$tsize = get_thumbnail_size('thumb_width', 'thumb_height'); }
+		$tsize = get_thumbnail_size($config->get_int('thumb_width'), $config->get_int('thumb_height')); }
 		else{
 		$tsize = get_thumbnail_size($image->width, $image->height); }
 

From 11881c99932513a38a0be88e601789c2b3adbce1 Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Fri, 23 Dec 2011 14:22:32 +0000
Subject: [PATCH 17/60] specify content-type for home page

---
 contrib/home/theme.php | 1 +
 1 file changed, 1 insertion(+)

diff --git a/contrib/home/theme.php b/contrib/home/theme.php
index 5d6bff31..1fe601ff 100644
--- a/contrib/home/theme.php
+++ b/contrib/home/theme.php
@@ -7,6 +7,7 @@ class HomeTheme extends Themelet {
 <html>
 	<head>
 		<title>$sitename</title>
+		<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
 		<link rel='stylesheet' href='$data_href/themes/$theme_name/style.css' type='text/css'>
 	</head>
 	<style>

From 002df1a7ba319eb4f6606d91543642a572f7ebc8 Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Fri, 23 Dec 2011 14:28:42 +0000
Subject: [PATCH 18/60] keywords for images with lite theme

---
 themes/lite/view.theme.php | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/themes/lite/view.theme.php b/themes/lite/view.theme.php
index e9538640..0bb17d06 100644
--- a/themes/lite/view.theme.php
+++ b/themes/lite/view.theme.php
@@ -5,6 +5,11 @@ class CustomViewImageTheme extends ViewImageTheme {
 		global $page;
 		$page->set_title("Image {$image->id}: ".html_escape($image->get_tag_list()));
 		$page->set_heading(html_escape($image->get_tag_list()));
+		$page->add_html_header("<meta name=\"keywords\" content=\"$metatags\">");
+		$page->add_html_header("<meta property=\"og:title\" content=\"$metatags\">");
+		$page->add_html_header("<meta property=\"og:type\" content=\"article\">");
+		$page->add_html_header("<meta property=\"og:image\" content=\"".make_http($image->get_thumb_link())."\">");
+		$page->add_html_header("<meta property=\"og:url\" content=\"".make_http(make_link("post/view/{$image->id}"))."\">");
 		$page->add_block(new Block("Navigation", $this->build_navigation($image), "left", 0));
 		$page->add_block(new Block("Statistics", $this->build_stats($image), "left", 10));
 		$page->add_block(new Block(null, $this->build_image_editor($image, $editor_parts), "main", 10));

From 913bb09cc6ff6b706ddbb0d376a33e41d812e398 Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Fri, 23 Dec 2011 14:34:42 +0000
Subject: [PATCH 19/60] PDO compat woo

---
 contrib/tag_editcloud/main.php | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

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

From cd11e75e405f1f8470750b929bd29197d37733ce Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Fri, 23 Dec 2011 21:27:38 +0000
Subject: [PATCH 20/60] Can now set rating/external source while uploading via
 the bookmarklets.

---
 core/extension.class.php |  7 ++++++
 ext/upload/main.php      | 46 ++++++++++++++++++++++++++++++++++++----
 2 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/core/extension.class.php b/core/extension.class.php
index 9b514318..7906822b 100644
--- a/core/extension.class.php
+++ b/core/extension.class.php
@@ -177,6 +177,13 @@ abstract class DataHandlerExtension implements Extension {
 				$iae = new ImageAdditionEvent($event->user, $image);
 				send_event($iae);
 				$event->image_id = $iae->image->id;
+				
+				// Rating Stuff.
+				if(file_exists("ext/rating") && !empty($event->metadata['rating'])){
+					global $database;
+					$rating = $event->metadata['rating'];
+					$database->Execute("UPDATE images SET rating=? WHERE id=?", array($rating, $event->image_id));
+				}
 			}
 		}
 
diff --git a/ext/upload/main.php b/ext/upload/main.php
index 167bce07..fd8e5e6a 100644
--- a/ext/upload/main.php
+++ b/ext/upload/main.php
@@ -173,7 +173,35 @@ class Upload implements Extension {
 						if(!empty($_GET['tags']) && $_GET['tags'] != "null") {
 							$tags = Tag::explode($_GET['tags']);
 						}
-						$ok = $this->try_transload($url, $tags, $url);
+						
+
+												
+						// Checks if url contains rating, also checks if the rating extension is enabled.
+						if($config->get_string("transload_engine", "none") != "none" && file_exists("ext/rating") && !empty($_GET['rating'])) {
+							$rating = strtolower($_GET['rating']);
+							// There must be a less messy way to do this.. 
+							if($rating !== "") {
+								if($rating == "s" || $rating == "safe" || $rating == "q" || $rating == "questionable" || $rating == "e" || $rating == "explicit") {
+									if($rating == "s" || $rating == "safe" || $rating == "q" || $rating == "questionable") {
+										if($rating == "s" || $rating == "safe") {
+											$rating = "s";
+										}else{
+											$rating = "q";
+										}
+									}else{
+										$rating = "e";
+									}
+								}else{
+									$rating = "u";
+								}
+							}else{
+								$rating = "u";
+								}
+						}else{
+							$rating = "";
+						}
+						
+						$ok = $this->try_transload($url, $tags, $rating, $url);
 						$this->theme->display_upload_status($page, $ok);
 					}
 					else
@@ -250,7 +278,7 @@ class Upload implements Extension {
 		}
 	}
 	
-	private function try_upload($file, $tags, $source, $replace='') {
+	private function try_upload($file, $tags, $rating, $source, $replace='') {
 		global $page;
 		global $config;
 		global $user;
@@ -296,13 +324,18 @@ class Upload implements Extension {
 		return $ok;
 	}
 
-	private function try_transload($url, $tags, $source, $replace='') {
+	private function try_transload($url, $tags, $rating, $source, $replace='') {
 		global $page;
 		global $config;
 
 		$ok = true;
 
-		if(empty($source)) $source = $url;
+		//Allows external source to be set.
+		if(!empty($_GET['source'])){
+			$source = $_GET['source'];
+		}else{
+			$source = $url;
+		}
 
 		// PHP falls back to system default if /tmp fails, can't we just
 		// use the system default to start with? :-/
@@ -363,6 +396,11 @@ class Upload implements Extension {
 			$metadata['tags'] = $tags;
 			$metadata['source'] = $source;
 			
+			/* check for rating > adds to metadata if it has */
+			if($config->get_string("transload_engine", "none") != "none" && file_exists("ext/rating") && !empty($_GET['rating'])){
+				$metadata['rating'] = $rating;
+			}
+			
 			/* check if we have been given an image ID to replace */
 			if (!empty($replace)) {
 				$metadata['replace'] = $replace;

From 42b902ecb56c762c1685173ac1205e26080a84cd Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Fri, 23 Dec 2011 21:28:47 +0000
Subject: [PATCH 21/60] Bookmarklet should now grab the rating, aswell as the
 image page link for source.

---
 ext/upload/theme.php | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/ext/upload/theme.php b/ext/upload/theme.php
index a18adbe5..7ce049cf 100644
--- a/ext/upload/theme.php
+++ b/ext/upload/theme.php
@@ -80,13 +80,17 @@ class UploadTheme extends Themelet {
 				$title . '</a> (Drag & drop onto your bookmarks toolbar, then click when looking at an image)';
 			}
 				{
+			/* Danbooru > Shimmie Bookmarklet.
+				This "should" work on any site running danbooru, unless for some odd reason they switched around the id's or aren't using post/list.
+			*/
 			$title = "Danbooru to " . $config->get_string('title');
 			$html .= '<p><a href="javascript:var img=document.getElementById(&quot;highres&quot;).href;var ste=&quot;' .
-				$link . $delimiter . 'url=&quot;;var tag=document.getElementById(&quot;post_old_tags&quot;).value;if (confirm(&quot;OK = Use Current tags.\nCancel = Use new tags.&quot;)==true)' .
-				'{if(tag.search(/\bflash\b/)==-1){location.href=ste+img+&quot;&amp;tags=&quot;+tag;}else{location.href=ste+document.getElementsByName(&quot;movie&quot;)[0].value' .
-				'+&quot;&amp;tags=&quot;+tag;}}else{var p=prompt(&quot;Enter Tags&quot;,&quot;&quot;);if(tag.search(/\bflash\b/)==-1){location.href=ste+img+&quot;&amp;tags=&quot;+p;}' .
-				'else{location.href=ste+document.getElementsByName(&quot;movie&quot;)[0].value+&quot;&amp;tags=&quot;+p;}}">' .
-				$title . '</a> (As above, Click on a Danbooru-run image page. (This also grabs the tags!))';
+				$link . $delimiter . 'url=&quot;;var tag=document.getElementById(&quot;post_old_tags&quot;).value;var doc=document.documentElement.innerHTML;var rtg=doc.match(&quot;<li>Rating: (.*)<\/li>&quot;);var srx=&quot;http://&quot; + document.location.hostname + document.location.href.match(&quot;\/post\/show\/.*\/&quot;);' .
+				'if (confirm(&quot;OK = Use Current tags.\nCancel = Use new tags.&quot;)==true)' .
+				'{if(tag.search(/\bflash\b/)==-1){location.href=ste+img+&quot;&amp;tags=&quot;+tag+&quot;&rating=&quot;+rtg[1]+&quot;&amp;source=&quot;+srx;}else{location.href=ste+document.getElementsByName(&quot;movie&quot;)[0].value' .
+				'+&quot;&amp;tags=&quot;+tag+&quot;&amp;rating=&quot;+rtg[1]+&quot;&amp;source=&quot;+srx;}}else{var p=prompt(&quot;Enter Tags&quot;,&quot;&quot;);if(tag.search(/\bflash\b/)==-1){location.href=ste+img+&quot;&amp;tags=&quot;+p+&quot;&amp;rating=&quot;+rtg[1]+&quot;&amp;source=&quot;+srx;}' .
+				'else{location.href=ste+document.getElementsByName(&quot;movie&quot;)[0].value+&quot;&amp;tags=&quot;+p+&quot;&amp;rating=&quot;+rtg[1]+&quot;&amp;source=&quot;+srx;}}">' .
+				$title . '</a> (As above, Click on a Danbooru-run image page. (This also grabs the tags, rating & source!))';
 
 			}
 				

From 5121e99dbe6ac18fe80fee627eb05d0f2921d5cb Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sat, 24 Dec 2011 14:49:55 +0000
Subject: [PATCH 22/60] speed hax and niceurl forcing from r34

---
 core/imageboard.pack.php |  9 ++++++---
 core/util.inc.php        |  2 +-
 ext/comment/theme.php    | 10 +++++++++-
 index.php                |  2 ++
 4 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/core/imageboard.pack.php b/core/imageboard.pack.php
index 0b2c89b8..5f110f07 100644
--- a/core/imageboard.pack.php
+++ b/core/imageboard.pack.php
@@ -500,9 +500,12 @@ class Image {
 		$tmpl = str_replace('$filename', $_escape($base_fname), $tmpl);
 		$tmpl = str_replace('$title', $_escape($config->get_string("title")), $tmpl);
 
-		$plte = new ParseLinkTemplateEvent($tmpl, $this);
-		send_event($plte);
-		$tmpl = $plte->link;
+		// nothing seems to use this, sending the event out to 50 exts is a lot of overhead
+		if(!SPEED_HAX) {
+			$plte = new ParseLinkTemplateEvent($tmpl, $this);
+			send_event($plte);
+			$tmpl = $plte->link;
+		}
 
 		return $tmpl;
 	}
diff --git a/core/util.inc.php b/core/util.inc.php
index c1333151..32523ac4 100644
--- a/core/util.inc.php
+++ b/core/util.inc.php
@@ -178,7 +178,7 @@ function make_link($page=null, $query=null) {
 
 	if(is_null($page)) $page = $config->get_string('main_page');
 
-	if($config->get_bool('nice_urls', false)) {
+	if(FORCE_NICE_URLS || $config->get_bool('nice_urls', false)) {
 		#$full = "http://" . $_SERVER["SERVER_NAME"] . $_SERVER["PHP_SELF"];
 		$full = $_SERVER["PHP_SELF"];
 		$base = str_replace("/index.php", "", $full);
diff --git a/ext/comment/theme.php b/ext/comment/theme.php
index 9c76f723..746d5a88 100644
--- a/ext/comment/theme.php
+++ b/ext/comment/theme.php
@@ -118,7 +118,15 @@ class CommentListTheme extends Themelet {
 		global $user;
 
 		$tfe = new TextFormattingEvent($comment->comment);
-		send_event($tfe);
+
+		// sending this event to all ~50 exts has a lot of overhead
+		if(SPEED_HAX) {
+			$bb = new BBCode();
+			$bb->receive_event($tfe);
+		}
+		else {
+			send_event($tfe);
+		}
 
 		$i_uid = int_escape($comment->owner_id);
 		$h_name = html_escape($comment->owner_name);
diff --git a/index.php b/index.php
index df3179d6..47ef6c56 100644
--- a/index.php
+++ b/index.php
@@ -59,6 +59,8 @@ define("CACHE_DIR", false);
 define("VERSION", 'trunk');
 define("SCORE_VERSION", 's2hack/'.VERSION);
 define("COOKIE_PREFIX", 'shm');
+define("SPEED_HAX", false);
+define("FORCE_NICE_URLS", false);
 
 if(empty($database_dsn) && !file_exists("config.php")) {
 	header("Location: install.php");

From ee1fc7e3ae9a88ac297a7de51be8b10cdf383534 Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Sat, 24 Dec 2011 20:18:00 +0000
Subject: [PATCH 23/60] Admin can now lock image while transloading.

---
 core/extension.class.php |  8 ++++-
 ext/upload/main.php      | 78 +++++++++++++++++++++++-----------------
 2 files changed, 53 insertions(+), 33 deletions(-)

diff --git a/core/extension.class.php b/core/extension.class.php
index 7906822b..4571b1c0 100644
--- a/core/extension.class.php
+++ b/core/extension.class.php
@@ -179,11 +179,17 @@ abstract class DataHandlerExtension implements Extension {
 				$event->image_id = $iae->image->id;
 				
 				// Rating Stuff.
-				if(file_exists("ext/rating") && !empty($event->metadata['rating'])){
+				if(!empty($event->metadata['rating'])){
 					global $database;
 					$rating = $event->metadata['rating'];
 					$database->Execute("UPDATE images SET rating=? WHERE id=?", array($rating, $event->image_id));
 				}
+				
+				// Locked Stuff.
+				if(!empty($event->metadata['locked'])){
+					$locked = $event->metadata['locked'];
+					send_event(new LockSetEvent($image, !empty($locked)));
+				}
 			}
 		}
 
diff --git a/ext/upload/main.php b/ext/upload/main.php
index fd8e5e6a..36e0914c 100644
--- a/ext/upload/main.php
+++ b/ext/upload/main.php
@@ -173,35 +173,8 @@ class Upload implements Extension {
 						if(!empty($_GET['tags']) && $_GET['tags'] != "null") {
 							$tags = Tag::explode($_GET['tags']);
 						}
-						
-
-												
-						// Checks if url contains rating, also checks if the rating extension is enabled.
-						if($config->get_string("transload_engine", "none") != "none" && file_exists("ext/rating") && !empty($_GET['rating'])) {
-							$rating = strtolower($_GET['rating']);
-							// There must be a less messy way to do this.. 
-							if($rating !== "") {
-								if($rating == "s" || $rating == "safe" || $rating == "q" || $rating == "questionable" || $rating == "e" || $rating == "explicit") {
-									if($rating == "s" || $rating == "safe" || $rating == "q" || $rating == "questionable") {
-										if($rating == "s" || $rating == "safe") {
-											$rating = "s";
-										}else{
-											$rating = "q";
-										}
-									}else{
-										$rating = "e";
-									}
-								}else{
-									$rating = "u";
-								}
-							}else{
-								$rating = "u";
-								}
-						}else{
-							$rating = "";
-						}
-						
-						$ok = $this->try_transload($url, $tags, $rating, $url);
+								
+						$ok = $this->try_transload($url, $tags, $url);
 						$this->theme->display_upload_status($page, $ok);
 					}
 					else
@@ -278,7 +251,7 @@ class Upload implements Extension {
 		}
 	}
 	
-	private function try_upload($file, $tags, $rating, $source, $replace='') {
+	private function try_upload($file, $tags, $source, $replace='') {
 		global $page;
 		global $config;
 		global $user;
@@ -324,9 +297,10 @@ class Upload implements Extension {
 		return $ok;
 	}
 
-	private function try_transload($url, $tags, $rating, $source, $replace='') {
+	private function try_transload($url, $tags, $source, $replace='') {
 		global $page;
 		global $config;
+		global $user;
 
 		$ok = true;
 
@@ -336,6 +310,41 @@ class Upload implements Extension {
 		}else{
 			$source = $url;
 		}
+		
+		// Checks if user is admin > check if you want locked.
+		if($user->is_admin()){
+			// There must be a less messy way to do this..
+			if($_GET['locked'] == "y" || $_GET['locked'] == "yes" || $_GET['locked'] == "true" || $_GET['locked'] == "on" || $_GET['locked'] == "n" || $_GET['locked'] == "no" || $_GET['locked'] == "false" || $_GET['locked'] == "off"){	
+				if($_GET['locked'] == "y" || $_GET['locked'] == "yes" || $_GET['locked'] == "true" || $_GET['locked'] == "on"){
+					$locked = "on";
+				}
+			}
+		}
+		
+		// Checks if url contains rating, also checks if the rating extension is enabled.
+		if($config->get_string("transload_engine", "none") != "none" && file_exists("ext/rating") && !empty($_GET['rating'])) {
+			$rating = strtolower($_GET['rating']);
+			// There REALLY must be a less messy way to do this.. 
+			if($rating !== "") {
+				if($rating == "s" || $rating == "safe" || $rating == "q" || $rating == "questionable" || $rating == "e" || $rating == "explicit") {
+					if($rating == "s" || $rating == "safe" || $rating == "q" || $rating == "questionable") {
+						if($rating == "s" || $rating == "safe") {
+							$rating = "s";
+						}else{
+							$rating = "q";
+						}
+					}else{
+						$rating = "e";
+						}
+				}else{
+					$rating = "u";
+				}
+			}else{
+				$rating = "u";
+			}
+		}else{
+			$rating = "";
+		}
 
 		// PHP falls back to system default if /tmp fails, can't we just
 		// use the system default to start with? :-/
@@ -396,8 +405,13 @@ class Upload implements Extension {
 			$metadata['tags'] = $tags;
 			$metadata['source'] = $source;
 			
+			/* check for locked > adds to metadata if it has */
+			if(!empty($locked)){
+			$metadata['locked'] = $locked;
+			}
+						
 			/* check for rating > adds to metadata if it has */
-			if($config->get_string("transload_engine", "none") != "none" && file_exists("ext/rating") && !empty($_GET['rating'])){
+			if(!empty($rating)){
 				$metadata['rating'] = $rating;
 			}
 			

From b5f5c861c43507511bc52eae73b6bd7bc71bf809 Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sat, 24 Dec 2011 21:28:29 +0000
Subject: [PATCH 24/60] quality in imagemagick mode

---
 ext/handle_pixel/main.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

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

From 883c73c9ff627adff6032baa62e4af13d4416efd Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sat, 24 Dec 2011 21:51:48 +0000
Subject: [PATCH 25/60] even if xdebug is installed, only run coverage when
 told to

---
 core/util.inc.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/core/util.inc.php b/core/util.inc.php
index 32523ac4..545b6b8d 100644
--- a/core/util.inc.php
+++ b/core/util.inc.php
@@ -1031,14 +1031,14 @@ function _end_cache() {
 \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 function _start_coverage() {
-	if(function_exists("xdebug_start_code_coverage")) {
+	if(COVERAGE && function_exists("xdebug_start_code_coverage")) {
 		#xdebug_start_code_coverage(XDEBUG_CC_UNUSED|XDEBUG_CC_DEAD_CODE);
 		xdebug_start_code_coverage(XDEBUG_CC_UNUSED);
 	}
 }
 
 function _end_coverage() {
-	if(function_exists("xdebug_get_code_coverage")) {
+	if(COVERAGE && function_exists("xdebug_get_code_coverage")) {
 		if(!file_exists("data/coverage")) mkdir("data/coverage");
 		$n = 0;
 		$t = time();

From 6d3cdb208c0159450465884a2d8607a33cfd4815 Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sat, 24 Dec 2011 21:55:33 +0000
Subject: [PATCH 26/60] those functions aren't /called/ unless coverage is set
 ._.;;

---
 core/util.inc.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/core/util.inc.php b/core/util.inc.php
index 545b6b8d..32523ac4 100644
--- a/core/util.inc.php
+++ b/core/util.inc.php
@@ -1031,14 +1031,14 @@ function _end_cache() {
 \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 function _start_coverage() {
-	if(COVERAGE && function_exists("xdebug_start_code_coverage")) {
+	if(function_exists("xdebug_start_code_coverage")) {
 		#xdebug_start_code_coverage(XDEBUG_CC_UNUSED|XDEBUG_CC_DEAD_CODE);
 		xdebug_start_code_coverage(XDEBUG_CC_UNUSED);
 	}
 }
 
 function _end_coverage() {
-	if(COVERAGE && function_exists("xdebug_get_code_coverage")) {
+	if(function_exists("xdebug_get_code_coverage")) {
 		if(!file_exists("data/coverage")) mkdir("data/coverage");
 		$n = 0;
 		$t = time();

From 2f9979c79088c4dd4407814e9d616afbdc1f8f30 Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sat, 24 Dec 2011 21:56:26 +0000
Subject: [PATCH 27/60] include config.php before define()ing settings, so that
 config.php can control them

---
 index.php | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/index.php b/index.php
index 47ef6c56..5c93e343 100644
--- a/index.php
+++ b/index.php
@@ -50,6 +50,12 @@
  * Each of these can be imported at the start of a function with eg "global $page, $user;"
  */
 
+if(empty($database_dsn) && !file_exists("config.php")) {
+	header("Location: install.php");
+	exit;
+}
+require_once "config.php";
+
 // set up and purify the environment
 define("DEBUG", true);
 define("COVERAGE", true);
@@ -62,12 +68,6 @@ define("COOKIE_PREFIX", 'shm');
 define("SPEED_HAX", false);
 define("FORCE_NICE_URLS", false);
 
-if(empty($database_dsn) && !file_exists("config.php")) {
-	header("Location: install.php");
-	exit;
-}
-
-require_once "config.php";
 require_once "core/util.inc.php";
 require_once "lib/context.php";
 if(CONTEXT) {

From 394f4518a31192b5403320b679210f2c0c744e65 Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Sat, 24 Dec 2011 23:28:33 +0000
Subject: [PATCH 28/60] More improvements to the uploader.

---
 ext/upload/minus.png | Bin 0 -> 212 bytes
 ext/upload/plus.png  | Bin 0 -> 269 bytes
 ext/upload/style.css |   5 +++++
 ext/upload/theme.php |  51 ++++++++++++++++++++++++++++++++++---------
 4 files changed, 46 insertions(+), 10 deletions(-)
 create mode 100644 ext/upload/minus.png
 create mode 100644 ext/upload/plus.png

diff --git a/ext/upload/minus.png b/ext/upload/minus.png
new file mode 100644
index 0000000000000000000000000000000000000000..57c86dec53054cc72ef0452fb7718bbc2e205be9
GIT binary patch
literal 212
zcmeAS@N?(olHy`uVBq!ia0vp^{2<K11|+SoP4xm&oCO|{#S9GG!XV7ZFl&wkP*5S+
zBgmJ5p-Pp3p`n?9;pcxK{gQ#9)PRBERRRNp)eHs(@%%~gN8NyGqdZ+4Ln>~)xwMhD
znL)t$V!5F82G3JItw%CKzG!e8IHxTzU=1m0n4-4v$*EsOiQz)wUkjY~bC?H&%Eq<7
z=@gUS!+&$mlI{Mc3hFkhH)k0pSzhM(YJXDvVJXAKB`RVCdTLofTNpfD{an^LB{Ts5
DG$%k}

literal 0
HcmV?d00001

diff --git a/ext/upload/plus.png b/ext/upload/plus.png
new file mode 100644
index 0000000000000000000000000000000000000000..d7ec0ae3036fcfceb702ee3787cc2e6ddf410d1b
GIT binary patch
literal 269
zcmeAS@N?(olHy`uVBq!ia0vp^{2<K11|+SoP4xm&oCO|{#S9GG!XV7ZFl&wkP*5S+
zBgmJ5p-Pp3p`n?9;pcxK{gQ#9)PRBERRRNp)eHs(@%%~gN8NyGCwsa$hE&{|GjSvD
zAqN4L^j>L&MZ!+2Ho1iJ6}se26bfKAWr&*O?9_h$NA0ETrpy1<eM_0W_3{+4NmicC
zOV+KJS7^t`=l5#X%#ig*o^Cw+b#~~Z^hf#n+d6~zGPkpr9gy9z<nGyTAA@fQe4MuL
zqFL^r5;i&0bN~IWwtMe?7LuD3dfRJ_P`*(2#bwX9a+;r7ub=y!AxP0ty;^DEJfQO!
NJYD@<);T3K0RW3HV-5fS

literal 0
HcmV?d00001

diff --git a/ext/upload/style.css b/ext/upload/style.css
index 1fe3f45d..ef8424c9 100644
--- a/ext/upload/style.css
+++ b/ext/upload/style.css
@@ -5,5 +5,10 @@
 #radio_button {
 	width: auto;
 }
+#wrapper {
+    opacity : 0.4;
+    filter: alpha(opacity=40); // msie
+}
+
 /* This is needed since the theme style.css forcibly sets vertical align to "top". */
 TABLE.vert TD, TABLE.vert TH {vertical-align: middle;}
diff --git a/ext/upload/theme.php b/ext/upload/theme.php
index 7ce049cf..50895783 100644
--- a/ext/upload/theme.php
+++ b/ext/upload/theme.php
@@ -16,13 +16,44 @@ class UploadTheme extends Themelet {
 		// Uploader 2.0!
 		$upload_list = "";
 		for($i=0; $i<$config->get_int('upload_count'); $i++) {
-			$n = $i + 1;
-			$upload_list .= "
-				<tr>
-					<td width='60'><form><input id='radio_buttona' type='radio' name='method' value='file' checked='checked' onclick='javascript:document.getElementById(&quot;url$i&quot;).style.display = &quot;none&quot;;document.getElementById(&quot;url$i&quot;).value = &quot;&quot;;document.getElementById(&quot;data$i&quot;).style.display = &quot;inline&quot;' /> File<br>";
+			$a=$i+1;
+			$s=$i-1;
+			if(!$i==0){
+				$upload_list .="<tr id='row$i' style='display:none'>";
+			}else{
+				$upload_list .= "<tr id='row$i'>";
+			}	
+				$upload_list .= "<td width='15'>";
+					
+					if($i==0){
+						$upload_list .= "<div id='hide$i'><img id='wrapper' src='ext/upload/minus.png' />" .
+						"<a href='javascript:document.getElementById(&quot;row$a&quot;).style.display = &quot;&quot;;javascript:document.getElementById(&quot;hide$i&quot;).style.display = &quot;none&quot;;javascript:document.getElementById(&quot;hide$a&quot;).style.display = &quot;&quot;;'>".
+						"<img src='ext/upload/plus.png'></a></div></td>";
+					}else{
+						$upload_list .="<div id='hide$i'>
+						<a href='javascript:document.getElementById(&quot;row$i&quot;).style.display = &quot;none&quot;;".
+						"document.getElementById(&quot;hide$i&quot;).style.display = &quot;none&quot;;".
+						"document.getElementById(&quot;hide$s&quot;).style.display = &quot;&quot;;".
+						"document.getElementById(&quot;data$i&quot;).value = &quot;&quot;;".
+						"document.getElementById(&quot;url$i&quot;).value = &quot;&quot;;'>".
+						"<img src='ext/upload/minus.png' /></a>";
+						if($a==$config->get_int('upload_count')){
+							$upload_list .="<img id='wrapper' src='ext/upload/plus.png' />";
+							}else{
+							$upload_list .=
+							"<a href='javascript:document.getElementById(&quot;row$a&quot;).style.display = &quot;&quot;;".
+							"document.getElementById(&quot;hide$i&quot;).style.display = &quot;none&quot;;".
+							"document.getElementById(&quot;hide$a&quot;).style.display = &quot;&quot;;'>".
+							"<img src='ext/upload/plus.png' /></a>";
+							}
+							$upload_list .= "</div></td>";
+					}
+					
+					$upload_list .=
+					"<td width='60'><form><input id='radio_buttona' type='radio' name='method' value='file' checked='checked' onclick='javascript:document.getElementById(&quot;url$i&quot;).style.display = &quot;none&quot;;document.getElementById(&quot;url$i&quot;).value = &quot;&quot;;document.getElementById(&quot;data$i&quot;).style.display = &quot;&quot;' /> File<br>";
 				if($tl_enabled) {
-					$upload_list .="
-					<input id='radio_buttonb' type='radio' name='method' value='url' onclick='javascript:document.getElementById(&quot;data$i&quot;).style.display = &quot;none&quot;;document.getElementById(&quot;data$i&quot;).value = &quot;&quot;;document.getElementById(&quot;url$i&quot;).style.display = &quot;inline&quot;' /> URL</ br></td></form>
+					$upload_list .=
+					"<input id='radio_buttonb' type='radio' name='method' value='url' onclick='javascript:document.getElementById(&quot;data$i&quot;).style.display = &quot;none&quot;;document.getElementById(&quot;data$i&quot;).value = &quot;&quot;;document.getElementById(&quot;url$i&quot;).style.display = &quot;&quot;' /> URL</ br></td></form>
 					
 					<td><input id='data$i' name='data$i' class='wid' type='file'><input id='url$i' name='url$i' class='wid' type='text' style='display:none'></td>
 					";
@@ -58,8 +89,8 @@ class UploadTheme extends Themelet {
 			".make_form(make_link("upload"), "POST", $multipart=True)."
 				<table id='large_upload_form' class='vert'>
 					$upload_list
-					<tr><td>Tags</td><td colspan='3'><input id='tag_box' name='tags' type='text'></td></tr>
-					<tr><td>Source</td><td colspan='3'><input name='source' type='text'></td></tr>
+					<tr><td></td><td>Tags<td colspan='3'><input id='tag_box' name='tags' type='text'></td></tr>
+					<tr><td></td><td>Source</td><td colspan='3'><input name='source' type='text'></td></tr>
 					<tr><td colspan='4'><input id='uploadbutton' type='submit' value='Post'></td></tr>
 				</table>
 			</form>
@@ -110,10 +141,10 @@ class UploadTheme extends Themelet {
 		$upload_list = '';
 		$upload_list .= "
 				<tr>
-					<td width='60'><form><input id='radio_buttona' type='radio' name='method' value='file' checked='checked' onclick='javascript:document.getElementById(&quot;url0&quot;).style.display = &quot;none&quot;;document.getElementById(&quot;url0&quot;).value = &quot;&quot;;document.getElementById(&quot;data0&quot;).style.display = &quot;inline&quot;' /> File<br>";
+					<td width='60'><form><input id='radio_buttona' type='radio' name='method' value='file' checked='checked' onclick='javascript:document.getElementById(&quot;url0&quot;).style.display = &quot;none&quot;;document.getElementById(&quot;url0&quot;).value = &quot;&quot;;document.getElementById(&quot;data0&quot;).style.display = &quot;&quot;' /> File<br>";
 				if($tl_enabled) {
 					$upload_list .="
-					<input id='radio_buttonb' type='radio' name='method' value='url' onclick='javascript:document.getElementById(&quot;data0&quot;).style.display = &quot;none&quot;;document.getElementById(&quot;data0&quot;).value = &quot;&quot;;document.getElementById(&quot;url0&quot;).style.display = &quot;inline&quot;' /> URL</ br></td></form>
+					<input id='radio_buttonb' type='radio' name='method' value='url' onclick='javascript:document.getElementById(&quot;data0&quot;).style.display = &quot;none&quot;;document.getElementById(&quot;data0&quot;).value = &quot;&quot;;document.getElementById(&quot;url0&quot;).style.display = &quot;&quot;' /> URL</ br></td></form>
 					<td><input id='data0' name='data0' class='wid' type='file'><input id='url0' name='url0' class='wid' type='text' style='display:none'></td>
 					";
 				} else { 

From c645fb4b0ef27a5141ecb69d5fa2bc7df72ff88c Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Sun, 25 Dec 2011 09:47:34 +0000
Subject: [PATCH 29/60] Title should now always stay as site name, to avoid tag
 hell for images with loads of tags.

---
 themes/warm/layout.class.php | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/themes/warm/layout.class.php b/themes/warm/layout.class.php
index 3d6c2cb7..c843eb3a 100644
--- a/themes/warm/layout.class.php
+++ b/themes/warm/layout.class.php
@@ -10,7 +10,9 @@ class Layout {
 		global $config;
 
 		$theme_name = $config->get_string('theme', 'default');
+		$site_name = $config->get_string('title');
 		$data_href = get_base_href();
+		$main_page = $config->get_string('main_page');
 		$contact_link = $config->get_string('contact_link');
 
 		$header_html = "";
@@ -67,7 +69,7 @@ $header_html
 <table id="header" class="bgtop" width="100%" height="113px">
 	<tr>
 		<td><center>
-			<h1><a href="/">{$page->heading}</a></h1>
+			<h1><a href="$data_href/$main_page">{$site_name}</a></h1>
 			<p>[Navigation links go here]
 		</center></td>
 		$head_block_html

From 66484a8e68fcd7de3a01eb852a04e98c0466d759 Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Sun, 25 Dec 2011 10:04:07 +0000
Subject: [PATCH 30/60] Thumbs should now be centered.

---
 themes/lite/themelet.class.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/themes/lite/themelet.class.php b/themes/lite/themelet.class.php
index d5b5e479..a9a21f8b 100644
--- a/themes/lite/themelet.class.php
+++ b/themes/lite/themelet.class.php
@@ -59,13 +59,13 @@ class Themelet {
 		$tsize = get_thumbnail_size($image->width, $image->height); }
 
 		return "
-			<div class='thumbblock'>
+			<center><div class='thumbblock'>
 			
 				<a href='$h_view_link' style='position: relative; display: block; height: {$tsize[1]}px; width: {$tsize[0]}px;'>
 					<img id='thumb_$i_id' title='$h_tip' alt='$h_tip' class='highlighted' style='height: {$tsize[1]}px; width: {$tsize[0]}px;' src='$h_thumb_link'>
 				</a>
 			
-			</div>
+			</div></center>
 		";
 	}
 

From cd609141f46ef7368b480f7fca00c6704af0ca1d Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sun, 25 Dec 2011 11:24:20 +0000
Subject: [PATCH 31/60] optional warehouse split levels

---
 core/util.inc.php | 7 ++++++-
 index.php         | 1 +
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/core/util.inc.php b/core/util.inc.php
index 32523ac4..a38fa9a1 100644
--- a/core/util.inc.php
+++ b/core/util.inc.php
@@ -504,7 +504,12 @@ function format_text($string) {
 function warehouse_path($base, $hash, $create=true) {
 	$ab = substr($hash, 0, 2);
 	$cd = substr($hash, 2, 2);
-	$pa = "$base/$ab/$hash";
+	if(WH_SPLITS == 2) {
+		$pa = "$base/$ab/$cd/$hash";
+	}
+	else {
+		$pa = "$base/$ab/$hash";
+	}
 	if($create && !file_exists(dirname($pa))) mkdir(dirname($pa), 0755, true);
 	return $pa;
 }
diff --git a/index.php b/index.php
index 5c93e343..6a800999 100644
--- a/index.php
+++ b/index.php
@@ -67,6 +67,7 @@ define("SCORE_VERSION", 's2hack/'.VERSION);
 define("COOKIE_PREFIX", 'shm');
 define("SPEED_HAX", false);
 define("FORCE_NICE_URLS", false);
+define("WH_SPLITS", 1);
 
 require_once "core/util.inc.php";
 require_once "lib/context.php";

From 070aeff1995d5b9d4315b4c6d8e767b543466999 Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sun, 25 Dec 2011 12:31:28 +0000
Subject: [PATCH 32/60] search images by uploader IP

---
 ext/user/main.php | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/ext/user/main.php b/ext/user/main.php
index 347699a2..ff1b2be8 100644
--- a/ext/user/main.php
+++ b/ext/user/main.php
@@ -228,6 +228,8 @@ class UserPage extends SimpleExtension {
 	}
 
 	public function onSearchTermParse(Event $event) {
+		global $user;
+
 		$matches = array();
 		if(preg_match("/^(poster|user)=(.*)$/i", $event->term, $matches)) {
 			$user = User::by_name($matches[2]);
@@ -243,6 +245,10 @@ class UserPage extends SimpleExtension {
 			$user_id = int_escape($matches[2]);
 			$event->add_querylet(new Querylet("images.owner_id = $user_id"));
 		}
+		else if($user->is_admin() && preg_match("/^(poster|user)_ip=([0-9\.]+)$/i", $event->term, $matches)) {
+			$user_ip = int_escape($matches[2]);
+			$event->add_querylet(new Querylet("images.owner_ip = '$user_ip'"));
+		}
 	}
 // }}}
 // Things done *with* the user {{{

From ba02e589b0c202778349b1b286570deea91b2ec5 Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sun, 25 Dec 2011 12:38:07 +0000
Subject: [PATCH 33/60] IP isn't an int

---
 ext/user/main.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ext/user/main.php b/ext/user/main.php
index ff1b2be8..07f14867 100644
--- a/ext/user/main.php
+++ b/ext/user/main.php
@@ -246,7 +246,7 @@ class UserPage extends SimpleExtension {
 			$event->add_querylet(new Querylet("images.owner_id = $user_id"));
 		}
 		else if($user->is_admin() && preg_match("/^(poster|user)_ip=([0-9\.]+)$/i", $event->term, $matches)) {
-			$user_ip = int_escape($matches[2]);
+			$user_ip = $matches[2]; // FIXME: ip_escape?
 			$event->add_querylet(new Querylet("images.owner_ip = '$user_ip'"));
 		}
 	}

From 3e6d5cec6f4a4216f06be87428434398315a277f Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sun, 25 Dec 2011 14:35:55 +0000
Subject: [PATCH 34/60] rating event rather than database access

---
 core/extension.class.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/core/extension.class.php b/core/extension.class.php
index 4571b1c0..d9cd0a18 100644
--- a/core/extension.class.php
+++ b/core/extension.class.php
@@ -180,9 +180,9 @@ abstract class DataHandlerExtension implements Extension {
 				
 				// Rating Stuff.
 				if(!empty($event->metadata['rating'])){
-					global $database;
+					global $user;
 					$rating = $event->metadata['rating'];
-					$database->Execute("UPDATE images SET rating=? WHERE id=?", array($rating, $event->image_id));
+					send_event(new RatingSetEvent($image, $user, $rating));
 				}
 				
 				// Locked Stuff.

From d167849ffc32a0d5a4daef8e231344502ed9a075 Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sun, 25 Dec 2011 14:47:54 +0000
Subject: [PATCH 35/60] huge if block is correct, but unnecessary - we can just
 take the first letter and the even system will validate it

---
 ext/upload/main.php | 20 ++------------------
 1 file changed, 2 insertions(+), 18 deletions(-)

diff --git a/ext/upload/main.php b/ext/upload/main.php
index 36e0914c..b624d992 100644
--- a/ext/upload/main.php
+++ b/ext/upload/main.php
@@ -323,25 +323,9 @@ class Upload implements Extension {
 		
 		// Checks if url contains rating, also checks if the rating extension is enabled.
 		if($config->get_string("transload_engine", "none") != "none" && file_exists("ext/rating") && !empty($_GET['rating'])) {
+			// Rating event will validate that this is s/q/e/u
 			$rating = strtolower($_GET['rating']);
-			// There REALLY must be a less messy way to do this.. 
-			if($rating !== "") {
-				if($rating == "s" || $rating == "safe" || $rating == "q" || $rating == "questionable" || $rating == "e" || $rating == "explicit") {
-					if($rating == "s" || $rating == "safe" || $rating == "q" || $rating == "questionable") {
-						if($rating == "s" || $rating == "safe") {
-							$rating = "s";
-						}else{
-							$rating = "q";
-						}
-					}else{
-						$rating = "e";
-						}
-				}else{
-					$rating = "u";
-				}
-			}else{
-				$rating = "u";
-			}
+			$rating = $rating[0];
 		}else{
 			$rating = "";
 		}

From 67e0c87b201f1cc6cde76134c7fc92c4905793d8 Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sun, 25 Dec 2011 15:11:26 +0000
Subject: [PATCH 36/60] create a generic bool_escape function, use that

---
 core/util.inc.php   | 19 +++++++++++++++++++
 ext/upload/main.php |  9 ++-------
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/core/util.inc.php b/core/util.inc.php
index a38fa9a1..a5bec9db 100644
--- a/core/util.inc.php
+++ b/core/util.inc.php
@@ -47,6 +47,25 @@ function sql_escape($input) {
 	return $database->db->Quote($input);
 }
 
+
+/**
+ * Turn all manner of HTML / INI / JS / DB booleans into a PHP one
+ *
+ * @retval boolean
+ */
+function bool_escape($input) {
+	$input = strtolower($input);
+	return (
+		$input == "y" ||
+		$input == "yes" ||
+		$input == "t" ||
+		$input == "true" ||
+		$input == "on" ||
+		$input == 1 ||
+		$input == true
+	);
+}
+
 /**
  * Some functions require a callback function for escaping,
  * but we might not want to alter the data
diff --git a/ext/upload/main.php b/ext/upload/main.php
index b624d992..0a40076c 100644
--- a/ext/upload/main.php
+++ b/ext/upload/main.php
@@ -313,12 +313,7 @@ class Upload implements Extension {
 		
 		// Checks if user is admin > check if you want locked.
 		if($user->is_admin()){
-			// There must be a less messy way to do this..
-			if($_GET['locked'] == "y" || $_GET['locked'] == "yes" || $_GET['locked'] == "true" || $_GET['locked'] == "on" || $_GET['locked'] == "n" || $_GET['locked'] == "no" || $_GET['locked'] == "false" || $_GET['locked'] == "off"){	
-				if($_GET['locked'] == "y" || $_GET['locked'] == "yes" || $_GET['locked'] == "true" || $_GET['locked'] == "on"){
-					$locked = "on";
-				}
-			}
+			$locked = bool_escape($_GET['locked']);
 		}
 		
 		// Checks if url contains rating, also checks if the rating extension is enabled.
@@ -391,7 +386,7 @@ class Upload implements Extension {
 			
 			/* check for locked > adds to metadata if it has */
 			if(!empty($locked)){
-			$metadata['locked'] = $locked;
+				$metadata['locked'] = $locked ? "on" : "";
 			}
 						
 			/* check for rating > adds to metadata if it has */

From b57a2d212152ec9228ad58b754b405b0dc4889e9 Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sun, 25 Dec 2011 16:42:05 +0000
Subject: [PATCH 37/60] paged tag lists backend, and speed hax

---
 ext/tag_list/main.php | 52 ++++++++++++++++++++++++++-----------------
 1 file changed, 31 insertions(+), 21 deletions(-)

diff --git a/ext/tag_list/main.php b/ext/tag_list/main.php
index 71767773..fd2a1971 100644
--- a/ext/tag_list/main.php
+++ b/ext/tag_list/main.php
@@ -129,9 +129,9 @@ class TagList implements Extension {
 		global $database;
 
 		$tags_min = $this->get_tags_min();
-		if(file_exists("data/tag_map_$tags_min.html")) {
-			return file_get_contents("data/tag_map_$tags_min.html");
-		}
+		$starts_with = @$_GET['starts_with'] || "a";
+		$cache_key = "data/tag_cloud-"+md5($tags_min + $starts_with)+".html";
+		if(file_exists($cache_key)) {return file_get_contents($cache_key);}
 
 		$tag_data = $database->get_all("
 				SELECT
@@ -139,8 +139,9 @@ class TagList implements Extension {
 					FLOOR(LOG(2.7, LOG(2.7, count - :tags_min + 1)+1)*1.5*100)/100 AS scaled
 				FROM tags
 				WHERE count >= :tags_min
+				AND tag ILIKE :starts_with
 				ORDER BY tag
-			", array("tags_min"=>$tags_min));
+			", array("tags_min"=>$tags_min, "starts_with"=>$starts_with+"%"));
 
 		$html = "";
 		foreach($tag_data as $row) {
@@ -152,7 +153,8 @@ class TagList implements Extension {
 			$html .= "&nbsp;<a style='font-size: ${size}em' href='$link'>$h_tag_no_underscores</a>&nbsp;\n";
 		}
 
-		// file_put_contents("data/tag_map_$tags_min.html", $html);
+		if(SPEED_HAX) {file_put_contents($cache_key, $html);}
+
 		return $html;
 	}
 
@@ -160,28 +162,33 @@ class TagList implements Extension {
 		global $database;
 
 		$tags_min = $this->get_tags_min();
-		if(file_exists("data/tag_alpha_$tags_min.html")) {
-			return file_get_contents("data/tag_alpha_$tags_min.html");
-		}
+		$starts_with = @$_GET['starts_with'] || "a";
+		$cache_key = "data/tag_alpha-"+md5($tags_min + $starts_with)+".html";
+		if(file_exists($cache_key)) {return file_get_contents($cache_key);}
 
-		$tag_data = $database->get_all(
-				"SELECT tag,count FROM tags WHERE count >= :tags_min ORDER BY tag",
-				array("tags_min"=>$tags_min));
+		$tag_data = $database->get_all("
+				SELECT tag, count
+				FROM tags
+				WHERE count >= :tags_min
+				AND tag ILIKE :starts_with
+				ORDER BY tag
+				", array("tags_min"=>$tags_min, "starts_with"=>$starts_with+"%"));
 
 		$html = "";
 		$lastLetter = "";
 		foreach($tag_data as $row) {
 			$h_tag = html_escape($row['tag']);
 			$count = $row['count'];
-			if($lastLetter != strtolower(substr($h_tag, 0, 1))) {
-				$lastLetter = strtolower(substr($h_tag, 0, 1));
+			if($lastLetter != strtolower(substr($h_tag, 0, count($starts_with)+1))) {
+				$lastLetter = strtolower(substr($h_tag, 0, count($starts_with)+1));
 				$html .= "<p>$lastLetter<br>";
 			}
 			$link = $this->tag_link($row['tag']);
 			$html .= "<a href='$link'>$h_tag&nbsp;($count)</a>\n";
 		}
 
-		// file_put_contents("data/tag_alpha_$tags_min.html", $html);
+		if(SPEED_HAX) {file_put_contents($cache_key, $html);}
+
 		return $html;
 	}
 
@@ -189,13 +196,15 @@ class TagList implements Extension {
 		global $database;
 
 		$tags_min = $this->get_tags_min();
-		if(file_exists("data/tag_popul_$tags_min.html")) {
-			return file_get_contents("data/tag_popul_$tags_min.html");
-		}
+		$cache_key = "data/tag_popul-"+md5($tags_min)+".html";
+		if(file_exists($cache_key)) {return file_get_contents($cache_key);}
 
-		$tag_data = $database->get_all(
-				"SELECT tag,count,FLOOR(LOG(count)) AS scaled FROM tags WHERE count >= :tags_min ORDER BY count DESC, tag ASC",
-				array("tags_min"=>$tags_min));
+		$tag_data = $database->get_all("
+				SELECT tag, count, FLOOR(LOG(count)) AS scaled
+				FROM tags
+				WHERE count >= :tags_min
+				ORDER BY count DESC, tag ASC
+				", array("tags_min"=>$tags_min));
 
 		$html = "Results grouped by log<sub>e</sub>(n)";
 		$lastLog = "";
@@ -211,7 +220,8 @@ class TagList implements Extension {
 			$html .= "<a href='$link'>$h_tag&nbsp;($count)</a>\n";
 		}
 
-		// file_put_contents("data/tag_popul_$tags_min.html", $html);
+		if(SPEED_HAX) {file_put_contents($cache_key, $html);}
+
 		return $html;
 	}
 

From e9fedb570a3e5968c1afd518298715f8f8646d40 Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sun, 25 Dec 2011 16:59:13 +0000
Subject: [PATCH 38/60] PHP is shit. MySQL is also shit.

---
 ext/tag_list/main.php | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/ext/tag_list/main.php b/ext/tag_list/main.php
index fd2a1971..8284daa9 100644
--- a/ext/tag_list/main.php
+++ b/ext/tag_list/main.php
@@ -113,6 +113,15 @@ class TagList implements Extension {
 			return $config->get_int('tags_min');
 		}
 	}
+
+	private function get_starts_with() {
+		if(isset($_GET['starts_with'])) {
+			return $_GET['starts_with'];
+		}
+		else {
+			return "";
+		}
+	}
 // }}}
 // maps {{{
 	private function build_navigation() {
@@ -129,7 +138,7 @@ class TagList implements Extension {
 		global $database;
 
 		$tags_min = $this->get_tags_min();
-		$starts_with = @$_GET['starts_with'] || "a";
+		$starts_with = $this->get_starts_with();
 		$cache_key = "data/tag_cloud-"+md5($tags_min + $starts_with)+".html";
 		if(file_exists($cache_key)) {return file_get_contents($cache_key);}
 
@@ -139,9 +148,9 @@ class TagList implements Extension {
 					FLOOR(LOG(2.7, LOG(2.7, count - :tags_min + 1)+1)*1.5*100)/100 AS scaled
 				FROM tags
 				WHERE count >= :tags_min
-				AND tag ILIKE :starts_with
+				AND tag LIKE :starts_with
 				ORDER BY tag
-			", array("tags_min"=>$tags_min, "starts_with"=>$starts_with+"%"));
+			", array("tags_min"=>$tags_min, "starts_with"=>$starts_with));
 
 		$html = "";
 		foreach($tag_data as $row) {
@@ -162,7 +171,7 @@ class TagList implements Extension {
 		global $database;
 
 		$tags_min = $this->get_tags_min();
-		$starts_with = @$_GET['starts_with'] || "a";
+		$starts_with = $this->get_starts_with();
 		$cache_key = "data/tag_alpha-"+md5($tags_min + $starts_with)+".html";
 		if(file_exists($cache_key)) {return file_get_contents($cache_key);}
 
@@ -170,9 +179,9 @@ class TagList implements Extension {
 				SELECT tag, count
 				FROM tags
 				WHERE count >= :tags_min
-				AND tag ILIKE :starts_with
+				AND tag LIKE :starts_with
 				ORDER BY tag
-				", array("tags_min"=>$tags_min, "starts_with"=>$starts_with+"%"));
+				", array("tags_min"=>$tags_min, "starts_with"=>$starts_with));
 
 		$html = "";
 		$lastLetter = "";

From e05d4619db96f9c0bd1dc06d965befb25d1546a2 Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sun, 25 Dec 2011 17:07:55 +0000
Subject: [PATCH 39/60] Also I hate PHP on a personal level.

---
 ext/tag_list/main.php | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/ext/tag_list/main.php b/ext/tag_list/main.php
index 8284daa9..50913674 100644
--- a/ext/tag_list/main.php
+++ b/ext/tag_list/main.php
@@ -116,10 +116,10 @@ class TagList implements Extension {
 
 	private function get_starts_with() {
 		if(isset($_GET['starts_with'])) {
-			return $_GET['starts_with'];
+			return $_GET['starts_with'] . "%";
 		}
 		else {
-			return "";
+			return "%";
 		}
 	}
 // }}}
@@ -139,7 +139,7 @@ class TagList implements Extension {
 
 		$tags_min = $this->get_tags_min();
 		$starts_with = $this->get_starts_with();
-		$cache_key = "data/tag_cloud-"+md5($tags_min + $starts_with)+".html";
+		$cache_key = "data/tag_cloud-" . md5("tc" . $tags_min . $starts_with) . ".html";
 		if(file_exists($cache_key)) {return file_get_contents($cache_key);}
 
 		$tag_data = $database->get_all("
@@ -172,7 +172,7 @@ class TagList implements Extension {
 
 		$tags_min = $this->get_tags_min();
 		$starts_with = $this->get_starts_with();
-		$cache_key = "data/tag_alpha-"+md5($tags_min + $starts_with)+".html";
+		$cache_key = "data/tag_alpha-" . md5("ta" . $tags_min . $starts_with) . ".html";
 		if(file_exists($cache_key)) {return file_get_contents($cache_key);}
 
 		$tag_data = $database->get_all("
@@ -205,7 +205,7 @@ class TagList implements Extension {
 		global $database;
 
 		$tags_min = $this->get_tags_min();
-		$cache_key = "data/tag_popul-"+md5($tags_min)+".html";
+		$cache_key = "data/tag_popul-" . md5("tp" . $tags_min) . ".html";
 		if(file_exists($cache_key)) {return file_get_contents($cache_key);}
 
 		$tag_data = $database->get_all("

From b7bd74055d47caafb2cc710b1c572dcc0e347975 Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sun, 25 Dec 2011 17:57:15 +0000
Subject: [PATCH 40/60] PHP is officially the worst web API ever

---
 core/util.inc.php | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/core/util.inc.php b/core/util.inc.php
index a5bec9db..98f17866 100644
--- a/core/util.inc.php
+++ b/core/util.inc.php
@@ -222,6 +222,44 @@ function make_link($page=null, $query=null) {
 	}
 }
 
+
+/**
+ * Take the current URL and modify some paramaters
+ *
+ * @retval string
+ */
+function modify_current_url($changes) {
+	// SHIT: PHP is officially the worst web API ever because it does not
+	// have a built-in function to do this.
+
+	// SHIT: parse_str is magically retarded; not only is it a useless name, it also
+	// didn't return the parsed array, preferring to overwrite global variables with
+	// whatever data the user supplied. Thankfully, 4.0.3 added an extra option to
+	// give it an array to use...
+	$params = array();
+	parse_str($_SERVER['QUERY_STRING'], $params);
+
+	if(isset($changes['q'])) {
+		$base = $changes['q'];
+		unset($changes['q']);
+	}
+	else {
+		$base = $_GET['q'];
+	}
+
+	if(isset($params['q'])) {
+		unset($params['q']);
+	}
+
+	foreach($changes as $k => $v) {
+		if(is_null($v) and isset($params[$k])) unset($params[$k]);
+		$params[$k] = $v;
+	}
+
+	return make_link($base, http_build_query($params));
+}
+
+
 /**
  * Turn a relative link into an absolute one, including hostname
  *

From 8887ffe10121319fd8b4ad2d995fcaefb96d4d8b Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sun, 25 Dec 2011 18:23:00 +0000
Subject: [PATCH 41/60] make paging optional

---
 ext/tag_list/main.php | 29 +++++++++++++++++++++++++----
 1 file changed, 25 insertions(+), 4 deletions(-)

diff --git a/ext/tag_list/main.php b/ext/tag_list/main.php
index 50913674..b3a13f4b 100644
--- a/ext/tag_list/main.php
+++ b/ext/tag_list/main.php
@@ -19,6 +19,7 @@ class TagList implements Extension {
 			$config->set_default_int("tags_min", 3);
 			$config->set_default_string("info_link", 'http://en.wikipedia.org/wiki/$tag');
 			$config->set_default_string("tag_list_image_type", 'related');
+			$config->set_default_bool("tag_list_pages", false);
 		}
 
 		if(($event instanceof PageRequestEvent) && $event->page_matches("tags")) {
@@ -94,6 +95,7 @@ class TagList implements Extension {
 				"Show related" => "related"
 			), "<br>Image tag list: ");
 			$sb->add_bool_option("tag_list_numbers", "<br>Show tag counts: ");
+			$sb->add_bool_option("tag_list_pages", "<br>Paged tag lists: ");
 			$event->panel->add_block($sb);
 		}
 	}
@@ -115,13 +117,30 @@ class TagList implements Extension {
 	}
 
 	private function get_starts_with() {
+		global $config;
 		if(isset($_GET['starts_with'])) {
 			return $_GET['starts_with'] . "%";
 		}
 		else {
-			return "%";
+			if($config->get_bool("tag_list_pages")) {
+				return "a%";
+			}
+			else {
+				return "%";
+			}
 		}
 	}
+
+	private function build_az() {
+		$alpha = "abcdefghijklmnopqrstuvwxyz";
+		$html = "";
+		for($n=0; $n<strlen($alpha); $n++) {
+			$a = $alpha[$n];
+			$html .= " <a href='".modify_current_url(array("starts_with"=>$a))."'>$a</a>";
+		}
+		$html .= "<p><hr>";
+		return $html;
+	}
 // }}}
 // maps {{{
 	private function build_navigation() {
@@ -130,12 +149,12 @@ class TagList implements Extension {
 		$h_alphabetic = "<a href='".make_link("tags/alphabetic")."'>Alphabetic</a>";
 		$h_popularity = "<a href='".make_link("tags/popularity")."'>Popularity</a>";
 		$h_cats = "<a href='".make_link("tags/categories")."'>Categories</a>";
-		$h_all = "<a href='?mincount=1'>Show All</a>";
+		$h_all = "<a href='".modify_current_url(array("mincount"=>1))."'>Show All</a>";
 		return "$h_index<br>&nbsp;<br>$h_map<br>$h_alphabetic<br>$h_popularity<br>$h_cats<br>&nbsp;<br>$h_all";
 	}
 
 	private function build_tag_map() {
-		global $database;
+		global $config, $database;
 
 		$tags_min = $this->get_tags_min();
 		$starts_with = $this->get_starts_with();
@@ -153,6 +172,7 @@ class TagList implements Extension {
 			", array("tags_min"=>$tags_min, "starts_with"=>$starts_with));
 
 		$html = "";
+		if($config->get_bool("tag_list_pages")) $html .= $this->build_az();
 		foreach($tag_data as $row) {
 			$h_tag = html_escape($row['tag']);
 			$size = sprintf("%.2f", (float)$row['scaled']);
@@ -168,7 +188,7 @@ class TagList implements Extension {
 	}
 
 	private function build_tag_alphabetic() {
-		global $database;
+		global $config, $database;
 
 		$tags_min = $this->get_tags_min();
 		$starts_with = $this->get_starts_with();
@@ -184,6 +204,7 @@ class TagList implements Extension {
 				", array("tags_min"=>$tags_min, "starts_with"=>$starts_with));
 
 		$html = "";
+		if($config->get_bool("tag_list_pages")) $html .= $this->build_az();
 		$lastLetter = "";
 		foreach($tag_data as $row) {
 			$h_tag = html_escape($row['tag']);

From 082730f29a92f291581ef82adecef346438c6ca7 Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sun, 25 Dec 2011 22:34:20 +0000
Subject: [PATCH 42/60] get the tag initials from the database itself

---
 ext/tag_list/main.php | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/ext/tag_list/main.php b/ext/tag_list/main.php
index b3a13f4b..dcdf3b2c 100644
--- a/ext/tag_list/main.php
+++ b/ext/tag_list/main.php
@@ -132,13 +132,29 @@ class TagList implements Extension {
 	}
 
 	private function build_az() {
-		$alpha = "abcdefghijklmnopqrstuvwxyz";
+		global $database;
+
+		$tags_min = $this->get_tags_min();
+
+		$cache_key = "data/tag_inits-" . md5("tc" . $tags_min) . ".html";
+		if(file_exists($cache_key)) {return file_get_contents($cache_key);}
+
+		$tag_data = $database->get_col("
+			SELECT DISTINCT
+				substr(tag, 1, 1)
+			FROM tags
+			WHERE count >= :tags_min
+			ORDER BY tag
+		", array("tags_min"=>$tags_min));
+
 		$html = "";
-		for($n=0; $n<strlen($alpha); $n++) {
-			$a = $alpha[$n];
+		foreach($tag_data as $a) {
 			$html .= " <a href='".modify_current_url(array("starts_with"=>$a))."'>$a</a>";
 		}
 		$html .= "<p><hr>";
+
+		if(SPEED_HAX) {file_put_contents($cache_key, $html);}
+
 		return $html;
 	}
 // }}}

From 009b7ccbbb4a8cdb03ba831e7ca7bc099c4b5bba Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sun, 25 Dec 2011 23:14:13 +0000
Subject: [PATCH 43/60] stick the tag list paging option in the right place,
 and PDO/PG compat

---
 ext/tag_list/main.php | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/ext/tag_list/main.php b/ext/tag_list/main.php
index dcdf3b2c..d4f99d9f 100644
--- a/ext/tag_list/main.php
+++ b/ext/tag_list/main.php
@@ -84,6 +84,7 @@ class TagList implements Extension {
 		if($event instanceof SetupBuildingEvent) {
 			$sb = new SetupBlock("Tag Map Options");
 			$sb->add_int_option("tags_min", "Only show tags used at least "); $sb->add_label(" times");
+			$sb->add_bool_option("tag_list_pages", "<br>Paged tag lists: ");
 			$event->panel->add_block($sb);
 
 			$sb = new SetupBlock("Popular / Related Tag List");
@@ -95,7 +96,6 @@ class TagList implements Extension {
 				"Show related" => "related"
 			), "<br>Image tag list: ");
 			$sb->add_bool_option("tag_list_numbers", "<br>Show tag counts: ");
-			$sb->add_bool_option("tag_list_pages", "<br>Paged tag lists: ");
 			$event->panel->add_block($sb);
 		}
 	}
@@ -144,7 +144,7 @@ class TagList implements Extension {
 				substr(tag, 1, 1)
 			FROM tags
 			WHERE count >= :tags_min
-			ORDER BY tag
+			ORDER BY substr(tag, 1, 1)
 		", array("tags_min"=>$tags_min));
 
 		$html = "";
@@ -177,15 +177,16 @@ class TagList implements Extension {
 		$cache_key = "data/tag_cloud-" . md5("tc" . $tags_min . $starts_with) . ".html";
 		if(file_exists($cache_key)) {return file_get_contents($cache_key);}
 
+		// SHIT: PDO/pgsql has problems using the same named param twice -_-;;
 		$tag_data = $database->get_all("
 				SELECT
 					tag,
-					FLOOR(LOG(2.7, LOG(2.7, count - :tags_min + 1)+1)*1.5*100)/100 AS scaled
+					FLOOR(LOG(2.7, LOG(2.7, count - :tags_min2 + 1)+1)*1.5*100)/100 AS scaled
 				FROM tags
 				WHERE count >= :tags_min
 				AND tag LIKE :starts_with
 				ORDER BY tag
-			", array("tags_min"=>$tags_min, "starts_with"=>$starts_with));
+			", array("tags_min"=>$tags_min, "tags_min2"=>$tags_min, "starts_with"=>$starts_with));
 
 		$html = "";
 		if($config->get_bool("tag_list_pages")) $html .= $this->build_az();

From 9b93df4e22e58c4dc9a9a95652ab3e81f0e48390 Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Tue, 27 Dec 2011 18:08:49 +0000
Subject: [PATCH 44/60] make apache cache-control/expires settings only apply
 to static files; shimmie will take care of the web pages

---
 .htaccess | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

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

From cfbeddde9f492a4a0c2c593afaac3462ee17394c Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Tue, 27 Dec 2011 19:23:37 +0000
Subject: [PATCH 45/60] HTTP level caching, so we can stick varnish in front of
 the web pages

---
 core/page.class.php | 19 +++++++++++++++++--
 ext/user/main.php   |  5 +++++
 index.php           |  1 +
 3 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/core/page.class.php b/core/page.class.php
index b2a8d662..d382caf2 100644
--- a/core/page.class.php
+++ b/core/page.class.php
@@ -183,7 +183,7 @@ class Page {
 	 * Display the page according to the mode and data given
 	 */
 	public function display() {
-		global $page;
+		global $page, $user;
 		
 		header("Content-type: ".$this->type);
 		header("X-Powered-By: SCore-".SCORE_VERSION);
@@ -196,7 +196,22 @@ class Page {
 
 		switch($this->mode) {
 			case "page":
-				header("Cache-control: no-cache");
+				header("Vary: Cookie, Accept-Encoding");
+				if(CACHE_HTTP) {
+					if($user->is_anonymous() && $_SERVER["REQUEST_METHOD"] == "GET") {
+						header("Cache-control: public, max-age=600");
+						header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 600) . ' GMT');
+					}
+					else {
+						#header("Cache-control: private, max-age=0");
+						header("Cache-control: no-cache");
+						header('Expires: ' . gmdate('D, d M Y H:i:s', time() - 600) . ' GMT');
+					}
+				}
+				else {
+					header("Cache-control: no-cache");
+					header('Expires: ' . gmdate('D, d M Y H:i:s', time() - 600) . ' GMT');
+				}
 				usort($this->blocks, "blockcmp");
 				$this->add_auto_html_headers();
 				$layout = new Layout();
diff --git a/ext/user/main.php b/ext/user/main.php
index 07f14867..0b1073fa 100644
--- a/ext/user/main.php
+++ b/ext/user/main.php
@@ -79,6 +79,11 @@ class UserPage extends SimpleExtension {
 			}
 			else if($event->get_arg(0) == "logout") {
 				set_prefixed_cookie("session", "", time()+60*60*24*$config->get_int('login_memory'), "/");
+				if(CACHE_HTTP) {
+					# to keep as few versions of content as possible,
+					# make cookies all-or-nothing
+					set_prefixed_cookie("user", "", time()+60*60*24*$config->get_int('login_memory'), "/");
+				}
 				log_info("user", "Logged out");
 				$page->set_mode("redirect");
 				$page->set_redirect(make_link());
diff --git a/index.php b/index.php
index 6a800999..48458b0c 100644
--- a/index.php
+++ b/index.php
@@ -62,6 +62,7 @@ define("COVERAGE", true);
 define("CONTEXT", false);
 define("CACHE_MEMCACHE", false);
 define("CACHE_DIR", false);
+define("CACHE_HTTP", false);
 define("VERSION", 'trunk');
 define("SCORE_VERSION", 's2hack/'.VERSION);
 define("COOKIE_PREFIX", 'shm');

From 636b5fc11942d0b016b93ddfe65cee31893ec268 Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Tue, 27 Dec 2011 20:00:56 +0000
Subject: [PATCH 46/60] debugging off by default

---
 index.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/index.php b/index.php
index 48458b0c..41e28b47 100644
--- a/index.php
+++ b/index.php
@@ -57,8 +57,8 @@ if(empty($database_dsn) && !file_exists("config.php")) {
 require_once "config.php";
 
 // set up and purify the environment
-define("DEBUG", true);
-define("COVERAGE", true);
+define("DEBUG", false);
+define("COVERAGE", false);
 define("CONTEXT", false);
 define("CACHE_MEMCACHE", false);
 define("CACHE_DIR", false);

From 1857075bd959e59958fe50d6f7839b36fec1e9ea Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sat, 31 Dec 2011 13:54:32 +0000
Subject: [PATCH 47/60] show comments made by user

---
 ext/comment/main.php  | 26 ++++++++++++++++++++++++++
 ext/comment/theme.php | 13 +++++++++++++
 2 files changed, 39 insertions(+)

diff --git a/ext/comment/main.php b/ext/comment/main.php
index 215be23d..6e165d03 100644
--- a/ext/comment/main.php
+++ b/ext/comment/main.php
@@ -171,6 +171,10 @@ class CommentList extends SimpleExtension {
 		$i_comment_count = Comment::count_comments_by_user($event->display_user);
 		$h_comment_rate = sprintf("%.1f", ($i_comment_count / $i_days_old));
 		$event->add_stats("Comments made: $i_comment_count, $h_comment_rate per day");
+
+		global $user;
+		$recent = $this->get_user_recent_comments($event->display_user->id, 10);
+		$this->theme->display_user_comments($recent);
 	}
 
 	public function onDisplayingImage(DisplayingImageEvent $event) {
@@ -312,6 +316,28 @@ class CommentList extends SimpleExtension {
 		return $comments;
 	}
 
+	private function get_user_recent_comments($user_id, $count) {
+		global $config;
+		global $database;
+		$rows = $database->get_all("
+				SELECT
+				users.id as user_id, users.name as user_name, users.email as user_email,
+				comments.comment as comment, comments.id as comment_id,
+				comments.image_id as image_id, comments.owner_ip as poster_ip,
+				comments.posted as posted
+				FROM comments
+				LEFT JOIN users ON comments.owner_id=users.id
+				WHERE users.id = :user_id
+				ORDER BY comments.id DESC
+				LIMIT :limit
+				", array("user_id"=>$user_id, "limit"=>$count));
+		$comments = array();
+		foreach($rows as $row) {
+			$comments[] = new Comment($row);
+		}
+		return $comments;
+	}
+
 	private function get_comments($image_id) {
 		global $config;
 		global $database;
diff --git a/ext/comment/theme.php b/ext/comment/theme.php
index 746d5a88..f48a7b25 100644
--- a/ext/comment/theme.php
+++ b/ext/comment/theme.php
@@ -114,6 +114,19 @@ class CommentListTheme extends Themelet {
 	}
 
 
+	/**
+	 * Show comments made by a user
+	 */
+	public function display_user_comments($comments) {
+		global $page;
+		$html = "";
+		foreach($comments as $comment) {
+			$html .= $this->comment_to_html($comment, true);
+		}
+		$page->add_block(new Block("Comments", $html, "left", 70));
+	}
+
+
 	protected function comment_to_html($comment, $trim=false) {
 		global $user;
 

From ad2bb8b8b60ee0d2bf37d76373cb4649ab442461 Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sat, 31 Dec 2011 14:12:05 +0000
Subject: [PATCH 48/60] switch timeago to a javascript implementation

---
 core/util.inc.php     |  31 +--------
 ext/setup/main.php    |   2 -
 ext/user/main.php     |   4 +-
 lib/jquery.timeago.js | 146 ++++++++++++++++++++++++++++++++++++++++++
 lib/shimmie.js        |   1 +
 5 files changed, 152 insertions(+), 32 deletions(-)
 create mode 100644 lib/jquery.timeago.js

diff --git a/core/util.inc.php b/core/util.inc.php
index 98f17866..71a317f3 100644
--- a/core/util.inc.php
+++ b/core/util.inc.php
@@ -129,34 +129,9 @@ function to_shorthand_int($int) {
  * @retval string
  */
 function autodate($date, $html=true) {
-	global $config;
-
-	$format = $config->get_string('autodate_format', "F j, Y");
-	$seconds = time() - strtotime($date);
-	$ago = seconds_to_time($seconds) . " ago";
-	$on = "on " . date($format, strtotime($date));
-
-	if($config->get_bool('use_autodate', true)) {
-		return ($html ? "<span title='$on'>$ago</span>" : $ago);
-	}
-	else {
-		return $on;
-	}
-}
-
-/**
- * Turn a number of seconds into a vague human timespan, eg 142 -> "2 minutes"
- *
- * @retval string
- */
-function seconds_to_time($seconds) {
-	if($seconds<60) return $seconds . " second" . plural($seconds); $seconds = round($seconds/60);
-	if($seconds<60) return $seconds . " minute" . plural($seconds); $seconds = round($seconds/60);
-	if($seconds<24) return $seconds . " hour" . plural($seconds);   $seconds = round($seconds/24);
-	if($seconds<7)  return $seconds . " day" . plural($seconds);    $seconds = round($seconds/7);
-	if($seconds<4)  return $seconds . " week" . plural($seconds);   $seconds = round($seconds/4);
-	if($seconds<12) return $seconds . " month" . plural($seconds);  $seconds = round($seconds/12);
-	                return $seconds . " year" . plural($seconds);
+	$cpu = date('c', strtotime($date));
+	$hum = date('F j, Y', strtotime($date));
+	return ($html ? "<time datetime='$cpu'>$hum</time>" : $hum);
 }
 
 
diff --git a/ext/setup/main.php b/ext/setup/main.php
index f1885568..7e7337e8 100644
--- a/ext/setup/main.php
+++ b/ext/setup/main.php
@@ -169,10 +169,8 @@ class Setup extends SimpleExtension {
 		$config->set_default_string("main_page", "post/list");
 		$config->set_default_string("base_href", "./index.php?q=");
 		$config->set_default_string("theme", "default");
-		$config->set_default_bool("use_autodate", true);
 		$config->set_default_bool("word_wrap", true);
 		$config->set_default_bool("comment_captcha", false);
-		$config->set_default_string("autodate_format", "F j, Y");
 		// Automatic caching is disabled by default
 		$config->set_default_string("autocache_location", "data/cache");
 		$config->set_default_bool("autocache_css", false);
diff --git a/ext/user/main.php b/ext/user/main.php
index 0b1073fa..fc0da212 100644
--- a/ext/user/main.php
+++ b/ext/user/main.php
@@ -166,8 +166,8 @@ class UserPage extends SimpleExtension {
 	public function onUserPageBuilding(Event $event) {
 		global $page, $user, $config;
 
-		$h_join_date = html_escape($event->display_user->join_date);
-		$event->add_stats("Join date: $h_join_date", 10);
+		$h_join_date = autodate($event->display_user->join_date);
+		$event->add_stats("Joined: $h_join_date", 10);
 
 		$av = $event->display_user->get_avatar_html();
 		if($av) $event->add_stats($av, 0);
diff --git a/lib/jquery.timeago.js b/lib/jquery.timeago.js
new file mode 100644
index 00000000..24ac69c7
--- /dev/null
+++ b/lib/jquery.timeago.js
@@ -0,0 +1,146 @@
+/**
+ * Timeago is a jQuery plugin that makes it easy to support automatically
+ * updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago").
+ *
+ * @name timeago
+ * @version 0.10.0
+ * @requires jQuery v1.2.3+
+ * @author Ryan McGeary
+ * @license MIT License - http://www.opensource.org/licenses/mit-license.php
+ *
+ * For usage and examples, visit:
+ * http://timeago.yarp.com/
+ *
+ * Copyright (c) 2008-2011, Ryan McGeary (ryanonjavascript -[at]- mcgeary [*dot*] org)
+ */
+(function($) {
+  $.timeago = function(timestamp) {
+    if (timestamp instanceof Date) {
+      return inWords(timestamp);
+    } else if (typeof timestamp === "string") {
+      return inWords($.timeago.parse(timestamp));
+    } else {
+      return inWords($.timeago.datetime(timestamp));
+    }
+  };
+  var $t = $.timeago;
+
+  $.extend($.timeago, {
+    settings: {
+      refreshMillis: 60000,
+      allowFuture: false,
+      strings: {
+        prefixAgo: null,
+        prefixFromNow: null,
+        suffixAgo: "ago",
+        suffixFromNow: "from now",
+        seconds: "less than a minute",
+        minute: "about a minute",
+        minutes: "%d minutes",
+        hour: "about an hour",
+        hours: "about %d hours",
+        day: "a day",
+        days: "%d days",
+        month: "about a month",
+        months: "%d months",
+        year: "about a year",
+        years: "%d years",
+        numbers: []
+      }
+    },
+    inWords: function(distanceMillis) {
+      var $l = this.settings.strings;
+      var prefix = $l.prefixAgo;
+      var suffix = $l.suffixAgo;
+      if (this.settings.allowFuture) {
+        if (distanceMillis < 0) {
+          prefix = $l.prefixFromNow;
+          suffix = $l.suffixFromNow;
+        }
+      }
+
+      var seconds = Math.abs(distanceMillis) / 1000;
+      var minutes = seconds / 60;
+      var hours = minutes / 60;
+      var days = hours / 24;
+      var years = days / 365;
+
+      function substitute(stringOrFunction, number) {
+        var string = $.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction;
+        var value = ($l.numbers && $l.numbers[number]) || number;
+        return string.replace(/%d/i, value);
+      }
+
+      var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) ||
+        seconds < 90 && substitute($l.minute, 1) ||
+        minutes < 45 && substitute($l.minutes, Math.round(minutes)) ||
+        minutes < 90 && substitute($l.hour, 1) ||
+        hours < 24 && substitute($l.hours, Math.round(hours)) ||
+        hours < 48 && substitute($l.day, 1) ||
+        days < 30 && substitute($l.days, Math.floor(days)) ||
+        days < 60 && substitute($l.month, 1) ||
+        days < 365 && substitute($l.months, Math.floor(days / 30)) ||
+        years < 2 && substitute($l.year, 1) ||
+        substitute($l.years, Math.floor(years));
+
+      return $.trim([prefix, words, suffix].join(" "));
+    },
+    parse: function(iso8601) {
+      var s = $.trim(iso8601);
+      s = s.replace(/\.\d\d\d+/,""); // remove milliseconds
+      s = s.replace(/-/,"/").replace(/-/,"/");
+      s = s.replace(/T/," ").replace(/Z/," UTC");
+      s = s.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400
+      return new Date(s);
+    },
+    datetime: function(elem) {
+      // jQuery's `is()` doesn't play well with HTML5 in IE
+      var isTime = $(elem).get(0).tagName.toLowerCase() === "time"; // $(elem).is("time");
+      var iso8601 = isTime ? $(elem).attr("datetime") : $(elem).attr("title");
+      return $t.parse(iso8601);
+    }
+  });
+
+  $.fn.timeago = function() {
+    var self = this;
+    self.each(refresh);
+
+    var $s = $t.settings;
+    if ($s.refreshMillis > 0) {
+      setInterval(function() { self.each(refresh); }, $s.refreshMillis);
+    }
+    return self;
+  };
+
+  function refresh() {
+    var data = prepareData(this);
+    if (!isNaN(data.datetime)) {
+      $(this).text(inWords(data.datetime));
+    }
+    return this;
+  }
+
+  function prepareData(element) {
+    element = $(element);
+    if (!element.data("timeago")) {
+      element.data("timeago", { datetime: $t.datetime(element) });
+      var text = $.trim(element.text());
+      if (text.length > 0) {
+        element.attr("title", text);
+      }
+    }
+    return element.data("timeago");
+  }
+
+  function inWords(date) {
+    return $t.inWords(distance(date));
+  }
+
+  function distance(date) {
+    return (new Date().getTime() - date.getTime());
+  }
+
+  // fix for IE6 suckage
+  document.createElement("abbr");
+  document.createElement("time");
+}(jQuery));
diff --git a/lib/shimmie.js b/lib/shimmie.js
index 6e72770c..258d592b 100644
--- a/lib/shimmie.js
+++ b/lib/shimmie.js
@@ -26,6 +26,7 @@ $(document).ready(function() {
 		$confirm.dialog('open');
 	});
 	
+	$("time").timeago();
 });
 
 var defaultTexts = new Array();

From 3b73013d1dccf84e67a3d4aa5f42611f71887be2 Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Mon, 26 Dec 2011 04:57:59 +0000
Subject: [PATCH 49/60] This should fix the "Undefined variable" error.

---
 themes/lite/view.theme.php | 1 +
 1 file changed, 1 insertion(+)

diff --git a/themes/lite/view.theme.php b/themes/lite/view.theme.php
index 0bb17d06..513e9fea 100644
--- a/themes/lite/view.theme.php
+++ b/themes/lite/view.theme.php
@@ -3,6 +3,7 @@
 class CustomViewImageTheme extends ViewImageTheme {
 	public function display_page($image, $editor_parts) {
 		global $page;
+		$metatags = str_replace(" ", ", ", html_escape($image->get_tag_list()));
 		$page->set_title("Image {$image->id}: ".html_escape($image->get_tag_list()));
 		$page->set_heading(html_escape($image->get_tag_list()));
 		$page->add_html_header("<meta name=\"keywords\" content=\"$metatags\">");

From c2ad8322efde3e1284e3810c06bf1cd5a75fed34 Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Mon, 26 Dec 2011 21:29:04 +0000
Subject: [PATCH 50/60] fixed downloading flash with bookmarklet + added
 comments

---
 ext/upload/theme.php | 32 ++++++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/ext/upload/theme.php b/ext/upload/theme.php
index 50895783..bc0991cc 100644
--- a/ext/upload/theme.php
+++ b/ext/upload/theme.php
@@ -27,7 +27,7 @@ class UploadTheme extends Themelet {
 					
 					if($i==0){
 						$upload_list .= "<div id='hide$i'><img id='wrapper' src='ext/upload/minus.png' />" .
-						"<a href='javascript:document.getElementById(&quot;row$a&quot;).style.display = &quot;&quot;;javascript:document.getElementById(&quot;hide$i&quot;).style.display = &quot;none&quot;;javascript:document.getElementById(&quot;hide$a&quot;).style.display = &quot;&quot;;'>".
+						"<a href='javascript:document.getElementById(&quot;row$a&quot;).style.display = &quot;&quot;;document.getElementById(&quot;hide$i&quot;).style.display = &quot;none&quot;;document.getElementById(&quot;hide$a&quot;).style.display = &quot;&quot;;'>".
 						"<img src='ext/upload/plus.png'></a></div></td>";
 					}else{
 						$upload_list .="<div id='hide$i'>
@@ -113,15 +113,31 @@ class UploadTheme extends Themelet {
 				{
 			/* Danbooru > Shimmie Bookmarklet.
 				This "should" work on any site running danbooru, unless for some odd reason they switched around the id's or aren't using post/list.
+				Most likely this will stop working when Danbooru updates to v2, all depends if they switch the ids or not >_>.
+				Clicking the link on a danbooru image page should give you something along the lines of:
+				'http://www.website.com/shimmie/upload?url="http://sonohara.donmai.us/data/crazylongurl.jpg&tags="too many tags"&rating="s"&source="http://danbooru.donmai.us/post/show/012345/"'
+				TODO: Possibly make the entire/most of the script into a .js file, and just make the bookmarklet load it on click (Something like that?)
 			*/
 			$title = "Danbooru to " . $config->get_string('title');
-			$html .= '<p><a href="javascript:var img=document.getElementById(&quot;highres&quot;).href;var ste=&quot;' .
-				$link . $delimiter . 'url=&quot;;var tag=document.getElementById(&quot;post_old_tags&quot;).value;var doc=document.documentElement.innerHTML;var rtg=doc.match(&quot;<li>Rating: (.*)<\/li>&quot;);var srx=&quot;http://&quot; + document.location.hostname + document.location.href.match(&quot;\/post\/show\/.*\/&quot;);' .
-				'if (confirm(&quot;OK = Use Current tags.\nCancel = Use new tags.&quot;)==true)' .
-				'{if(tag.search(/\bflash\b/)==-1){location.href=ste+img+&quot;&amp;tags=&quot;+tag+&quot;&rating=&quot;+rtg[1]+&quot;&amp;source=&quot;+srx;}else{location.href=ste+document.getElementsByName(&quot;movie&quot;)[0].value' .
-				'+&quot;&amp;tags=&quot;+tag+&quot;&amp;rating=&quot;+rtg[1]+&quot;&amp;source=&quot;+srx;}}else{var p=prompt(&quot;Enter Tags&quot;,&quot;&quot;);if(tag.search(/\bflash\b/)==-1){location.href=ste+img+&quot;&amp;tags=&quot;+p+&quot;&amp;rating=&quot;+rtg[1]+&quot;&amp;source=&quot;+srx;}' .
-				'else{location.href=ste+document.getElementsByName(&quot;movie&quot;)[0].value+&quot;&amp;tags=&quot;+p+&quot;&amp;rating=&quot;+rtg[1]+&quot;&amp;source=&quot;+srx;}}">' .
-				$title . '</a> (As above, Click on a Danbooru-run image page. (This also grabs the tags, rating & source!))';
+			$html .= '<p><a href="javascript:'.
+				/* This should stop the bookmarklet being insanely long...not that it's already huge or anything. */
+				'var ste=&quot;'. $link . $delimiter .'url=&quot;;var tag=document.getElementById(&quot;post_tags&quot;).value;var rtg=document.documentElement.innerHTML.match(&quot;<li>Rating: (.*)<\/li>&quot;);var srx=&quot;http://&quot; + document.location.hostname+document.location.href.match(&quot;\/post\/show\/.*\/&quot;);' .
+				//The default confirm sucks, mainly due to being unable to change the text in the Ok/Cancel box (Yes/No would be better.)
+				'if (confirm(&quot;OK = Use Current tags.\nCancel = Use new tags.&quot;)==true){' . //Just incase some people don't want the insane amount of tags danbooru has.
+					//The flash check is kind of picky, although it should work on "most" images..there will be either some old or extremely new ones that lack the flash tag.
+					'if(tag.search(/\bflash\b/)==-1){'.
+						'location.href=ste+document.getElementById(&quot;highres&quot;).href+&quot;&amp;tags=&quot;+tag+&quot;&amp;rating=&quot;+rtg[1]+&quot;&amp;source=&quot;+srx;}'.
+					'else{'.
+						'location.href=ste+document.getElementsByName(&quot;movie&quot;)[0].value+&quot;&amp;tags=&quot;+tag+&quot;&amp;rating=&quot;+rtg[1]+&quot;&amp;source=&quot;+srx;}'.
+				//The following is more or less the same as above, instead using the tags on danbooru, should load a prompt box instead.
+				'}else{'.
+					'var p=prompt(&quot;Enter Tags&quot;,&quot;&quot;);'.
+					'if(tag.search(/\bflash\b/)==-1){'.
+						'location.href=ste+document.getElementById(&quot;highres&quot;).href+&quot;&amp;tags=&quot;+p+&quot;&amp;rating=&quot;+rtg[1]+&quot;&amp;source=&quot;+srx;}' .
+					'else{'.
+						'location.href=ste+document.getElementsByName(&quot;movie&quot;)[0].value+&quot;&amp;tags=&quot;+p+&quot;&amp;rating=&quot;+rtg[1]+&quot;&amp;source=&quot;+srx;}'.
+				'}">' .
+				$title . '</a> (As above, Click on a Danbooru-run image page. (This also grabs the tags/rating/source!))';
 
 			}
 				

From d9e1b935b0dcad06df0b933c213886f6ba0c9ef7 Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Tue, 27 Dec 2011 12:10:01 +0000
Subject: [PATCH 51/60] +/- buttons should now work in FF, instead of directing
 you to blank page

---
 ext/upload/theme.php | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/ext/upload/theme.php b/ext/upload/theme.php
index bc0991cc..fae6501f 100644
--- a/ext/upload/theme.php
+++ b/ext/upload/theme.php
@@ -27,11 +27,11 @@ class UploadTheme extends Themelet {
 					
 					if($i==0){
 						$upload_list .= "<div id='hide$i'><img id='wrapper' src='ext/upload/minus.png' />" .
-						"<a href='javascript:document.getElementById(&quot;row$a&quot;).style.display = &quot;&quot;;document.getElementById(&quot;hide$i&quot;).style.display = &quot;none&quot;;document.getElementById(&quot;hide$a&quot;).style.display = &quot;&quot;;'>".
+						"<a href='#' onclick='javascript:document.getElementById(&quot;row$a&quot;).style.display = &quot;&quot;;document.getElementById(&quot;hide$i&quot;).style.display = &quot;none&quot;;document.getElementById(&quot;hide$a&quot;).style.display = &quot;&quot;;'>".
 						"<img src='ext/upload/plus.png'></a></div></td>";
 					}else{
 						$upload_list .="<div id='hide$i'>
-						<a href='javascript:document.getElementById(&quot;row$i&quot;).style.display = &quot;none&quot;;".
+						<a href='#' onclick='javascript:document.getElementById(&quot;row$i&quot;).style.display = &quot;none&quot;;".
 						"document.getElementById(&quot;hide$i&quot;).style.display = &quot;none&quot;;".
 						"document.getElementById(&quot;hide$s&quot;).style.display = &quot;&quot;;".
 						"document.getElementById(&quot;data$i&quot;).value = &quot;&quot;;".
@@ -41,7 +41,7 @@ class UploadTheme extends Themelet {
 							$upload_list .="<img id='wrapper' src='ext/upload/plus.png' />";
 							}else{
 							$upload_list .=
-							"<a href='javascript:document.getElementById(&quot;row$a&quot;).style.display = &quot;&quot;;".
+							"<a href='#' onclick='javascript:document.getElementById(&quot;row$a&quot;).style.display = &quot;&quot;;".
 							"document.getElementById(&quot;hide$i&quot;).style.display = &quot;none&quot;;".
 							"document.getElementById(&quot;hide$a&quot;).style.display = &quot;&quot;;'>".
 							"<img src='ext/upload/plus.png' /></a>";

From 12d4fcf813a6bee3c1b23ae0c790b498d65da693 Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Wed, 28 Dec 2011 03:11:36 +0000
Subject: [PATCH 52/60] related block should now change title depending on what
 tag list is set to

---
 ext/tag_list/theme.php | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/ext/tag_list/theme.php b/ext/tag_list/theme.php
index f0fac49b..54e35f28 100644
--- a/ext/tag_list/theme.php
+++ b/ext/tag_list/theme.php
@@ -52,8 +52,12 @@ class TagListTheme extends Themelet {
 				$html .= " <span class='tag_count'>$count</span>";
 			}
 		}
-
-		$page->add_block(new Block("Related", $html, "left"));
+		
+		if($config->get_string('tag_list_image_type')=="tags"){
+			$page->add_block(new Block("Tags", $html, "left"));}
+		else{
+			$page->add_block(new Block("Related Tags", $html, "left"));
+		}
 	}
 
 

From b9bd4db41e407da84dd25ec7343f4be6109a2451 Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Wed, 28 Dec 2011 03:13:14 +0000
Subject: [PATCH 53/60] Tag list should now show under the search block,
 instead of under every other block

---
 ext/tag_list/theme.php         | 4 ++--
 themes/danbooru/view.theme.php | 2 +-
 themes/lite/view.theme.php     | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/ext/tag_list/theme.php b/ext/tag_list/theme.php
index 54e35f28..99d83664 100644
--- a/ext/tag_list/theme.php
+++ b/ext/tag_list/theme.php
@@ -54,9 +54,9 @@ class TagListTheme extends Themelet {
 		}
 		
 		if($config->get_string('tag_list_image_type')=="tags"){
-			$page->add_block(new Block("Tags", $html, "left"));}
+			$page->add_block(new Block("Tags", $html, "left", 10));}
 		else{
-			$page->add_block(new Block("Related Tags", $html, "left"));
+			$page->add_block(new Block("Related Tags", $html, "left", 10));
 		}
 	}
 
diff --git a/themes/danbooru/view.theme.php b/themes/danbooru/view.theme.php
index e9538640..49663fa4 100644
--- a/themes/danbooru/view.theme.php
+++ b/themes/danbooru/view.theme.php
@@ -6,7 +6,7 @@ class CustomViewImageTheme extends ViewImageTheme {
 		$page->set_title("Image {$image->id}: ".html_escape($image->get_tag_list()));
 		$page->set_heading(html_escape($image->get_tag_list()));
 		$page->add_block(new Block("Navigation", $this->build_navigation($image), "left", 0));
-		$page->add_block(new Block("Statistics", $this->build_stats($image), "left", 10));
+		$page->add_block(new Block("Statistics", $this->build_stats($image), "left", 15));
 		$page->add_block(new Block(null, $this->build_image_editor($image, $editor_parts), "main", 10));
 		$page->add_block(new Block(null, $this->build_pin($image), "main", 11));
 	}
diff --git a/themes/lite/view.theme.php b/themes/lite/view.theme.php
index 513e9fea..5eb9d195 100644
--- a/themes/lite/view.theme.php
+++ b/themes/lite/view.theme.php
@@ -12,7 +12,7 @@ class CustomViewImageTheme extends ViewImageTheme {
 		$page->add_html_header("<meta property=\"og:image\" content=\"".make_http($image->get_thumb_link())."\">");
 		$page->add_html_header("<meta property=\"og:url\" content=\"".make_http(make_link("post/view/{$image->id}"))."\">");
 		$page->add_block(new Block("Navigation", $this->build_navigation($image), "left", 0));
-		$page->add_block(new Block("Statistics", $this->build_stats($image), "left", 10));
+		$page->add_block(new Block("Statistics", $this->build_stats($image), "left", 15));
 		$page->add_block(new Block(null, $this->build_image_editor($image, $editor_parts), "main", 10));
 		$page->add_block(new Block(null, $this->build_pin($image), "main", 11));
 	}

From dc4d156e1a0184ec2e8fc7ab7905e37b744746cc Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Wed, 28 Dec 2011 14:47:02 +0000
Subject: [PATCH 54/60] contact link should now properly link to email

---
 contrib/home/theme.php              | 2 +-
 themes/danbooru/layout.class.php    | 2 +-
 themes/default/layout.class.php     | 2 +-
 themes/flat/layout.class.php        | 2 +-
 themes/futaba/layout.class.php      | 2 +-
 themes/lite/layout.class.php        | 2 +-
 themes/old_default/layout.class.php | 2 +-
 themes/warm/layout.class.php        | 2 +-
 8 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/contrib/home/theme.php b/contrib/home/theme.php
index 1fe601ff..21364625 100644
--- a/contrib/home/theme.php
+++ b/contrib/home/theme.php
@@ -47,7 +47,7 @@ EOD
 			$counter_html
 			<div class='space' id='foot'>
 				<small><small>
-				<a href='$contact_link'>Contact</a> &ndash; Serving $num_comma posts &ndash;
+				<a href='mailto:$contact_link'>Contact</a> &ndash; Serving $num_comma posts &ndash;
 				Running <a href='http://code.shishnet.org/shimmie2/'>Shimmie</a>
 				</small></small>
 			</div>
diff --git a/themes/danbooru/layout.class.php b/themes/danbooru/layout.class.php
index 5045adcc..cfdcc91f 100644
--- a/themes/danbooru/layout.class.php
+++ b/themes/danbooru/layout.class.php
@@ -88,7 +88,7 @@ class Layout {
 
 		$debug = get_debug_info();
 
-		$contact = empty($contact_link) ? "" : "<br><a href='$contact_link'>Contact</a>";
+		$contact = empty($contact_link) ? "" : "<br><a href='mailto:$contact_link'>Contact</a>";
 
 		if(empty($this->subheading)) {
 			$subheading = "";
diff --git a/themes/default/layout.class.php b/themes/default/layout.class.php
index 3ee91b82..0c733c1b 100644
--- a/themes/default/layout.class.php
+++ b/themes/default/layout.class.php
@@ -42,7 +42,7 @@ class Layout {
 
 		$debug = get_debug_info();
 
-		$contact = empty($contact_link) ? "" : "<br><a href='$contact_link'>Contact</a>";
+		$contact = empty($contact_link) ? "" : "<br><a href='mailto:$contact_link'>Contact</a>";
 
 		$wrapper = "";
 		if(strlen($page->heading) > 100) {
diff --git a/themes/flat/layout.class.php b/themes/flat/layout.class.php
index f0e9a95b..c4fe7a05 100644
--- a/themes/flat/layout.class.php
+++ b/themes/flat/layout.class.php
@@ -42,7 +42,7 @@ class Layout {
 
 		$debug = get_debug_info();
 
-		$contact = empty($contact_link) ? "" : "<br><a href='$contact_link'>Contact</a>";
+		$contact = empty($contact_link) ? "" : "<br><a href='mailto:$contact_link'>Contact</a>";
 		$subheading = empty($page->subheading) ? "" : "<div id='subtitle'>{$page->subheading}</div>";
 
 		$wrapper = "";
diff --git a/themes/futaba/layout.class.php b/themes/futaba/layout.class.php
index 51f76716..21dacbc5 100644
--- a/themes/futaba/layout.class.php
+++ b/themes/futaba/layout.class.php
@@ -37,7 +37,7 @@ class Layout {
 
 		$debug = get_debug_info();
 
-		$contact = empty($contact_link) ? "" : "<br><a href='$contact_link'>Contact</a>";
+		$contact = empty($contact_link) ? "" : "<br><a href='mailto:$contact_link'>Contact</a>";
 
 		if(empty($page->subheading)) {
 			$subheading = "";
diff --git a/themes/lite/layout.class.php b/themes/lite/layout.class.php
index c7273ab3..5053515f 100644
--- a/themes/lite/layout.class.php
+++ b/themes/lite/layout.class.php
@@ -138,7 +138,7 @@ class Layout {
 
 		$debug = get_debug_info();
 
-		$contact = empty($contact_link) ? "" : "<br><a href='$contact_link'>Contact</a>";
+		$contact = empty($contact_link) ? "" : "<br><a href='mailto:$contact_link'>Contact</a>";
 		$subheading = empty($page->subheading) ? "" : "<div id='subtitle'>{$page->subheading}</div>";
 
 		$wrapper = "";
diff --git a/themes/old_default/layout.class.php b/themes/old_default/layout.class.php
index cb4e6952..5dff2b59 100644
--- a/themes/old_default/layout.class.php
+++ b/themes/old_default/layout.class.php
@@ -37,7 +37,7 @@ class Layout {
 
 		$debug = get_debug_info();
 
-		$contact = empty($contact_link) ? "" : "<br><a href='$contact_link'>Contact</a>";
+		$contact = empty($contact_link) ? "" : "<br><a href='mailto:$contact_link'>Contact</a>";
 		$subheading = empty($page->subheading) ? "" : "<div id='subtitle'>{$page->subheading}</div>";
 
 		$wrapper = "";
diff --git a/themes/warm/layout.class.php b/themes/warm/layout.class.php
index c843eb3a..680bdcc4 100644
--- a/themes/warm/layout.class.php
+++ b/themes/warm/layout.class.php
@@ -47,7 +47,7 @@ class Layout {
 
 		$debug = get_debug_info();
 
-		$contact = empty($contact_link) ? "" : "<br><a href='$contact_link'>Contact</a>";
+		$contact = empty($contact_link) ? "" : "<br><a href='mailto:$contact_link'>Contact</a>";
 		$subheading = empty($page->subheading) ? "" : "<div id='subtitle'>{$page->subheading}</div>";
 
 		$wrapper = "";

From dff1eef51a0efd17ff7b698470aa506d1d24a737 Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Thu, 29 Dec 2011 22:55:44 +0000
Subject: [PATCH 55/60] make_form now has a onsubmit option

---
 core/util.inc.php | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/core/util.inc.php b/core/util.inc.php
index 71a317f3..6c727710 100644
--- a/core/util.inc.php
+++ b/core/util.inc.php
@@ -254,13 +254,16 @@ function make_http($link) {
  *
  * @retval string
  */
-function make_form($target, $method="POST", $multipart=False, $form_id="") {
+function make_form($target, $method="POST", $multipart=False, $form_id="", $onsubmit="") {
 	global $user;
 	$auth = $user->get_auth_html();
 	$extra = empty($form_id) ? '' : " id='$form_id'";
 	if($multipart) {
 		$extra .= " enctype='multipart/form-data'";
 	}
+	if($onsubmit) {
+		$extra .= " onsubmit='$onsubmit'";
+	}
 	return "<form action='$target' method='$method'$extra>$auth";
 }
 

From 0d93f29bce8907e7412f304a694cf84b0ba80ed2 Mon Sep 17 00:00:00 2001
From: Daku <dakutree@gmail.com>
Date: Thu, 29 Dec 2011 23:05:09 +0000
Subject: [PATCH 56/60] Delete by Query now requires you to enable the form,
 aswell as confirm the deletion.

---
 contrib/admin/theme.php | 32 ++++++++++++++++++++++++++++----
 1 file changed, 28 insertions(+), 4 deletions(-)

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

From c39697a40f25564d1152aa84b015042e752f4b5b Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sat, 31 Dec 2011 14:21:02 +0000
Subject: [PATCH 57/60] stub for comment time-ago

---
 ext/comment/theme.php    | 1 +
 themes/default/style.css | 4 ++++
 2 files changed, 5 insertions(+)

diff --git a/ext/comment/theme.php b/ext/comment/theme.php
index f48a7b25..264cd67b 100644
--- a/ext/comment/theme.php
+++ b/ext/comment/theme.php
@@ -179,6 +179,7 @@ class CommentListTheme extends Themelet {
 			return "
 				<a name='$i_comment_id'></a>
 				<div class='$oe comment'>
+				<!--<span class='timeago' style='float: right;'>$h_timestamp</span>-->
 				$h_userlink: $h_comment
 				$h_dellink
 				</div>
diff --git a/themes/default/style.css b/themes/default/style.css
index 811fc9d7..db384169 100644
--- a/themes/default/style.css
+++ b/themes/default/style.css
@@ -128,6 +128,10 @@ UL {
 .comment {
 	text-align: left;
 }
+.comment .timeago {
+	float: right;
+	font-size: 75%;
+}
 
 .more:after {
 	content: " >>>";

From 56a780bfd380fb20e93fb98efc89e1933ecbfe35 Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sun, 1 Jan 2012 16:54:44 +0000
Subject: [PATCH 58/60] in per-letter mode, don't separate a and A

---
 core/database.class.php | 3 +++
 ext/tag_list/main.php   | 6 +++---
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/core/database.class.php b/core/database.class.php
index 69d54e9e..53ed4b4d 100644
--- a/core/database.class.php
+++ b/core/database.class.php
@@ -75,6 +75,7 @@ class MySQL extends DBEngine {
 		$data = str_replace("SCORE_DATETIME", "DATETIME", $data);
 		$data = str_replace("SCORE_NOW", "\"1970-01-01\"", $data);
 		$data = str_replace("SCORE_STRNORM", "", $data);
+		$data = str_replace("SCORE_ILIKE", "LIKE", $data);
 		return $data;
 	}
 
@@ -96,6 +97,7 @@ class PostgreSQL extends DBEngine {
 		$data = str_replace("SCORE_DATETIME", "TIMESTAMP", $data);
 		$data = str_replace("SCORE_NOW", "current_time", $data);
 		$data = str_replace("SCORE_STRNORM", "lower", $data);
+		$data = str_replace("SCORE_ILIKE", "ILIKE", $data);
 		return $data;
 	}
 
@@ -142,6 +144,7 @@ class SQLite extends DBEngine {
 		$data = str_replace("SCORE_BOOL", "CHAR(1)", $data);
 		$data = str_replace("SCORE_NOW", "\"1970-01-01\"", $data);
 		$data = str_replace("SCORE_STRNORM", "", $data);
+		$data = str_replace("SCORE_ILIKE", "LIKE", $data);
 		$cols = array();
 		$extras = "";
 		foreach(explode(",", $data) as $bit) {
diff --git a/ext/tag_list/main.php b/ext/tag_list/main.php
index dcdf3b2c..1e71be3b 100644
--- a/ext/tag_list/main.php
+++ b/ext/tag_list/main.php
@@ -141,7 +141,7 @@ class TagList implements Extension {
 
 		$tag_data = $database->get_col("
 			SELECT DISTINCT
-				substr(tag, 1, 1)
+				SCORE_STRNORM(substr(tag, 1, 1))
 			FROM tags
 			WHERE count >= :tags_min
 			ORDER BY tag
@@ -183,7 +183,7 @@ class TagList implements Extension {
 					FLOOR(LOG(2.7, LOG(2.7, count - :tags_min + 1)+1)*1.5*100)/100 AS scaled
 				FROM tags
 				WHERE count >= :tags_min
-				AND tag LIKE :starts_with
+				AND tag SCORE_ILIKE :starts_with
 				ORDER BY tag
 			", array("tags_min"=>$tags_min, "starts_with"=>$starts_with));
 
@@ -215,7 +215,7 @@ class TagList implements Extension {
 				SELECT tag, count
 				FROM tags
 				WHERE count >= :tags_min
-				AND tag LIKE :starts_with
+				AND tag SCORE_ILIKE :starts_with
 				ORDER BY tag
 				", array("tags_min"=>$tags_min, "starts_with"=>$starts_with));
 

From 5b717870d1ee8a5b53e643f1c31f92b372c96717 Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sun, 1 Jan 2012 17:13:50 +0000
Subject: [PATCH 59/60] case sensitivity blargh

---
 core/util.inc.php     |  6 +++++-
 ext/tag_list/main.php | 23 +++++++++--------------
 2 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/core/util.inc.php b/core/util.inc.php
index 6c727710..25e020f9 100644
--- a/core/util.inc.php
+++ b/core/util.inc.php
@@ -204,6 +204,10 @@ function make_link($page=null, $query=null) {
  * @retval string
  */
 function modify_current_url($changes) {
+	return modify_url($_SERVER['QUERY_STRING'], $changes);
+}
+
+function modify_url($url, $changes) {
 	// SHIT: PHP is officially the worst web API ever because it does not
 	// have a built-in function to do this.
 
@@ -212,7 +216,7 @@ function modify_current_url($changes) {
 	// whatever data the user supplied. Thankfully, 4.0.3 added an extra option to
 	// give it an array to use...
 	$params = array();
-	parse_str($_SERVER['QUERY_STRING'], $params);
+	parse_str($url, $params);
 
 	if(isset($changes['q'])) {
 		$base = $changes['q'];
diff --git a/ext/tag_list/main.php b/ext/tag_list/main.php
index 0b1c537e..7efb1223 100644
--- a/ext/tag_list/main.php
+++ b/ext/tag_list/main.php
@@ -136,16 +136,13 @@ class TagList implements Extension {
 
 		$tags_min = $this->get_tags_min();
 
-		$cache_key = "data/tag_inits-" . md5("tc" . $tags_min) . ".html";
-		if(file_exists($cache_key)) {return file_get_contents($cache_key);}
-
-		$tag_data = $database->get_col("
+		$tag_data = $database->get_col($database->engine->scoreql_to_sql("
 			SELECT DISTINCT
 				SCORE_STRNORM(substr(tag, 1, 1))
 			FROM tags
 			WHERE count >= :tags_min
-			ORDER BY substr(tag, 1, 1)
-		", array("tags_min"=>$tags_min));
+			ORDER BY SCORE_STRNORM(substr(tag, 1, 1))
+		"), array("tags_min"=>$tags_min));
 
 		$html = "";
 		foreach($tag_data as $a) {
@@ -153,8 +150,6 @@ class TagList implements Extension {
 		}
 		$html .= "<p><hr>";
 
-		if(SPEED_HAX) {file_put_contents($cache_key, $html);}
-
 		return $html;
 	}
 // }}}
@@ -178,15 +173,15 @@ class TagList implements Extension {
 		if(file_exists($cache_key)) {return file_get_contents($cache_key);}
 
 		// SHIT: PDO/pgsql has problems using the same named param twice -_-;;
-		$tag_data = $database->get_all("
+		$tag_data = $database->get_all($database->engine->scoreql_to_sql("
 				SELECT
 					tag,
 					FLOOR(LOG(2.7, LOG(2.7, count - :tags_min2 + 1)+1)*1.5*100)/100 AS scaled
 				FROM tags
 				WHERE count >= :tags_min
 				AND tag SCORE_ILIKE :starts_with
-				ORDER BY tag
-			", array("tags_min"=>$tags_min, "tags_min2"=>$tags_min, "starts_with"=>$starts_with));
+				ORDER BY SCORE_STRNORM(tag)
+			"), array("tags_min"=>$tags_min, "tags_min2"=>$tags_min, "starts_with"=>$starts_with));
 
 		$html = "";
 		if($config->get_bool("tag_list_pages")) $html .= $this->build_az();
@@ -212,13 +207,13 @@ class TagList implements Extension {
 		$cache_key = "data/tag_alpha-" . md5("ta" . $tags_min . $starts_with) . ".html";
 		if(file_exists($cache_key)) {return file_get_contents($cache_key);}
 
-		$tag_data = $database->get_all("
+		$tag_data = $database->get_all($database->engine->scoreql_to_sql("
 				SELECT tag, count
 				FROM tags
 				WHERE count >= :tags_min
 				AND tag SCORE_ILIKE :starts_with
-				ORDER BY tag
-				", array("tags_min"=>$tags_min, "starts_with"=>$starts_with));
+				ORDER BY SCORE_STRNORM(tag)
+				"), array("tags_min"=>$tags_min, "starts_with"=>$starts_with));
 
 		$html = "";
 		if($config->get_bool("tag_list_pages")) $html .= $this->build_az();

From 8cfa72d7cf69b5dc09630ce12135a647913a7ead Mon Sep 17 00:00:00 2001
From: Shish <shish@shishnet.org>
Date: Sun, 1 Jan 2012 20:36:51 +0000
Subject: [PATCH 60/60] copyright bumps

---
 themes/danbooru/layout.class.php    | 2 +-
 themes/default/layout.class.php     | 2 +-
 themes/flat/layout.class.php        | 2 +-
 themes/futaba/layout.class.php      | 2 +-
 themes/lite/layout.class.php        | 2 +-
 themes/old_default/layout.class.php | 2 +-
 themes/warm/layout.class.php        | 2 +-
 7 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/themes/danbooru/layout.class.php b/themes/danbooru/layout.class.php
index cfdcc91f..8781bbd4 100644
--- a/themes/danbooru/layout.class.php
+++ b/themes/danbooru/layout.class.php
@@ -219,7 +219,7 @@ $header_html
         <em>
 			Images &copy; their respective owners,
 			<a href="http://code.shishnet.org/shimmie2/">Shimmie</a> &copy;
-			<a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2011,
+			<a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2012,
 			based on the Danbooru concept.
 			$debug
 			$contact
diff --git a/themes/default/layout.class.php b/themes/default/layout.class.php
index 0c733c1b..3846c72c 100644
--- a/themes/default/layout.class.php
+++ b/themes/default/layout.class.php
@@ -71,7 +71,7 @@ $header_html
 		<div id="footer">
 			Images &copy; their respective owners,
 			<a href="http://code.shishnet.org/shimmie2/">Shimmie</a> &copy;
-			<a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2011,
+			<a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2012,
 			based on the Danbooru concept.
 			$debug
 			$contact
diff --git a/themes/flat/layout.class.php b/themes/flat/layout.class.php
index c4fe7a05..91b24ebf 100644
--- a/themes/flat/layout.class.php
+++ b/themes/flat/layout.class.php
@@ -71,7 +71,7 @@ $header_html
 		<div id="footer">
 			Images &copy; their respective owners,
 			<a href="http://code.shishnet.org/shimmie2/">Shimmie</a> &copy;
-			<a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2011,
+			<a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2012,
 			based on the Danbooru concept.
 			$debug
 			$contact
diff --git a/themes/futaba/layout.class.php b/themes/futaba/layout.class.php
index 21dacbc5..3ca6727e 100644
--- a/themes/futaba/layout.class.php
+++ b/themes/futaba/layout.class.php
@@ -79,7 +79,7 @@ $header_html
 			<hr>
 			Images &copy; their respective owners,
 			<a href="http://code.shishnet.org/shimmie2/">Shimmie</a> &copy;
-			<a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2011,
+			<a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2012,
 			based on the Danbooru concept.
 			<br>Futaba theme based on 4chan's layout and CSS :3
 			$debug
diff --git a/themes/lite/layout.class.php b/themes/lite/layout.class.php
index 5053515f..00fd54c9 100644
--- a/themes/lite/layout.class.php
+++ b/themes/lite/layout.class.php
@@ -176,7 +176,7 @@ class Layout {
 		<div id="footer">
 			Images &copy; their respective owners,
 			<a href="http://code.shishnet.org/shimmie2/">Shimmie</a> &copy;
-			<a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2011,
+			<a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2012,
 			based on the Danbooru concept.<br />
 			Lite Theme by <a href="http://seemslegit.com">Zach</a>
 			$debug
diff --git a/themes/old_default/layout.class.php b/themes/old_default/layout.class.php
index 5dff2b59..1e5325cb 100644
--- a/themes/old_default/layout.class.php
+++ b/themes/old_default/layout.class.php
@@ -69,7 +69,7 @@ $header_html
 			<hr>
 			Images &copy; their respective owners,
 			<a href="http://code.shishnet.org/shimmie2/">Shimmie</a> &copy;
-			<a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2011,
+			<a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2012,
 			based on the Danbooru concept.
 			$debug
 			$contact
diff --git a/themes/warm/layout.class.php b/themes/warm/layout.class.php
index 680bdcc4..e60a7e4a 100644
--- a/themes/warm/layout.class.php
+++ b/themes/warm/layout.class.php
@@ -85,7 +85,7 @@ $header_html
 		<div id="footer">
 			Images &copy; their respective owners,
 			<a href="http://code.shishnet.org/shimmie2/">Shimmie</a> &copy;
-			<a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2011,
+			<a href="http://www.shishnet.org/">Shish</a> &amp; Co 2007-2012,
 			based on the Danbooru concept.
 			$debug
 			$contact