diff --git a/.gitignore b/.gitignore
index e0874880..d583e74d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,6 +35,7 @@ ext/image_hash_ban
ext/ipban
ext/link_image
ext/log_db
+ext/mass_tagger
ext/news
ext/notes
ext/numeric_score
diff --git a/contrib/mass_tagger/main.php b/contrib/mass_tagger/main.php
new file mode 100644
index 00000000..65276e20
--- /dev/null
+++ b/contrib/mass_tagger/main.php
@@ -0,0 +1,60 @@
+
+ * License: WTFPL
+ * Description: Tag a bunch of images at once
+ * Documentation:
+ * Once enabled, a new "Mass Tagger" box will appear on the left hand side of
+ * post listings, with a button to enable the mass tagger. Once clicked JS will
+ * add buttons to each image to mark them for tagging, and a field for
+ * inputting tags will appear. Once the "Tag" button is clicked, the tags in
+ * the text field will be added to marked images.
+ *
+ * As of now only compatible with the lite theme.
+ */
+
+class MassTagger extends SimpleExtension {
+ public function onInitExt($event) {
+ return;
+ }
+
+ public function onPostListBuilding($event) {
+ global $config, $page, $user;
+
+ if( !$user->is_admin() ) return;
+
+ $this->theme->display_mass_tagger( $page, $event, $config );
+ }
+
+ public function onPageRequest($event) {
+ global $config, $page, $user;
+ if( !$event->page_matches("mass_tagger") ) return;
+ if( !$user->is_admin() ) return;
+
+ if($event->get_arg(0) == "tag") $this->_apply_mass_tags( $config, $page, $user, $event );
+ }
+
+ private function _apply_mass_tags( $config, $page, $user, $event ) {
+
+ if( !isset($_POST['ids']) or !isset($_POST['tag']) ) return;
+
+ $tag = $_POST['tag'];
+ $ids = explode( ':', $_POST['ids'] );
+ $ids = array_filter ( $ids , 'is_numeric' );
+
+ $ids = array_map( "Image::by_id", $ids );
+
+ $func = function( $image ) use ( $tag ) {
+ $tag .= " " . $image->get_tag_list();
+ $image->set_tags( $tag );
+ };
+ array_walk( $ids, $func );
+
+ $page->set_mode("redirect");
+ $page->set_redirect(make_link("post/list"));
+
+ }
+
+}
+?>
diff --git a/contrib/mass_tagger/script.js b/contrib/mass_tagger/script.js
new file mode 100644
index 00000000..e2ee466e
--- /dev/null
+++ b/contrib/mass_tagger/script.js
@@ -0,0 +1,68 @@
+
+function toggle_tag( button, id ) {
+ id += ":";
+ var list = $('#mass_tagger_ids');
+ var string = list.val();
+
+ if( string.indexOf( id ) > -1 ) return remove_mass_tag_id( button, list, id, string );
+
+ return add_mass_tag_id( button, list, id, string );
+}
+
+function add_mass_tag_id( button, list, id, string ) {
+ $(button).attr( 'style', 'display:block;border: 3px solid blue;' );
+ string += id;
+ list.val( string );
+ return false;
+}
+
+function remove_mass_tag_id( button, list, id, string ) {
+ $(button).attr( 'style', '' );
+ string = string.replace( id, '' );
+ list.val( string );
+ return false;
+}
+
+function activate_mass_tagger ( image_link ) {
+
+ find_thumb_link_containers().each(
+ function ( index, block ) {
+ add_mass_tag_button( block, image_link );
+ }
+ );
+ $('#mass_tagger_controls').attr( 'style', 'display:block' );
+ $('#mass_tagger_activate').attr( 'style', 'display:none' );
+
+ return false;
+}
+
+function add_mass_tag_button ( block, image_link ) {
+
+ var id = get_image_id( block );
+
+ var button = create_mass_tag_button( id, image_link );
+ $(block).append( button );
+
+ return;
+}
+
+function get_image_id ( block ) {
+ var link = $(block).children(":first").attr('href');
+ var id = link.split('/').pop();
+
+ return id;
+}
+
+function create_mass_tag_button ( id, image_link ) {
+ var img = $('');
+ img.attr( "src", image_link+'/ext/mass_tagger/toggle.gif' );
+
+ var link = $('');
+ link.attr("class",'zoom');
+ link.attr("onclick",'return toggle_tag( this, "'+id+'")');
+ link.attr("href",'#');
+
+ link.append( img );
+
+ return link;
+}
diff --git a/contrib/mass_tagger/style.css b/contrib/mass_tagger/style.css
new file mode 100644
index 00000000..13467ae1
--- /dev/null
+++ b/contrib/mass_tagger/style.css
@@ -0,0 +1,8 @@
+
+.zoom{ position:absolute;display:none;margin:-110px 27px; }
+.thumbblock:hover .zoom{ display:block; }
+.zoom:hover{ border: 3px solid blue; }
+/*.zoom img:hover{ background:url(/contrib/simpletest/data/pbx_screenshot.jpg) no-repeat;}*/
+
+.zoom img { width: 100px; height: 100px; }
+#mass_tagger_controls { display:none; }
diff --git a/contrib/mass_tagger/theme.php b/contrib/mass_tagger/theme.php
new file mode 100644
index 00000000..28197b3e
--- /dev/null
+++ b/contrib/mass_tagger/theme.php
@@ -0,0 +1,26 @@
+
+
+