more extensions
git-svn-id: file:///home/shish/svn/shimmie2/branches/branch_2.1@649 7f39781d-f577-437e-ae19-be835c7a54ca
This commit is contained in:
		
							parent
							
								
									91139cb688
								
							
						
					
					
						commit
						0836574070
					
				
							
								
								
									
										114
									
								
								contrib/browser_search/main.php
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										114
									
								
								contrib/browser_search/main.php
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,114 @@ | ||||
| <?php | ||||
| /** | ||||
|  * Name: Browser Search | ||||
|  * Author: ATravelingGeek <atg@atravelinggeek.com> | ||||
|  * Some code (and lots of help) by Artanis (Erik Youngren <artanis.00@gmail.com>) from the 'tagger' extention - Used with permission | ||||
|  * Link: http://atravelinggeek.com/ | ||||
|  * License: GPLv2 | ||||
|  * Description: Allows the user to add a browser 'plugin' to search the site with real-time suggestions | ||||
|  * Version 0.1c | ||||
|  * October 26, 2007 | ||||
|  * | ||||
|  */ | ||||
|   | ||||
| class BrowserSearch extends Extension { | ||||
| 	public function receive_event($event) { | ||||
| 	global $page; | ||||
| 	global $config; | ||||
| 	 | ||||
| 		if(is_a($event, 'InitExtEvent')) { | ||||
| 			$config->set_default_string("search_suggestions_results_order", 'a'); | ||||
| 		} | ||||
| 	 | ||||
| 		// Add in header code to let the browser know that the search plugin exists
 | ||||
| 		if(is_a($event, 'PageRequestEvent')) { | ||||
| 			// We need to build the data for the header
 | ||||
| 			global $config; | ||||
| 			$search_title = $config->get_string('title'); | ||||
| 			$search_file_url = make_link('browser_search/please_dont_use_this_tag_as_it_would_break_stuff__search.xml'); | ||||
| 			$page->add_header("<link rel='search' type='application/opensearchdescription+xml' title='$search_title' href='$search_file_url'>"); | ||||
| 		} | ||||
| 		 | ||||
| 		// The search.xml file that is generated on the fly
 | ||||
| 		if(is_a($event, 'PageRequestEvent') && ($event->page_name == "browser_search") && $event->get_arg(0) == "please_dont_use_this_tag_as_it_would_break_stuff__search.xml") { | ||||
| 			// First, we need to build all the variables we'll need
 | ||||
| 			 | ||||
| 			$search_title = $config->get_string('title'); | ||||
| 			//$search_form_url =  $config->get_string('base_href'); //make_link('post/list');
 | ||||
| 			$search_form_url =  make_link('post/list/{searchTerms}'); | ||||
| 			$suggenton_url = make_link('browser_search/')."{searchTerms}"; | ||||
| 			 | ||||
| 			 | ||||
| 			// Now for the XML
 | ||||
| 			$xml = " | ||||
| 				<SearchPlugin xmlns='http://www.mozilla.org/2006/browser/search/' xmlns:os='http://a9.com/-/spec/opensearch/1.1/'> | ||||
| 				<os:ShortName>$search_title</os:ShortName> | ||||
| 				<os:InputEncoding>UTF-8</os:InputEncoding> | ||||
| 				<os:Image width='16'  | ||||
| 				height='16'>data:image/x-icon;base64,AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWFhYAfX19AH9/fwCAgIAAgYGBAIODgwCEhIQAhoaGAIeHhwCJiYkAioqKAIyMjACPj48AkJCQAJKSkgCTk5MAlZWVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEREREREREREREREREREREREAAAAAAAAAAAAAABERERERAAEBAQEBAQEBAQAAEREREQABAQEBAQEBAQEAAQAREREAAQEBAQEBAQEBAAEBABERAAEBAQEBAQEBAQABAQAREQAGBgUEAwIBAQEAAgEAEREADAwMCwsKCQkHAAkIABERABAQEBAQEA4ODAANDQAREQAQEBAQEBAQEBAAEBAAEREAEBAQEBAQEBAQABAQABERAAAAAAAAAAAAAAAQEAAREREAEBAPEBAQEBAQABAAEREREQAQEBAQEBAPEBAAABERERERAAAAAAAAAAAAAAAREREREREREREREREREREREf//AACADwAAgAcAAIADAACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAMABAADgAQAA8AEAAP//AAA=</os:Image>
 | ||||
| 				<SearchForm>$search_form_url</SearchForm> | ||||
| 				<os:Url type='text/html' method='GET' template='$search_form_url'> | ||||
| 				  <os:Param name='search' value='{searchTerms}'/> | ||||
| 				</os:Url> | ||||
| 				<Url type='application/x-suggestions+json' template='$suggenton_url'/> | ||||
| 				</SearchPlugin> | ||||
| 			";
 | ||||
| 			 | ||||
| 			// And now to send it to the browser
 | ||||
| 			$page->set_mode("data"); | ||||
| 			$page->set_type("text/xml"); | ||||
| 			$page->set_data($xml); | ||||
| 		} else if(is_a($event, 'PageRequestEvent') && ($event->page_name == "browser_search") && !$config->get_bool("disable_search_suggestions")) { // We need to return results!
 | ||||
| 			global $database; | ||||
| 			 | ||||
| 			// We have to build some json stuff
 | ||||
| 			$tag_search = $event->get_arg(0); | ||||
| 			 | ||||
| 			// Now to get DB results
 | ||||
| 			if($config->get_string("search_suggestions_results_order") == "a") {		 | ||||
| 				$tags = $database->execute("SELECT tag FROM tags WHERE tag LIKE ? AND count > 0 ORDER BY tag ASC LIMIT 30",array($tag_search."%")); | ||||
| 			} else { | ||||
| 				$tags = $database->execute("SELECT tag FROM tags WHERE tag LIKE ? AND count > 0 ORDER BY count DESC LIMIT 30",array($tag_search."%")); | ||||
| 			} | ||||
| 			 | ||||
| 			 | ||||
| 			// And to do stuff with it. We want our output to look like:
 | ||||
| 			// ["shimmie",["shimmies","shimmy","shimmie","21 shimmies","hip shimmies","skea shimmies"],[],[]]
 | ||||
| 			$json_tag_list = ""; | ||||
| 			 | ||||
| 			$tags_array = array(); | ||||
| 			foreach($tags as $tag) { | ||||
| 				array_push($tags_array,$tag['tag']); | ||||
| 			} | ||||
| 			 | ||||
| 			 | ||||
| 			$json_tag_list .= implode("\",\"", $tags_array); | ||||
| //			$json_tag_list = implode($tags_array,", ");
 | ||||
| //			$json_tag_list = "\"".implode($tags_array,"\", \"")."\"";
 | ||||
| 
 | ||||
| 			 | ||||
| 			// And now for the final output
 | ||||
| 			$json_string = "[\"$tag_search\",[\"$json_tag_list\"],[],[]]";
 | ||||
| 			$page->set_mode("data"); | ||||
| 			$page->set_data($json_string); | ||||
| 		} | ||||
| 		 | ||||
| 		if(is_a($event, 'SetupBuildingEvent')) { | ||||
| 		 | ||||
| 			$sort_by = array(); | ||||
| 			$sort_by['Alphabetical'] = 'a'; | ||||
| 			$sort_by['Tag Count'] = 't'; | ||||
| 		 | ||||
| 			$sb = new SetupBlock("Browser Search"); | ||||
| 			$sb->add_bool_option("disable_search_suggestions", "Disable search suggestions when using browser-based search: "); | ||||
| 			$sb->add_label("<br>"); | ||||
| 			$sb->add_choice_option("search_suggestions_results_order", $sort_by, "Sort the suggestions by:"); | ||||
| 			$event->panel->add_block($sb); | ||||
| 		} | ||||
| 		 | ||||
| 	} | ||||
| 	 | ||||
| 
 | ||||
| } | ||||
| add_event_listener(new BrowserSearch()); | ||||
| ?>
 | ||||
							
								
								
									
										427
									
								
								contrib/danbooru_api/main.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										427
									
								
								contrib/danbooru_api/main.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,427 @@ | ||||
