/** * @return bool */ private function download_shimmie() { global $config; $commitSHA = $_GET['sha']; $g_userrepo = $config->get_string('update_guserrepo'); $url = "https://codeload.github.com/" . $g_userrepo . "/zip/" . $commitSHA; $filename = "./data/update_{$commitSHA}.zip"; log_info("update", "Attempting to download Shimmie commit: " . $commitSHA); if ($headers = transload($url, $filename)) { if ($headers['Content-Type'] !== "application/zip" || (int) $headers['Content-Length'] !== filesize($filename)) { unlink("./data/update_{$commitSHA}.zip"); log_warning("update", "Download failed: not zip / not same size as remote file."); return false; } return true; } log_warning("update", "Download failed to download."); return false; }
/** * Handle an transload. * * @param string $url * @param mixed $tags * @param string $source * @param string $replace * @return bool Returns TRUE on transload successful. */ private function try_transload($url, $tags, $source, $replace = '') { global $page, $config, $user; $ok = true; // Checks if user is admin > check if you want locked. if ($user->can("edit_image_lock") && !empty($_GET['locked'])) { $locked = bool_escape($_GET['locked']); } // Checks if url contains rating, also checks if the rating extension is enabled. if ($config->get_string("transload_engine", "none") != "none" && class_exists("Ratings") && !empty($_GET['rating'])) { // Rating event will validate that this is s/q/e/u $rating = strtolower($_GET['rating']); $rating = $rating[0]; } else { $rating = ""; } $tmp_filename = tempnam(ini_get('upload_tmp_dir'), "shimmie_transload"); // transload() returns Array or Bool, depending on the transload_engine. $headers = transload($url, $tmp_filename); $s_filename = is_array($headers) ? findHeader($headers, 'Content-Disposition') : null; $h_filename = $s_filename ? preg_replace('/^.*filename="([^ ]+)"/i', '$1', $s_filename) : 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; } if (filesize($tmp_filename) == 0) { $this->theme->display_upload_error($page, "Error with " . html_escape($filename), "No data found -- perhaps the site has hotlink protection?"); $ok = false; } else { $pathinfo = pathinfo($url); $metadata = array(); $metadata['filename'] = $filename; $metadata['extension'] = getExtension(findHeader($headers, 'Content-Type')) ?: $pathinfo['extension']; $metadata['tags'] = $tags; $metadata['source'] = $url == $source && !$config->get_bool('upload_tlsource') ? "" : $source; /* check for locked > adds to metadata if it has */ if (!empty($locked)) { $metadata['locked'] = $locked ? "on" : ""; } /* check for rating > adds to metadata if it has */ if (!empty($rating)) { $metadata['rating'] = $rating; } /* check if we have been given an image ID to replace */ if (!empty($replace)) { $metadata['replace'] = $replace; } $event = new DataUploadEvent($tmp_filename, $metadata); try { send_event($event); } catch (UploadException $ex) { $this->theme->display_upload_error($page, "Error with " . html_escape($url), $ex->getMessage()); $ok = false; } } unlink($tmp_filename); return $ok; }
/** * 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; } }
/** * 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()); } }