Merge branch 'master' of https://github.com/shish/shimmie2
This commit is contained in:
commit
711ad775da
@ -142,7 +142,7 @@ abstract class DataHandlerExtension extends Extension {
|
||||
public function onDataUpload(DataUploadEvent $event) {
|
||||
global $user;
|
||||
|
||||
if($this->supported_ext($event->type) && $this->check_contents($event->tmpname)) {
|
||||
if(($supported_ext = $this->supported_ext($event->type)) && ($check_contents = $this->check_contents($event->tmpname))) {
|
||||
if(!move_upload_to_archive($event)) return;
|
||||
send_event(new ThumbnailGenerationEvent($event->hash, $event->type));
|
||||
|
||||
@ -197,6 +197,9 @@ abstract class DataHandlerExtension extends Extension {
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif($supported_ext && !$check_contents){
|
||||
throw new UploadException("Invalid or corrupted file");
|
||||
}
|
||||
}
|
||||
|
||||
public function onThumbnailGeneration(ThumbnailGenerationEvent $event) {
|
||||
|
@ -26,6 +26,7 @@
|
||||
$tag_n = 0; // temp hack
|
||||
$_flexihash = null;
|
||||
$_fh_last_opts = null;
|
||||
$order_sql = null; // this feels ugly
|
||||
|
||||
require_once "lib/flexihash.php";
|
||||
|
||||
@ -114,7 +115,7 @@ class Image {
|
||||
assert(is_numeric($start));
|
||||
assert(is_numeric($limit));
|
||||
assert(is_array($tags));
|
||||
global $database, $user;
|
||||
global $database, $user, $config, $order_sql;
|
||||
|
||||
$images = array();
|
||||
|
||||
@ -128,13 +129,15 @@ class Image {
|
||||
}
|
||||
|
||||
$querylet = Image::build_search_querylet($tags);
|
||||
$querylet->append(new Querylet("ORDER BY images.id DESC LIMIT :limit OFFSET :offset", array("limit"=>$limit, "offset"=>$start)));
|
||||
$querylet->append(new Querylet(" ORDER BY images.".($order_sql ?: $config->get_string("index_order"))));
|
||||
$querylet->append(new Querylet(" LIMIT :limit OFFSET :offset", array("limit"=>$limit, "offset"=>$start)));
|
||||
#var_dump($querylet->sql); var_dump($querylet->variables);
|
||||
$result = $database->execute($querylet->sql, $querylet->variables);
|
||||
|
||||
while($row = $result->fetch()) {
|
||||
$images[] = new Image($row);
|
||||
}
|
||||
$order_sql = null;
|
||||
return $images;
|
||||
}
|
||||
|
||||
@ -476,6 +479,18 @@ class Image {
|
||||
$this->delete_tags_from_image();
|
||||
// insert each new tags
|
||||
foreach($tags as $tag) {
|
||||
if(preg_match("/^source[=|:](.*)$/i", $tag, $matches)) {
|
||||
$this->set_source($matches[1]);
|
||||
continue;
|
||||
}
|
||||
if(preg_match("/^pool[=|:](.*)$/i", $tag, $matches)) {
|
||||
if(class_exists("Pools")) {
|
||||
$pls = new Pools();
|
||||
$pls->add_post_from_tag($matches[1], $this->id);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
$id = $database->get_one(
|
||||
$database->scoreql_to_sql(
|
||||
"SELECT id FROM tags WHERE SCORE_STRNORM(tag) = SCORE_STRNORM(:tag)"
|
||||
@ -651,6 +666,8 @@ class Image {
|
||||
}
|
||||
}
|
||||
|
||||
$terms = Tag::resolve_aliases($terms);
|
||||
|
||||
// parse the words that are searched for into
|
||||
// various types of querylet
|
||||
foreach($terms as $term) {
|
||||
@ -663,8 +680,6 @@ class Image {
|
||||
continue;
|
||||
}
|
||||
|
||||
$term = Tag::resolve_alias($term);
|
||||
|
||||
$stpe = new SearchTermParseEvent($term, $terms);
|
||||
send_event($stpe);
|
||||
if($stpe->is_querylet_set()) {
|
||||
@ -812,6 +827,8 @@ class Image {
|
||||
}
|
||||
}
|
||||
|
||||
$terms = Tag::resolve_aliases($terms);
|
||||
|
||||
reset($terms); // rewind to first element in array.
|
||||
|
||||
// turn each term into a specific type of querylet
|
||||
@ -821,8 +838,6 @@ class Image {
|
||||
$negative = true;
|
||||
$term = substr($term, 1);
|
||||
}
|
||||
|
||||
$term = Tag::resolve_alias($term);
|
||||
|
||||
$stpe = new SearchTermParseEvent($term, $terms);
|
||||
send_event($stpe);
|
||||
@ -1070,11 +1085,22 @@ class Tag {
|
||||
assert(is_array($tags));
|
||||
|
||||
$new = array();
|
||||
foreach($tags as $tag) {
|
||||
$new_set = explode(' ', Tag::resolve_alias($tag));
|
||||
foreach($new_set as $new_one) {
|
||||
$new[] = $new_one;
|
||||
|
||||
$i = 0;
|
||||
$tag_count = count($tags);
|
||||
while($i<$tag_count) {
|
||||
$aliases = explode(' ', Tag::resolve_alias($tags[$i]));
|
||||
foreach($aliases as $alias){
|
||||
if(!in_array($alias, $new)){
|
||||
if($tags[$i] == $alias){
|
||||
$new[] = $alias;
|
||||
}elseif(!in_array($alias, $tags)){
|
||||
$tags[] = $alias;
|
||||
$tag_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
||||
$new = array_iunique($new); // remove any duplicate tags
|
||||
|
@ -509,14 +509,15 @@ function captcha_check() {
|
||||
* @param string &$file File path
|
||||
* @return string
|
||||
*/
|
||||
function getMimeType($file, $ext="") {
|
||||
function getMimeType($file, $ext="", $list=false) {
|
||||
|
||||
// Static extension lookup
|
||||
$ext = strtolower($ext);
|
||||
static $exts = array(
|
||||
'jpg' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png',
|
||||
'tif' => 'image/tiff', 'tiff' => 'image/tiff', 'ico' => 'image/x-icon',
|
||||
'swf' => 'application/x-shockwave-flash', 'pdf' => 'application/pdf',
|
||||
'swf' => 'application/x-shockwave-flash', 'video/x-flv' => 'flv',
|
||||
'svg' => 'image/svg+xml', 'pdf' => 'application/pdf',
|
||||
'zip' => 'application/zip', 'gz' => 'application/x-gzip',
|
||||
'tar' => 'application/x-tar', 'bz' => 'application/x-bzip',
|
||||
'bz2' => 'application/x-bzip2', 'txt' => 'text/plain',
|
||||
@ -529,6 +530,8 @@ function getMimeType($file, $ext="") {
|
||||
'mp4' => 'video/mp4', 'ogv' => 'video/ogg', 'webm' => 'video/webm'
|
||||
);
|
||||
|
||||
if ($list == true){ return $exts; }
|
||||
|
||||
if (isset($exts[$ext])) { return $exts[$ext]; }
|
||||
|
||||
$type = false;
|
||||
@ -556,6 +559,17 @@ function getMimeType($file, $ext="") {
|
||||
return 'application/octet-stream';
|
||||
}
|
||||
|
||||
|
||||
function getExtension ($mime_type){
|
||||
if(empty($mime_type)){
|
||||
return false;
|
||||
}
|
||||
|
||||
$extensions = getMimeType(null, null, true);
|
||||
$ext = array_search($mime_type, $extensions);
|
||||
return ($ext ?: false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
@ -801,17 +815,24 @@ function transload($url, $mfile) {
|
||||
$ch = curl_init($url);
|
||||
$fp = fopen($mfile, "w");
|
||||
|
||||
curl_setopt($ch, CURLOPT_FILE, $fp);
|
||||
curl_setopt($ch, CURLOPT_HEADER, 0);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_VERBOSE, 1);
|
||||
curl_setopt($ch, CURLOPT_HEADER, 1);
|
||||
curl_setopt($ch, CURLOPT_REFERER, $url);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, "Shimmie-".VERSION);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
|
||||
curl_exec($ch);
|
||||
$response = curl_exec($ch);
|
||||
|
||||
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
|
||||
$headers = http_parse_headers(implode("\n", preg_split('/\R/', rtrim(substr($response, 0, $header_size)))));
|
||||
$body = substr($response, $header_size);
|
||||
|
||||
curl_close($ch);
|
||||
fwrite($fp, $body);
|
||||
fclose($fp);
|
||||
|
||||
return true;
|
||||
return $headers;
|
||||
}
|
||||
|
||||
if($config->get_string("transload_engine") === "wget") {
|
||||
@ -839,12 +860,36 @@ function transload($url, $mfile) {
|
||||
fwrite($fp, $data);
|
||||
fclose($fp);
|
||||
|
||||
return true;
|
||||
$headers = http_parse_headers(implode("\n", $http_response_header));
|
||||
|
||||
return $headers;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!function_exists('http_parse_headers')) { #http://www.php.net/manual/en/function.http-parse-headers.php#112917
|
||||
function http_parse_headers ($raw_headers){
|
||||
$headers = array(); // $headers = [];
|
||||
|
||||
foreach (explode("\n", $raw_headers) as $i => $h) {
|
||||
$h = explode(':', $h, 2);
|
||||
|
||||
if (isset($h[1])){
|
||||
if(!isset($headers[$h[0]])){
|
||||
$headers[$h[0]] = trim($h[1]);
|
||||
}else if(is_array($headers[$h[0]])){
|
||||
$tmp = array_merge($headers[$h[0]],array(trim($h[1])));
|
||||
$headers[$h[0]] = $tmp;
|
||||
}else{
|
||||
$tmp = array_merge(array($headers[$h[0]]),array(trim($h[1])));
|
||||
$headers[$h[0]] = $tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $headers;
|
||||
}
|
||||
}
|
||||
|
||||
$_included = array();
|
||||
/**
|
||||
|
@ -45,7 +45,7 @@ class Artists extends Extension {
|
||||
|
||||
public function onSearchTermParse(SearchTermParseEvent $event) {
|
||||
$matches = array();
|
||||
if(preg_match("/^author=(.*)$/", $event->term, $matches)) {
|
||||
if(preg_match("/^author[=|:](.*)$/", $event->term, $matches)) {
|
||||
$char = $matches[1];
|
||||
$event->add_querylet(new Querylet("Author = :author_char", array("author_char"=>$char)));
|
||||
}
|
||||
|
@ -262,12 +262,12 @@ class CommentList extends Extension {
|
||||
|
||||
public function onSearchTermParse(SearchTermParseEvent $event) {
|
||||
$matches = array();
|
||||
if(preg_match("/comments(<|>|<=|>=|=)(\d+)/", $event->term, $matches)) {
|
||||
$cmp = $matches[1];
|
||||
if(preg_match("/^comments([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])(\d+)$/", $event->term, $matches)) {
|
||||
$cmp = ltrim($matches[1], ":") ?: "=";
|
||||
$comments = $matches[2];
|
||||
$event->add_querylet(new Querylet("images.id IN (SELECT DISTINCT image_id FROM comments GROUP BY image_id HAVING count(image_id) $cmp $comments)"));
|
||||
}
|
||||
else if(preg_match("/commented_by=(.*)/i", $event->term, $matches)) {
|
||||
else if(preg_match("/^commented_by[=|:](.*)$/i", $event->term, $matches)) {
|
||||
global $database;
|
||||
$user = User::by_name($matches[1]);
|
||||
if(!is_null($user)) {
|
||||
@ -279,7 +279,7 @@ class CommentList extends Extension {
|
||||
|
||||
$event->add_querylet(new Querylet("images.id IN (SELECT image_id FROM comments WHERE owner_id = $user_id)"));
|
||||
}
|
||||
else if(preg_match("/commented_by_userid=([0-9]+)/i", $event->term, $matches)) {
|
||||
else if(preg_match("/^commented_by_userno[=|:]([0-9]+)$/i", $event->term, $matches)) {
|
||||
$user_id = int_escape($matches[1]);
|
||||
$event->add_querylet(new Querylet("images.id IN (SELECT image_id FROM comments WHERE owner_id = $user_id)"));
|
||||
}
|
||||
@ -293,6 +293,8 @@ class CommentList extends Extension {
|
||||
$user_ratings = Ratings::get_user_privs($user);
|
||||
}
|
||||
|
||||
$where = SPEED_HAX ? "WHERE posted > now() - interval '24 hours'" : "";
|
||||
|
||||
$total_pages = $database->cache->get("comment_pages");
|
||||
if(empty($total_pages)) {
|
||||
$total_pages = (int)($database->get_one("SELECT COUNT(c1) FROM (SELECT COUNT(image_id) AS c1 FROM comments $where GROUP BY image_id) AS s1") / 10);
|
||||
@ -307,7 +309,6 @@ class CommentList extends Extension {
|
||||
$threads_per_page = 10;
|
||||
$start = $threads_per_page * ($current_page - 1);
|
||||
|
||||
$where = SPEED_HAX ? "WHERE posted > now() - interval '24 hours'" : "";
|
||||
$get_threads = "
|
||||
SELECT image_id,MAX(posted) AS latest
|
||||
FROM comments $where
|
||||
@ -320,13 +321,15 @@ class CommentList extends Extension {
|
||||
$images = array();
|
||||
while($row = $result->fetch()) {
|
||||
$image = Image::by_id($row["image_id"]);
|
||||
$comments = $this->get_comments($image->id);
|
||||
if(class_exists("Ratings")) {
|
||||
if(strpos($user_ratings, $image->rating) === FALSE) {
|
||||
$image = null; // this is "clever", I may live to regret it
|
||||
if (!is_null($image)) {
|
||||
$comments = $this->get_comments($image->id);
|
||||
if(class_exists("Ratings")) {
|
||||
if(strpos($user_ratings, $image->rating) === FALSE) {
|
||||
$image = null; // this is "clever", I may live to regret it
|
||||
}
|
||||
}
|
||||
if(!is_null($image)) $images[] = array($image, $comments);
|
||||
}
|
||||
if(!is_null($image)) $images[] = array($image, $comments);
|
||||
}
|
||||
|
||||
$this->theme->display_comment_list($images, $current_page, $total_pages, $user->can("create_comment"));
|
||||
@ -335,8 +338,7 @@ class CommentList extends Extension {
|
||||
|
||||
// get comments {{{
|
||||
private function get_recent_comments($count) {
|
||||
global $config;
|
||||
global $database;
|
||||
global $config, $database;
|
||||
$rows = $database->get_all("
|
||||
SELECT
|
||||
users.id as user_id, users.name as user_name, users.email as user_email, users.class as user_class,
|
||||
@ -356,8 +358,7 @@ class CommentList extends Extension {
|
||||
}
|
||||
|
||||
private function get_user_comments(/*int*/ $user_id, /*int*/ $count, /*int*/ $offset=0) {
|
||||
global $config;
|
||||
global $database;
|
||||
global $config, $database;
|
||||
$rows = $database->get_all("
|
||||
SELECT
|
||||
users.id as user_id, users.name as user_name, users.email as user_email, users.class as user_class,
|
||||
@ -378,8 +379,7 @@ class CommentList extends Extension {
|
||||
}
|
||||
|
||||
private function get_comments(/*int*/ $image_id) {
|
||||
global $config;
|
||||
global $database;
|
||||
global $config, $database;
|
||||
$i_image_id = int_escape($image_id);
|
||||
$rows = $database->get_all("
|
||||
SELECT
|
||||
@ -402,9 +402,7 @@ class CommentList extends Extension {
|
||||
|
||||
// add / remove / edit comments {{{
|
||||
private function is_comment_limit_hit() {
|
||||
global $user;
|
||||
global $config;
|
||||
global $database;
|
||||
global $user, $config, $database;
|
||||
|
||||
// sqlite fails at intervals
|
||||
if($database->get_driver_name() === "sqlite") return false;
|
||||
@ -493,9 +491,9 @@ class CommentList extends Extension {
|
||||
}
|
||||
return $pagenum;
|
||||
}
|
||||
|
||||
private function add_comment_wrapper(/*int*/ $image_id, User $user, /*string*/ $comment) {
|
||||
global $database;
|
||||
global $config;
|
||||
global $database, $config;
|
||||
|
||||
// basic sanity checks
|
||||
if(!$user->can("create_comment")) {
|
||||
|
@ -54,14 +54,6 @@ class DanbooruApi extends Extension {
|
||||
}
|
||||
}
|
||||
|
||||
public function onSearchTermParse(SearchTermParseEvent $event) {
|
||||
$matches = array();
|
||||
if(preg_match("/^md5:([0-9a-fA-F]*)$/i", $event->term, $matches)) {
|
||||
$hash = strtolower($matches[1]);
|
||||
$event->add_querylet(new Querylet("images.hash = '$hash'")); // :-O
|
||||
}
|
||||
}
|
||||
|
||||
// Danbooru API
|
||||
private function api_danbooru(PageRequestEvent $event)
|
||||
{
|
||||
|
@ -117,12 +117,12 @@ class Favorites extends Extension {
|
||||
|
||||
public function onSearchTermParse(SearchTermParseEvent $event) {
|
||||
$matches = array();
|
||||
if(preg_match("/favorites(<|>|<=|>=|=)(\d+)/", $event->term, $matches)) {
|
||||
$cmp = $matches[1];
|
||||
if(preg_match("/^favorites([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])(\d+)$/", $event->term, $matches)) {
|
||||
$cmp = ltrim($matches[1], ":") ?: "=";
|
||||
$favorites = $matches[2];
|
||||
$event->add_querylet(new Querylet("images.id IN (SELECT id FROM images WHERE favorites $cmp $favorites)"));
|
||||
}
|
||||
else if(preg_match("/favorited_by=(.*)/i", $event->term, $matches)) {
|
||||
else if(preg_match("/^favorited_by[=|:](.*)$/i", $event->term, $matches)) {
|
||||
global $database;
|
||||
$user = User::by_name($matches[1]);
|
||||
if(!is_null($user)) {
|
||||
@ -134,7 +134,7 @@ class Favorites extends Extension {
|
||||
|
||||
$event->add_querylet(new Querylet("images.id IN (SELECT image_id FROM user_favorites WHERE user_id = $user_id)"));
|
||||
}
|
||||
else if(preg_match("/favorited_by_userno=([0-9]+)/i", $event->term, $matches)) {
|
||||
else if(preg_match("/^favorited_by_userno[=|:](\d+)$/i", $event->term, $matches)) {
|
||||
$user_id = int_escape($matches[1]);
|
||||
$event->add_querylet(new Querylet("images.id IN (SELECT image_id FROM user_favorites WHERE user_id = $user_id)"));
|
||||
}
|
||||
|
@ -13,6 +13,10 @@ class PixelFileHandlerTheme extends Themelet {
|
||||
foreach ($exif as $key => $section) {
|
||||
foreach ($section as $name => $val) {
|
||||
if($key == "IFD0") {
|
||||
// Cheap fix for array'd values in EXIF-data
|
||||
if (is_array($val)) {
|
||||
$val = implode(',', $val);
|
||||
}
|
||||
$head .= html_escape("$name: $val")."<br>\n";
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,16 @@
|
||||
* <li>size>=500x500 -- no small images
|
||||
* <li>size<1000x1000 -- no large images
|
||||
* </ul>
|
||||
* <li>width (=, <, >, <=, >=) width, eg
|
||||
* <ul>
|
||||
* <li>width=1024 -- find images with 1024 width
|
||||
* <li>width>2000 -- find images bigger than 2000 width
|
||||
* </ul>
|
||||
* <li>height (=, <, >, <=, >=) height, eg
|
||||
* <ul>
|
||||
* <li>height=768 -- find images with 768 height
|
||||
* <li>height>1000 -- find images bigger than 1000 height
|
||||
* </ul>
|
||||
* <li>ratio (=, <, >, <=, >=) width : height, eg
|
||||
* <ul>
|
||||
* <li>ratio=4:3, ratio=16:9 -- standard wallpaper
|
||||
@ -38,41 +48,67 @@
|
||||
* <li>id<20 -- search only the first few images
|
||||
* <li>id>=500 -- search later images
|
||||
* </ul>
|
||||
* <li>user=Username, eg
|
||||
* <li>user=Username & poster=Username, eg
|
||||
* <ul>
|
||||
* <li>user=Shish -- find all of Shish's posts
|
||||
* <li>poster=Shish -- same as above
|
||||
* </ul>
|
||||
* <li>hash=md5sum, eg
|
||||
* <li>user_id=userID & poster_id=userID, eg
|
||||
* <ul>
|
||||
* <li>user_id=2 -- find all posts by user id 2
|
||||
* <li>poster_id=2 -- same as above
|
||||
* </ul>
|
||||
* <li>hash=md5sum & md5=md5sum, eg
|
||||
* <ul>
|
||||
* <li>hash=bf5b59173f16b6937a4021713dbfaa72 -- find the "Taiga want up!" image
|
||||
* <li>md5=bf5b59173f16b6937a4021713dbfaa72 -- same as above
|
||||
* </ul>
|
||||
* <li>filetype=type, eg
|
||||
* <li>filetype=type & ext=type, eg
|
||||
* <ul>
|
||||
* <li>filetype=png -- find all PNG images
|
||||
* <li>ext=png -- same as above
|
||||
* </ul>
|
||||
* <li>filename=blah, eg
|
||||
* <li>filename=blah & name=blah, eg
|
||||
* <ul>
|
||||
* <li>filename=kitten -- find all images with "kitten" in the original filename
|
||||
* <li>name=kitten -- same as above
|
||||
* </ul>
|
||||
* <li>posted (=, <, >, <=, >=) date, eg
|
||||
* <ul>
|
||||
* <li>posted>=2009-12-25 posted<=2010-01-01 -- find images posted between christmas and new year
|
||||
* </ul>
|
||||
* <li>tags (=, <, >, <=, >=) count, eg
|
||||
* <ul>
|
||||
* <li>tags=1 -- search for images with only 1 tag
|
||||
* <li>tags>=10 -- search for images with 10 or more tags
|
||||
* <li>tags<25 -- search for images with less than 25 tags
|
||||
* </ul>
|
||||
* <li>source=(URL, any, none) eg
|
||||
* <ul>
|
||||
* <li>source=http://example.com -- find all images with "http://example.com" in the source
|
||||
* <li>source=any -- find all images with a source
|
||||
* <li>source=none -- find all images without a source
|
||||
* </ul>
|
||||
* <li>order=(id, width, height, filesize, filename)_(ASC, DESC), eg
|
||||
* <ul>
|
||||
* <li>order=width -- find all images sorted from highest > lowest width
|
||||
* <li>order=filesize_asc -- find all images sorted from lowest > highest filesize
|
||||
* </ul>
|
||||
* </ul>
|
||||
* <p>Search items can be combined to search for images which match both,
|
||||
* or you can stick "-" in front of an item to search for things that don't
|
||||
* match it.
|
||||
* <p>Metatags can be followed by ":" rather than "=" if you prefer.
|
||||
* <br />I.E: "posted:2014-01-01", "id:>=500" etc.
|
||||
* <p>Some search methods provided by extensions:
|
||||
* <ul>
|
||||
* <li>Danbooru API
|
||||
* <ul>
|
||||
* <li>md5:[hash] -- same as "hash=", but the API calls it by a different name
|
||||
* </ul>
|
||||
* <li>Numeric Score
|
||||
* <ul>
|
||||
* <li>score (=, <, >, <=, >=) number -- seach by score
|
||||
* <li>upvoted_by=Username -- search for a user's likes
|
||||
* <li>downvoted_by=Username -- search for a user's dislikes
|
||||
* <li>upvoted_by_id=UserID -- search for a user's likes by user ID
|
||||
* <li>downvoted_by_id=UserID -- search for a user's dislikes by user ID
|
||||
* </ul>
|
||||
* <li>Image Rating
|
||||
* <ul>
|
||||
@ -81,11 +117,29 @@
|
||||
* <li>Favorites
|
||||
* <ul>
|
||||
* <li>favorites (=, <, >, <=, >=) number -- search for images favourited a certain number of times
|
||||
* <li>favourited_by=Username -- search for a user's choices
|
||||
* <li>favourited_by=Username -- search for a user's choices by username
|
||||
* <li>favorited_by_userno=UserID -- search for a user's choice by userID
|
||||
* </ul>
|
||||
* <li>Notes
|
||||
* <ul>
|
||||
* <li>notes (=, <, >, <=, >=) number -- search by the number of notes an image has
|
||||
* <li>notes_by=Username -- search for images containing notes created by username
|
||||
* <li>notes_by_userno=UserID -- search for images containing notes created by userID
|
||||
* </ul>
|
||||
* <li>Artists
|
||||
* <ul>
|
||||
* <li>author=ArtistName -- search for images by artist
|
||||
* </ul>
|
||||
* <li>Image Comments
|
||||
* <ul>
|
||||
* <li>comments (=, <, >, <=, >=) number -- search for images by number of comments
|
||||
* <li>commented_by=Username -- search for images containing user's comments by username
|
||||
* <li>commented_by_userno=UserID -- search for images containing user's comments by userID
|
||||
* </ul>
|
||||
* <li>Pools
|
||||
* <ul>
|
||||
* <li>pool=(PoolID, any, none) -- search for images in a pool by PoolID.
|
||||
* <li>pool_by_name=PoolName -- search for images in a pool by PoolName. underscores are replaced with spaces
|
||||
* </ul>
|
||||
* </ul>
|
||||
*/
|
||||
@ -141,6 +195,7 @@ class Index extends Extension {
|
||||
global $config;
|
||||
$config->set_default_int("index_images", 24);
|
||||
$config->set_default_bool("index_tips", true);
|
||||
$config->set_default_string("index_order", "id DESC");
|
||||
}
|
||||
|
||||
public function onPageRequest(PageRequestEvent $event) {
|
||||
@ -240,48 +295,70 @@ class Index extends Extension {
|
||||
public function onSearchTermParse(SearchTermParseEvent $event) {
|
||||
$matches = array();
|
||||
// check for tags first as tag based searches are more common.
|
||||
if(preg_match("/tags(<|>|<=|>=|=)(\d+)/", $event->term, $matches)) {
|
||||
$cmp = $matches[1];
|
||||
if(preg_match("/^tags([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])(\d+)$/", $event->term, $matches)) {
|
||||
$cmp = ltrim($matches[1], ":") ?: "=";
|
||||
$tags = $matches[2];
|
||||
$event->add_querylet(new Querylet('images.id IN (SELECT DISTINCT image_id FROM image_tags GROUP BY image_id HAVING count(image_id) '.$cmp.' '.$tags.')'));
|
||||
}
|
||||
else if(preg_match("/^ratio(<|>|<=|>=|=)(\d+):(\d+)$/", $event->term, $matches)) {
|
||||
$cmp = $matches[1];
|
||||
else if(preg_match("/^ratio([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])(\d+):(\d+)$/", $event->term, $matches)) {
|
||||
$cmp = preg_replace('/^:/', '=', $matches[1]);
|
||||
$args = array("width{$this->stpen}"=>int_escape($matches[2]), "height{$this->stpen}"=>int_escape($matches[3]));
|
||||
$event->add_querylet(new Querylet("width / height $cmp :width{$this->stpen} / :height{$this->stpen}", $args));
|
||||
}
|
||||
else if(preg_match("/^(filesize|id)(<|>|<=|>=|=)(\d+[kmg]?b?)$/i", $event->term, $matches)) {
|
||||
else if(preg_match("/^(filesize|id)([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])(\d+[kmg]?b?)$/i", $event->term, $matches)) {
|
||||
$col = $matches[1];
|
||||
$cmp = $matches[2];
|
||||
$cmp = ltrim($matches[2], ":") ?: "=";
|
||||
$val = parse_shorthand_int($matches[3]);
|
||||
$event->add_querylet(new Querylet("images.$col $cmp :val{$this->stpen}", array("val{$this->stpen}"=>$val)));
|
||||
}
|
||||
else if(preg_match("/^(hash|md5)=([0-9a-fA-F]*)$/i", $event->term, $matches)) {
|
||||
else if(preg_match("/^(hash|md5)[=|:]([0-9a-fA-F]*)$/i", $event->term, $matches)) {
|
||||
$hash = strtolower($matches[2]);
|
||||
$event->add_querylet(new Querylet('images.hash = :hash', array("hash" => $hash)));
|
||||
}
|
||||
else if(preg_match("/^(filetype|ext)=([a-zA-Z0-9]*)$/i", $event->term, $matches)) {
|
||||
else if(preg_match("/^(filetype|ext)[=|:]([a-zA-Z0-9]*)$/i", $event->term, $matches)) {
|
||||
$ext = strtolower($matches[2]);
|
||||
$event->add_querylet(new Querylet('images.ext = :ext', array("ext" => $ext)));
|
||||
}
|
||||
else if(preg_match("/^(filename|name)=([a-zA-Z0-9]*)$/i", $event->term, $matches)) {
|
||||
else if(preg_match("/^(filename|name)[=|:]([a-zA-Z0-9]*)$/i", $event->term, $matches)) {
|
||||
$filename = strtolower($matches[2]);
|
||||
$event->add_querylet(new Querylet("images.filename LIKE :filename{$this->stpen}", array("filename{$this->stpen}"=>"%$filename%")));
|
||||
}
|
||||
else if(preg_match("/^(source)=([a-zA-Z0-9]*)$/i", $event->term, $matches)) {
|
||||
$filename = strtolower($matches[2]);
|
||||
$event->add_querylet(new Querylet('images.source LIKE :src', array("src"=>"%$filename%")));
|
||||
else if(preg_match("/^(source)[=|:](.*)$/i", $event->term, $matches)) {
|
||||
$source = strtolower($matches[2]);
|
||||
|
||||
if(preg_match("/^(any|none)$/", $source)){
|
||||
$not = ($source == "any" ? "NOT" : "");
|
||||
$event->add_querylet(new Querylet("images.source IS $not NULL"));
|
||||
}else{
|
||||
$event->add_querylet(new Querylet('images.source LIKE :src', array("src"=>"%$source%")));
|
||||
}
|
||||
}
|
||||
else if(preg_match("/^posted(<|>|<=|>=|=)([0-9-]*)$/", $event->term, $matches)) {
|
||||
$cmp = $matches[1];
|
||||
else if(preg_match("/^posted([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])([0-9-]*)$/", $event->term, $matches)) {
|
||||
$cmp = ltrim($matches[1], ":") ?: "=";
|
||||
$val = $matches[2];
|
||||
$event->add_querylet(new Querylet("images.posted $cmp :posted{$this->stpen}", array("posted{$this->stpen}"=>$val)));
|
||||
}
|
||||
else if(preg_match("/^size(<|>|<=|>=|=)(\d+)x(\d+)$/", $event->term, $matches)) {
|
||||
$cmp = $matches[1];
|
||||
else if(preg_match("/^size([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])(\d+)x(\d+)$/", $event->term, $matches)) {
|
||||
$cmp = ltrim($matches[1], ":") ?: "=";
|
||||
$args = array("width{$this->stpen}"=>int_escape($matches[2]), "height{$this->stpen}"=>int_escape($matches[3]));
|
||||
$event->add_querylet(new Querylet("width $cmp :width{$this->stpen} AND height $cmp :height{$this->stpen}", $args));
|
||||
}
|
||||
else if(preg_match("/^width([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])(\d+)$/", $event->term, $matches)) {
|
||||
$cmp = ltrim($matches[1], ":") ?: "=";
|
||||
$event->add_querylet(new Querylet("width $cmp :width{$this->stpen}", array("width{$this->stpen}"=>int_escape($matches[2]))));
|
||||
}
|
||||
else if(preg_match("/^height([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])(\d+)$/", $event->term, $matches)) {
|
||||
$cmp = ltrim($matches[1], ":") ?: "=";
|
||||
$event->add_querylet(new Querylet("height $cmp :height{$this->stpen}",array("height{$this->stpen}"=>int_escape($matches[2]))));
|
||||
}
|
||||
else if(preg_match("/^order[=|:](id|width|height|filesize|filename)[_]?(desc|asc)?$/i", $event->term, $matches)){
|
||||
global $order_sql;
|
||||
$ord = strtolower($matches[1]);
|
||||
$default_order_for_column = preg_match("/^(id|filename)$/", $matches[1]) ? "ASC" : "DESC";
|
||||
$sort = isset($matches[2]) ? strtoupper($matches[2]) : $default_order_for_column;
|
||||
$order_sql = "$ord $sort";
|
||||
$event->add_querylet(new Querylet("1=1")); //small hack to avoid metatag being treated as normal tag
|
||||
}
|
||||
|
||||
$this->stpen++;
|
||||
}
|
||||
|
@ -210,16 +210,16 @@ class Notes extends Extension {
|
||||
*/
|
||||
public function onSearchTermParse(SearchTermParseEvent $event) {
|
||||
$matches = array();
|
||||
if(preg_match("/note=(.*)/i", $event->term, $matches)) {
|
||||
if(preg_match("/^note[=|:](.*)$/i", $event->term, $matches)) {
|
||||
$notes = int_escape($matches[1]);
|
||||
$event->add_querylet(new Querylet("images.id IN (SELECT image_id FROM notes WHERE note = $notes)"));
|
||||
}
|
||||
else if(preg_match("/notes(<|>|<=|>=|=)(\d+)/", $event->term, $matches)) {
|
||||
$cmp = $matches[1];
|
||||
else if(preg_match("/^notes([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])(\d+)%/", $event->term, $matches)) {
|
||||
$cmp = ltrim($matches[1], ":") ?: "=";
|
||||
$notes = $matches[2];
|
||||
$event->add_querylet(new Querylet("images.id IN (SELECT id FROM images WHERE notes $cmp $notes)"));
|
||||
}
|
||||
else if(preg_match("/notes_by=(.*)/i", $event->term, $matches)) {
|
||||
else if(preg_match("/^notes_by[=|:](.*)$/i", $event->term, $matches)) {
|
||||
global $database;
|
||||
$user = User::by_name($matches[1]);
|
||||
if(!is_null($user)) {
|
||||
@ -231,7 +231,7 @@ class Notes extends Extension {
|
||||
|
||||
$event->add_querylet(new Querylet("images.id IN (SELECT image_id FROM notes WHERE user_id = $user_id)"));
|
||||
}
|
||||
else if(preg_match("/notes_by_userno=([0-9]+)/i", $event->term, $matches)) {
|
||||
else if(preg_match("/^notes_by_userno[=|:](\d+)$/i", $event->term, $matches)) {
|
||||
$user_id = int_escape($matches[1]);
|
||||
$event->add_querylet(new Querylet("images.id IN (SELECT image_id FROM notes WHERE user_id = $user_id)"));
|
||||
}
|
||||
|
@ -31,16 +31,14 @@ class NumericScore extends Extension {
|
||||
public function onDisplayingImage(DisplayingImageEvent $event) {
|
||||
global $user, $page;
|
||||
if(!$user->is_anonymous()) {
|
||||
$html = $this->theme->get_voter_html($event->image);
|
||||
$page->add_block(new Block("Image Score", $html, "left", 20));
|
||||
$this->theme->get_voter($event->image);
|
||||
}
|
||||
}
|
||||
|
||||
public function onUserPageBuilding(UserPageBuildingEvent $event) {
|
||||
global $page, $user;
|
||||
if($user->can("edit_other_vote")) {
|
||||
$html = $this->theme->get_nuller_html($event->display_user);
|
||||
$page->add_block(new Block("Votes", $html, "main", 60));
|
||||
$this->theme->get_nuller($event->display_user);
|
||||
}
|
||||
}
|
||||
|
||||
@ -219,12 +217,12 @@ class NumericScore extends Extension {
|
||||
|
||||
public function onSearchTermParse(SearchTermParseEvent $event) {
|
||||
$matches = array();
|
||||
if(preg_match("/^score(<|<=|=|>=|>)(-?\d+)$/", $event->term, $matches)) {
|
||||
$cmp = $matches[1];
|
||||
if(preg_match("/^score([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])(-?\d+)$/", $event->term, $matches)) {
|
||||
$cmp = ltrim($matches[1], ":") ?: "=";
|
||||
$score = $matches[2];
|
||||
$event->add_querylet(new Querylet("numeric_score $cmp $score"));
|
||||
}
|
||||
if(preg_match("/^upvoted_by=(.*)$/", $event->term, $matches)) {
|
||||
if(preg_match("/^upvoted_by[=|:](.*)$/", $event->term, $matches)) {
|
||||
$duser = User::by_name($matches[1]);
|
||||
if(is_null($duser)) {
|
||||
throw new SearchTermParseException(
|
||||
@ -234,7 +232,7 @@ class NumericScore extends Extension {
|
||||
"images.id in (SELECT image_id FROM numeric_score_votes WHERE user_id=:ns_user_id AND score=1)",
|
||||
array("ns_user_id"=>$duser->id)));
|
||||
}
|
||||
if(preg_match("/^downvoted_by=(.*)$/", $event->term, $matches)) {
|
||||
if(preg_match("/^downvoted_by[=|:](.*)$/", $event->term, $matches)) {
|
||||
$duser = User::by_name($matches[1]);
|
||||
if(is_null($duser)) {
|
||||
throw new SearchTermParseException(
|
||||
@ -244,13 +242,13 @@ class NumericScore extends Extension {
|
||||
"images.id in (SELECT image_id FROM numeric_score_votes WHERE user_id=:ns_user_id AND score=-1)",
|
||||
array("ns_user_id"=>$duser->id)));
|
||||
}
|
||||
if(preg_match("/^upvoted_by_id=(\d+)$/", $event->term, $matches)) {
|
||||
if(preg_match("/^upvoted_by_id[=|:](\d+)$/", $event->term, $matches)) {
|
||||
$iid = int_escape($matches[1]);
|
||||
$event->add_querylet(new Querylet(
|
||||
"images.id in (SELECT image_id FROM numeric_score_votes WHERE user_id=:ns_user_id AND score=1)",
|
||||
array("ns_user_id"=>$iid)));
|
||||
}
|
||||
if(preg_match("/^downvoted_by_id=(\d+)$/", $event->term, $matches)) {
|
||||
if(preg_match("/^downvoted_by_id[=|:](\d+)$/", $event->term, $matches)) {
|
||||
$iid = int_escape($matches[1]);
|
||||
$event->add_querylet(new Querylet(
|
||||
"images.id in (SELECT image_id FROM numeric_score_votes WHERE user_id=:ns_user_id AND score=-1)",
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
class NumericScoreTheme extends Themelet {
|
||||
public function get_voter_html(Image $image) {
|
||||
global $user;
|
||||
public function get_voter(Image $image) {
|
||||
global $user, $page;
|
||||
$i_image_id = int_escape($image->id);
|
||||
$i_score = int_escape($image->numeric_score);
|
||||
|
||||
@ -46,11 +46,11 @@ class NumericScoreTheme extends Themelet {
|
||||
</div>
|
||||
";
|
||||
}
|
||||
return $html;
|
||||
$page->add_block(new Block("Image Score", $html, "left", 20));
|
||||
}
|
||||
|
||||
public function get_nuller_html(User $duser) {
|
||||
global $user;
|
||||
public function get_nuller(User $duser) {
|
||||
global $user, $page;
|
||||
$html = "
|
||||
<form action='".make_link("numeric_score/remove_votes_by")."' method='POST'>
|
||||
".$user->get_auth_html()."
|
||||
@ -58,7 +58,7 @@ class NumericScoreTheme extends Themelet {
|
||||
<input type='submit' value='Delete all votes by this user'>
|
||||
</form>
|
||||
";
|
||||
return $html;
|
||||
$page->add_block(new Block("Votes", $html, "main", 60));
|
||||
}
|
||||
|
||||
public function view_popular($images, $dte) {
|
||||
|
@ -1,8 +1,10 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Name: Ouroboros API
|
||||
* Author: Diftraku <diftraku[at]derpy.me>
|
||||
* Description: Ouroboros-like API for Shimmie
|
||||
* Version: 0.2
|
||||
* Documentation:
|
||||
* Currently working features
|
||||
* <ul>
|
||||
@ -10,6 +12,7 @@
|
||||
* <ul>
|
||||
* <li>Index/List</li>
|
||||
* <li>Show</li>
|
||||
* <li>Create</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>Tag:
|
||||
@ -210,7 +213,10 @@ class _SafeOuroborosImage
|
||||
$this->parent_id = null;
|
||||
if (defined('ENABLED_EXTS')) {
|
||||
if (strstr(ENABLED_EXTS, 'rating') !== false) {
|
||||
//$this->rating = $img->rating;
|
||||
// 'u' is not a "valid" rating
|
||||
if ($img->rating == 's' || $img->rating == 'q' || $img->rating == 'e') {
|
||||
$this->rating = $img->rating;
|
||||
}
|
||||
}
|
||||
if (strstr(ENABLED_EXTS, 'numeric_score') !== false) {
|
||||
$this->score = $img->numeric_score;
|
||||
@ -234,6 +240,76 @@ class _SafeOuroborosImage
|
||||
$this->sample_url = make_http($img->get_image_link());
|
||||
}
|
||||
}
|
||||
|
||||
class OuroborosPost extends _SafeOuroborosImage
|
||||
{
|
||||
/**
|
||||
* Multipart File
|
||||
* @var array
|
||||
*/
|
||||
public $file = array();
|
||||
|
||||
/**
|
||||
* Create with rating locked
|
||||
* @var bool
|
||||
*/
|
||||
public $is_rating_locked = false;
|
||||
|
||||
/**
|
||||
* Create with notes locked
|
||||
* @var bool
|
||||
*/
|
||||
public $is_note_locked = false;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize an OuroborosPost for creation
|
||||
* Mainly just acts as a wrapper and validation layer
|
||||
* @TODO implement more validation from OuroborosAPI
|
||||
* @param array $post
|
||||
*/
|
||||
public function __construct(array $post)
|
||||
{
|
||||
if (array_key_exists('tags', $post)) {
|
||||
$this->tags = $post['tags'];
|
||||
}
|
||||
if (array_key_exists('file', $post)) {
|
||||
if (!is_null($post['file'])) {
|
||||
assert(is_array($post['file']));
|
||||
assert(array_key_exists('tmp_name', $post['file']));
|
||||
assert(array_key_exists('name', $post['file']));
|
||||
$this->file = $post['file'];
|
||||
}
|
||||
}
|
||||
if (array_key_exists('rating', $post)) {
|
||||
assert(
|
||||
$post['rating'] == 's' ||
|
||||
$post['rating'] == 'q' ||
|
||||
$post['rating'] == 'e'
|
||||
);
|
||||
$this->rating = $post['rating'];
|
||||
}
|
||||
if (array_key_exists('source', $post)) {
|
||||
$this->file_url = $post['source'];
|
||||
}
|
||||
if (array_key_exists('sourceurl', $post)) {
|
||||
$this->source = $post['sourceurl'];
|
||||
}
|
||||
if (array_key_exists('description', $post)) {
|
||||
$this->description = $post['description'];
|
||||
}
|
||||
if (array_key_exists('is_rating_locked', $post)) {
|
||||
$this->is_rating_locked = $post['is_rating_locked'];
|
||||
}
|
||||
if (array_key_exists('is_note_locked', $post)) {
|
||||
$this->is_note_locked = $post['is_note_locked'];
|
||||
}
|
||||
if (array_key_exists('parent_id', $post)) {
|
||||
$this->parent_id = $post['parent_id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class _SafeOuroborosTag
|
||||
{
|
||||
public $ambiguous = false;
|
||||
@ -249,19 +325,43 @@ class _SafeOuroborosTag
|
||||
$this->name = $tag['tag'];
|
||||
}
|
||||
}
|
||||
|
||||
class OuroborosAPI extends Extension
|
||||
{
|
||||
private $event;
|
||||
const ERROR_HTTP_200 = 'Request was successful';
|
||||
const ERROR_HTTP_403 = 'Access denied';
|
||||
const ERROR_HTTP_404 = 'Not found';
|
||||
const ERROR_HTTP_420 = 'Record could not be saved';
|
||||
const ERROR_HTTP_421 = 'User is throttled, try again later';
|
||||
const ERROR_HTTP_422 = 'The resource is locked and cannot be modified';
|
||||
const ERROR_HTTP_423 = 'Resource already exists';
|
||||
const ERROR_HTTP_424 = 'The given parameters were invalid';
|
||||
const ERROR_HTTP_500 = 'Some unknown error occurred on the server';
|
||||
const ERROR_HTTP_503 = 'Server cannot currently handle the request, try again later';
|
||||
private $type;
|
||||
const HEADER_HTTP_200 = 'OK';
|
||||
const MSG_HTTP_200 = 'Request was successful';
|
||||
|
||||
const HEADER_HTTP_403 = 'Forbidden';
|
||||
const MSG_HTTP_403 = 'Access denied';
|
||||
|
||||
const HEADER_HTTP_404 = 'Not found';
|
||||
const MSG_HTTP_404 = 'Not found';
|
||||
|
||||
const HEADER_HTTP_418 = 'I\'m a teapot';
|
||||
const MSG_HTTP_418 = 'Short and stout';
|
||||
|
||||
const HEADER_HTTP_420 = 'Invalid Record';
|
||||
const MSG_HTTP_420 = 'Record could not be saved';
|
||||
|
||||
const HEADER_HTTP_421 = 'User Throttled';
|
||||
const MSG_HTTP_421 = 'User is throttled, try again later';
|
||||
|
||||
const HEADER_HTTP_422 = 'Locked';
|
||||
const MSG_HTTP_422 = 'The resource is locked and cannot be modified';
|
||||
|
||||
const HEADER_HTTP_423 = 'Already Exists';
|
||||
const MSG_HTTP_423 = 'Resource already exists';
|
||||
|
||||
const HEADER_HTTP_424 = 'Invalid Parameters';
|
||||
const MSG_HTTP_424 = 'The given parameters were invalid';
|
||||
|
||||
const HEADER_HTTP_500 = 'Internal Server Error';
|
||||
const MSG_HTTP_500 = 'Some unknown error occurred on the server';
|
||||
|
||||
const HEADER_HTTP_503 = 'Service Unavailable';
|
||||
const MSG_HTTP_503 = 'Server cannot currently handle the request, try again later';
|
||||
|
||||
const ERROR_POST_CREATE_MD5 = 'MD5 mismatch';
|
||||
const ERROR_POST_CREATE_DUPE = 'Duplicate';
|
||||
@ -272,120 +372,462 @@ class OuroborosAPI extends Extension
|
||||
|
||||
if (preg_match("%\.(xml|json)$%", implode('/', $event->args), $matches) === 1) {
|
||||
$this->event = $event;
|
||||
$type = $matches[1];
|
||||
if ($type == 'json') {
|
||||
$this->type = $matches[1];
|
||||
if ($this->type == 'json') {
|
||||
$page->set_type('application/json; charset=utf-8');
|
||||
}
|
||||
elseif ($type == 'xml') {
|
||||
$page->set_type('text/xml');
|
||||
} elseif ($this->type == 'xml') {
|
||||
$page->set_type('text/xml; charset=utf-8');
|
||||
}
|
||||
$page->set_mode('data');
|
||||
$this->tryAuth();
|
||||
|
||||
if ($event->page_matches('post')) {
|
||||
if ($this->match('create')) {
|
||||
// Create
|
||||
$post = array(
|
||||
'tags' => !empty($_REQUEST['post']['tags']) ? filter_var($_REQUEST['post']['tags'], FILTER_SANITIZE_STRING) : 'tagme',
|
||||
'file' => !empty($_REQUEST['post']['file']) ? filter_var($_REQUEST['post']['file'], FILTER_UNSAFE_RAW) : null,
|
||||
'rating' => !empty($_REQUEST['post']['rating']) ? filter_var($_REQUEST['post']['rating'], FILTER_SANITIZE_NUMBER_INT) : null,
|
||||
'source' => !empty($_REQUEST['post']['source']) ? filter_var($_REQUEST['post']['source'], FILTER_SANITIZE_URL) : null,
|
||||
'sourceurl' => !empty($_REQUEST['post']['sourceurl']) ? filter_var($_REQUEST['post']['sourceurl'], FILTER_SANITIZE_URL) : '',
|
||||
'description' => !empty($_REQUEST['post']['description']) ? filter_var($_REQUEST['post']['description'], FILTER_SANITIZE_STRING) : '',
|
||||
'is_rating_locked' => !empty($_REQUEST['post']['is_rating_locked']) ? filter_var($_REQUEST['post']['is_rating_locked'], FILTER_SANITIZE_NUMBER_INT) : false,
|
||||
'is_note_locked' => !empty($_REQUEST['post']['is_note_locked']) ? filter_var($_REQUEST['post']['is_note_locked'], FILTER_SANITIZE_NUMBER_INT) : false,
|
||||
'parent_id' => !empty($_REQUEST['post']['parent_id']) ? filter_var($_REQUEST['post']['parent_id'], FILTER_SANITIZE_NUMBER_INT) : null,
|
||||
);
|
||||
$md5 = !empty($_REQUEST['md5']) ? filter_var($_REQUEST['md5'], FILTER_SANITIZE_STRING) : null;
|
||||
// @TODO Should move the validation logic into OuroborosPost instead?
|
||||
if ($user->can("create_image")) {
|
||||
$post = array(
|
||||
'tags' => !empty($_REQUEST['post']['tags']) ? filter_var(
|
||||
urldecode($_REQUEST['post']['tags']),
|
||||
FILTER_SANITIZE_STRING
|
||||
) : 'tagme',
|
||||
'file' => !empty($_REQUEST['post']['file']) ? filter_var(
|
||||
$_REQUEST['post']['file'],
|
||||
FILTER_UNSAFE_RAW
|
||||
) : null,
|
||||
'rating' => !empty($_REQUEST['post']['rating']) ? filter_var(
|
||||
$_REQUEST['post']['rating'],
|
||||
FILTER_SANITIZE_NUMBER_INT
|
||||
) : 'q',
|
||||
'source' => !empty($_REQUEST['post']['source']) ? filter_var(
|
||||
urldecode($_REQUEST['post']['source']),
|
||||
FILTER_SANITIZE_URL
|
||||
) : null,
|
||||
'sourceurl' => !empty($_REQUEST['post']['sourceurl']) ? filter_var(
|
||||
urldecode($_REQUEST['post']['sourceurl']),
|
||||
FILTER_SANITIZE_URL
|
||||
) : '',
|
||||
'description' => !empty($_REQUEST['post']['description']) ? filter_var(
|
||||
$_REQUEST['post']['description'],
|
||||
FILTER_SANITIZE_STRING
|
||||
) : '',
|
||||
'is_rating_locked' => !empty($_REQUEST['post']['is_rating_locked']) ? filter_var(
|
||||
$_REQUEST['post']['is_rating_locked'],
|
||||
FILTER_SANITIZE_NUMBER_INT
|
||||
) : false,
|
||||
'is_note_locked' => !empty($_REQUEST['post']['is_note_locked']) ? filter_var(
|
||||
$_REQUEST['post']['is_note_locked'],
|
||||
FILTER_SANITIZE_NUMBER_INT
|
||||
) : false,
|
||||
'parent_id' => !empty($_REQUEST['post']['parent_id']) ? filter_var(
|
||||
$_REQUEST['post']['parent_id'],
|
||||
FILTER_SANITIZE_NUMBER_INT
|
||||
) : null,
|
||||
);
|
||||
$md5 = !empty($_REQUEST['md5']) ? filter_var($_REQUEST['md5'], FILTER_SANITIZE_STRING) : null;
|
||||
$this->postCreate(new OuroborosPost($post), $md5);
|
||||
} else {
|
||||
$this->sendResponse(403, 'You cannot create new posts');
|
||||
}
|
||||
|
||||
}
|
||||
elseif ($this->match('update')) {
|
||||
} elseif ($this->match('update')) {
|
||||
// Update
|
||||
}
|
||||
elseif ($this->match('show')) {
|
||||
//@todo add post update
|
||||
} elseif ($this->match('show')) {
|
||||
// Show
|
||||
if (isset($_REQUEST['id'])) {
|
||||
$id = $_REQUEST['id'];
|
||||
$posts = array();
|
||||
$posts[] = new _SafeOuroborosImage(Image::by_id($id));
|
||||
$page->set_data(json_encode($posts));
|
||||
}
|
||||
else {
|
||||
$page->set_data(json_encode(array()));
|
||||
}
|
||||
}
|
||||
elseif ($this->match('index') || $this->match('list')) {
|
||||
$id = !empty($_REQUEST['id']) ? filter_var($_REQUEST['id'], FILTER_SANITIZE_NUMBER_INT) : null;
|
||||
$this->postShow($id);
|
||||
} elseif ($this->match('index') || $this->match('list')) {
|
||||
// List
|
||||
$limit = !empty($_REQUEST['limit']) ? intval(filter_var($_REQUEST['limit'], FILTER_SANITIZE_NUMBER_INT)) : 45;
|
||||
$p = !empty($_REQUEST['page']) ? intval(filter_var($_REQUEST['page'], FILTER_SANITIZE_NUMBER_INT)) : 1;
|
||||
$limit = !empty($_REQUEST['limit']) ? intval(
|
||||
filter_var($_REQUEST['limit'], FILTER_SANITIZE_NUMBER_INT)
|
||||
) : 45;
|
||||
$p = !empty($_REQUEST['page']) ? intval(
|
||||
filter_var($_REQUEST['page'], FILTER_SANITIZE_NUMBER_INT)
|
||||
) : 1;
|
||||
$tags = !empty($_REQUEST['tags']) ? filter_var($_REQUEST['tags'], FILTER_SANITIZE_STRING) : array();
|
||||
if (!empty($tags)) {
|
||||
$tags = Tag::explode($tags);
|
||||
}
|
||||
$start = ( $p - 1 ) * $limit;
|
||||
//var_dump($limit, $p, $tags, $start);die();
|
||||
$results = Image::find_images(max($start, 0), min($limit, 100), $tags);
|
||||
$posts = array();
|
||||
foreach ($results as $img) {
|
||||
if (!is_object($img)) {
|
||||
continue;
|
||||
}
|
||||
$posts[] = new _SafeOuroborosImage($img);
|
||||
}
|
||||
$page->set_data(json_encode($posts));
|
||||
$this->postIndex($limit, $p, $tags);
|
||||
}
|
||||
} elseif ($event->page_matches('tag')) {
|
||||
if ($this->match('index') || $this->match('list')) {
|
||||
$limit = !empty($_REQUEST['limit']) ? intval(
|
||||
filter_var($_REQUEST['limit'], FILTER_SANITIZE_NUMBER_INT)
|
||||
) : 50;
|
||||
$p = !empty($_REQUEST['page']) ? intval(
|
||||
filter_var($_REQUEST['page'], FILTER_SANITIZE_NUMBER_INT)
|
||||
) : 1;
|
||||
$order = (!empty($_REQUEST['order']) && ($_REQUEST['order'] == 'date' || $_REQUEST['order'] == 'count' || $_REQUEST['order'] == 'name')) ? filter_var(
|
||||
$_REQUEST['order'],
|
||||
FILTER_SANITIZE_STRING
|
||||
) : 'date';
|
||||
$id = !empty($_REQUEST['id']) ? intval(
|
||||
filter_var($_REQUEST['id'], FILTER_SANITIZE_NUMBER_INT)
|
||||
) : null;
|
||||
$after_id = !empty($_REQUEST['after_id']) ? intval(
|
||||
filter_var($_REQUEST['after_id'], FILTER_SANITIZE_NUMBER_INT)
|
||||
) : null;
|
||||
$name = !empty($_REQUEST['name']) ? filter_var($_REQUEST['name'], FILTER_SANITIZE_STRING) : '';
|
||||
$name_pattern = !empty($_REQUEST['name_pattern']) ? filter_var(
|
||||
$_REQUEST['name_pattern'],
|
||||
FILTER_SANITIZE_STRING
|
||||
) : '';
|
||||
$this->tagIndex($limit, $p, $order, $id, $after_id, $name, $name_pattern);
|
||||
}
|
||||
}
|
||||
elseif ($event->page_matches('tag')) {
|
||||
if ($this->match('index') || $this->match('list')) {
|
||||
$limit = !empty($_REQUEST['limit']) ? intval(filter_var($_REQUEST['limit'], FILTER_SANITIZE_NUMBER_INT)) : 50;
|
||||
$p = !empty($_REQUEST['page']) ? intval(filter_var($_REQUEST['page'], FILTER_SANITIZE_NUMBER_INT)) : 1;
|
||||
$order = (!empty($_REQUEST['order']) && ($_REQUEST['order'] == 'date' || $_REQUEST['order'] == 'count' || $_REQUEST['order'] == 'name')) ? filter_var($_REQUEST['order'], FILTER_SANITIZE_STRING) : 'date';
|
||||
$id = !empty($_REQUEST['id']) ? intval(filter_var($_REQUEST['id'], FILTER_SANITIZE_NUMBER_INT)) : null;
|
||||
$after_id = !empty($_REQUEST['after_id']) ? intval(filter_var($_REQUEST['after_id'], FILTER_SANITIZE_NUMBER_INT)) : null;
|
||||
$name = !empty($_REQUEST['name']) ? filter_var($_REQUEST['name'], FILTER_SANITIZE_STRING) : '';
|
||||
$name_pattern = !empty($_REQUEST['name_pattern']) ? filter_var($_REQUEST['name_pattern'], FILTER_SANITIZE_STRING) : '';
|
||||
$start = ( $p - 1 ) * $limit;
|
||||
$tag_data = array();
|
||||
switch ($order) {
|
||||
case 'name':
|
||||
$tag_data = $database->get_col($database->scoreql_to_sql("
|
||||
SELECT DISTINCT
|
||||
id, SCORE_STRNORM(substr(tag, 1, 1)), count
|
||||
FROM tags
|
||||
WHERE count >= :tags_min
|
||||
ORDER BY SCORE_STRNORM(substr(tag, 1, 1)) LIMIT :start, :max_items
|
||||
"), array("tags_min" => $config->get_int('tags_min'), 'start' => $start, 'max_items' => $limit));
|
||||
break;
|
||||
case 'count':
|
||||
$tag_data = $database->get_all("
|
||||
SELECT id, tag, count
|
||||
FROM tags
|
||||
WHERE count >= :tags_min
|
||||
ORDER BY count DESC, tag ASC LIMIT :start, :max_items
|
||||
", array("tags_min" => $config->get_int('tags_min'), 'start' => $start, 'max_items' => $limit));
|
||||
break;
|
||||
case 'date':
|
||||
$tag_data = $database->get_all("
|
||||
SELECT id, tag, count
|
||||
FROM tags
|
||||
WHERE count >= :tags_min
|
||||
ORDER BY count DESC, tag ASC LIMIT :start, :max_items
|
||||
", array("tags_min" => $config->get_int('tags_min'), 'start' => $start, 'max_items' => $limit));
|
||||
break;
|
||||
}
|
||||
$tags = array();
|
||||
foreach ($tag_data as $tag) {
|
||||
if (!is_array($tag)) {
|
||||
continue;
|
||||
}
|
||||
$tags[] = new _SafeOuroborosTag($tag);
|
||||
}
|
||||
$page->set_data(json_encode($tags));
|
||||
} elseif ($event->page_matches('post/show')) {
|
||||
$page->set_mode('redirect');
|
||||
$page->set_redirect(make_link(str_replace('post/show', 'post/view', implode('/', $event->args))));
|
||||
$page->display();
|
||||
die();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Post
|
||||
*/
|
||||
|
||||
/**
|
||||
* Wrapper for post creation
|
||||
* @param OuroborosPost $post
|
||||
* @param string $md5
|
||||
*/
|
||||
protected function postCreate(OuroborosPost $post, $md5 = '')
|
||||
{
|
||||
global $page, $config, $user;
|
||||
if (!empty($md5)) {
|
||||
$img = Image::by_hash($md5);
|
||||
if (!is_null($img)) {
|
||||
$this->sendResponse(420, self::ERROR_POST_CREATE_DUPE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
$meta = array();
|
||||
$meta['tags'] = $post->tags;
|
||||
$meta['source'] = $post->source;
|
||||
if (defined('ENABLED_EXTS')) {
|
||||
if (strstr(ENABLED_EXTS, 'rating') !== false) {
|
||||
$meta['rating'] = $post->rating;
|
||||
}
|
||||
}
|
||||
// Check where we should try for the file
|
||||
if (empty($post->file) && !empty($post->file_url) && filter_var(
|
||||
$post->file_url,
|
||||
FILTER_VALIDATE_URL
|
||||
) !== false
|
||||
) {
|
||||
// Transload from source
|
||||
$meta['file'] = tempnam('/tmp', 'shimmie_transload_' . $config->get_string('transload_engine'));
|
||||
$meta['filename'] = basename($post->file_url);
|
||||
if (!transload($post->file_url, $meta['file'])) {
|
||||
$this->sendResponse(500, 'Transloading failed');
|
||||
return;
|
||||
}
|
||||
$meta['hash'] = md5_file($meta['file']);
|
||||
} else {
|
||||
// Use file
|
||||
$meta['file'] = $post->file['tmp_name'];
|
||||
$meta['filename'] = $post->file['name'];
|
||||
$meta['hash'] = md5_file($meta['file']);
|
||||
}
|
||||
if (!empty($md5) && $md5 !== $meta['hash']) {
|
||||
$this->sendResponse(420, self::ERROR_POST_CREATE_MD5);
|
||||
return;
|
||||
}
|
||||
if (!empty($meta['hash'])) {
|
||||
$img = Image::by_hash($meta['hash']);
|
||||
if (!is_null($img)) {
|
||||
$this->sendResponse(420, self::ERROR_POST_CREATE_DUPE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
$meta['extension'] = pathinfo($meta['filename'], PATHINFO_EXTENSION);
|
||||
try {
|
||||
$upload = new DataUploadEvent($meta['file'], $meta);
|
||||
send_event($upload);
|
||||
$image = Image::by_hash($meta['hash']);
|
||||
if (!is_null($image)) {
|
||||
$this->sendResponse(200, make_link('post/view/' . $image->id), true);
|
||||
return;
|
||||
} else {
|
||||
// Fail, unsupported file?
|
||||
$this->sendResponse(500, 'Unknown error');
|
||||
return;
|
||||
}
|
||||
} catch (UploadException $e) {
|
||||
// Cleanup in case shit hit the fan
|
||||
$this->sendResponse(500, $e->getMessage());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for getting a single post
|
||||
* @param int $id
|
||||
*/
|
||||
protected function postShow($id = null)
|
||||
{
|
||||
if (!is_null($id)) {
|
||||
$post = new _SafeOuroborosImage(Image::by_id($id));
|
||||
$this->sendData('post', $post);
|
||||
} else {
|
||||
$this->sendResponse(424, 'ID is mandatory');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for getting a list of posts
|
||||
* @param $limit
|
||||
* @param $page
|
||||
* @param $tags
|
||||
*/
|
||||
protected function postIndex($limit, $page, $tags)
|
||||
{
|
||||
$start = ($page - 1) * $limit;
|
||||
$results = Image::find_images(max($start, 0), min($limit, 100), $tags);
|
||||
$posts = array();
|
||||
foreach ($results as $img) {
|
||||
if (!is_object($img)) {
|
||||
continue;
|
||||
}
|
||||
$posts[] = new _SafeOuroborosImage($img);
|
||||
}
|
||||
$this->sendData('post', $posts, max($start, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tag
|
||||
*/
|
||||
|
||||
/**
|
||||
* Wrapper for getting a list of tags
|
||||
* @param $limit
|
||||
* @param $page
|
||||
* @param $order
|
||||
* @param $id
|
||||
* @param $after_id
|
||||
* @param $name
|
||||
* @param $name_pattern
|
||||
*/
|
||||
protected function tagIndex($limit, $page, $order, $id, $after_id, $name, $name_pattern)
|
||||
{
|
||||
global $database, $config;
|
||||
$start = ($page - 1) * $limit;
|
||||
$tag_data = array();
|
||||
switch ($order) {
|
||||
case 'name':
|
||||
$tag_data = $database->get_col(
|
||||
$database->scoreql_to_sql(
|
||||
"
|
||||
SELECT DISTINCT
|
||||
id, SCORE_STRNORM(substr(tag, 1, 1)), count
|
||||
FROM tags
|
||||
WHERE count >= :tags_min
|
||||
ORDER BY SCORE_STRNORM(substr(tag, 1, 1)) LIMIT :start, :max_items
|
||||
"
|
||||
),
|
||||
array('tags_min' => $config->get_int('tags_min'), 'start' => $start, 'max_items' => $limit)
|
||||
);
|
||||
break;
|
||||
case 'count':
|
||||
$tag_data = $database->get_all(
|
||||
"
|
||||
SELECT id, tag, count
|
||||
FROM tags
|
||||
WHERE count >= :tags_min
|
||||
ORDER BY count DESC, tag ASC LIMIT :start, :max_items
|
||||
",
|
||||
array('tags_min' => $config->get_int('tags_min'), 'start' => $start, 'max_items' => $limit)
|
||||
);
|
||||
break;
|
||||
case 'date':
|
||||
$tag_data = $database->get_all(
|
||||
"
|
||||
SELECT id, tag, count
|
||||
FROM tags
|
||||
WHERE count >= :tags_min
|
||||
ORDER BY count DESC, tag ASC LIMIT :start, :max_items
|
||||
",
|
||||
array('tags_min' => $config->get_int('tags_min'), 'start' => $start, 'max_items' => $limit)
|
||||
);
|
||||
break;
|
||||
}
|
||||
$tags = array();
|
||||
foreach ($tag_data as $tag) {
|
||||
if (!is_array($tag)) {
|
||||
continue;
|
||||
}
|
||||
$tags[] = new _SafeOuroborosTag($tag);
|
||||
}
|
||||
$this->sendData('tag', $tags, $start);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility methods
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sends a simple {success,reason} message to browser
|
||||
*
|
||||
* @param int $code HTTP equivalent code for the message
|
||||
* @param string $reason Reason for the code
|
||||
* @param bool $location Is $reason a location? (used mainly for post/create)
|
||||
*/
|
||||
private function sendResponse($code = 200, $reason = '', $location = false)
|
||||
{
|
||||
global $page;
|
||||
if ($code == 200) {
|
||||
$success = true;
|
||||
} else {
|
||||
$success = false;
|
||||
}
|
||||
if (empty($reason)) {
|
||||
if (defined("self::MSG_HTTP_{$code}")) {
|
||||
$reason = constant("self::MSG_HTTP_{$code}");
|
||||
} else {
|
||||
$reason = self::MSG_HTTP_418;
|
||||
}
|
||||
}
|
||||
if ($code != 200) {
|
||||
$proto = $_SERVER['SERVER_PROTOCOL'];
|
||||
if (defined("self::HEADER_HTTP_{$code}")) {
|
||||
$header = constant("self::HEADER_HTTP_{$code}");
|
||||
} else {
|
||||
// I'm a teapot!
|
||||
$code = 418;
|
||||
$header = self::HEADER_HTTP_418;
|
||||
}
|
||||
header("{$proto} {$code} {$header}", true);
|
||||
}
|
||||
$response = array('success' => $success, 'reason' => $reason);
|
||||
if ($this->type == 'json') {
|
||||
if ($location !== false) {
|
||||
$response['location'] = $response['reason'];
|
||||
unset($response['reason']);
|
||||
}
|
||||
$response = json_encode($response);
|
||||
} elseif ($this->type == 'xml') {
|
||||
// Seriously, XML sucks...
|
||||
$xml = new XMLWriter();
|
||||
$xml->openMemory();
|
||||
$xml->startDocument('1.0', 'utf-8');
|
||||
$xml->startElement('response');
|
||||
$xml->writeAttribute('success', var_export($success, true));
|
||||
if ($location !== false) {
|
||||
$xml->writeAttribute('location', $reason);
|
||||
} else {
|
||||
$xml->writeAttribute('reason', $reason);
|
||||
}
|
||||
$xml->endElement();
|
||||
$xml->endDocument();
|
||||
$response = $xml->outputMemory(true);
|
||||
unset($xml);
|
||||
}
|
||||
$page->set_data($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send data to the browser
|
||||
* @param string $type
|
||||
* @param mixed $data
|
||||
* @param int $offset
|
||||
*/
|
||||
private function sendData($type = '', $data = array(), $offset = 0)
|
||||
{
|
||||
global $page;
|
||||
$response = '';
|
||||
if ($this->type == 'json') {
|
||||
$response = json_encode($data);
|
||||
} elseif ($this->type == 'xml') {
|
||||
$xml = new XMLWriter();
|
||||
$xml->openMemory();
|
||||
$xml->startDocument('1.0', 'utf-8');
|
||||
if (array_key_exists(0, $data)) {
|
||||
$xml->startElement($type . 's');
|
||||
if ($type == 'post') {
|
||||
$xml->writeAttribute('count', count($data));
|
||||
$xml->writeAttribute('offset', $offset);
|
||||
}
|
||||
if ($type == 'tag') {
|
||||
$xml->writeAttribute('type', 'array');
|
||||
}
|
||||
foreach ($data as $item) {
|
||||
$this->createItemXML($xml, $type, $item);
|
||||
}
|
||||
$xml->endElement();
|
||||
} else {
|
||||
$this->createItemXML($xml, $type, $data);
|
||||
}
|
||||
$xml->endDocument();
|
||||
$response = $xml->outputMemory(true);
|
||||
unset($xml);
|
||||
}
|
||||
$page->set_data($response);
|
||||
}
|
||||
|
||||
private function createItemXML(XMLWriter &$xml, $type, $item)
|
||||
{
|
||||
$xml->startElement($type);
|
||||
foreach ($item as $key => $val) {
|
||||
if ($key == 'created_at' && $type == 'post') {
|
||||
$xml->writeAttribute($key, $val['s']);
|
||||
} else {
|
||||
if (is_bool($val)) {
|
||||
$val = $val ? 'true' : 'false';
|
||||
}
|
||||
$xml->writeAttribute($key, $val);
|
||||
}
|
||||
}
|
||||
$xml->endElement();
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to figure who is uploading
|
||||
*
|
||||
* Currently checks for either user & session in request or cookies
|
||||
* and initializes a global User
|
||||
* @param void
|
||||
* @return void
|
||||
*/
|
||||
private function tryAuth()
|
||||
{
|
||||
global $config, $user;
|
||||
|
||||
if (isset($_REQUEST['user']) && isset($_REQUEST['session'])) {
|
||||
//Auth by session data from query
|
||||
$name = $_REQUEST['user'];
|
||||
$session = $_REQUEST['session'];
|
||||
$duser = User::by_session($name, $session);
|
||||
if (!is_null($duser)) {
|
||||
$user = $duser;
|
||||
} else {
|
||||
$user = User::by_id($config->get_int("anon_id", 0));
|
||||
}
|
||||
} elseif (isset($_COOKIE[$config->get_string('cookie_prefix', 'shm') . '_' . 'session']) &&
|
||||
isset($_COOKIE[$config->get_string('cookie_prefix', 'shm') . '_' . 'user'])
|
||||
) {
|
||||
//Auth by session data from cookies
|
||||
$session = $_COOKIE[$config->get_string('cookie_prefix', 'shm') . '_' . 'session'];
|
||||
$user = $_COOKIE[$config->get_string('cookie_prefix', 'shm') . '_' . 'user'];
|
||||
$duser = User::by_session($user, $session);
|
||||
if (!is_null($duser)) {
|
||||
$user = $duser;
|
||||
} else {
|
||||
$user = User::by_id($config->get_int("anon_id", 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function match($page) {
|
||||
/**
|
||||
* Helper for matching API methods from event
|
||||
* @param $page
|
||||
* @return bool
|
||||
*/
|
||||
private function match($page)
|
||||
{
|
||||
return (preg_match("%{$page}\.(xml|json)$%", implode('/', $this->event->args), $matches) === 1);
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +71,13 @@ class Pools extends Extension {
|
||||
|
||||
log_info("pools", "extension installed");
|
||||
}
|
||||
|
||||
if ($config->get_int("ext_pools_version") < 2){
|
||||
$database->Execute("ALTER TABLE pools ADD UNIQUE INDEX (title);");
|
||||
$database->Execute("ALTER TABLE pools ADD lastupdated TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;");
|
||||
|
||||
$config->set_int("ext_pools_version", 2);
|
||||
}
|
||||
}
|
||||
|
||||
// Add a block to the Board Config / Setup
|
||||
@ -111,7 +118,7 @@ class Pools extends Extension {
|
||||
$this->theme->new_pool_composer($page);
|
||||
} else {
|
||||
$errMessage = "You must be registered and logged in to create a new pool.";
|
||||
$this->theme->display_error($errMessage);
|
||||
$this->theme->display_error(401, "Error", $errMessage);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -122,7 +129,7 @@ class Pools extends Extension {
|
||||
$page->set_redirect(make_link("pool/view/".$newPoolID));
|
||||
}
|
||||
catch(PoolCreationException $e) {
|
||||
$this->theme->display_error($e->error);
|
||||
$this->theme->display_error(400, "Error", $e->error);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -168,7 +175,7 @@ class Pools extends Extension {
|
||||
$page->set_mode("redirect");
|
||||
$page->set_redirect(make_link("pool/view/".$pool_id));
|
||||
} else {
|
||||
$this->theme->display_error("Permssion denied.");
|
||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -177,7 +184,7 @@ class Pools extends Extension {
|
||||
if ($this->have_permission($user, $pool)) {
|
||||
$this->import_posts($pool_id);
|
||||
} else {
|
||||
$this->theme->display_error("Permssion denied.");
|
||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
||||
}
|
||||
break;
|
||||
|
||||
@ -187,7 +194,7 @@ class Pools extends Extension {
|
||||
$page->set_mode("redirect");
|
||||
$page->set_redirect(make_link("pool/view/".$pool_id));
|
||||
} else {
|
||||
$this->theme->display_error("Permssion denied.");
|
||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
||||
}
|
||||
break;
|
||||
|
||||
@ -197,7 +204,18 @@ class Pools extends Extension {
|
||||
$page->set_mode("redirect");
|
||||
$page->set_redirect(make_link("pool/view/".$pool_id));
|
||||
} else {
|
||||
$this->theme->display_error("Permssion denied.");
|
||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "edit_description":
|
||||
if ($this->have_permission($user, $pool)) {
|
||||
$this->edit_description();
|
||||
$page->set_mode("redirect");
|
||||
$page->set_redirect(make_link("pool/view/".$pool_id));
|
||||
} else {
|
||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
||||
}
|
||||
|
||||
break;
|
||||
@ -210,7 +228,7 @@ class Pools extends Extension {
|
||||
$page->set_mode("redirect");
|
||||
$page->set_redirect(make_link("pool/list"));
|
||||
} else {
|
||||
$this->theme->display_error("Permssion denied.");
|
||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
||||
}
|
||||
break;
|
||||
|
||||
@ -275,6 +293,45 @@ class Pools extends Extension {
|
||||
}
|
||||
}
|
||||
|
||||
public function onSearchTermParse(SearchTermParseEvent $event) {
|
||||
$matches = array();
|
||||
if(preg_match("/^pool[=|:]([0-9]+|any|none)$/", $event->term, $matches)) {
|
||||
$poolID = $matches[1];
|
||||
|
||||
if(preg_match("/^(any|none)$/", $poolID)){
|
||||
$not = ($poolID == "none" ? "NOT" : "");
|
||||
$event->add_querylet(new Querylet("images.id $not IN (SELECT DISTINCT image_id FROM pool_images)"));
|
||||
}else{
|
||||
$event->add_querylet(new Querylet("images.id IN (SELECT DISTINCT image_id FROM pool_images WHERE pool_id = $poolID)"));
|
||||
}
|
||||
}
|
||||
else if(preg_match("/^pool_by_name[=|:](.*)$/", $event->term, $matches)) {
|
||||
$poolTitle = str_replace("_", " ", $matches[1]);
|
||||
|
||||
$pool = $this->get_single_pool_from_title($poolTitle);
|
||||
$poolID = 0;
|
||||
if ($pool){ $poolID = $pool['id']; }
|
||||
$event->add_querylet(new Querylet("images.id IN (SELECT DISTINCT image_id FROM pool_images WHERE pool_id = $poolID)"));
|
||||
}
|
||||
}
|
||||
|
||||
public function add_post_from_tag(/*str*/ $poolTag, /*int*/ $imageID){
|
||||
$poolTag = str_replace("_", " ", $poolTag);
|
||||
//First check if pool tag is a title
|
||||
if(ctype_digit($poolTag)){
|
||||
//If string only contains numeric characters, assume it is $poolID
|
||||
if($this->get_single_pool($poolTag)){ //Make sure pool exists
|
||||
$this->add_post($poolTag, $imageID);
|
||||
}
|
||||
}else{
|
||||
//If string doesn't contain only numeric characters, check to see if tag is title.
|
||||
$pool = $this->get_single_pool_from_title($poolTag);
|
||||
if($pool){
|
||||
$this->add_post($pool['id'], $imageID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------- */
|
||||
/* -------------- Private Functions -------------- */
|
||||
/* ------------------------------------------------- */
|
||||
@ -309,13 +366,26 @@ class Pools extends Extension {
|
||||
|
||||
$poolsPerPage = $config->get_int("poolsListsPerPage");
|
||||
|
||||
|
||||
$order_by = "";
|
||||
$order = get_prefixed_cookie("ui-order-pool");
|
||||
if($order == "created" || is_null($order)){
|
||||
$order_by = "ORDER BY p.date DESC";
|
||||
}elseif($order == "updated"){
|
||||
$order_by = "ORDER BY p.lastupdated DESC";
|
||||
}elseif($order == "name"){
|
||||
$order_by = "ORDER BY p.title ASC";
|
||||
}elseif($order == "count"){
|
||||
$order_by = "ORDER BY p.posts DESC";
|
||||
}
|
||||
|
||||
$pools = $database->get_all("
|
||||
SELECT p.id, p.user_id, p.public, p.title, p.description,
|
||||
p.posts, u.name as user_name
|
||||
FROM pools AS p
|
||||
INNER JOIN users AS u
|
||||
ON p.user_id = u.id
|
||||
ORDER BY p.date DESC
|
||||
$order_by
|
||||
LIMIT :l OFFSET :o
|
||||
", array("l"=>$poolsPerPage, "o"=>$pageNumber * $poolsPerPage)
|
||||
);
|
||||
@ -336,7 +406,10 @@ class Pools extends Extension {
|
||||
throw new PoolCreationException("You must be registered and logged in to add a image.");
|
||||
}
|
||||
if(empty($_POST["title"])) {
|
||||
throw new PoolCreationException("Pool needs a title");
|
||||
throw new PoolCreationException("Pool title is empty.");
|
||||
}
|
||||
if($this->get_single_pool_from_title($_POST["title"])) {
|
||||
throw new PoolCreationException("A pool using this title already exists.");
|
||||
}
|
||||
|
||||
$public = $_POST["public"] == "Y" ? "Y" : "N";
|
||||
@ -361,7 +434,7 @@ class Pools extends Extension {
|
||||
global $database;
|
||||
return $database->get_all("SELECT * FROM pools WHERE id=:id", array("id"=>$poolID));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve information about a pool given a pool ID.
|
||||
* @param $poolID Integer
|
||||
@ -372,6 +445,16 @@ class Pools extends Extension {
|
||||
return $database->get_row("SELECT * FROM pools WHERE id=:id", array("id"=>$poolID));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve information about a pool given a pool title.
|
||||
* @param $poolTitle Integer
|
||||
* @retval 2D array (with only 1 element in the one dimension)
|
||||
*/
|
||||
private function get_single_pool_from_title(/*string*/ $poolTitle) {
|
||||
global $database;
|
||||
return $database->get_row("SELECT * FROM pools WHERE title=:title", array("title"=>$poolTitle));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the pool IDs that an image is in, given an image ID.
|
||||
* @param $imageID Integer
|
||||
@ -476,6 +559,17 @@ class Pools extends Extension {
|
||||
return $poolID;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allows editing of pool description.
|
||||
*/
|
||||
private function edit_description() {
|
||||
global $database;
|
||||
|
||||
$poolID = int_escape($_POST['pool_id']);
|
||||
$database->execute("UPDATE pools SET description=:dsc WHERE id=:pid", array("dsc"=>$_POST['description'], "pid"=>$poolID));
|
||||
|
||||
return $poolID;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function checks if a given image is contained within a given pool.
|
||||
|
10
ext/pools/script.js
Normal file
10
ext/pools/script.js
Normal file
@ -0,0 +1,10 @@
|
||||
$(function() {
|
||||
var order_pool = $.cookie("shm_ui-order-pool") || "created";
|
||||
$("#order_pool option[value="+order_pool+"]").attr("selected", true);
|
||||
|
||||
$('#order_pool').change(function(){
|
||||
var val = $("#order_pool option:selected").val();
|
||||
$.cookie("shm_ui-order-pool", val, {path: '/', expires: 365}); //FIXME: This won't play nice if COOKIE_PREFIX is not "shm_".
|
||||
window.location.href = '';
|
||||
});
|
||||
});
|
@ -67,11 +67,21 @@ class PoolsTheme extends Themelet {
|
||||
<br><a href="'.make_link("pool/updated").'">Pool Changes</a>
|
||||
';
|
||||
|
||||
$order_html = '
|
||||
<select id="order_pool">
|
||||
<option value="created">Recently created</option>
|
||||
<option value="updated">Last updated</option>
|
||||
<option value="name">Name</option>
|
||||
<option value="count">Post count</option>
|
||||
</select>
|
||||
';
|
||||
|
||||
$blockTitle = "Pools";
|
||||
$page->set_title(html_escape($blockTitle));
|
||||
$page->set_heading(html_escape($blockTitle));
|
||||
$page->add_block(new Block($blockTitle, $html, "main", 10));
|
||||
$page->add_block(new Block("Navigation", $nav_html, "left", 10));
|
||||
$page->add_block(new Block("Order By", $order_html, "left", 15));
|
||||
|
||||
$this->display_paginator($page, "pool/list", null, $pageNumber, $totalPages);
|
||||
}
|
||||
@ -156,6 +166,13 @@ class PoolsTheme extends Themelet {
|
||||
$pool_images .= "\n".$thumb_html."\n";
|
||||
}
|
||||
|
||||
$nav_html = '
|
||||
<a href="'.make_link().'">Index</a>
|
||||
<br><a href="'.make_link("pool/new").'">Create Pool</a>
|
||||
<br><a href="'.make_link("pool/updated").'">Pool Changes</a>
|
||||
';
|
||||
|
||||
$page->add_block(new Block("Navigation", $nav_html, "left", 10));
|
||||
$page->add_block(new Block("Viewing Posts", $pool_images, "main", 30));
|
||||
$this->display_paginator($page, "pool/view/".$pools[0]['id'], null, $pageNumber, $totalPages);
|
||||
}
|
||||
@ -312,8 +329,17 @@ class PoolsTheme extends Themelet {
|
||||
public function edit_pool(Page $page, /*array*/ $pools, /*array*/ $images) {
|
||||
global $user;
|
||||
|
||||
$this->display_top($pools, "Editing Pool", true);
|
||||
|
||||
/* EDIT POOL DESCRIPTION */
|
||||
$desc_html = "
|
||||
".make_form(make_link("pool/edit_description"))."
|
||||
<textarea name='description'>".$pools[0]['description']."</textarea><br />
|
||||
<input type='hidden' name='pool_id' value='".$pools[0]['id']."'>
|
||||
<input type='submit' value='Change Description' />
|
||||
</form>
|
||||
";
|
||||
|
||||
/* REMOVE POOLS */
|
||||
$pool_images = "\n<form action='".make_link("pool/remove_posts")."' method='POST' name='checks'>";
|
||||
|
||||
foreach($images as $pair) {
|
||||
@ -331,6 +357,9 @@ class PoolsTheme extends Themelet {
|
||||
"<input type='hidden' name='pool_id' value='".$pools[0]['id']."'>".
|
||||
"</form>";
|
||||
|
||||
$pools[0]['description'] = ""; //This is a rough fix to avoid showing the description twice.
|
||||
$this->display_top($pools, "Editing Pool", true);
|
||||
$page->add_block(new Block("Editing Description", $desc_html, "main", 28));
|
||||
$page->add_block(new Block("Editing Posts", $pool_images, "main", 30));
|
||||
}
|
||||
|
||||
@ -389,20 +418,5 @@ class PoolsTheme extends Themelet {
|
||||
|
||||
$this->display_paginator($page, "pool/updated", null, $pageNumber, $totalPages);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Display an error message to the user.
|
||||
*/
|
||||
public function display_error(/*int*/ $code, /*string*/ $title, /*string*/ $message) {
|
||||
global $page;
|
||||
|
||||
// Quick n' Dirty fix
|
||||
$message = $code;
|
||||
|
||||
$page->set_title("Error");
|
||||
$page->set_heading("Error");
|
||||
$page->add_block(new Block("Error", $errMessage, "main", 10));
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
@ -116,7 +116,7 @@ class Ratings extends Extension {
|
||||
$set = Ratings::privs_to_sql(Ratings::get_user_privs($user));
|
||||
$event->add_querylet(new Querylet("rating IN ($set)"));
|
||||
}
|
||||
if(preg_match("/^rating=(?:([sqeu]+)|(safe|questionable|explicit|unknown))$/D", strtolower($event->term), $matches)) {
|
||||
if(preg_match("/^rating[=|:](?:([sqeu]+)|(safe|questionable|explicit|unknown))$/D", strtolower($event->term), $matches)) {
|
||||
$ratings = $matches[1] ? $matches[1] : array($matches[2][0]);
|
||||
$ratings = array_intersect(str_split($ratings), str_split(Ratings::get_user_privs($user)));
|
||||
$set = "'" . join("', '", $ratings) . "'";
|
||||
@ -199,7 +199,7 @@ class Ratings extends Extension {
|
||||
|
||||
private function no_rating_query($context) {
|
||||
foreach($context as $term) {
|
||||
if(preg_match("/^rating=/", $term)) {
|
||||
if(preg_match("/^rating[=|:]/", $term)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* Imageboard to Shimmie */
|
||||
// This should work with "most" sites running Danbooru/Gelbooru/Shimmie
|
||||
// TODO: Make this use jQuery! (if we can be sure that jquery is loaded)
|
||||
// maxsize, supext, CA are set inside the bookmarklet (see theme.php)
|
||||
|
||||
var maxsize = (maxsize.match("(?:\.*[0-9])")) * 1024; // This assumes we are only working with MB.
|
||||
@ -25,67 +24,84 @@ else if(CA === 2) { // New Tags
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Danbooru (oreno.imouto | konachan | sankakucomplex)
|
||||
* Danbooru2
|
||||
* jQuery should always active here, meaning we can use jQuery in this part of the bookmarklet.
|
||||
*/
|
||||
if(document.getElementById("post_tags") !== null) {
|
||||
|
||||
if(document.getElementById("post_tag_string") !== null) {
|
||||
if (typeof tag !== "ftp://ftp." && chk !==1) {
|
||||
var tag = document.getElementById("post_tags").value;
|
||||
var tag = $('#post_tag_string').text().replace(/\n/g, "");
|
||||
}
|
||||
tag = tag.replace(/\+/g, "%2B"); // This should stop + not showing in tags :x
|
||||
tag = tag.replace(/\+/g, "%2B");
|
||||
|
||||
var source = "http://" + document.location.hostname + document.location.href.match("\/post\/show\/[0-9]+");
|
||||
if(source.search("oreno\\.imouto") >= 0 || source.search("konachan\\.com") >= 0) {
|
||||
var rating = document.getElementById("stats").innerHTML.match("<li>Rating: (.*) <span")[1];
|
||||
}
|
||||
else {
|
||||
var rating = document.getElementById("stats").innerHTML.match("<li>Rating: (.*)<\/li>")[1];
|
||||
var source = "http://" + document.location.hostname + document.location.href.match("\/posts\/[0-9]+");
|
||||
|
||||
var rlist = $('[name="post[rating]"]');
|
||||
for(x=0;x<3;x++){
|
||||
var rating = (rlist[x].checked == true ? rlist[x].value : rating);
|
||||
}
|
||||
|
||||
if(tag.search(/\bflash\b/)===-1){
|
||||
var highres_url = document.getElementById("highres").href;
|
||||
if(source.search("oreno\\.imouto") >= 0 || source.search("konachan\\.com") >= 0){ // oreno's theme seems to have moved the filesize
|
||||
var filesize = document.getElementById("highres").innerHTML.match("[a-zA-Z0-9]+ \\(+([0-9]+\\.[0-9]+) ([a-zA-Z]+)");
|
||||
var fileinfo = $('#sidebar > section:eq(3) > ul > :contains("Size") > a');
|
||||
var furl = "http://" + document.location.hostname + fileinfo.attr('href');
|
||||
var fs = fileinfo.text().split(" ");
|
||||
var filesize = (fs[1] == "MB" ? fs[0] * 1024 : fs[0]);
|
||||
|
||||
if(supext.search(furl.match("[a-zA-Z0-9]+$")[0]) !== -1){
|
||||
if(filesize <= maxsize){
|
||||
location.href = ste+furl+"&tags="+tag+"&rating="+rating+"&source="+source;
|
||||
}
|
||||
else{
|
||||
alert(toobig);
|
||||
}
|
||||
}
|
||||
else{
|
||||
alert(notsup);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* konachan | sankakucomplex | gelbooru
|
||||
*/
|
||||
else if(document.getElementById('tag-sidebar') !== null) {
|
||||
if (typeof tag !== "ftp://ftp." && chk !==1) {
|
||||
if(document.location.href.search("sankakucomplex\\.com") >= 0 || document.location.href.search("gelbooru\\.com")){
|
||||
var tag = document.getElementById('tag-sidebar').innerText.replace(/ /g, "_").replace(/[\?_]*(.*?)_(\(\?\)_)?[0-9]+\n/g, "$1 ");
|
||||
}else{
|
||||
var filesize = document.getElementById("stats").innerHTML.match("[0-9] \\(((?:\.*[0-9])) ([a-zA-Z]+)");
|
||||
}
|
||||
if(filesize[2] == "MB") {
|
||||
var filesize = filesize[1] * 1024;
|
||||
}
|
||||
else {
|
||||
var filesize = filesize[2].match("[0-9]+");
|
||||
}
|
||||
|
||||
if(supext.search(highres_url.match("http\:\/\/.*\\.([a-z0-9]+)")[1]) !== -1) {
|
||||
if(filesize <= maxsize) {
|
||||
if(source.search("oreno\\.imouto") >= 0) {
|
||||
// this regex tends to be a bit picky with tags -_-;;
|
||||
var highres_url = highres_url.match("(http\:\/\/[a-z0-9]+\.[a-z]+\.[a-z]\/[a-z0-9]+\/[a-z0-9]+)\/[a-z0-9A-Z%_-]+(\.[a-zA-Z0-9]+)");
|
||||
var highres_url = highres_url[1]+highres_url[2]; // this should bypass hotlink protection
|
||||
}
|
||||
else if(source.search("konachan\\.com") >= 0) {
|
||||
// konachan affixs konachan.com to the start of the tags, this requires different regex
|
||||
var highres_url = highres_url.match("(http\:\/\/[a-z0-9]+\.[a-z]+\.[a-z]\/[a-z0-9]+\/[a-z0-9]+)\/[a-z0-9A-Z%_]+\.[a-zA-Z0-9%_-]+(\.[a-z0-9A-Z]+)")
|
||||
var highres_url = highres_url[1]+highres_url[2];
|
||||
}
|
||||
location.href = ste+highres_url+"&tags="+tag+"&rating="+rating+"&source="+source;
|
||||
}
|
||||
else{
|
||||
alert(toobig);
|
||||
}
|
||||
}
|
||||
else{
|
||||
alert(notsup);
|
||||
var tag = document.getElementById("post_tags").value;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(supext.search("swf") !== -1) {
|
||||
location.href = ste+document.getElementsByName("movie")[0].value+"&tags="+tag+"&rating="+rating+"&source="+source;
|
||||
tag = tag.replace(/\+/g, "%2B");
|
||||
|
||||
var source = "http://" + document.location.hostname + (document.location.href.match("\/post\/show\/[0-9]+") || encodeURIComponent(document.location.href.match(/\/index\.php\?page=post&s=view&id=[0-9]+/)));
|
||||
|
||||
var rating = document.getElementById("stats").innerHTML.match("Rating: ([a-zA-Z]+)")[1];
|
||||
|
||||
if(source.search("sankakucomplex\\.com") >= 0 || source.search("konachan\\.com") >= 0){
|
||||
var fileinfo = document.getElementById("highres");
|
||||
//NOTE: If highres doesn't exist, post must be flash (only sankakucomplex has flash)
|
||||
}else if(source.search("gelbooru\\.com") >= 0){
|
||||
var fileinfo = document.getElementById('pfd').parentNode.parentNode.getElementsByTagName('a')[0];
|
||||
//gelbooru has no easy way to select the original image link, so we need to double check it is the correct link.
|
||||
fileinfo = (fileinfo.getAttribute('href') == "#" ? document.getElementById('pfd').parentNode.parentNode.getElementsByTagName('a')[1] : fileinfo);
|
||||
}
|
||||
fileinfo = fileinfo || document.getElementsByTagName('embed')[0]; //If fileinfo is null then image is most likely flash.
|
||||
var furl = fileinfo.href || fileinfo.src;
|
||||
var fs = (fileinfo.innerText.match(/[0-9]+ (KB|MB)/) || ["0 KB"])[0].split(" ");
|
||||
var filesize = (fs[1] == "MB" ? fs[0] * 1024 : fs[0]);
|
||||
|
||||
if(supext.search(furl.match("[a-zA-Z0-9]+$")[0]) !== -1){
|
||||
if(filesize <= maxsize){
|
||||
location.href = ste+furl+"&tags="+tag+"&rating="+rating+"&source="+source;
|
||||
}
|
||||
else{
|
||||
alert(notsup);
|
||||
alert(toobig);
|
||||
}
|
||||
}
|
||||
else{
|
||||
alert(notsup);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -128,37 +144,4 @@ else if(document.getElementsByTagName("title")[0].innerHTML.search("Image [0-9.-
|
||||
alert(notsup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Gelbooru
|
||||
*/
|
||||
else if(document.getElementById("tags") !== null) {
|
||||
if (typeof tag !=="ftp://ftp." && chk !==1) {
|
||||
var tag = document.getElementById("tags").value;
|
||||
}
|
||||
|
||||
var rating = document.getElementById("stats").innerHTML.match("<li>Rating: (.*)<\/li>")[1];
|
||||
|
||||
// Can't seem to grab source due to url containing a &
|
||||
// var source="http://" + document.location.hostname + document.location.href.match("\/index\.php?page=post&s=view\\&id=.*");
|
||||
|
||||
// Updated Nov. 24, 2013 by jgen.
|
||||
var gmi;
|
||||
try {
|
||||
gmi = document.getElementById("image").src.match(".*img[0-9]*\.gelbooru\.com[\/]+images[\/]+[0-9]+[\/]+[a-z0-9]+\.[a-z0-9]+")[0];
|
||||
|
||||
// Since Gelbooru does not allow flash, no need to search for flash tag.
|
||||
// Gelbooru doesn't show file size in statistics either...
|
||||
if(supext.search(gmi.match("http\:\/\/.*\\.([a-z0-9]+)")[1]) !== -1){
|
||||
location.href = ste+gmi+"&tags="+tag+"&rating="+rating;//+"&source="+source;
|
||||
}
|
||||
else{
|
||||
alert(notsup);
|
||||
}
|
||||
}
|
||||
catch (err)
|
||||
{
|
||||
alert("Unable to locate the image on the page!\n(Gelbooru may have changed the structure of their page, please file a bug.)");
|
||||
}
|
||||
}
|
||||
}
|
@ -329,9 +329,12 @@ class Upload extends Extension {
|
||||
}
|
||||
|
||||
$tmp_filename = tempnam(ini_get('upload_tmp_dir'), "shimmie_transload");
|
||||
$filename = basename($url);
|
||||
|
||||
if(!transload($url, $tmp_filename)) {
|
||||
$headers = transload($url, $tmp_filename);
|
||||
$h_filename = (isset($headers['Content-Disposition']) ? preg_replace('/^.*filename="([^ ]+)"/i', '$1', $headers['Content-Disposition']) : null);
|
||||
$filename = $h_filename ?: basename($url);
|
||||
|
||||
if(!$headers) {
|
||||
$this->theme->display_upload_error($page, "Error with ".html_escape($filename),
|
||||
"Error reading from ".html_escape($url));
|
||||
return false;
|
||||
@ -341,12 +344,11 @@ class Upload extends Extension {
|
||||
$this->theme->display_upload_error($page, "Error with ".html_escape($filename),
|
||||
"No data found -- perhaps the site has hotlink protection?");
|
||||
$ok = false;
|
||||
}
|
||||
else {
|
||||
}else{
|
||||
global $user;
|
||||
$pathinfo = pathinfo($url);
|
||||
$metadata['filename'] = $pathinfo['basename'];
|
||||
$metadata['extension'] = $pathinfo['extension'];
|
||||
$metadata['filename'] = $filename;
|
||||
$metadata['extension'] = getExtension($headers['Content-Type']) ?: $pathinfo['extension'];
|
||||
$metadata['tags'] = $tags;
|
||||
$metadata['source'] = $source;
|
||||
|
||||
|
@ -309,7 +309,7 @@ class UserPage extends Extension {
|
||||
global $user;
|
||||
|
||||
$matches = array();
|
||||
if(preg_match("/^(poster|user)=(.*)$/i", $event->term, $matches)) {
|
||||
if(preg_match("/^(poster|user)[=|:](.*)$/i", $event->term, $matches)) {
|
||||
$duser = User::by_name($matches[2]);
|
||||
if(!is_null($duser)) {
|
||||
$user_id = $duser->id;
|
||||
@ -319,11 +319,11 @@ class UserPage extends Extension {
|
||||
}
|
||||
$event->add_querylet(new Querylet("images.owner_id = $user_id"));
|
||||
}
|
||||
else if(preg_match("/^(poster|user)_id=([0-9]+)$/i", $event->term, $matches)) {
|
||||
else if(preg_match("/^(poster|user)_id[=|:]([0-9]+)$/i", $event->term, $matches)) {
|
||||
$user_id = int_escape($matches[2]);
|
||||
$event->add_querylet(new Querylet("images.owner_id = $user_id"));
|
||||
}
|
||||
else if($user->can("view_ip") && preg_match("/^(poster|user)_ip=([0-9\.]+)$/i", $event->term, $matches)) {
|
||||
else if($user->can("view_ip") && preg_match("/^(poster|user)_ip[=|:]([0-9\.]+)$/i", $event->term, $matches)) {
|
||||
$user_ip = $matches[2]; // FIXME: ip_escape?
|
||||
$event->add_querylet(new Querylet("images.owner_ip = '$user_ip'"));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user