| <?php | ||||
| /* | ||||
| Name: Danbooru Client API for Shimmie2 | ||||
| Description: Provides simple interfaces for third party software to interact with Shimmie via | ||||
| simple HTTP GET/POST requests. | ||||
| 
 | ||||
| Author: JJS <jsutinen@gmail.com> | ||||
| Notes: | ||||
| danbooru API based on documentation from danbooru 1.0 - http://attachr.com/7569 | ||||
| I've only been able to test add_post and find_tags because I use the old danbooru firefox extension for firefox 1.5 | ||||
| 
 | ||||
| Functions currently implemented: | ||||
| add_comment - NOT DONE YET, waiting on some backend shimmie code :) | ||||
| add_post - title and rating are currently ignored because shimmie does not support them | ||||
| find_posts - sort of works, filename is returned as the original filename and probably won't help when it comes to actually downloading it | ||||
| find_tags - id, name, and after_id all work but the tags parameter is ignored just like danbooru 1.0 ignores it | ||||
| 
 | ||||
| CHANGELOG | ||||
| 21-OCT-07 9:07PM CST - JJS | ||||
| Turns out I actually did need to implement the new parameter names | ||||
| for danbooru api v1.8.1. Now danbooruup should work when used with /api/danbooru/post/create.xml | ||||
| Also correctly redirects the url provided by danbooruup in the event | ||||
| of a duplicate image. | ||||
| 
 | ||||
| 19-OCT-07 4:46PM CST - JJS | ||||
| Add compatibility with danbooru api v1.8.1 style urls  | ||||
| for find_posts and add_post. NOTE: This does not implement  | ||||
| the changes to the parameter names, it is simply a  | ||||
| workaround for the latest danbooruup firefox extension.  | ||||
| Completely compatibility will probably involve a rewrite with a different URL | ||||
| 
 | ||||
| */ | ||||
| 
 | ||||
