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