/** * @param Page $page * @param int $image_id * @param array $history */ public function display_history_page(Page $page, $image_id, $history) { global $user; $start_string = "\n\t\t\t<div style='text-align: left'>\n\t\t\t\t" . make_form(make_link("tag_history/revert")) . "\n\t\t\t\t\t<ul style='list-style-type:none;'>\n\t\t"; $history_list = ""; $n = 0; foreach ($history as $fields) { $n++; $current_id = $fields['id']; $current_tags = html_escape($fields['tags']); $name = $fields['name']; $h_ip = $user->can("view_ip") ? " " . show_ip($fields['user_ip'], "Tagging Image #{$image_id} as '{$current_tags}'") : ""; $setter = "<a href='" . make_link("user/" . url_escape($name)) . "'>" . html_escape($name) . "</a>{$h_ip}"; $selected = $n == 2 ? " checked" : ""; $current_tags = Tag::explode($current_tags); $taglinks = array(); foreach ($current_tags as $tag) { $taglinks[] = "<a href='" . make_link("post/list/" . $tag . "/1") . "'>" . $tag . "</a>"; } $current_tags = Tag::implode($taglinks); $history_list .= "\n\t\t\t\t<li>\n\t\t\t\t\t<input type='radio' name='revert' id='{$current_id}' value='{$current_id}'{$selected}>\n\t\t\t\t\t<label for='{$current_id}'>{$current_tags} (Set by {$setter})</label>\n\t\t\t\t</li>\n\t\t\t\t"; } $end_string = "\n\t\t\t\t\t</ul>\n\t\t\t\t\t<input type='submit' value='Revert To'>\n\t\t\t\t</form>\n\t\t\t</div>\n\t\t"; $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)); }
/** * @param string $filename * @param array $metadata * @return Image|null */ protected function create_image_from_data($filename, $metadata) { global $config; $image = new Image(); // FIXME: need more flash format specs :| $image->width = 0; $image->height = 0; $image->filesize = $metadata['size']; $image->hash = $metadata['hash']; //Cheat by using the filename to store artist/title if available require_once 'lib/getid3/getid3/getid3.php'; $getID3 = new getID3(); $ThisFileInfo = $getID3->analyze($filename, TRUE); if (isset($ThisFileInfo['tags']['id3v2']['artist'][0]) && isset($ThisFileInfo['tags']['id3v2']['title'][0])) { $image->filename = $ThisFileInfo['tags']['id3v2']['artist'][0] . " - " . $ThisFileInfo['tags']['id3v2']['title'][0] . ".mp3"; } else { if (isset($ThisFileInfo['tags']['id3v1']['artist'][0]) && isset($ThisFileInfo['tags']['id3v1']['title'][0])) { $image->filename = $ThisFileInfo['tags']['id3v1']['artist'][0] . " - " . $ThisFileInfo['tags']['id3v1']['title'][0] . ".mp3"; } else { $image->filename = $metadata['filename']; } } $image->ext = $metadata['extension']; $image->tag_array = Tag::explode($metadata['tags']); $image->source = $metadata['source']; return $image; }
/** * @param string $filename * @param mixed[] $metadata * @return Image */ private function create_image_from_data($filename, $metadata) { $image = new Image(); $msp = new MiniSVGParser($filename); $image->width = $msp->width; $image->height = $msp->height; $image->filesize = $metadata['size']; $image->hash = $metadata['hash']; $image->filename = $metadata['filename']; $image->ext = $metadata['extension']; $image->tag_array = Tag::explode($metadata['tags']); $image->source = $metadata['source']; return $image; }
protected function create_image_from_data($filename, $metadata) { global $config; $image = new Image(); // FIXME: need more flash format specs :| $image->width = 0; $image->height = 0; $image->filesize = $metadata['size']; $image->hash = $metadata['hash']; $image->filename = $metadata['filename']; $image->ext = $metadata['extension']; $image->tag_array = Tag::explode($metadata['tags']); $image->source = $metadata['source']; return $image; }
/** * @param string $filename * @param array $metadata * @return Image|null */ protected function create_image_from_data($filename, $metadata) { $image = new Image(); $info = getimagesize($filename); if (!$info) { return null; } $image->width = $info[0]; $image->height = $info[1]; $image->filesize = $metadata['size']; $image->hash = $metadata['hash']; $image->filename = ($pos = strpos($metadata['filename'], '?')) !== false ? substr($metadata['filename'], 0, $pos) : $metadata['filename']; $image->ext = ($pos = strpos($metadata['extension'], '?')) !== false ? substr($metadata['extension'], 0, $pos) : $metadata['extension']; $image->tag_array = Tag::explode($metadata['tags']); $image->source = $metadata['source']; return $image; }
/** * @param $filename * @param $metadata * @return Image */ private function create_image_from_data($filename, $metadata) { $image = new Image(); $fp = fopen($filename, "r"); $header = unpack("snull/stype/scount", fread($fp, 6)); $subheader = unpack("cwidth/cheight/ccolours/cnull/splanes/sbpp/lsize/loffset", fread($fp, 16)); fclose($fp); $image->width = $subheader['width']; $image->height = $subheader['height']; $image->filesize = $metadata['size']; $image->hash = $metadata['hash']; $image->filename = $metadata['filename']; $image->ext = $metadata['extension']; $image->tag_array = Tag::explode($metadata['tags']); $image->source = $metadata['source']; return $image; }
protected function create_image_from_data($filename, $metadata) { global $config; $image = new Image(); $info = ""; if (!($info = getimagesize($filename))) { return null; } $image->width = $info[0]; $image->height = $info[1]; $image->filesize = $metadata['size']; $image->hash = $metadata['hash']; $image->filename = $metadata['filename']; $image->ext = $metadata['extension']; $image->tag_array = Tag::explode($metadata['tags']); $image->source = $metadata['source']; return $image; }
public function onPageRequest(PageRequestEvent $event) { global $page, $user; if ($event->page_matches("mass_tagger/tag") && $user->is_admin()) { if (!isset($_POST['ids']) or !isset($_POST['tag'])) { return; } $tag = $_POST['tag']; $tag_array = explode(" ", $tag); $pos_tag_array = array(); $neg_tag_array = array(); foreach ($tag_array as $new_tag) { if (strpos($new_tag, '-') === 0) { $neg_tag_array[] = substr($new_tag, 1); } else { $pos_tag_array[] = $new_tag; } } $ids = explode(':', $_POST['ids']); $ids = array_filter($ids, 'is_numeric'); $images = array_map("Image::by_id", $ids); if (isset($_POST['setadd']) && $_POST['setadd'] == 'set') { foreach ($images as $image) { $image->set_tags(Tag::explode($tag)); } } else { foreach ($images as $image) { if (!empty($neg_tag_array)) { $img_tags = array_merge($pos_tag_array, explode(" ", $image->get_tag_list())); $img_tags = array_diff($img_tags, $neg_tag_array); $image->set_tags(Tag::explode($img_tags)); } else { $image->set_tags(Tag::explode($tag . " " . $image->get_tag_list())); } } } $page->set_mode("redirect"); if (!isset($_SERVER['HTTP_REFERER'])) { $_SERVER['HTTP_REFERER'] = make_link(); } $page->set_redirect($_SERVER['HTTP_REFERER']); } }
protected function create_image_from_data($filename, $metadata) { global $config; $image = new Image(); $image->filesize = $metadata['size']; $image->hash = $metadata['hash']; $image->filename = $metadata['filename']; $image->ext = $metadata['extension']; $image->tag_array = Tag::explode($metadata['tags']); $image->source = $metadata['source']; // redundant, since getimagesize() works on SWF o_O // $rect = $this->swf_get_bounds($filename); // if(is_null($rect)) { // return $null; // } // $image->width = $rect[1]; // $image->height = $rect[3]; if (!($info = getimagesize($filename))) { return null; } $image->width = $info[0]; $image->height = $info[1]; return $image; }
public static function resolve_list($tags) { $tags = Tag::explode($tags); $new = array(); foreach ($tags as $tag) { $new_set = explode(' ', Tag::resolve_alias($tag)); foreach ($new_set as $new_one) { $new[] = $new_one; } } $new = array_map(array('Tag', 'sanitise'), $new); $new = array_iunique($new); // remove any duplicate tags return $new; }
private function mass_tag_edit($search, $replace) { global $database; global $config; $search_set = Tag::explode($search); $replace_set = Tag::explode($replace); $last_id = -1; while (true) { // make sure we don't look at the same images twice. // search returns high-ids first, so we want to look // at images with lower IDs than the previous. $search_forward = $search_set; if ($last_id >= 0) { $search_forward[] = "id<{$last_id}"; } $images = Image::find_images(0, 100, $search_forward); if (count($images) == 0) { break; } foreach ($images as $image) { // remove the search'ed tags $before = $image->get_tag_array(); $after = array(); foreach ($before as $tag) { if (!in_array($tag, $search_set)) { $after[] = $tag; } } // add the replace'd tags foreach ($replace_set as $tag) { $after[] = $tag; } $image->set_tags($after); $last_id = $image->id; } } }
/** * @param string|string[] $tags * @param string $source */ private function mass_source_edit($tags, $source) { $tags = Tag::explode($tags); $last_id = -1; while (true) { // make sure we don't look at the same images twice. // search returns high-ids first, so we want to look // at images with lower IDs than the previous. $search_forward = $tags; if ($last_id >= 0) { $search_forward[] = "id<{$last_id}"; } $images = Image::find_images(0, 100, $search_forward); if (count($images) == 0) { break; } foreach ($images as $image) { $image->set_source($source); $last_id = $image->id; } } }
public function handle_commands($event) { global $config, $page, $user; if ($event->page_matches("artist")) { switch ($event->get_arg(0)) { //*************ARTIST SECTION************** case "list": $this->get_listing($page, $event); $this->theme->sidebar_options("neutral"); break; case "new": if (!$user->is_anonymous()) { $this->theme->new_artist_composer(); } else { $errMessage = "You must be registered and logged in to create a new artist."; $this->theme->display_error($page, "Error", $errMessage); } break; case "new_artist": $page->set_mode("redirect"); $page->set_redirect(make_link("artist/new")); break; case "create": if (!$user->is_anonymous()) { $newArtistID = $this->add_artist(); if ($newArtistID == -1) { $errMessage = "Error when entering artist data."; $this->theme->display_error($page, "Error", $errMessage); } else { $page->set_mode("redirect"); $page->set_redirect(make_link("artist/view/" . $newArtistID)); } } else { $errMessage = "You must be registered and logged in to create a new artist."; $this->theme->display_error($page, "Error", $errMessage); } break; case "view": $artistID = $event->get_arg(1); $artist = $this->get_artist($artistID); $aliases = $this->get_alias($artist['id']); $members = $this->get_members($artist['id']); $urls = $this->get_urls($artist['id']); $userIsLogged = !$user->is_anonymous(); $userIsAdmin = $user->is_admin(); $images = Image::find_images(0, 4, Tag::explode($artist['name'])); $this->theme->show_artist($artist, $aliases, $members, $urls, $images, $userIsLogged, $userIsAdmin); if ($userIsLogged) { //$this->theme->show_new_alias_composer($artistID); //$this->theme->show_new_member_composer($artistID); //$this->theme->show_new_url_composer($artistID); } $this->theme->sidebar_options("editor", $artistID, $userIsAdmin); break; case "edit": $artistID = $event->get_arg(1); $artist = $this->get_artist($artistID); $aliases = $this->get_alias($artistID); $members = $this->get_members($artistID); $urls = $this->get_urls($artistID); if (!$user->is_anonymous()) { $this->theme->show_artist_editor($artist, $aliases, $members, $urls); $userIsAdmin = $user->is_admin(); $this->theme->sidebar_options("editor", $artistID, $userIsAdmin); } else { $errMessage = "You must be registered and logged in to edit an artist."; $this->theme->display_error($page, "Error", $errMessage); } break; case "edit_artist": $artistID = $_POST['artist_id']; $page->set_mode("redirect"); $page->set_redirect(make_link("artist/edit/" . $artistID)); break; case "edited": $artistID = int_escape($_POST['id']); $this->update_artist(); $page->set_mode("redirect"); $page->set_redirect(make_link("artist/view/" . $artistID)); break; case "nuke_artist": $artistID = $_POST['artist_id']; $page->set_mode("redirect"); $page->set_redirect(make_link("artist/nuke/" . $artistID)); break; case "nuke": $artistID = $event->get_arg(1); $this->delete_artist($artistID); // this will delete the artist, it's alias, it's urls and it's members $page->set_mode("redirect"); $page->set_redirect(make_link("artist/list")); break; case "add_alias": $artistID = $_POST['artist_id']; $this->theme->show_new_alias_composer($artistID); break; case "add_member": $artistID = $_POST['artist_id']; $this->theme->show_new_member_composer($artistID); break; case "add_url": $artistID = $_POST['artist_id']; $this->theme->show_new_url_composer($artistID); break; //***********ALIAS SECTION *********************** //***********ALIAS SECTION *********************** case "alias": switch ($event->get_arg(1)) { case "add": $artistID = $_POST['artistID']; $this->add_alias(); $page->set_mode("redirect"); $page->set_redirect(make_link("artist/view/" . $artistID)); break; case "delete": $aliasID = $event->get_arg(2); $artistID = $this->get_artistID_by_aliasID($aliasID); $this->delete_alias($aliasID); $page->set_mode("redirect"); $page->set_redirect(make_link("artist/view/" . $artistID)); break; case "edit": $aliasID = int_escape($event->get_arg(2)); $alias = $this->get_alias_by_id($aliasID); $this->theme->show_alias_editor($alias); break; case "edited": $this->update_alias(); $aliasID = int_escape($_POST['aliasID']); $artistID = $this->get_artistID_by_aliasID($aliasID); $page->set_mode("redirect"); $page->set_redirect(make_link("artist/view/" . $artistID)); break; } break; // case: alias //**************** URLS SECTION ********************** //**************** URLS SECTION ********************** case "url": switch ($event->get_arg(1)) { case "add": $artistID = $_POST['artistID']; $this->add_urls(); $page->set_mode("redirect"); $page->set_redirect(make_link("artist/view/" . $artistID)); break; case "delete": $urlID = $event->get_arg(2); $artistID = $this->get_artistID_by_urlID($urlID); $this->delete_url($urlID); $page->set_mode("redirect"); $page->set_redirect(make_link("artist/view/" . $artistID)); break; case "edit": $urlID = int_escape($event->get_arg(2)); $url = $this->get_url_by_id($urlID); $this->theme->show_url_editor($url); break; case "edited": $this->update_url(); $urlID = int_escape($_POST['urlID']); $artistID = $this->get_artistID_by_urlID($urlID); $page->set_mode("redirect"); $page->set_redirect(make_link("artist/view/" . $artistID)); break; } break; // case: urls //******************* MEMBERS SECTION ********************* //******************* MEMBERS SECTION ********************* case "member": switch ($event->get_arg(1)) { case "add": $artistID = $_POST['artistID']; $this->add_members(); $page->set_mode("redirect"); $page->set_redirect(make_link("artist/view/" . $artistID)); break; case "delete": $memberID = int_escape($event->get_arg(2)); $artistID = $this->get_artistID_by_memberID($memberID); $this->delete_member($memberID); $page->set_mode("redirect"); $page->set_redirect(make_link("artist/view/" . $artistID)); break; case "edit": $memberID = int_escape($event->get_arg(2)); $member = $this->get_member_by_id($memberID); $this->theme->show_member_editor($member); break; case "edited": $this->update_member(); $memberID = int_escape($_POST['memberID']); $artistID = $this->get_artistID_by_memberID($memberID); $page->set_mode("redirect"); $page->set_redirect(make_link("artist/view/" . $artistID)); break; } break; //case: members } } }
/** * @param Image $image * @return string */ private function build_tag_map(Image $image) { global $database, $config; $html = ""; $cloud = ""; $precloud = ""; $postcloud = ""; $sort_method = $config->get_string("tageditcloud_sort"); $tags_min = $config->get_int("tageditcloud_minusage"); $used_first = $config->get_bool("tageditcloud_usedfirst"); $max_count = $config->get_int("tageditcloud_maxcount"); $def_count = $config->get_int("tageditcloud_defcount"); $ignore_tags = Tag::explode($config->get_string("tageditcloud_ignoretags")); if (class_exists("TagCategories")) { $categories = $database->get_all("SELECT category, color FROM image_tag_categories"); $cat_color = array(); foreach ($categories as $row) { $cat_color[$row['category']] = $row['color']; } } $tag_data = null; switch ($sort_method) { case 'a': case 'p': default: $tag_data = $database->get_all("SELECT tag, FLOOR(LN(LN(count - :tag_min1 + 1)+1)*150)/200 AS scaled, count\n\t\t\t\t\tFROM tags WHERE count >= :tag_min2 ORDER BY " . ($sort_method == 'a' ? "tag" : "count DESC") . " LIMIT :limit", array("tag_min1" => $tags_min, "tag_min2" => $tags_min, "limit" => $max_count)); break; case 'r': $relevant_tags = array_diff($image->get_tag_array(), $ignore_tags); if (count($relevant_tags) > 0) { $relevant_tags = implode(",", array_map(array($database, "escape"), $relevant_tags)); $tag_data = $database->get_all("SELECT t2.tag AS tag, COUNT(image_id) AS count, FLOOR(LN(LN(COUNT(image_id) - :tag_min1 + 1)+1)*150)/200 AS scaled\n\t\t\t\t\t\tFROM image_tags it1 JOIN image_tags it2 USING(image_id) JOIN tags t1 ON it1.tag_id = t1.id JOIN tags t2 ON it2.tag_id = t2.id\n\t\t\t\t\t\tWHERE t1.count >= :tag_min2 AND t1.tag IN({$relevant_tags}) GROUP BY t2.tag ORDER BY count DESC LIMIT :limit", array("tag_min1" => $tags_min, "tag_min2" => $tags_min, "limit" => $max_count)); } break; } $counter = 1; foreach ($tag_data as $row) { $full_tag = $row['tag']; if (class_exists("TagCategories")) { $tc = explode(':', $row['tag']); if (isset($tc[1]) && isset($cat_color[$tc[0]])) { $h_tag = html_escape($tc[1]); $color = '; color:' . $cat_color[$tc[0]]; } else { $h_tag = html_escape($row['tag']); $color = ''; } } else { $h_tag = html_escape($row['tag']); $color = ''; } $size = sprintf("%.2f", max($row['scaled'], 0.5)); $js = htmlspecialchars('tageditcloud_toggle_tag(this,' . json_encode($full_tag) . ')', ENT_QUOTES); //Ugly, but it works if (array_search($row['tag'], $image->get_tag_array()) !== FALSE) { if ($used_first) { $precloud .= " <span onclick='{$js}' class='tag-selected' style='font-size: {$size}em{$color}' title='{$row['count']}'>{$h_tag}</span> \n"; continue; } else { $entry = " <span onclick='{$js}' class='tag-selected' style='font-size: {$size}em{$color}' title='{$row['count']}'>{$h_tag}</span> \n"; } } else { $entry = " <span onclick='{$js}' style='font-size: {$size}em{$color}' title='{$row['count']}'>{$h_tag}</span> \n"; } if ($counter++ <= $def_count) { $cloud .= $entry; } else { $postcloud .= $entry; } } if ($precloud != '') { $html .= "<div id='tagcloud_set'>{$precloud}</div>"; } if ($postcloud != '') { $postcloud = "<div id='tagcloud_extra' style='display: none;'>{$postcloud}</div>"; } $html .= "<div id='tagcloud_unset'>{$cloud}{$postcloud}</div>"; if ($sort_method != 'a' && $counter > $def_count) { $rem = $counter - $def_count; $html .= "</div><br>[<span onclick='tageditcloud_toggle_extra(this);' style='color: #0000EF; font-weight:bold;'>show {$rem} more tags</span>]"; } return "<div id='tageditcloud' class='tageditcloud'>{$html}</div>"; // FIXME: stupidasallhell }
/** * @param string $filename * @param mixed[] $metadata * @return Image|null */ protected function create_image_from_data($filename, $metadata) { $image = new Image(); require_once 'lib/getid3/getid3/getid3.php'; $getID3 = new getID3(); $ThisFileInfo = $getID3->analyze($filename); if (isset($ThisFileInfo['video']['resolution_x']) && isset($ThisFileInfo['video']['resolution_y'])) { $image->width = $ThisFileInfo['video']['resolution_x']; $image->height = $ThisFileInfo['video']['resolution_y']; } else { $image->width = 0; $image->height = 0; } switch ($ThisFileInfo['mime_type']) { case "video/webm": $image->ext = "webm"; break; case "video/quicktime": $image->ext = "mp4"; break; case "application/ogg": $image->ext = "ogv"; break; case "video/x-flv": $image->ext = "flv"; break; } $image->filesize = $metadata['size']; $image->hash = $metadata['hash']; $image->filename = $metadata['filename']; $image->tag_array = Tag::explode($metadata['tags']); $image->source = $metadata['source']; return $image; }
/** * @param Page $page * @param string[] $search */ private function add_refine_block(Page $page, $search) { global $database, $config; $wild_tags = Tag::explode($search); $str_search = Tag::implode($search); $related_tags = $database->cache->get("related_tags:{$str_search}"); if (empty($related_tags)) { // $search_tags = array(); $tag_id_array = array(); $tags_ok = true; foreach ($wild_tags as $tag) { $tag = str_replace("*", "%", $tag); $tag = str_replace("?", "_", $tag); $tag_ids = $database->get_col("SELECT id FROM tags WHERE tag LIKE :tag", array("tag" => $tag)); // $search_tags = array_merge($search_tags, // $database->get_col("SELECT tag FROM tags WHERE tag LIKE :tag", array("tag"=>$tag))); $tag_id_array = array_merge($tag_id_array, $tag_ids); $tags_ok = count($tag_ids) > 0; if (!$tags_ok) { break; } } $tag_id_list = join(', ', $tag_id_array); if ($tags_ok) { $query = "\n\t\t\t\t\tSELECT t2.tag AS tag, COUNT(it2.image_id) AS calc_count\n\t\t\t\t\tFROM\n\t\t\t\t\t\timage_tags AS it1,\n\t\t\t\t\t\timage_tags AS it2,\n\t\t\t\t\t\ttags AS t1,\n\t\t\t\t\t\ttags AS t2\n\t\t\t\t\tWHERE\n\t\t\t\t\t\tt1.id IN({$tag_id_list})\n\t\t\t\t\t\tAND it1.image_id=it2.image_id\n\t\t\t\t\t\tAND it1.tag_id = t1.id\n\t\t\t\t\t\tAND it2.tag_id = t2.id\n\t\t\t\t\tGROUP BY t2.tag\n\t\t\t\t\tORDER BY calc_count\n\t\t\t\t\tDESC LIMIT :limit\n\t\t\t\t"; $args = array("limit" => $config->get_int('tag_list_length')); $related_tags = $database->get_all($query, $args); $database->cache->set("related_tags:{$str_search}", $related_tags, 60 * 60); } } if (!empty($related_tags)) { $this->theme->display_refine_block($page, $related_tags, $wild_tags); } }
/** * HERE WE GET THE IMAGES FROM THE TAG ON IMPORT * @param int $pool_id */ private function import_posts($pool_id) { global $page, $config; $poolsMaxResults = $config->get_int("poolsMaxImportResults", 1000); $images = $images = Image::find_images(0, $poolsMaxResults, Tag::explode($_POST["pool_tag"])); $this->theme->pool_result($page, $images, $this->get_pool($pool_id)); }
private function delete_by_query() { global $page; $query = $_POST['query']; $reason = @$_POST['reason']; assert(strlen($query) > 1); log_warning("admin", "Mass deleting: {$query}"); $count = 0; foreach (Image::find_images(0, 1000000, Tag::explode($query)) as $image) { if ($reason && class_exists("ImageBan")) { send_event(new AddImageHashBanEvent($image->hash, $reason)); } send_event(new ImageDeletionEvent($image)); $count++; } log_debug("admin", "Deleted {$count} images", true); $page->set_mode("redirect"); $page->set_redirect(make_link("post/list")); return false; }
public function receive_event(Event $event) { global $config, $database, $page, $user; if (is_null($this->theme)) { $this->theme = get_theme_object($this); } $is_full = disk_free_space(realpath("./images/")) < 100 * 1024 * 1024; if ($event instanceof InitExtEvent) { global $config; $config->set_default_int('upload_count', 3); $config->set_default_int('upload_size', '1MB'); $config->set_default_bool('upload_anon', false); } if ($event instanceof PostListBuildingEvent) { global $user; if ($this->can_upload($user)) { if ($is_full) { $this->theme->display_full($page); } else { $this->theme->display_block($page); } } } if ($event instanceof PageRequestEvent && $event->page_matches("upload")) { if (count($_FILES) + count($_POST) > 0) { $tags = Tag::explode($_POST['tags']); $source = isset($_POST['source']) ? $_POST['source'] : null; if ($this->can_upload($user)) { $ok = true; foreach ($_FILES as $file) { $ok = $ok & $this->try_upload($file, $tags, $source); } foreach ($_POST as $name => $value) { if (substr($name, 0, 3) == "url" && strlen($value) > 0) { $ok = $ok & $this->try_transload($value, $tags, $source); } } $this->theme->display_upload_status($page, $ok); } else { $this->theme->display_permission_denied($page); } } else { if (!empty($_GET['url'])) { global $user; if ($this->can_upload($user)) { $url = $_GET['url']; $tags = array('tagme'); if (!empty($_GET['tags']) && $_GET['tags'] != "null") { $tags = Tag::explode($_GET['tags']); } $ok = $this->try_transload($url, $tags, $url); $this->theme->display_upload_status($page, $ok); } else { $this->theme->display_permission_denied($page); } } else { if (!$is_full) { $this->theme->display_page($page); } } } } if ($event instanceof SetupBuildingEvent) { $sb = new SetupBlock("Upload"); $sb->position = 10; $sb->add_int_option("upload_count", "Max uploads: "); $sb->add_shorthand_int_option("upload_size", "<br>Max size per file: "); $sb->add_bool_option("upload_anon", "<br>Allow anonymous uploads: "); $sb->add_choice_option("transload_engine", array("Disabled" => "none", "cURL" => "curl", "fopen" => "fopen", "WGet" => "wget"), "<br>Transload: "); $event->panel->add_block($sb); } if ($event instanceof DataUploadEvent) { global $config; if ($is_full) { throw new UploadException("Upload failed; disk nearly full"); } if (filesize($event->tmpname) > $config->get_int('upload_size')) { $size = to_shorthand_int(filesize($event->tmpname)); $limit = to_shorthand_int($config->get_int('upload_size')); throw new UploadException("File too large ({$size} > {$limit})"); } } }
/** * 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 doesnt authenticate, he post will be added anonymously. * - If the md5 parameter is supplied and does not match the hash of whats 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. */ private function api_add_post() { global $user, $config, $page; $danboorup_kludge = 1; // danboorup for firefox makes broken links out of location: /path // 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 (!$user->can("create_image")) { $page->set_code(409); $page->add_http_header("X-Danbooru-Errors: authentication error"); return; } 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 $source = isset($_REQUEST['source']) ? $_REQUEST['source'] : $_REQUEST['post']['source']; $file = tempnam("/tmp", "shimmie_transload"); $ok = transload($source, $file); if (!$ok) { $page->set_code(409); $page->add_http_header("X-Danbooru-Errors: fopen read error"); return; } $filename = basename($source); } else { // Nothing was specified at all $page->set_code(409); $page->add_http_header("X-Danbooru-Errors: no input files"); return; } // Get tags out of url $posttags = Tag::explode(isset($_REQUEST['tags']) ? $_REQUEST['tags'] : $_REQUEST['post']['tags']); // Was an md5 supplied? Does it match the file hash? $hash = md5_file($file); if (isset($_REQUEST['md5']) && strtolower($_REQUEST['md5']) != $hash) { $page->set_code(409); $page->add_http_header("X-Danbooru-Errors: md5 mismatch"); return; } // Upload size checking is now performed in the upload extension // It is also currently broken due to some confusion over file variable ($tmp_filename?) // Does it exist already? $existing = Image::by_hash($hash); if (!is_null($existing)) { $page->set_code(409); $page->add_http_header("X-Danbooru-Errors: duplicate"); $existinglink = make_link("post/view/" . $existing->id); if ($danboorup_kludge) { $existinglink = make_http($existinglink); } $page->add_http_header("X-Danbooru-Location: {$existinglink}"); return; } // Fire off an event which should process the new file and add it to the db $fileinfo = pathinfo($filename); $metadata = array(); $metadata['filename'] = $fileinfo['basename']; $metadata['extension'] = $fileinfo['extension']; $metadata['tags'] = $posttags; $metadata['source'] = $source; //log_debug("danbooru_api","========== NEW($filename) ========="); //log_debug("danbooru_api", "upload($filename): fileinfo(".var_export($fileinfo,TRUE)."), metadata(".var_export($metadata,TRUE).")..."); try { $nevent = new DataUploadEvent($file, $metadata); //log_debug("danbooru_api", "send_event(".var_export($nevent,TRUE).")"); send_event($nevent); // If it went ok, grab the id for the newly uploaded image and pass it in the header $newimg = Image::by_hash($hash); // FIXME: Unsupported file doesn't throw an error? $newid = make_link("post/view/" . $newimg->id); if ($danboorup_kludge) { $newid = make_http($newid); } // Did we POST or GET this call? if ($_SERVER['REQUEST_METHOD'] == 'POST') { $page->add_http_header("X-Danbooru-Location: {$newid}"); } else { $page->add_http_header("Location: {$newid}"); } } catch (UploadException $ex) { // Did something screw up? $page->set_code(409); $page->add_http_header("X-Danbooru-Errors: exception - " . $ex->getMessage()); } }
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_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 = Tag::explode(isset($_REQUEST['tags']) ? $_REQUEST['tags'] : $_REQUEST['post']['tags']); $hash = md5_file($file); // Was an md5 supplied? Does it match the file hash? if (isset($_REQUEST['md5'])) { if (strtolower($_REQUEST['md5']) != $hash) { header("HTTP/1.0 409 Conflict"); header("X-Danbooru-Errors: md5 mismatch"); return; } } // Upload size checking is now performed in the upload extension // It is also currently broken due to some confusion over file variable ($tmp_filename?) // Does it exist already? $existing = Image::by_hash($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 file and add it to the db $fileinfo = pathinfo($filename); $metadata['filename'] = $fileinfo['basename']; $metadata['extension'] = $fileinfo['extension']; $metadata['tags'] = $posttags; $metadata['source'] = $source; try { $nevent = new DataUploadEvent($user, $file, $metadata); send_event($nevent); // If it went ok, grab the id for the newly uploaded image and pass it in the header $newimg = Image::by_hash($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}"); } } catch (UploadException $ex) { // Did something screw up? header("HTTP/1.0 409 Conflict"); header("X-Danbooru-Errors: " . $ex->getMessage()); return; } } 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') { $this->authenticate_user(); if (isset($_GET['md5'])) { $md5list = explode(",", $_GET['md5']); foreach ($md5list as $md5) { $results[] = Image::by_hash($md5); } } elseif (isset($_GET['id'])) { $idlist = explode(",", $_GET['id']); foreach ($idlist as $id) { $results[] = Image::by_id($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 = Image::find_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=\"" . $this->xmlspecialchars($taglist) . "\" source=\"" . $this->xmlspecialchars($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']); } } } 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=\"" . $this->xmlspecialchars($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}"); } }
public function onPageRequest(PageRequestEvent $event) { global $user, $page; if ($event->page_matches("admin/bulk_rate")) { if (!$user->is_admin()) { throw new PermissionDeniedException(); } else { $n = 0; while (true) { $images = Image::find_images($n, 100, Tag::explode($_POST["query"])); if (count($images) == 0) { break; } reset($images); // rewind to first element in array. foreach ($images as $image) { send_event(new RatingSetEvent($image, $_POST['rating'])); } $n += 100; } #$database->execute(" # update images set rating=? where images.id in ( # select image_id from image_tags join tags # on image_tags.tag_id = tags.id where tags.tag = ?); # ", array($_POST["rating"], $_POST["tag"])); $page->set_mode("redirect"); $page->set_redirect(make_link("post/list")); } } }
private function delete_by_query($query) { global $page, $user; assert(strlen($query) > 1); foreach (Image::find_images(0, 1000000, Tag::explode($query)) as $image) { send_event(new ImageDeletionEvent($image)); } }
public function receive_event(Event $event) { global $config, $database, $page, $user; if (is_null($this->theme)) { $this->theme = get_theme_object($this); } // f*****g PHP "security" measures -_-;;; $free_num = @disk_free_space(realpath("./images/")); if ($free_num === FALSE) { $is_full = false; } else { $is_full = $free_num < 100 * 1024 * 1024; } if ($event instanceof InitExtEvent) { $config->set_default_int('upload_count', 3); $config->set_default_int('upload_size', '1MB'); $config->set_default_bool('upload_anon', false); $config->set_default_bool('upload_replace', true); } if ($event instanceof PostListBuildingEvent) { if ($this->can_upload($user)) { if ($is_full) { $this->theme->display_full($page); } else { $this->theme->display_block($page); } } } if ($event instanceof PageRequestEvent) { if ($event->page_matches("upload/replace")) { /* Upload & Replace Image Request */ if (!$config->get_bool("upload_replace")) { throw new UploadException("Upload Replacing Images is not enabled."); } // check if the user is an administrator and can upload files. if (!$user->is_admin()) { $this->theme->display_permission_denied($page); } else { if ($is_full) { throw new UploadException("Can not replace Image: disk nearly full"); } // Try to get the image ID $image_id = int_escape($event->get_arg(0)); if (empty($image_id)) { $image_id = isset($_POST['image_id']) ? $_POST['image_id'] : null; } if (empty($image_id)) { throw new UploadException("Can not replace Image: No valid Image ID given."); } $image_old = Image::by_id($image_id); if (is_null($image_old)) { $this->theme->display_error($page, "Image not found", "No image in the database has the ID #{$image_id}"); } if (count($_FILES) + count($_POST) > 0) { if (count($_FILES) > 1) { throw new UploadException("Can not upload more than one image for replacing."); } $source = isset($_POST['source']) ? $_POST['source'] : null; $tags = ''; // Tags aren't changed when uploading. Set to null to stop PHP warnings. if (count($_FILES)) { foreach ($_FILES as $file) { $ok = $this->try_upload($file, $tags, $source, $image_id); break; // leave the foreach loop. } } else { foreach ($_POST as $name => $value) { if (substr($name, 0, 3) == "url" && strlen($value) > 0) { $ok = $this->try_transload($value, $tags, $source, $image_id); break; // leave the foreach loop. } } } $this->theme->display_upload_status($page, $ok); } else { if (!empty($_GET['url'])) { $url = $_GET['url']; $ok = $this->try_transload($url, $tags, $url, $image_id); $this->theme->display_upload_status($page, $ok); } else { $this->theme->display_replace_page($page, $image_id); } } } // END of if admin / can_upload } else { if ($event->page_matches("upload")) { if (!$this->can_upload($user)) { $this->theme->display_permission_denied($page); } else { /* Regular Upload Image */ if (count($_FILES) + count($_POST) > 0) { $tags = Tag::explode($_POST['tags']); $source = isset($_POST['source']) ? $_POST['source'] : null; $ok = true; foreach ($_FILES as $file) { $ok = $ok & $this->try_upload($file, $tags, $source); } foreach ($_POST as $name => $value) { if (substr($name, 0, 3) == "url" && strlen($value) > 0) { $ok = $ok & $this->try_transload($value, $tags, $source); } } $this->theme->display_upload_status($page, $ok); } else { if (!empty($_GET['url'])) { $url = $_GET['url']; $tags = array('tagme'); if (!empty($_GET['tags']) && $_GET['tags'] != "null") { $tags = Tag::explode($_GET['tags']); } $ok = $this->try_transload($url, $tags, $url); $this->theme->display_upload_status($page, $ok); } else { if (!$is_full) { $this->theme->display_page($page); } } } } // END of if can_upload } } } // END of if PageRequestEvent if ($event instanceof SetupBuildingEvent) { $tes = array(); $tes["Disabled"] = "none"; if (function_exists("curl_init")) { $tes["cURL"] = "curl"; } $tes["fopen"] = "fopen"; $tes["WGet"] = "wget"; $sb = new SetupBlock("Upload"); $sb->position = 10; // Output the limits from PHP so the user has an idea of what they can set. $sb->add_label("<i>PHP's Upload Limit = " . ini_get('max_file_uploads') . "</i><br/>"); $sb->add_int_option("upload_count", "Max uploads: "); $sb->add_label("<br/><i>PHP's Max Size Upload = " . ini_get('upload_max_filesize') . "</i><br/>"); $sb->add_shorthand_int_option("upload_size", "<br/>Max size per file: "); $sb->add_bool_option("upload_anon", "<br/>Allow anonymous uploads: "); $sb->add_bool_option("upload_replace", "<br/>Allow replacing images: "); $sb->add_choice_option("transload_engine", $tes, "<br/>Transload: "); $event->panel->add_block($sb); } if ($event instanceof DataUploadEvent) { if ($is_full) { throw new UploadException("Upload failed; disk nearly full"); } if (filesize($event->tmpname) > $config->get_int('upload_size')) { $size = to_shorthand_int(filesize($event->tmpname)); $limit = to_shorthand_int($config->get_int('upload_size')); throw new UploadException("File too large ({$size} > {$limit})"); } } }
private function add_refine_block($page, $search) { global $database; global $config; $wild_tags = Tag::explode($search); // $search_tags = array(); $tag_id_array = array(); $tags_ok = true; foreach ($wild_tags as $tag) { $tag = str_replace("*", "%", $tag); $tag = str_replace("?", "_", $tag); $tag_ids = $database->db->GetCol("SELECT id FROM tags WHERE tag LIKE ?", array($tag)); // $search_tags = array_merge($search_tags, // $database->db->GetCol("SELECT tag FROM tags WHERE tag LIKE ?", array($tag))); $tag_id_array = array_merge($tag_id_array, $tag_ids); $tags_ok = count($tag_ids) > 0; if (!$tags_ok) { break; } } $tag_id_list = join(', ', $tag_id_array); if ($tags_ok) { $query = "\n\t\t\t\tSELECT t2.tag AS tag, COUNT(it2.image_id) AS calc_count\n\t\t\t\tFROM\n\t\t\t\t\timage_tags AS it1,\n\t\t\t\t\timage_tags AS it2,\n\t\t\t\t\ttags AS t1,\n\t\t\t\t\ttags AS t2\n\t\t\t\tWHERE\n\t\t\t\t\tt1.id IN({$tag_id_list})\n\t\t\t\t\tAND it1.image_id=it2.image_id\n\t\t\t\t\tAND it1.tag_id = t1.id\n\t\t\t\t\tAND it2.tag_id = t2.id\n\t\t\t\tGROUP BY t2.tag\n\t\t\t\tORDER BY calc_count\n\t\t\t\tDESC LIMIT ?\n\t\t\t"; $args = array($config->get_int('tag_list_length')); $related_tags = $database->get_all($query, $args); print $database->db->ErrorMsg(); if (count($related_tags) > 0) { $this->theme->display_refine_block($page, $related_tags, $wild_tags); } } }
/** * Wrapper for post creation * @param OuroborosPost $post * @param string $md5 */ protected function postCreate(OuroborosPost $post, $md5 = '') { global $config; $handler = $config->get_string("upload_collision_handler"); if (!empty($md5) && !($handler == 'merge')) { $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)) { $handler = $config->get_string("upload_collision_handler"); if ($handler == "merge") { $merged = array_merge(Tag::explode($post->tags), $img->get_tag_array()); send_event(new TagSetEvent($img, $merged)); // This is really the only thing besides tags we should care if (isset($meta['source'])) { send_event(new SourceSetEvent($img, $meta['source'])); } $this->sendResponse(200, self::OK_POST_CREATE_UPDATE . ' ID: ' . $img->id); return; } else { $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; } }
public function onPageRequest(PageRequestEvent $event) { global $config, $database, $page, $user; if ($event->page_matches("post/list")) { if (isset($_GET['search'])) { $search = url_escape(Tag::implode(Tag::resolve_aliases(Tag::explode($_GET['search'], false)))); if (empty($search)) { $page->set_mode("redirect"); $page->set_redirect(make_link("post/list/1")); } else { $page->set_mode("redirect"); $page->set_redirect(make_link('post/list/' . $search . '/1')); } return; } $search_terms = $event->get_search_terms(); $page_number = $event->get_page_number(); $page_size = $event->get_page_size(); $count_search_terms = count($search_terms); try { #log_debug("index", "Search for ".implode(" ", $search_terms), false, array("terms"=>$search_terms)); $total_pages = Image::count_pages($search_terms); if (SPEED_HAX && $count_search_terms === 0 && $page_number < 10) { // extra caching for the first few post/list pages $images = $database->cache->get("post-list:{$page_number}"); if (!$images) { $images = Image::find_images(($page_number - 1) * $page_size, $page_size, $search_terms); $database->cache->set("post-list:{$page_number}", $images, 600); } } else { $images = Image::find_images(($page_number - 1) * $page_size, $page_size, $search_terms); } } catch (SearchTermParseException $stpe) { // FIXME: display the error somewhere $total_pages = 0; $images = array(); } $count_images = count($images); if ($count_search_terms === 0 && $count_images === 0 && $page_number === 1) { $this->theme->display_intro($page); send_event(new PostListBuildingEvent($search_terms)); } else { if ($count_search_terms > 0 && $count_images === 1 && $page_number === 1) { $page->set_mode("redirect"); $page->set_redirect(make_link('post/view/' . $images[0]->id)); } else { $plbe = new PostListBuildingEvent($search_terms); send_event($plbe); $this->theme->set_page($page_number, $total_pages, $search_terms); $this->theme->display_page($page, $images); if (count($plbe->parts) > 0) { $this->theme->display_admin_block($plbe->parts); } } } } }
/** * @param string|int $id * @return array */ private function tags_for_upload_slot($id) { if (isset($_POST["tags{$id}"])) { # merge then explode, not explode then merge - else # one of the merges may create a surplus "tagme" $tags = Tag::explode($_POST['tags'] . " " . $_POST["tags{$id}"]); } else { $tags = Tag::explode($_POST['tags']); } return $tags; }
public function receive_event(Event $event) { global $config, $database, $page, $user; if (is_null($this->theme)) { $this->theme = get_theme_object($this); } if ($event instanceof AdminBuildingEvent) { $this->theme->display_bulk_rater(); } if ($event instanceof PageRequestEvent && $event->page_matches("admin/bulk_rate")) { global $database, $user, $page; if (!$user->is_admin()) { throw PermissionDeniedException(); } else { $n = 0; while (true) { $images = Image::find_images($n, 100, Tag::explode($_POST["query"])); if (count($images) == 0) { break; } foreach ($images as $image) { send_event(new RatingSetEvent($image, $user, $_POST['rating'])); } $n += 100; } #$database->execute(" # update images set rating=? where images.id in ( # select image_id from image_tags join tags # on image_tags.tag_id = tags.id where tags.tag = ?); # ", array($_POST["rating"], $_POST["tag"])); $page->set_mode("redirect"); $page->set_redirect(make_link("admin")); } } if ($event instanceof InitExtEvent) { if ($config->get_int("ext_ratings2_version") < 2) { $this->install(); } $config->set_default_string("ext_rating_anon_privs", 'squ'); $config->set_default_string("ext_rating_user_privs", 'sqeu'); $config->set_default_string("ext_rating_admin_privs", 'sqeu'); } if ($event instanceof RatingSetEvent) { $this->set_rating($event->image->id, $event->rating); } if ($event instanceof ImageInfoBoxBuildingEvent) { if ($this->can_rate()) { $event->add_part($this->theme->get_rater_html($event->image->id, $event->image->rating), 80); } } if ($event instanceof ImageInfoSetEvent) { if ($this->can_rate() && isset($_POST["rating"])) { send_event(new RatingSetEvent($event->image, $user, $_POST['rating'])); } } if ($event instanceof SetupBuildingEvent) { $privs = array(); $privs['Safe Only'] = 's'; $privs['Safe and Unknown'] = 'su'; $privs['Safe and Questionable'] = 'sq'; $privs['Safe, Questionable, Unknown'] = 'squ'; $privs['All'] = 'sqeu'; $sb = new SetupBlock("Image Ratings"); $sb->add_choice_option("ext_rating_anon_privs", $privs, "Anonymous: "); $sb->add_choice_option("ext_rating_user_privs", $privs, "<br>Users: "); $sb->add_choice_option("ext_rating_admin_privs", $privs, "<br>Admins: "); $event->panel->add_block($sb); } if ($event instanceof ParseLinkTemplateEvent) { $event->replace('$rating', $this->theme->rating_to_name($event->image->rating)); } if ($event instanceof SearchTermParseEvent) { $matches = array(); if (is_null($event->term) && $this->no_rating_query($event->context)) { $set = Ratings::privs_to_sql(Ratings::get_user_privs($user)); $event->add_querylet(new Querylet("rating IN ({$set})")); } if (preg_match("/^rating=([sqeu]+)\$/", $event->term, $matches)) { $sqes = $matches[1]; $arr = array(); for ($i = 0; $i < strlen($sqes); $i++) { $arr[] = "'" . $sqes[$i] . "'"; } $set = join(', ', $arr); $event->add_querylet(new Querylet("rating IN ({$set})")); } if (preg_match("/^rating=(safe|questionable|explicit|unknown)\$/", strtolower($event->term), $matches)) { $text = $matches[1]; $char = $text[0]; $event->add_querylet(new Querylet("rating = ?", array($char))); } } }