| class DanbooruApi extends Extension  | ||||
| { | ||||
| 	// Receive the event
 | ||||
| 	public function receive_event($event)  | ||||
| 	{ | ||||
| 		// Check if someone is accessing /api/danbooru (us)
 | ||||
| 		if(is_a($event, 'PageRequestEvent') && ($event->page_name == "api") && ($event->get_arg(0) == 'danbooru'))  | ||||
| 		{ | ||||
| 			// execute the danbooru processing code
 | ||||
| 			$this->api_danbooru($event); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	// Danbooru API
 | ||||
| 	private function api_danbooru($event) | ||||
| 	{ | ||||
| 		global $page; | ||||
| 		global $config; | ||||
| 		global $database; | ||||
| 		global $user; | ||||
| 		$page->set_mode("data"); | ||||
| 		$page->set_type("application/xml"); | ||||
| 		//debug
 | ||||
| 		//$page->set_type("text/plain");
 | ||||
| 		 | ||||
| 		$results = array(); | ||||
| 		 | ||||
| 		/* | ||||
| 		add_comment()  | ||||
| 		Adds a comment to a post.  | ||||
| 		Parameters  | ||||
| 		* body: the body of the comment  | ||||
| 		* post_id: the post id  | ||||
| 		* login: your login  | ||||
| 		* password: your password Response  | ||||
| 		* 200: success  | ||||
| 		* 500: error. response body will the the error message. | ||||
| 		*/ | ||||
| 		if($event->get_arg(1) == 'add_comment') | ||||
| 		{ | ||||
| 			// On error the response body is the error message so plain text is fine
 | ||||
| 			$page->set_type("text/plain"); | ||||
| 			// We do wish to auth the user if possible, if it fails treat as anonymous
 | ||||
| 			$this->authenticate_user(); | ||||
| 			// Check if anonymous commenting is allowed before proceeding
 | ||||
| 			if($config->get_bool("comment_anon") || !$user->is_anonymous()) | ||||
| 			{ | ||||
| 				// Did the user supply a post_id and a comment body?
 | ||||
| 				if(isset($_REQUEST['post_id']) && isset($_REQUEST['body']) && trim($_REQUEST['body']) != "") | ||||
| 				{ | ||||
| 					// waiting for someone to write an event handler for the comments extension :)
 | ||||
| 				} else  | ||||
| 				{ | ||||
| 					// User didn't supply necessary parameters, tell them that
 | ||||
| 					header("HTTP/1.0 500 Internal Server Error"); | ||||
| 					$page->set_data("You forgot to supply either a post id or the body of your comment"); | ||||
| 				} | ||||
| 			} else  | ||||
| 			{ | ||||
| 				header("HTTP/1.0 500 Internal Server Error"); | ||||
| 				$page->set_data("You supplied an invalid login or password or anonymous commenting is currently disabled"); | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		/* | ||||
| 		add_post() | ||||
| 		Adds a post to the database.  | ||||
| 		Parameters  | ||||
| 		* login: login | ||||
| 		* password: password  | ||||
| 		* file: file as a multipart form  | ||||
| 		* source: source url  | ||||
| 		* title: title **IGNORED** | ||||
| 		* tags: list of tags as a string, delimited by whitespace  | ||||
| 		* md5: MD5 hash of upload in hexadecimal format  | ||||
| 		* rating: rating of the post. can be explicit, questionable, or safe. **IGNORED** | ||||
| 		Notes  | ||||
| 		* The only necessary parameter is tags and either file or source.  | ||||
| 		* If you want to sign your post, you need a way to authenticate your account, either by supplying login and password, or by supplying a cookie.  | ||||
| 		* If an account is not supplied or if it doesn‘t authenticate, he post will be added anonymously.  | ||||
| 		* If the md5 parameter is supplied and does not match the hash of what‘s on the server, the post is rejected.  | ||||
| 		Response  | ||||
| 		The response depends on the method used:  | ||||
| 		Post  | ||||
| 		* X-Danbooru-Location set to the URL for newly uploaded post.  | ||||
| 		Get  | ||||
| 		* Redirected to the newly uploaded post. | ||||
| 		*/ | ||||
| 		if(($event->get_arg(1) == 'add_post') || (($event->get_arg(1) == 'post') && ($event->get_arg(2) == 'create.xml'))) | ||||
| 		{ | ||||
| 			// No XML data is returned from this function
 | ||||
| 			$page->set_type("text/plain"); | ||||
| 			// Check first if a login was supplied, if it wasn't check if the user is logged in via cookie
 | ||||
| 			// If all that fails, it's an anonymous upload
 | ||||
| 			$this->authenticate_user(); | ||||
| 			// Now we check if a file was uploaded or a url was provided to transload
 | ||||
| 			// Much of this code is borrowed from /ext/upload
 | ||||
| 			if($config->get_bool("upload_anon") || !$user->is_anonymous()) | ||||
| 			{ | ||||
| 				$file = null; | ||||
| 				$filename = ""; | ||||
| 				$source = ""; | ||||
| 				if(isset($_FILES['file'])) | ||||
| 				{	// A file was POST'd in
 | ||||
| 					$file = $_FILES['file']['tmp_name']; | ||||
| 					$filename = $_FILES['file']['name']; | ||||
| 					// If both a file is posted and a source provided, I'm assuming source is the source of the file
 | ||||
| 					if(isset($_REQUEST['source']) && !empty($_REQUEST['source'])) | ||||
| 					{ | ||||
| 						$source = $_REQUEST['source']; | ||||
| 					} else | ||||
| 					{ | ||||
| 						$source = null; | ||||
| 					} | ||||
| 				} elseif(isset($_FILES['post'])) | ||||
| 				{ | ||||
| 					$file = $_FILES['post']['tmp_name']['file']; | ||||
| 					$filename = $_FILES['post']['name']['file']; | ||||
| 					if(isset($_REQUEST['post']['source']) && !empty($_REQUEST['post']['source'])) | ||||
| 					{ | ||||
| 						$source = $_REQUEST['post']['source']; | ||||
| 					} else  | ||||
| 					{ | ||||
| 						$source = null; | ||||
| 					} | ||||
| 				} elseif(isset($_REQUEST['source']) || isset($_REQUEST['post']['source'])) | ||||
| 				{	// A url was provided
 | ||||
| 					$url = isset($_REQUEST['source']) ? $_REQUEST['source'] : $_REQUEST['post']['source']; | ||||
| 					$source = $url; | ||||
| 					$tmp_filename = tempnam("/tmp", "shimmie_transload"); | ||||
| 					 | ||||
| 					// Are we using fopen wrappers or curl?
 | ||||
| 					if($config->get_string("transload_engine") == "fopen")  | ||||
| 					{ | ||||
| 						$fp = fopen($url, "r"); | ||||
| 						if(!$fp) { | ||||
| 							header("HTTP/1.0 409 Conflict"); | ||||
| 							header("X-Danbooru-Errors: fopen read error"); | ||||
| 						} | ||||
| 						 | ||||
| 						$data = ""; | ||||
| 						$length = 0; | ||||
| 						while(!feof($fp) && $length <= $config->get_int('upload_size'))  | ||||
| 						{ | ||||
| 							$data .= fread($fp, 8192); | ||||
| 							$length = strlen($data); | ||||
| 						} | ||||
| 						fclose($fp); | ||||
| 
 | ||||
| 						$fp = fopen($tmp_filename, "w"); | ||||
| 						fwrite($fp, $data); | ||||
| 						fclose($fp); | ||||
| 					} | ||||
| 
 | ||||
| 					if($config->get_string("transload_engine") == "curl")  | ||||
| 					{ | ||||
| 						$ch = curl_init($url); | ||||
| 						$fp = fopen($tmp_filename, "w"); | ||||
| 
 | ||||
| 						curl_setopt($ch, CURLOPT_FILE, $fp); | ||||
| 						curl_setopt($ch, CURLOPT_HEADER, 0); | ||||
| 
 | ||||
| 						curl_exec($ch); | ||||
| 						curl_close($ch); | ||||
| 						fclose($fp); | ||||
| 					} | ||||
| 					$file = $tmp_filename; | ||||
| 					$filename = basename($url); | ||||
| 				} else  | ||||
| 				{	// Nothing was specified at all
 | ||||
| 					header("HTTP/1.0 409 Conflict"); | ||||
| 					header("X-Danbooru-Errors: no input files"); | ||||
| 					return; | ||||
| 				} | ||||
| 				 | ||||
| 				// Get tags out of url
 | ||||
| 				$posttags = isset($_REQUEST['tags']) ? $_REQUEST['tags'] : $_REQUEST['post']['tags']; | ||||
| 				 | ||||
| 				// Now that we have some sort of physical file, process it
 | ||||
| 				$image = new Image($file, $filename, $posttags, $source); | ||||
| 				// This occurs if the uploaded file is not an image
 | ||||
| 				if(!$image->is_ok()) | ||||
| 				{ | ||||
| 					header("HTTP/1.0 409 Conflict"); | ||||
| 					header("X-Danbooru-Errors: unknown"); | ||||
| 					return; | ||||
| 				} | ||||
| 				// Was an md5 supplied? Does it match the image hash?
 | ||||
| 				if(isset($_REQUEST['md5'])) | ||||
| 				{ | ||||
| 					if($_REQUEST['md5'] != $image->hash) | ||||
| 					{ | ||||
| 						header("HTTP/1.0 409 Conflict"); | ||||
| 						header("X-Danbooru-Errors: md5 mismatch"); | ||||
| 						return; | ||||
| 					} | ||||
| 				} | ||||
| 				// Is the image too large?
 | ||||
| 				if(filesize($file['tmp_name']) > $config->get_int('upload_size')) | ||||
| 				{ | ||||
| 					header("HTTP/1.0 409 Conflict"); | ||||
| 					header("X-Danbooru-Errors: too large"); | ||||
| 					return; | ||||
| 				} | ||||
| 				// Does it exist already?
 | ||||
| 				$existing = $database->get_image_by_hash($image->hash); | ||||
| 				if(!is_null($existing)) { | ||||
| 					header("HTTP/1.0 409 Conflict"); | ||||
| 					header("X-Danbooru-Errors: duplicate"); | ||||
| 					$existinglink = make_link("post/view/" . $existing->id); | ||||
| 					header("X-Danbooru-Location: $existinglink"); | ||||
| 				} | ||||
| 
 | ||||
| 				// Fire off an event which should process the new image and add it to the db
 | ||||
| 				$nevent = new UploadingImageEvent($user, $image); | ||||
| 				send_event($nevent); | ||||
| 				// Did something screw up?
 | ||||
| 				if($event->vetoed) { | ||||
| 					header("HTTP/1.0 409 Conflict"); | ||||
| 					header("X-Danbooru-Errors: $event->veto_reason"); | ||||
| 					return; | ||||
| 				} else | ||||
| 				{	// If it went ok, grab the id for the newly uploaded image and pass it in the header
 | ||||
| 					$newimg = $database->get_image_by_hash($image->hash); | ||||
| 					$newid = make_link("post/view/" . $newimg->id); | ||||
| 					// Did we POST or GET this call?
 | ||||
| 					if($_SERVER['REQUEST_METHOD'] == 'POST') | ||||
| 					{ | ||||
| 						header("X-Danbooru-Location: $newid"); | ||||
| 					} | ||||
| 					else | ||||
| 					header("Location: $newid"); | ||||
| 				} | ||||
| 			} else  | ||||
| 			{ | ||||
| 				header("HTTP/1.0 409 Conflict"); | ||||
| 				header("X-Danbooru-Errors: authentication error"); | ||||
| 				return; | ||||
| 			} | ||||
| 		} | ||||
| 		 | ||||
| 		/* | ||||
| 		find_posts()  | ||||
| 		Find all posts that match the search criteria. Posts will be ordered by id descending.  | ||||
| 		Parameters  | ||||
| 		* md5: md5 hash to search for (comma delimited)  | ||||
| 		* id: id to search for (comma delimited)  | ||||
| 		* tags: what tags to search for  | ||||
| 		* limit: limit  | ||||
| 		* offset: offset  | ||||
| 		* after_id: limit results to posts added after this id | ||||
| 		*/ | ||||
| 		if(($event->get_arg(1) == 'find_posts') || (($event->get_arg(1) == 'post') && ($event->get_arg(2) == 'index.xml'))) | ||||
| 		{ | ||||
| 			if(isset($_GET['md5'])) | ||||
| 			{ | ||||
| 				$md5list = explode(",",$_GET['md5']); | ||||
| 				foreach($md5list as $md5) | ||||
| 				{ | ||||
| 					$results[] = $database->get_image_by_hash($md5); | ||||
| 				} | ||||
| 			} elseif(isset($_GET['id'])) | ||||
| 			{ | ||||
| 				$idlist = explode(",",$_GET['id']); | ||||
| 				foreach($idlist as $id) | ||||
| 				{ | ||||
| 					$results[] = $database->get_image($id); | ||||
| 				} | ||||
| 			} else | ||||
| 			{ | ||||
| 				$limit = isset($_GET['limit']) ? int_escape($_GET['limit']) : 100; | ||||
| 				$start = isset($_GET['offset']) ? int_escape($_GET['offset']) : 0; | ||||
| 				$tags = isset($_GET['tags']) ? tag_explode($_GET['tags']) : array(); | ||||
| 				$results = $database->get_images($start,$limit,$tags); | ||||
| 			} | ||||
| 			 | ||||
| 			// Now we have the array $results filled with Image objects
 | ||||
| 			// Let's display them
 | ||||
| 			$xml = "<posts>\n"; | ||||
| 			foreach($results as $img) | ||||
| 			{ | ||||
| 				// Sanity check to see if $img is really an image object
 | ||||
| 				// If it isn't (e.g. someone requested an invalid md5 or id), break out of the this
 | ||||
| 				if(!is_object($img)) | ||||
| 					continue; | ||||
| 				$taglist = $img->get_tag_list(); | ||||
| 				$owner = $img->get_owner(); | ||||
| 				$xml .= "<post md5=\"$img->hash\" rating=\"Questionable\" date=\"$img->posted\" is_warehoused=\"false\" file_name=\"$img->filename\" tags=\"$taglist\" source=\"$img->source\" score=\"0\" id=\"$img->id\" author=\"$owner->name\"/>\n";
 | ||||
| 			} | ||||
| 			$xml .= "</posts>"; | ||||
| 			$page->set_data($xml); | ||||
| 		} | ||||
| 		 | ||||
| 		/* | ||||
| 		find_tags() Find all tags that match the search criteria.  | ||||
| 		Parameters  | ||||
| 		* id: A comma delimited list of tag id numbers.  | ||||
| 		* name: A comma delimited list of tag names.  | ||||
| 		* tags: any typical tag query. See Tag#parse_query for details. 
 | ||||
| 		* after_id: limit results to tags with an id number after after_id. Useful if you only want to refresh | ||||
| 		*/ | ||||
| 		if($event->get_arg(1) == 'find_tags') | ||||
| 		{ | ||||
| 			if(isset($_GET['id'])) | ||||
| 			{ | ||||
| 				$idlist = explode(",",$_GET['id']); | ||||
| 				foreach($idlist as $id) | ||||
| 				{ | ||||
| 					$sqlresult = $database->execute("SELECT id,tag,count FROM tags WHERE id = ?", array($id)); | ||||
| 					if(!$sqlresult->EOF) | ||||
| 					{ | ||||
| 						$results[] = array($sqlresult->fields['count'], $sqlresult->fields['tag'], $sqlresult->fields['id']); | ||||
| 					} | ||||
| 				} | ||||
| 			} elseif(isset($_GET['name'])) | ||||
| 			{ | ||||
| 				$namelist = explode(",",$_GET['name']); | ||||
| 				foreach($namelist as $name) | ||||
| 				{ | ||||
| 					$sqlresult = $database->execute("SELECT id,tag,count FROM tags WHERE tag = ?", array($name)); | ||||
| 					if(!$sqlresult->EOF) | ||||
| 					{ | ||||
| 						$results[] = array($sqlresult->fields['count'], $sqlresult->fields['tag'], $sqlresult->fields['id']); | ||||
| 					} | ||||
| 				} | ||||
| 			}  | ||||
| 			/* Currently disabled to maintain identical functionality to danbooru 1.0's own "broken" find_tags | ||||
| 			elseif(isset($_GET['tags'])) | ||||
| 			{ | ||||
| 				$start = isset($_GET['after_id']) ? int_escape($_GET['offset']) : 0; | ||||
| 				$tags = tag_explode($_GET['tags']); | ||||
| 				 | ||||
| 			} | ||||
| 			*/ | ||||
| 			else  | ||||
| 			{ | ||||
| 				$start = isset($_GET['after_id']) ? int_escape($_GET['offset']) : 0; | ||||
| 				$sqlresult = $database->execute("SELECT id,tag,count FROM tags WHERE count > 0 AND id >= ? ORDER BY id DESC",array($start)); | ||||
| 				while(!$sqlresult->EOF) | ||||
| 				{ | ||||
| 					$results[] = array($sqlresult->fields['count'], $sqlresult->fields['tag'], $sqlresult->fields['id']); | ||||
| 					$sqlresult->MoveNext(); | ||||
| 				} | ||||
| 			} | ||||
| 			 | ||||
| 			// Tag results collected, build XML output
 | ||||
| 			$xml = "<tags>\n"; | ||||
| 			foreach($results as $tag) | ||||
| 			{ | ||||
| 				$xml .= "<tag type=\"0\" count=\"$tag[0]\" name=\"$tag[1]\" id=\"$tag[2]\"/>\n"; | ||||
| 			} | ||||
| 			$xml .= "</tags>"; | ||||
| 			$page->set_data($xml); | ||||
| 		} | ||||
| 		 | ||||
| 		// Hackery for danbooruup 0.3.2 providing the wrong view url. This simply redirects to the proper
 | ||||
| 		// Shimmie view page
 | ||||
| 		// Example: danbooruup says the url is http://shimmie/api/danbooru/post/show/123
 | ||||
| 		// This redirects that to http://shimmie/post/view/123
 | ||||
| 		if(($event->get_arg(1) == 'post') && ($event->get_arg(2) == 'show')) | ||||
| 		{ | ||||
| 			$fixedlocation = make_link("post/view/" . $event->get_arg(3)); | ||||
| 			header("Location: $fixedlocation"); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	// Turns out I use this a couple times so let's make it a utility function
 | ||||
| 	// Authenticates a user based on the contents of the login and password parameters
 | ||||
| 	// or makes them anonymous. Does not set any cookies or anything permanent.
 | ||||
| 	private function authenticate_user() | ||||
| 	{ | ||||
| 		global $database; | ||||
| 		global $user; | ||||
| 
 | ||||
| 		if(isset($_REQUEST['login']) && isset($_REQUEST['password'])) | ||||
| 		{ | ||||
| 			// Get this user from the db, if it fails the user becomes anonymous
 | ||||
| 			// Code borrowed from /ext/user
 | ||||
| 			$name = $_REQUEST['login']; | ||||
| 			$pass = $_REQUEST['password']; | ||||
| 			$hash = md5( strtolower($name) . $pass ); | ||||
| 			$duser = $database->get_user_by_name_and_hash($name, $hash); | ||||
| 			if(!is_null($duser)) { | ||||
| 				$user = $duser; | ||||
| 			} else | ||||
| 			{ | ||||
| 				$user = $database->get_user_by_id($config->get_int("anon_id", 0)); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| add_event_listener(new DanbooruApi()); | ||||
| ?>
 | ||||
							
								
								
									
										41
									
								
								contrib/link_image/_style.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								contrib/link_image/_style.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | ||||
| /* | ||||
|  * This file may not be distributed without its readme.txt | ||||
| **/ | ||||
| 
 | ||||
| /* * * Link to Image * * */ | ||||
| #Link_to_Image { | ||||
| 	/* allows borders to encompass the content; */ | ||||
| 	overflow:hidden; | ||||
| } | ||||
| 
 | ||||
| #Link_to_Image fieldset { | ||||
| 	width: 32%; | ||||
| 	float:left; | ||||
| 	min-width:25em; | ||||
| } | ||||
| 
 | ||||
| #Link_to_Image input, #Link_to_Image label { | ||||
| 	display:block; | ||||
| 	width:66%; | ||||
| 	float:left; | ||||
| 	margin-bottom:2.5px; | ||||
| } | ||||
| 
 | ||||
| #Link_to_Image label { | ||||
| 	width:30%; | ||||
| 	text-align:left; | ||||
| 	padding-right:2%; | ||||
| 	cursor:pointer; | ||||
| } | ||||
| #Link_to_Image input { | ||||
| 	font-size:0.7em; | ||||
| 	font-family:courier, fixed, monospace; | ||||
| } | ||||
| 
 | ||||
| #Link_to_Image br { | ||||
| 	clear:both; | ||||
| } | ||||
| 
 | ||||
| #Link_to_Image label:hover { | ||||
| 	border-bottom:1px dashed; | ||||
| } | ||||
							
								
								
									
										45
									
								
								contrib/link_image/main.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								contrib/link_image/main.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | ||||
| <?php | ||||
| /** | ||||
|  * Name: Link to Image | ||||
|  * Author: Artanis <artanis.00@gmail.com> | ||||
|  * Description: Show various forms of link to each image, for copy & paste | ||||
|  */ | ||||
| class LinkImage extends Extension { | ||||
| 	var $theme; | ||||
| 	 | ||||
| 	public function receive_event($event) { | ||||
| 		if(is_null($this->theme)) $this->theme = get_theme_object("link_image", "LinkImageTheme"); | ||||
| 			if(is_a($event, 'DisplayingImageEvent')) { | ||||
| 				global $config; | ||||
| 				$data_href = get_base_href(); | ||||
| 				$event->page->add_header("<link rel='stylesheet' href='$data_href/ext/link_image/_style.css' type='text/css'>",0); | ||||
| 				 | ||||
| 				$this->theme->links_block($event->page,$this->data($event->image)); | ||||
| 			} | ||||
| 			if(is_a($event, 'SetupBuildingEvent')) { | ||||
| 				$sb = new SetupBlock("Link to Image"); | ||||
| 				$sb->add_text_option("ext_link-img_text-link_format", "Text Link Format: "); | ||||
| 				$event->panel->add_block($sb); | ||||
| 			} | ||||
| 			if(is_a($event, 'InitExtEvent')) { | ||||
| 				global $config; | ||||
| 				//just set default if empty.
 | ||||
| 				$config->set_default_string("ext_link-img_text-link_format", | ||||
| 										'$title - $id ($ext $size $filesize)'); | ||||
| 			} | ||||
| 		} | ||||
| 	private function data($image) { | ||||
| 		global $config; | ||||
| 		 | ||||
| 		$text_link = $image->parse_link_template($config->get_string("ext_link-img_text-link_format")); | ||||
| 		$text_link = $text_link==" "? null : $text_link; // null blank setting so the url gets filled in on the text links.
 | ||||
| 		 | ||||
| 		return array( | ||||
| 			'thumb_src'	=>	$image->get_thumb_link(), | ||||
| 			'image_src'	=>	$image->get_image_link(), | ||||
| 			'post_link'	=>	$image->get_short_link(), | ||||
| 			'text_link'		=>	$text_link); | ||||
| 	} | ||||
| } | ||||
| add_event_listener(new LinkImage()); | ||||
| ?>
 | ||||
							
								
								
									
										82
									
								
								contrib/link_image/readme.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								contrib/link_image/readme.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,82 @@ | ||||
| Link to Image adds BBCode and HTML link codes to the image view. Offers code for a customizable text link, thumbnail links, and full image inline. | ||||
| 
 | ||||
| Author: Erik Youngren <artanis.00@gmail.com> | ||||
| 
 | ||||
| License: GPLv2 | ||||
| 
 | ||||
| Submit a Bug Report or Suggestion for Link to Image: | ||||
|  * http://trac.shishnet.org/shimmie2/newticket?owner=artanis.00@gmail.com&component=third%20party%20extensions&keywords=link_to_image | ||||
| 
 | ||||
| = Use = | ||||
| There is one option in Board Config: Text Link Format. | ||||
| It takes the following arguments as well as plain text. | ||||
| || arguments    || replacement                      || | ||||
| || $id          || The image ID.                    || | ||||
| || $hash        || The MD5 hash of the image.       || | ||||
| || $tags        || The image's tag list.            || | ||||
| || $base        || The base HREF as set in Config.  || | ||||
| || $ext         || The image's extension.           || | ||||
| || $size        || The image's display size.        || | ||||
| || $filesize    || The image's size in KB.          || | ||||
| || $filename    || The image's original filename.   || | ||||
| || $title       || The site title as set in Config. || | ||||
| Link to Image will default this option to '$title - $id ($ext $size $filesize)'. | ||||
| To reset to the default, simply clear the current setting. Link to Image will then fill in the default value after the save. | ||||
| 
 | ||||
| To leave the setting blank for any reason, leave a space (' ') in it. | ||||
| 
 | ||||
| = Install = | ||||
|  1. Copy the folder {{{contrib/link_image/}}} to {{{ext/}}}. | ||||
|  2. In the Config panel, make sure Base URL is set (you may as well set Data URL while you're there, if you haven't already.) | ||||
|  3. Make sure Image Link, Thumb Link, and Short Link all contain the full path ("http://" and onward,) either by using $base or plain text. Link to Image will not be able to retrieve the correct paths without these variables. | ||||
| 
 | ||||
| = Change Log = | ||||
| == Version 0.3.0 == | ||||
|  * Moved Link to Image over to the official theme engine. This functions basically the same as what the prototype was, but it's more thought out and nicer. | ||||
|  * Cleaned up the insides a bit. | ||||
| 
 | ||||
| == Version 0.2.0 == | ||||
|  * Changed the HTML generation to use a prototype theme engine. All HTML generation is now contained within {{{link_image.html.php}}}, which may be copied to the current theme folder and edited from there. | ||||
|   | ||||
| == Version 0.1.4 - 20070510 == | ||||
|  * Style changes. | ||||
|  * Added output containing only the locations of the thumb, image and post. | ||||
|  * Added a link to wikipedia's HTML page, just as BBCode has a wikipedia link. | ||||
| 
 | ||||
| == Version 0.1.3b - 20070509 == | ||||
|  * Renamed style.css to _style.css to avoid the auto loader. | ||||
| 
 | ||||
| == Version 0.1.3 - 20070508 == | ||||
|  * Created Readme.txt | ||||
|  * Merged 0.1.2 into 0.1.2b | ||||
|  * Removed uneeded documentation from main.php | ||||
|  * Rewrote the css to be unique. Previously used CSS I wrote for elsewhere. Styled to reduce space consumption. | ||||
|  * Added code to insert the CSS import. | ||||
|   * Updated Nice URLs to allow access to the /ext/ folder. (Why is my stylesheet returning HTML instead of CSS?) | ||||
|  * First SVN update. | ||||
| 
 | ||||
| == Version 0.1.2b - 20070507 == | ||||
| (fairly simultaneous with 0.1.2) | ||||
|  * shish: | ||||
|   * Updated to new extension format | ||||
|    * Created folder link_image in trunk/contrib | ||||
|    * Renamed link_image.ext.php to main.php and moved to /link_image/ | ||||
|    * Created style.css {{{ /* 404'd :|*/ }}}. | ||||
|   * Documentation (different from mine.) | ||||
|   * Changed add_text_option() and added add_label() in SetupBuildingEvent because I was using an edited version of the function that shish didn't know about. It was a wonder that didn't throw massive errors. | ||||
|   * Published on SVN. | ||||
| 
 | ||||
| == Version 0.1.2 - 20070506 == | ||||
|  * Textboxes now select-all when they gain focus. | ||||
|  * Commenting and documentation. | ||||
| 
 | ||||
| == Version 0.1.1 - 20070506 == | ||||
|  * Fixed HTML thumbnail link code. (image tag was being html_escaped twice, resulting in "$gt;" and "<" from the first escape becoming "&gt;" and "&lt;") It turns out that html_escape was completely unnecessary, all I had to do was replace the single-quotes around the attributes with escaped double-quotes ('\"'.) | ||||
| 
 | ||||
| == Version 0.1.0 - 20070506 == | ||||
|  * Release. | ||||
| 
 | ||||
| = Links = | ||||
|  * http://trac.shishnet.org/shimmie2/wiki/Contrib/Extensions/LinkToImage - Home | ||||
|  * http://forum.shishnet.org/viewtopic.php?p=153 - Discussion | ||||
|  * http://trac.shishnet.org/shimmie2/browser/trunk/contrib/link_image - Shimmie2 Trac SVN | ||||
							
								
								
									
										71
									
								
								contrib/link_image/theme.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								contrib/link_image/theme.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,71 @@ | ||||
| <?php | ||||
| class LinkImageTheme extends Themelet { | ||||
| 	public function links_block($page,$data) { | ||||
| 		 | ||||
| 		$thumb_src = $data['thumb_src']; | ||||
| 		$image_src = $data['image_src']; | ||||
| 		$post_link = $data['post_link']; | ||||
| 		$text_link	 = $data['text_link']; | ||||
| 		 | ||||
| 		$page->add_block( new Block( | ||||
| 			"Link to Image", | ||||
| 			"<fieldset>". | ||||
| 				"<legend><a href='http://en.wikipedia.org/wiki/Bbcode' target='_blank'>BBCode</a></legend>". | ||||
| 					$this->link_code("Text Link",$this->url($post_link, $text_link,"ubb"),"ubb_text-link"). | ||||
| 					$this->link_code("Thumbnail Link",$this->url($post_link, $this->img($thumb_src,"ubb"),"ubb"),"ubb_thumb-link"). | ||||
| 					$this->link_code("Inline Image", $this->img($image_src,"ubb"), "ubb_full-img"). | ||||
| 				"</fieldset>". | ||||
| 				 | ||||
| 				"<fieldset>". | ||||
| 				"<legend><a href='http://en.wikipedia.org/wiki/Html' target='_blank'>HTML</a></legend>". | ||||
| 					$this->link_code("Text Link", $this->url($post_link, $text_link,"html"), "html_text-link"). | ||||
| 					$this->link_code("Thumbnail Link", $this->url($post_link,$this->img($thumb_src,"html"),"html"), "html_thumb-link"). | ||||
| 					$this->link_code("Inline Image", $this->img($image_src,"html"), "html_full-image"). | ||||
| 				"</fieldset>". | ||||
| 				 | ||||
| 				"<fieldset>". | ||||
| 					"<legend>Plain Text</legend>". | ||||
| 					$this->link_code("Post URL",$post_link,"text_post-link"). | ||||
| 					$this->link_code("Thumbnail URL",$thumb_src,"text_thumb-url"). | ||||
| 					$this->link_code("Image URL",$image_src,"text_image-src"). | ||||
| 				"</fieldset>", | ||||
| 			"main", | ||||
| 			50)); | ||||
| 	} | ||||
| 	 | ||||
| 	protected function url ($url,$content,$type) { | ||||
| 		if ($content == NULL) {$content=$url;} | ||||
| 		 | ||||
| 		switch ($type) { | ||||
| 			case "html": | ||||
| 				$text = "<a href=\"".$url."\">".$content."</a>"; | ||||
| 				break; | ||||
| 			case "ubb": | ||||
| 				$text = "[url=".$url."]".$content."[/url]"; | ||||
| 				break; | ||||
| 			default: | ||||
| 				$text = $link." - ".$content; | ||||
| 		} | ||||
| 		return $text; | ||||
| 	} | ||||
| 	 | ||||
| 	protected function img ($src,$type) { | ||||
| 		switch ($type) { | ||||
| 			case "html": | ||||
| 				$text = "<img src=\"$src\" />";
 | ||||
| 				break; | ||||
| 			case "ubb": | ||||
| 				$text = "[img]".$src."[/img]"; | ||||
| 				break; | ||||
| 			default: | ||||
| 				$text = $src; | ||||
| 		} | ||||
| 		return $text; | ||||
| 	} | ||||
| 	 | ||||
| 	protected function link_code($label,$content,$id=NULL) { | ||||
| 		return	"<label for='".$id."' title='Click to select the textbox'>$label</label>\n". | ||||
| 				"<input type='text' readonly='readonly' id='".$id."' name='".$id."' value='".html_escape($content)."' onfocus='this.select();'></input>\n<br/>\n"; | ||||
| 	} | ||||
| } | ||||
| ?>
 | ||||
							
								
								
									
										205
									
								
								contrib/tag_history/main.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										205
									
								
								contrib/tag_history/main.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,205 @@ | ||||
| <?php | ||||
| /** | ||||
|  * Name: Tag History | ||||
|  * Author: Bzchan <bzchan@animemahou.com> | ||||
|  * Description: Keep a record of tag changes | ||||
|  */ | ||||
| 
 | ||||
| class Tag_History extends Extension { | ||||
| 	var $theme; | ||||
| 
 | ||||
| 	public function receive_event($event) { | ||||
| 		if(is_null($this->theme)) $this->theme = get_theme_object("tag_history", "Tag_HistoryTheme"); | ||||
| 
 | ||||
| 		if(is_a($event, 'InitExtEvent')) { | ||||
| 			// shimmie is being installed so call install to create the table.
 | ||||
| 			global $config; | ||||
| 			if($config->get_int("ext_tag_history_version") < 3) { | ||||
| 				$this->install(); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if(is_a($event, 'PageRequestEvent') && ($event->page_name == "tag_history")) | ||||
| 		{ | ||||
| 			if($event->get_arg(0) == "revert") | ||||
| 			{ | ||||
| 				// this is a request to revert to a previous version of the tags
 | ||||
| 				$this->process_revert_request($_POST['revert']); | ||||
| 			} | ||||
| 			else if($event->count_args() == 1) | ||||
| 			{ | ||||
| 				// must be an attempt to view a tag history
 | ||||
| 				$image_id = int_escape($event->get_arg(0)); | ||||
| 				$this->theme->display_history_page($event->page, $image_id, $this->get_tag_history_from_id($image_id)); | ||||
| 			} | ||||
| 			else { | ||||
| 				$this->theme->display_global_page($event->page, $this->get_global_tag_history()); | ||||
| 			} | ||||
| 		} | ||||
| 		if(is_a($event, 'DisplayingImageEvent')) | ||||
| 		{ | ||||
| 			// handle displaying a link on the view page
 | ||||
| 			$this->theme->display_history_link($event->page, $event->image->id); | ||||
| 		} | ||||
| 		if(is_a($event, 'ImageDeletionEvent')) | ||||
| 		{ | ||||
| 			// handle removing of history when an image is deleted
 | ||||
| 			$this->delete_all_tag_history($event->image->id); | ||||
| 		} | ||||
| 		if(is_a($event, 'SetupBuildingEvent')) { | ||||
| 			$sb = new SetupBlock("Tag History"); | ||||
| 			$sb->add_label("Limit to "); | ||||
| 			$sb->add_int_option("history_limit"); | ||||
| 			$sb->add_label(" entires per image"); | ||||
| 			$event->panel->add_block($sb); | ||||
| 		} | ||||
| 		if(is_a($event, 'TagSetEvent')) { | ||||
| 			$this->add_tag_history($event->image_id, $event->tags); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	protected function install() | ||||
| 	{ | ||||
| 		global $database; | ||||
| 		global $config; | ||||
| 
 | ||||
| 		if($config->get_int("ext_tag_history_version") < 1) { | ||||
| 			$database->Execute("CREATE TABLE tag_histories
 | ||||
| 			( | ||||
| 	    		id integer NOT NULL auto_increment PRIMARY KEY, | ||||
| 	    		image_id integer NOT NULL, | ||||
| 	    		tags text NOT NULL | ||||
| 			)");
 | ||||
| 			$config->set_int("ext_tag_history_version", 1); | ||||
| 		} | ||||
| 		 | ||||
| 		if($config->get_int("ext_tag_history_version") == 1) { | ||||
| 			$database->Execute("ALTER TABLE tag_histories ADD COLUMN user_id INTEGER NOT NULL"); | ||||
| 			$database->Execute("ALTER TABLE tag_histories ADD COLUMN date_set DATETIME NOT NULL"); | ||||
| 			$config->set_int("ext_tag_history_version", 2); | ||||
| 		} | ||||
| 
 | ||||
| 		if($config->get_int("ext_tag_history_version") == 2) { | ||||
| 			$database->Execute("ALTER TABLE tag_histories ADD COLUMN user_ip CHAR(15) NOT NULL"); | ||||
| 			$config->set_int("ext_tag_history_version", 3); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	/* | ||||
| 	 * this function is called when a revert request is received | ||||
| 	 */ | ||||
| 	private function process_revert_request($revert_id) | ||||
| 	{ | ||||
| 		global $page; | ||||
| 		// check for the nothing case
 | ||||
| 		if($revert_id=="nothing") | ||||
| 		{ | ||||
| 			// tried to set it too the same thing so ignore it (might be a bot)
 | ||||
| 			// go back to the index page with you
 | ||||
| 			$page->set_mode("redirect"); | ||||
| 			$page->set_redirect(make_link()); | ||||
| 			return; | ||||
| 		} | ||||
| 		 | ||||
| 		$revert_id = int_escape($revert_id); | ||||
| 		 | ||||
| 		// lets get this revert id assuming it exists
 | ||||
| 		$result = $this->get_tag_history_from_revert($revert_id); | ||||
| 		 | ||||
| 		if($result==null) | ||||
| 		{ | ||||
| 			// there is no history entry with that id so either the image was deleted
 | ||||
| 			// while the user was viewing the history, someone is playing with form
 | ||||
| 			// variables or we have messed up in code somewhere.
 | ||||
| 			die("Error: No tag history with specified id was found."); | ||||
| 		} | ||||
| 		 | ||||
| 		// lets get the values out of the result
 | ||||
| 		$stored_result_id = $result->fields['id']; | ||||
| 		$stored_image_id = $result->fields['image_id']; | ||||
| 		$stored_tags = $result->fields['tags']; | ||||
| 		 | ||||
| 		// all should be ok so we can revert by firing the SetUserTags event.
 | ||||
| 		send_event(new TagSetEvent($stored_image_id, $stored_tags)); | ||||
| 		 | ||||
| 		// all should be done now so redirect the user back to the image
 | ||||
| 		$page->set_mode("redirect"); | ||||
| 		$page->set_redirect(make_link("post/view/$stored_image_id")); | ||||
| 	} | ||||
| 	 | ||||
| 	public function get_tag_history_from_revert($revert_id) | ||||
| 	{ | ||||
| 		global $database; | ||||
| 		$row = $database->execute(" | ||||
| 				SELECT tag_histories.*, users.name | ||||
| 				FROM tag_histories | ||||
| 				JOIN users ON tag_histories.user_id = users.id | ||||
| 				WHERE tag_histories.id = ?", array($revert_id));
 | ||||
| 		return ($row ? $row : null); | ||||
| 	} | ||||
| 	 | ||||
| 	public function get_tag_history_from_id($image_id) | ||||
| 	{ | ||||
| 		global $database; | ||||
| 		$row = $database->db->GetAll(" | ||||
| 				SELECT tag_histories.*, users.name | ||||
| 				FROM tag_histories | ||||
| 				JOIN users ON tag_histories.user_id = users.id | ||||
| 				WHERE image_id = ? | ||||
| 				ORDER BY tag_histories.id DESC",
 | ||||
| 				array($image_id)); | ||||
| 		return ($row ? $row : array()); | ||||
| 	} | ||||
| 	 | ||||
| 	public function get_global_tag_history() | ||||
| 	{ | ||||
| 		global $database; | ||||
| 		$row = $database->db->GetAll(" | ||||
| 				SELECT tag_histories.*, users.name | ||||
| 				FROM tag_histories | ||||
| 				JOIN users ON tag_histories.user_id = users.id | ||||
| 				ORDER BY tag_histories.id DESC | ||||
| 				LIMIT 100");
 | ||||
| 		return ($row ? $row : array()); | ||||
| 	} | ||||
| 	 | ||||
| 	/* | ||||
| 	 * this function is called when an image has been deleted | ||||
| 	 */ | ||||
| 	private function delete_all_tag_history($image_id) | ||||
| 	{ | ||||
| 		global $database; | ||||
| 		$database->execute("DELETE FROM tag_histories WHERE image_id = ?", array($image_id)); | ||||
| 	} | ||||
| 
 | ||||
| 	/* | ||||
| 	 * this function is called just before an images tag are changed | ||||
| 	 */ | ||||
| 	private function add_tag_history($image_id, $tags) | ||||
| 	{ | ||||
| 		global $database; | ||||
| 		global $config; | ||||
| 		global $user; | ||||
| 
 | ||||
| 		if(is_array($tags)) $tags = implode(' ', $tags); | ||||
| 		 | ||||
| 		// add a history entry		
 | ||||
| 		$allowed = $config->get_int("history_limit",10); | ||||
| 		if($allowed<=0) return; | ||||
| 		$row = $database->execute(" | ||||
| 				INSERT INTO tag_histories(image_id, tags, user_id, user_ip, date_set) | ||||
| 				VALUES (?, ?, ?, ?, now())",
 | ||||
| 				array($image_id, $tags, $user->id, $_SERVER['REMOTE_ADDR'])); | ||||
| 		$entries = $database->db->GetOne("SELECT COUNT(*) FROM `tag_histories` WHERE image_id = ?", array($image_id)); | ||||
| 		 | ||||
| 		// if needed remove oldest one
 | ||||
| 		if($entries > $allowed) | ||||
| 		{ | ||||
| 			// TODO: Make these queries better
 | ||||
| 			$min_id = $database->db->GetOne("SELECT MIN(id) FROM tag_histories WHERE image_id = ?", array($image_id)); | ||||
| 			$database->execute("DELETE FROM tag_histories WHERE id = ?", array($min_id)); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| add_event_listener(new Tag_History()); | ||||
| ?>
 | ||||
							
								
								
									
										85
									
								
								contrib/tag_history/theme.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								contrib/tag_history/theme.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,85 @@ | ||||
| <?php | ||||
| 
 | ||||
| class Tag_HistoryTheme extends Themelet { | ||||
| 	public function display_history_page($page, $image_id, $history) { | ||||
| 		$start_string = " | ||||
| 			<div style='text-align: left'> | ||||
| 				<form enctype='multipart/form-data' action='".make_link("tag_history/revert")."' method='POST'> | ||||
| 					<ul style='list-style-type:none;'> | ||||
| 		";
 | ||||
| 
 | ||||
| 		global $user; | ||||
| 		$history_list = ""; | ||||
| 		foreach($history as $fields) | ||||
| 		{ | ||||
| 			$current_id = $fields['id']; | ||||
| 			$current_tags = html_escape($fields['tags']); | ||||
| 			$name = $fields['name']; | ||||
| 			$setter = "<a href='".make_link("user/".url_escape($name))."'>".html_escape($name)."</a>"; | ||||
| 			if($user->is_admin()) { | ||||
| 				$setter .= " / " . $fields['user_ip']; | ||||
| 			} | ||||
| 			$history_list .= "<li><input type='radio' name='revert' value='$current_id'>$current_tags (Set by $setter)</li>\n"; | ||||
| 		} | ||||
| 		 | ||||
| 		$end_string = " | ||||
| 					</ul> | ||||
| 					<input type='submit' value='Revert'> | ||||
| 				</form> | ||||
| 			</div> | ||||
| 		";
 | ||||
| 		$history_html = $start_string . $history_list . $end_string; | ||||
| 
 | ||||
| 		$page->set_title("Image $image_id Tag History"); | ||||
| 		$page->set_heading("Tag History: $image_id"); | ||||
| 		$page->add_block(new NavBlock()); | ||||
| 		$page->add_block(new Block("Tag History", $history_html, "main", 10)); | ||||
| 	} | ||||
| 
 | ||||
| 	public function display_global_page($page, $history) { | ||||
| 		$start_string = " | ||||
| 			<div style='text-align: left'> | ||||
| 				<form enctype='multipart/form-data' action='".make_link("tag_history/revert")."' method='POST'> | ||||
| 					<ul style='list-style-type:none;'> | ||||
| 		";
 | ||||
| 		$end_string = " | ||||
| 					</ul> | ||||
| 					<input type='submit' value='Revert'> | ||||
| 				</form> | ||||
| 			</div> | ||||
| 		";
 | ||||
| 
 | ||||
| 		global $user; | ||||
| 		$history_list = ""; | ||||
| 		foreach($history as $fields) | ||||
| 		{ | ||||
| 			$current_id = $fields['id']; | ||||
| 			$image_id = $fields['image_id']; | ||||
| 			$current_tags = html_escape($fields['tags']); | ||||
| 			$name = $fields['name']; | ||||
| 			$setter = "<a href='".make_link("user/".url_escape($name))."'>".html_escape($name)."</a>"; | ||||
| 			if($user->is_admin()) { | ||||
| 				$setter .= " / " . $fields['user_ip']; | ||||
| 			} | ||||
| 			$history_list .= " | ||||
| 				<li> | ||||
| 					<input type='radio' name='revert' value='$current_id'> | ||||
| 					<a href='".make_link("post/view/$image_id")."'>$image_id</a>: | ||||
| 					$current_tags (Set by $setter) | ||||
| 				</li> | ||||
| 			";
 | ||||
| 		} | ||||
| 
 | ||||
| 		$history_html = $start_string . $history_list . $end_string; | ||||
| 		$page->set_title("Global Tag History"); | ||||
| 		$page->set_heading("Global Tag History"); | ||||
| 		$page->add_block(new NavBlock()); | ||||
| 		$page->add_block(new Block("Tag History", $history_html, "main", 10)); | ||||
| 	} | ||||
| 
 | ||||
| 	public function display_history_link($page, $image_id) { | ||||
| 		$link = "<a href='".make_link("tag_history/$image_id")."'>Tag History</a>\n"; | ||||
| 		$page->add_block(new Block(null, $link, "main", 5)); | ||||
| 	} | ||||
| } | ||||
| ?>
 | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user