From 40269a6f4a447e387961c87dfd563cee56b9f97f Mon Sep 17 00:00:00 2001 From: matthew Date: Thu, 10 Oct 2019 10:16:15 -0500 Subject: [PATCH 01/30] Cron uploader enhancements and bug fixes --- ext/cron_uploader/config.php | 98 ++++++ ext/cron_uploader/main.php | 637 ++++++++++++++++++----------------- ext/cron_uploader/style.css | 3 + ext/cron_uploader/theme.php | 126 +++++++ 4 files changed, 562 insertions(+), 302 deletions(-) create mode 100644 ext/cron_uploader/config.php create mode 100644 ext/cron_uploader/style.css create mode 100644 ext/cron_uploader/theme.php diff --git a/ext/cron_uploader/config.php b/ext/cron_uploader/config.php new file mode 100644 index 00000000..c749d635 --- /dev/null +++ b/ext/cron_uploader/config.php @@ -0,0 +1,98 @@ +set_default_int(self::COUNT, 1); + $config->set_default_string(self::DIR, data_path(self::DEFAULT_PATH)); + + $upload_key = $config->get_string(self::KEY, ""); + if (empty($upload_key)) { + $upload_key = self::generate_key(); + + $config->set_string(self::KEY, $upload_key); + } + + } + + public static function get_user(): int + { + global $config; + return $config->get_int(self::USER); + } + + public static function set_user(int $value): void + { + global $config; + $config->set_int(self::USER, $value); + } + + + public static function get_key(): string + { + global $config; + return $config->get_string(self::KEY); + } + + public static function set_key(string $value): void + { + global $config; + $config->set_string(self::KEY, $value); + } + + public static function get_count(): int + { + global $config; + return $config->get_int(self::COUNT); + } + + public static function set_count(int $value): int + { + global $config; + $config->get_int(self::COUNT, $value); + } + + public static function get_dir(): string + { + global $config; + $value = $config->get_string(self::DIR); + if (empty($value)) { + $value = data_path("cron_uploader"); + self::set_dir($value); + } + return $value; + } + + public static function set_dir(string $value): void + { + global $config; + $config->set_string(self::DIR, $value); + } + + + /* + * Generates a unique key for the website to prevent unauthorized access. + */ + private static function generate_key() + { + $length = 20; + $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + $randomString = ''; + + for ($i = 0; $i < $length; $i++) { + $randomString .= $characters [rand(0, strlen($characters) - 1)]; + } + + return $randomString; + } +} diff --git a/ext/cron_uploader/main.php b/ext/cron_uploader/main.php index 68a85635..98999d29 100644 --- a/ext/cron_uploader/main.php +++ b/ext/cron_uploader/main.php @@ -1,43 +1,31 @@ parent=="system") { + $event->add_nav_link("cron_docs", new Link('cron_upload'), "Cron Upload"); + } + } /** * Checks if the cron upload page has been accessed @@ -45,308 +33,352 @@ class CronUploader extends Extension */ public function onPageRequest(PageRequestEvent $event) { - global $config, $user; + global $user; if ($event->page_matches("cron_upload")) { - $this->upload_key = $config->get_string(self::CONFIG_KEY, ""); - - // If the key is in the url, upload - if ($this->upload_key != "" && $event->get_arg(0) == $this->upload_key) { - // log in as admin - $this->set_dir(); - - $lockfile = fopen($this->root_dir . "/.lock", "w"); - if (!flock($lockfile, LOCK_EX | LOCK_NB)) { - throw new Exception("Cron upload process is already running"); - } - try { - $this->process_upload(); // Start upload - } finally { - flock($lockfile, LOCK_UN); - fclose($lockfile); - } - } elseif ($user->can(Permissions::BULK_ADD)) { - $this->set_dir(); + $key = $event->get_arg(0); + if (!empty($key)) { + $this->process_upload($key); // Start upload + } elseif ($user->is_admin()) { $this->display_documentation(); } } } - private function display_documentation() - { - global $page; - $this->set_dir(); // Determines path to cron_uploader_dir - - - $queue_dir = $this->root_dir . "/" . self::QUEUE_DIR; - $uploaded_dir = $this->root_dir . "/" . self::UPLOADED_DIR; - $failed_dir = $this->root_dir . "/" . self::FAILED_DIR; - - $queue_dirinfo = $this->scan_dir($queue_dir); - $uploaded_dirinfo = $this->scan_dir($uploaded_dir); - $failed_dirinfo = $this->scan_dir($failed_dir); - - $cron_url = make_http(make_link("/cron_upload/" . $this->upload_key)); - $cron_cmd = "curl --silent $cron_url"; - $log_path = $this->root_dir . "/uploads.log"; - - $info_html = "Information -
- - - - - - - - - - - - - - - - - - - - - -
DirectoryFilesSize (MB)Directory Path
Queue{$queue_dirinfo['total_files']}{$queue_dirinfo['total_mb']}
Uploaded{$uploaded_dirinfo['total_files']}{$uploaded_dirinfo['total_mb']}
Failed{$failed_dirinfo['total_files']}{$failed_dirinfo['total_mb']}
- -
Cron Command:
- Create a cron job with the command above.
- Read the documentation if you're not sure what to do.
"; - - $install_html = " - This cron uploader is fairly easy to use but has to be configured first. -
1. Install & activate this plugin. -
-
2. Upload your images you want to be uploaded to the queue directory using your FTP client. -
($queue_dir) -
This also supports directory names to be used as tags. -
-
3. Go to the Board Config to the Cron Uploader menu and copy the Cron Command. -
($cron_cmd) -
-
4. Create a cron job or something else that can open a url on specified times. -
If you're not sure how to do this, you can give the command to your web host and you can ask them to create the cron job for you. -
When you create the cron job, you choose when to upload new images. -
-
5. When the cron command is set up, your image queue will upload x file(s) at the specified times. -
You can see any uploads or failed uploads in the log file. ($log_path) -
Your uploaded images will be moved to the 'uploaded' directory, it's recommended that you remove everything out of this directory from time to time. -
($uploaded_dir) -
-
Whenever the url in that cron job command is opened, a new file will upload from the queue. -
So when you want to manually upload an image, all you have to do is open the link once. -
This link can be found under 'Cron Command' in the board config, just remove the 'wget ' part and only the url remains. -
($cron_url)"; - - $page->set_title("Cron Uploader"); - $page->set_heading("Cron Uploader"); - - $block = new Block("Cron Uploader", $info_html, "main", 10); - $block_install = new Block("Installation Guide", $install_html, "main", 20); - $page->add_block($block); - $page->add_block($block_install); - } - - public function onInitExt(InitExtEvent $event) - { - global $config; - // Set default values - $config->set_default_int(self::CONFIG_COUNT, 1); - $this->set_dir(); - - $this->upload_key = $config->get_string(self::CONFIG_KEY, ""); - if (empty($this->upload_key)) { - $this->upload_key = $this->generate_key(); - - $config->set_string(self::CONFIG_KEY, $this->upload_key); - } - } - public function onSetupBuilding(SetupBuildingEvent $event) { - $this->set_dir(); + global $database; - $cron_url = make_http(make_link("/cron_upload/" . $this->upload_key)); - $cron_cmd = "curl --silent $cron_url"; $documentation_link = make_http(make_link("cron_upload")); - $sb = new SetupBlock("Cron Uploader"); - $sb->add_label("Settings
"); - $sb->add_int_option(self::CONFIG_COUNT, "How many to upload each time"); - $sb->add_text_option(self::CONFIG_DIR, "
Set Cron Uploader root directory
"); + $users = $database->get_pairs("SELECT name, id FROM users UNION ALL SELECT '', null order by name"); - $sb->add_label("
Cron Command:
- Create a cron job with the command above.
- Read the documentation if you're not sure what to do."); + $sb = new SetupBlock("Cron Uploader"); + $sb->start_table(); + $sb->add_int_option(CronUploaderConfig::COUNT, "Upload per run", true); + $sb->add_text_option(CronUploaderConfig::DIR, "Root dir", true); + $sb->add_text_option(CronUploaderConfig::KEY, "Key", true); + $sb->add_choice_option(CronUploaderConfig::USER, $users,"User", true); + $sb->end_table(); + $sb->add_label("Read the documentation for cron setup instructions."); $event->panel->add_block($sb); } - /* - * Generates a unique key for the website to prevent unauthorized access. - */ - private function generate_key() + public function onAdminBuilding(AdminBuildingEvent $event) { - $length = 20; - $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; - $randomString = ''; + $failed_dir = $this->get_failed_dir(); + $results = get_dir_contents($failed_dir); - for ($i = 0; $i < $length; $i++) { - $randomString .= $characters [rand(0, strlen($characters) - 1)]; + $failed_dirs = []; + foreach ($results as $result) { + $path = join_path($failed_dir, $result); + if (is_dir($path)) { + $failed_dirs[] = $result; + } } - return $randomString; + $this->theme->display_form($failed_dirs); } - /* - * Set the directory for the image queue. If no directory was given, set it to the default directory. - */ - private function set_dir() + public function onAdminAction(AdminActionEvent $event) { - global $config; - // Determine directory (none = default) - - $dir = $config->get_string(self::CONFIG_DIR, ""); - - // Sets new default dir if not in config yet/anymore - if ($dir == "") { - $dir = data_path("cron_uploader"); - $config->set_string(self::CONFIG_DIR, $dir); + $action = $event->action; + switch ($action) { + case "cron_uploader_clear_queue": + $event->redirect = true; + $this->clear_folder(self::QUEUE_DIR); + break; + case "cron_uploader_clear_uploaded": + $event->redirect = true; + $this->clear_folder(self::UPLOADED_DIR); + break; + case "cron_uploader_clear_failed": + $event->redirect = true; + $this->clear_folder(self::FAILED_DIR); + break; + case "cron_uploader_restage": + $event->redirect = true; + if (array_key_exists("failed_dir", $_POST) && !empty($_POST["failed_dir"])) { + $this->restage_folder($_POST["failed_dir"]); + } + break; } + } + + private function restage_folder(string $folder) + { + if (empty($folder)) { + throw new Exception("folder empty"); + } + $queue_dir = $this->get_queue_dir(); + $stage_dir = join_path($this->get_failed_dir(), $folder); + + if (!is_dir($stage_dir)) { + throw new Exception("Could not find $stage_dir"); + } + + $this->prep_root_dir(); + + $results = get_dir_contents($queue_dir); + + if (count($results) > 0) { + flash_message("Queue folder must be empty to re-stage", "error"); + return; + } + + $results = get_dir_contents($stage_dir); + + if (count($results) == 0) { + if(rmdir($stage_dir)===false) { + flash_message("Nothing to stage from $folder, cannot remove folder"); + } else { + flash_message("Nothing to stage from $folder, removing folder"); + } + return; + } + + foreach ($results as $result) { + $original_path = join_path($stage_dir, $result); + $new_path = join_path($queue_dir, $result); + + rename($original_path, $new_path); + } + + flash_message("Re-staged $folder to queue"); + rmdir($stage_dir); + } + + private function clear_folder($folder) + { + $path = join_path(CronUploaderConfig::get_dir(), $folder); + deltree($path); + flash_message("Cleared $path"); + } + + + private function get_cron_url() + { + return make_http(make_link("/cron_upload/" . CronUploaderConfig::get_key())); + } + + private function get_cron_cmd() + { + return "curl --silent " . $this->get_cron_url(); + } + + private function display_documentation() + { + global $database; + + $this->prep_root_dir(); + + $queue_dir = $this->get_queue_dir(); + $uploaded_dir = $this->get_uploaded_dir(); + $failed_dir = $this->get_failed_dir(); + + $queue_dirinfo = scan_dir($queue_dir); + $uploaded_dirinfo = scan_dir($uploaded_dir); + $failed_dirinfo = scan_dir($failed_dir); + + + $running = false; + $lockfile = fopen($this->get_lock_file(), "w"); + try { + if (!flock($lockfile, LOCK_EX | LOCK_NB)) { + $running = true; + } else { + flock($lockfile, LOCK_UN); + } + } finally { + fclose($lockfile); + } + + $logs = []; + if (Extension::is_enabled(LogDatabaseInfo::KEY)) { + $logs = $database->get_all( + "SELECT * FROM score_log WHERE section = :section ORDER BY date_sent DESC LIMIT 100", + ["section" => self::NAME] + ); + } + + $this->theme->display_documentation( + $running, $queue_dirinfo, $uploaded_dirinfo, $failed_dirinfo, + $this->get_cron_cmd(), $this->get_cron_url(), $logs + ); + } + + function get_queue_dir() + { + $dir = CronUploaderConfig::get_dir(); + return join_path($dir, self::QUEUE_DIR); + } + + function get_uploaded_dir() + { + $dir = CronUploaderConfig::get_dir(); + return join_path($dir, self::UPLOADED_DIR); + } + + function get_failed_dir() + { + $dir = CronUploaderConfig::get_dir(); + return join_path($dir, self::FAILED_DIR); + } + + private function prep_root_dir(): string + { + // Determine directory (none = default) + $dir = CronUploaderConfig::get_dir(); // Make the directory if it doesn't exist yet - if (!is_dir($dir . "/" . self::QUEUE_DIR . "/")) { - mkdir($dir . "/" . self::QUEUE_DIR . "/", 0775, true); + if (!is_dir($this->get_queue_dir())) { + mkdir($this->get_queue_dir(), 0775, true); } - if (!is_dir($dir . "/" . self::UPLOADED_DIR . "/")) { - mkdir($dir . "/" . self::UPLOADED_DIR . "/", 0775, true); + if (!is_dir($this->get_uploaded_dir())) { + mkdir($this->get_uploaded_dir(), 0775, true); } - if (!is_dir($dir . "/" . self::FAILED_DIR . "/")) { - mkdir($dir . "/" . self::FAILED_DIR . "/", 0775, true); + if (!is_dir($this->get_failed_dir())) { + mkdir($this->get_failed_dir(), 0775, true); } - $this->root_dir = $dir; return $dir; } - /** - * Returns amount of files & total size of dir. - */ - public function scan_dir(string $path): array + private function get_lock_file(): string { - $bytestotal = 0; - $nbfiles = 0; - - $ite = new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS); - foreach (new RecursiveIteratorIterator($ite) as $filename => $cur) { - $filesize = $cur->getSize(); - $bytestotal += $filesize; - $nbfiles++; - } - - $size_mb = $bytestotal / 1048576; // to mb - $size_mb = number_format($size_mb, 2, '.', ''); - return ['total_files' => $nbfiles, 'total_mb' => $size_mb]; + $root_dir = CronUploaderConfig::get_dir(); + return join_path($root_dir, ".lock"); } /** * Uploads the image & handles everything */ - public function process_upload(int $upload_count = 0): bool + public function process_upload(string $key, ?int $upload_count = null): bool { - global $config, $database; + global $database; - //set_time_limit(0); - - - $output_subdir = date('Ymd-His', time()) . "/"; - $this->generate_image_queue(); - - // Gets amount of imgs to upload - if ($upload_count == 0) { - $upload_count = $config->get_int(self::CONFIG_COUNT, 1); + if ($key!=CronUploaderConfig::get_key()) { + throw new SCoreException("Cron upload key incorrect"); + } + $user_id = CronUploaderConfig::get_user(); + if(empty($user_id)) { + throw new SCoreException("Cron upload user not set"); + } + $user = User::by_id($user_id); + if ($user == null) { + throw new SCoreException("No user found for cron upload user $user_id"); } - // Throw exception if there's nothing in the queue - if (count($this->image_queue) == 0) { - $this->add_upload_info("Your queue is empty so nothing could be uploaded."); - $this->handle_log(); - return false; + send_event(new UserLoginEvent($user)); + $this->log_message(SCORE_LOG_INFO, "Logged in as user {$user->name}"); + + $lockfile = fopen($this->get_lock_file(), "w"); + if (!flock($lockfile, LOCK_EX | LOCK_NB)) { + throw new SCoreException("Cron upload process is already running"); } - // Randomize Images - //shuffle($this->image_queue); + try { + //set_time_limit(0); - $merged = 0; - $added = 0; - $failed = 0; - - // Upload the file(s) - for ($i = 0; $i < $upload_count && sizeof($this->image_queue) > 0; $i++) { - $img = array_pop($this->image_queue); - - $database->beginTransaction(); - try { - $this->add_upload_info("Adding file: {$img[1]} - tags: {$img[2]}"); - $result = $this->add_image($img[0], $img[1], $img[2]); - $database->commit(); - $this->move_uploaded($img[0], $img[1], $output_subdir, false); - if ($result->merged) { - $merged++; - } else { - $added++; - } - } catch (Exception $e) { - $database->rollback(); - $failed++; - $this->move_uploaded($img[0], $img[1], $output_subdir, true); - $msgNumber = $this->add_upload_info("(" . gettype($e) . ") " . $e->getMessage()); - $msgNumber = $this->add_upload_info($e->getTraceAsString()); + // Gets amount of imgs to upload + if ($upload_count == null) { + $upload_count = CronUploaderConfig::get_count(); } + + $output_subdir = date('Ymd-His', time()); + $image_queue = $this->generate_image_queue($upload_count); + + + // Throw exception if there's nothing in the queue + if (count($image_queue) == 0) { + $this->log_message(SCORE_LOG_WARNING, "Your queue is empty so nothing could be uploaded."); + $this->handle_log(); + return false; + } + + // Randomize Images + //shuffle($this->image_queue); + + $merged = 0; + $added = 0; + $failed = 0; + + // Upload the file(s) + for ($i = 0; $i < $upload_count && sizeof($image_queue) > 0; $i++) { + $img = array_pop($image_queue); + + try { + $database->beginTransaction(); + $this->log_message(SCORE_LOG_INFO, "Adding file: {$img[0]} - tags: {$img[2]}"); + $result = $this->add_image($img[0], $img[1], $img[2]); + $database->commit(); + $this->move_uploaded($img[0], $img[1], $output_subdir, false); + if ($result->merged) { + $merged++; + } else { + $added++; + } + } catch (Exception $e) { + try { + $database->rollback(); + } catch (Exception $e) { + } + + $failed++; + $this->move_uploaded($img[0], $img[1], $output_subdir, true); + $this->log_message(SCORE_LOG_ERROR, "(" . gettype($e) . ") " . $e->getMessage()); + $this->log_message(SCORE_LOG_ERROR, $e->getTraceAsString()); + + + } + } + + + $this->log_message(SCORE_LOG_INFO, "Items added: $added"); + $this->log_message(SCORE_LOG_INFO, "Items merged: $merged"); + $this->log_message(SCORE_LOG_INFO, "Items failed: $failed"); + + + // Display upload log + $this->handle_log(); + + return true; + } finally { + flock($lockfile, LOCK_UN); + fclose($lockfile); } - $msgNumber = $this->add_upload_info("Items added: $added"); - $msgNumber = $this->add_upload_info("Items merged: $merged"); - $msgNumber = $this->add_upload_info("Items failed: $failed"); - - // Display & save upload log - $this->handle_log(); - - return true; } - private function move_uploaded($path, $filename, $output_subdir, $corrupt = false) + private function move_uploaded(string $path, string $filename, string $output_subdir, bool $corrupt = false) { - // Create - $newDir = $this->root_dir; + $relativeDir = dirname(substr($path, strlen(CronUploaderConfig::get_dir()) + 7)); - $relativeDir = dirname(substr($path, strlen($this->root_dir) + 7)); + if($relativeDir==".") { + $relativeDir = ""; + } // Determine which dir to move to if ($corrupt) { // Move to corrupt dir - $newDir .= "/" . self::FAILED_DIR . "/" . $output_subdir . $relativeDir; - $info = "ERROR: Image was not uploaded."; + $newDir = join_path($this->get_failed_dir(), $output_subdir, $relativeDir); + $info = "ERROR: Image was not uploaded. "; } else { - $newDir .= "/" . self::UPLOADED_DIR . "/" . $output_subdir . $relativeDir; + $newDir = join_path($this->get_uploaded_dir(), $output_subdir, $relativeDir); $info = "Image successfully uploaded. "; } - $newDir = str_replace("//", "/", $newDir . "/"); + $newDir = str_replace(DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, $newDir); if (!is_dir($newDir)) { mkdir($newDir, 0775, true); } + $newFile = join_path($newDir, $filename); // move file to correct dir - rename($path, $newDir . $filename); + rename($path, $newFile); - $this->add_upload_info($info . "Image \"$filename\" moved from queue to \"$newDir\"."); + $this->log_message(SCORE_LOG_INFO, $info . "Image \"$filename\" moved from queue to \"$newDir\"."); } /** @@ -357,7 +389,7 @@ class CronUploader extends Extension assert(file_exists($tmpname)); $tagArray = Tag::explode($tags); - if (count($tagArray)==0) { + if (count($tagArray) == 0) { $tagArray[] = "tagme"; } @@ -377,11 +409,11 @@ class CronUploader extends Extension if ($event->image_id == -1) { throw new Exception("File type not recognised. Filename: {$filename}"); } elseif ($event->merged === true) { - $infomsg = "Image merged. ID: {$event->image_id} Filename: {$filename}"; + $infomsg = "Image merged. ID: {$event->image_id} - Filename: {$filename}"; } else { $infomsg = "Image uploaded. ID: {$event->image_id} - Filename: {$filename}"; } - $msgNumber = $this->add_upload_info($infomsg); + $this->log_message(SCORE_LOG_INFO, $infomsg); // Set tags $img = Image::by_id($event->image_id); @@ -390,18 +422,31 @@ class CronUploader extends Extension return $event; } - private function generate_image_queue(): void + private const PARTIAL_DOWNLOAD_EXTENSIONS = ['crdownload','part']; + + private function is_skippable_file(string $path) { + $info = pathinfo($path); + + if(in_array(strtolower($info['extension']),self::PARTIAL_DOWNLOAD_EXTENSIONS)) { + return true; + } + + return false; + } + + private function generate_image_queue(string $root_dir, ?int $limit = null): array { - $base = $this->root_dir . "/" . self::QUEUE_DIR; + $base = $this->get_queue_dir(); + $output = []; if (!is_dir($base)) { - $this->add_upload_info("Image Queue Directory could not be found at \"$base\"."); - return; + $this->log_message(SCORE_LOG_WARNING, "Image Queue Directory could not be found at \"$base\"."); + return []; } $ite = new RecursiveDirectoryIterator($base, FilesystemIterator::SKIP_DOTS); foreach (new RecursiveIteratorIterator($ite) as $fullpath => $cur) { - if (!is_link($fullpath) && !is_dir($fullpath)) { + if (!is_link($fullpath) && !is_dir($fullpath) && !$this->is_skippable_file($fullpath)) { $pathinfo = pathinfo($fullpath); $relativePath = substr($fullpath, strlen($base)); @@ -412,34 +457,33 @@ class CronUploader extends Extension 1 => $pathinfo ["basename"], 2 => $tags ]; - array_push($this->image_queue, $img); + $output[] = $img; + if (!empty($limit) && count($output) >= $limit) { + break; + } } } + return $output; } - /** - * Adds a message to the info being published at the end - */ - private function add_upload_info(string $text, int $addon = 0): int + + private function log_message(int $severity, string $message): void { - $info = $this->upload_info; + global $database; + + log_msg(self::NAME, $severity, $message); + $time = "[" . date('Y-m-d H:i:s') . "]"; + $this->output_buffer[] = $time . " " . $message; - // If addon function is not used - if ($addon == 0) { - $this->upload_info .= "$time $text\r\n"; + $log_path = $this->get_log_file(); - // Returns the number of the current line - $currentLine = substr_count($this->upload_info, "\n") - 1; - return $currentLine; - } + file_put_contents($log_path, $time . " " . $message); + } - // else if addon function is used, select the line & modify it - $lines = substr($info, "\n"); // Seperate the string to array in lines - $lines[$addon] = "$lines[$addon] $text"; // Add the content to the line - $this->upload_info = implode("\n", $lines); // Put string back together & update - - return $addon; // Return line number + private function get_log_file(): string + { + return join_path(CronUploaderConfig::get_dir(), "uploads.log"); } /** @@ -452,18 +496,7 @@ class CronUploader extends Extension // Display message $page->set_mode(PageMode::DATA); $page->set_type("text/plain"); - $page->set_data($this->upload_info); - - // Save log - $log_path = $this->root_dir . "/uploads.log"; - - if (file_exists($log_path)) { - $prev_content = file_get_contents($log_path); - } else { - $prev_content = ""; - } - - $content = $prev_content . "\r\n" . $this->upload_info; - file_put_contents($log_path, $content); + $page->set_data(implode("\r\n", $this->output_buffer)); } } + diff --git a/ext/cron_uploader/style.css b/ext/cron_uploader/style.css new file mode 100644 index 00000000..2643a6a1 --- /dev/null +++ b/ext/cron_uploader/style.css @@ -0,0 +1,3 @@ +table.log th { + width: 200px; +} \ No newline at end of file diff --git a/ext/cron_uploader/theme.php b/ext/cron_uploader/theme.php new file mode 100644 index 00000000..8c438d23 --- /dev/null +++ b/ext/cron_uploader/theme.php @@ -0,0 +1,126 @@ +Information +
+ + " . ($running ? "" : "") . " + + + + + + + + + + + + + + + + + + + + +
Cron upload is currently running
DirectoryFilesSize (MB)Directory Path
Queue{$queue_dirinfo['total_files']}{$queue_dirinfo['total_mb']}{$queue_dirinfo['path']}
Uploaded{$uploaded_dirinfo['total_files']}{$uploaded_dirinfo['total_mb']}{$uploaded_dirinfo['path']}
Failed{$failed_dirinfo['total_files']}{$failed_dirinfo['total_mb']}{$failed_dirinfo['path']}
+ +
Cron Command:
+ Create a cron job with the command above.
+ Read the documentation if you're not sure what to do.
"; + + $install_html = " + This cron uploader is fairly easy to use but has to be configured first. +
    +
  1. Install & activate this plugin.
  2. +
  3. Go to the Board Config and change any settings to match your preference.
  4. +
  5. Copy the cron command above.
  6. +
  7. Create a cron job or something else that can open a url on specified times. +
    cron is a service that runs commands over and over again on a a schedule. You can set up cron (or any similar tool) to run the command above to trigger the import on whatever schedule you desire. +
    If you're not sure how to do this, you can give the command to your web host and you can ask them to create the cron job for you. +
    When you create the cron job, you choose when to upload new images.
  8. +
"; + + $usage_html = "Upload your images you want to be uploaded to the queue directory using your FTP client or other means. +
({$queue_dirinfo['path']}) +
    +
  1. Any sub-folders will be turned into tags.
  2. +
  3. If the file name matches \"## - tag1 tag2.png\" the tags will be used.
  4. +
  5. If both are found, they will all be used.
  6. +
  7. The character \";\" will be changed into \":\" in any tags.
  8. +
  9. You can inherit categories by creating a folder that ends with \";\". For instance category;\\tag1 would result in the tag category:tag1. This allows creating a category folder, then creating many subfolders that will use that category.
  10. +
+ The cron uploader works by importing files from the queue folder whenever this url is visited: +
$cron_url
+ + + "; + + $page->set_title("Cron Uploader"); + $page->set_heading("Cron Uploader"); + + $block = new Block("Cron Uploader", $info_html, "main", 10); + $block_install = new Block("Setup Guide", $install_html, "main", 30); + $block_usage= new Block("Usage Guide", $usage_html, "main", 20); + $page->add_block($block); + $page->add_block($block_install); + $page->add_block($block_usage); + + if(!empty($log_entries)) { + $log_html = ""; + foreach($log_entries as $entry) { + $log_html .= ""; + } + $log_html .= "
{$entry["date_sent"]}{$entry["message"]}
"; + $block = new Block("Log", $log_html, "main", 40); + $page->add_block($block); + } + } + + public function display_form(array $failed_dirs) + { + global $page, $database; + + $link = make_http(make_link("cron_upload")); + $html = "Cron uploader documentation"; + + $html .= make_form(make_link("admin/cron_uploader_restage")); + $html .= ""; + $html .= ""; + $html .= ""; + $html .= "
Failed dir
"; + + $html .= make_form(make_link("admin/cron_uploader_clear_queue"), "POST",false,"","return confirm('Are you sure you want to delete everything in the queue folder?');") + ."
" + ."
"; + $html .= make_form(make_link("admin/cron_uploader_clear_uploaded"), "POST",false,"","return confirm('Are you sure you want to delete everything in the uploaded folder?');") + ."
" + ."
"; + $html .= make_form(make_link("admin/cron_uploader_clear_failed"), "POST",false,"","return confirm('Are you sure you want to delete everything in the failed folder?');") + ."
" + ."
"; + $html .= "\n"; + $page->add_block(new Block("Cron Upload", $html)); + } +} From 92a0afc15ef1f9e43159d273ac332adca6ada99c Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Thu, 10 Oct 2019 10:25:37 -0500 Subject: [PATCH 02/30] Supporting function for cron uploader changes --- core/util.php | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/core/util.php b/core/util.php index 70b5f2ea..b79a2238 100644 --- a/core/util.php +++ b/core/util.php @@ -350,6 +350,51 @@ function join_url(string $base, string ...$paths) return $output; } +function get_dir_contents(string $dir): array +{ + if(empty($dir)) { + throw new Exception("dir required"); + } + if(!is_dir($dir)) { + return []; + } + $results = array_diff( + scandir( + $dir), + ['..', '.']); + + return $results; +} + +/** + * Returns amount of files & total size of dir. + */ +function scan_dir(string $path): array +{ + $bytestotal = 0; + $nbfiles = 0; + + $ite = new RecursiveDirectoryIterator( + $path, + FilesystemIterator::KEY_AS_PATHNAME | + FilesystemIterator::CURRENT_AS_FILEINFO | + FilesystemIterator::SKIP_DOTS); + foreach (new RecursiveIteratorIterator($ite) as $filename => $cur) { + try { + $filesize = $cur->getSize(); + $bytestotal += $filesize; + $nbfiles++; + } catch (RuntimeException $e) { + // This usually just means that the file got eaten by the import + continue; + } + } + + $size_mb = $bytestotal / 1048576; // to mb + $size_mb = number_format($size_mb, 2, '.', ''); + return ['path' => $path, 'total_files' => $nbfiles, 'total_mb' => $size_mb]; +} + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * Debugging functions * From d605e0e572bf8612aa2a88d77f606ef44c199617 Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Thu, 17 Oct 2019 14:22:33 -0500 Subject: [PATCH 03/30] Added cron_admin permission --- core/permissions.php | 1 + core/userclass.php | 2 ++ ext/cron_uploader/main.php | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/core/permissions.php b/core/permissions.php index bd60b0c0..e546236b 100644 --- a/core/permissions.php +++ b/core/permissions.php @@ -80,4 +80,5 @@ abstract class Permissions public const NOTES_ADMIN = "notes_admin"; public const POOLS_ADMIN = "pools_admin"; public const TIPS_ADMIN = "tips_admin"; + public const CRON_ADMIN = "cron_admin"; } diff --git a/core/userclass.php b/core/userclass.php index 5c60c9a0..2207fa63 100644 --- a/core/userclass.php +++ b/core/userclass.php @@ -150,6 +150,7 @@ new UserClass("base", null, [ Permissions::NOTES_ADMIN => false, Permissions::POOLS_ADMIN => false, Permissions::TIPS_ADMIN => false, + Permissions::CRON_ADMIN => false, ]); new UserClass("anonymous", "base", [ @@ -226,6 +227,7 @@ new UserClass("admin", "base", [ Permissions::NOTES_ADMIN => true, Permissions::POOLS_ADMIN => true, Permissions::TIPS_ADMIN => true, + Permissions::CRON_ADMIN => true, ]); new UserClass("hellbanned", "user", [ diff --git a/ext/cron_uploader/main.php b/ext/cron_uploader/main.php index 98999d29..38ff3e8c 100644 --- a/ext/cron_uploader/main.php +++ b/ext/cron_uploader/main.php @@ -39,7 +39,7 @@ class CronUploader extends Extension $key = $event->get_arg(0); if (!empty($key)) { $this->process_upload($key); // Start upload - } elseif ($user->is_admin()) { + } elseif ($user->can(Permissions::CRON_ADMIN)) { $this->display_documentation(); } } From 6b030c00eb307221e35ab3832e92e4ff2353ce9f Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Fri, 16 Aug 2019 09:18:14 -0500 Subject: [PATCH 04/30] Constants for index config --- core/event.php | 2 +- core/imageboard/image.php | 6 +-- ext/arrowkey_navigation/main.php | 2 +- ext/index/config.php | 11 +++++ ext/index/events.php | 65 ++++++++++++++++++++++++++++ ext/index/main.php | 73 +++----------------------------- ext/numeric_score/main.php | 2 +- 7 files changed, 88 insertions(+), 73 deletions(-) create mode 100644 ext/index/config.php create mode 100644 ext/index/events.php diff --git a/core/event.php b/core/event.php index 5ae1ad55..248bf6ae 100644 --- a/core/event.php +++ b/core/event.php @@ -154,7 +154,7 @@ class PageRequestEvent extends Event public function get_page_size(): int { global $config; - return $config->get_int('index_images'); + return $config->get_int(IndexConfig::IMAGES); } } diff --git a/core/imageboard/image.php b/core/imageboard/image.php index 4277443c..c268266e 100644 --- a/core/imageboard/image.php +++ b/core/imageboard/image.php @@ -150,8 +150,8 @@ class Image $result = Image::get_accelerated_result($tag_conditions, $img_conditions, $start, $limit); if (!$result) { $querylet = Image::build_search_querylet($tag_conditions, $img_conditions); - $querylet->append(new Querylet(" ORDER BY ".(Image::$order_sql ?: "images.".$config->get_string("index_order")))); - if ($limit!=null) { + $querylet->append(new Querylet(" ORDER BY ".(Image::$order_sql ?: "images.".$config->get_string(IndexConfig::ORDER)))); + if($limit!=null) { $querylet->append(new Querylet(" LIMIT :limit ", ["limit" => $limit])); $querylet->append(new Querylet(" OFFSET :offset ", ["offset"=>$start])); } @@ -334,7 +334,7 @@ class Image public static function count_pages(array $tags=[]): float { global $config; - return ceil(Image::count_images($tags) / $config->get_int('index_images')); + return ceil(Image::count_images($tags) / $config->get_int(IndexConfig::IMAGES)); } private static function terms_to_conditions(array $terms): array diff --git a/ext/arrowkey_navigation/main.php b/ext/arrowkey_navigation/main.php index 640d2b12..6464f592 100644 --- a/ext/arrowkey_navigation/main.php +++ b/ext/arrowkey_navigation/main.php @@ -52,7 +52,7 @@ class ArrowkeyNavigation extends Extension global $config, $database; // get the amount of images per page - $images_per_page = $config->get_int('index_images'); + $images_per_page = $config->get_int(IndexConfig::IMAGES); // if there are no tags, use default if (is_null($event->get_arg(1))) { diff --git a/ext/index/config.php b/ext/index/config.php new file mode 100644 index 00000000..91329926 --- /dev/null +++ b/ext/index/config.php @@ -0,0 +1,11 @@ +term = $term; + $this->context = $context; + } + + public function is_querylet_set(): bool + { + return (count($this->querylets) > 0); + } + + public function get_querylets(): array + { + return $this->querylets; + } + + public function add_querylet(Querylet $q) + { + $this->querylets[] = $q; + } +} + +class SearchTermParseException extends SCoreException +{ +} + +class PostListBuildingEvent extends Event +{ + /** @var array */ + public $search_terms = []; + + /** @var array */ + public $parts = []; + + /** + * #param string[] $search + */ + public function __construct(array $search) + { + $this->search_terms = $search; + } + + public function add_control(string $html, int $position=50) + { + while (isset($this->parts[$position])) { + $position++; + } + $this->parts[$position] = $html; + } +} diff --git a/ext/index/main.php b/ext/index/main.php index 7a116df2..1e084f21 100644 --- a/ext/index/main.php +++ b/ext/index/main.php @@ -1,68 +1,7 @@ term = $term; - $this->context = $context; - } - - public function is_querylet_set(): bool - { - return (count($this->querylets) > 0); - } - - public function get_querylets(): array - { - return $this->querylets; - } - - public function add_querylet(Querylet $q) - { - $this->querylets[] = $q; - } -} - -class SearchTermParseException extends SCoreException -{ -} - -class PostListBuildingEvent extends Event -{ - /** @var array */ - public $search_terms = []; - - /** @var array */ - public $parts = []; - - /** - * #param string[] $search - */ - public function __construct(array $search) - { - $this->search_terms = $search; - } - - public function add_control(string $html, int $position=50) - { - while (isset($this->parts[$position])) { - $position++; - } - $this->parts[$position] = $html; - } -} +require_once "config.php"; +require_once "events.php"; class Index extends Extension { @@ -72,9 +11,9 @@ class Index extends Extension public function onInitExt(InitExtEvent $event) { global $config; - $config->set_default_int("index_images", 24); - $config->set_default_bool("index_tips", true); - $config->set_default_string("index_order", "id DESC"); + $config->set_default_int(IndexConfig::IMAGES, 24); + $config->set_default_bool(IndexConfig::TIPS, true); + $config->set_default_string(IndexConfig::ORDER, "id DESC"); } public function onPageRequest(PageRequestEvent $event) @@ -167,7 +106,7 @@ class Index extends Extension $sb->position = 20; $sb->add_label("Show "); - $sb->add_int_option("index_images"); + $sb->add_int_option(IndexConfig::IMAGES); $sb->add_label(" images on the post list"); $event->panel->add_block($sb); diff --git a/ext/numeric_score/main.php b/ext/numeric_score/main.php index bff6701b..5e6d0f22 100644 --- a/ext/numeric_score/main.php +++ b/ext/numeric_score/main.php @@ -129,7 +129,7 @@ class NumericScore extends Extension $sql = "SELECT id FROM images WHERE EXTRACT(YEAR FROM posted) = :year "; - $args = ["limit" => $config->get_int("index_images"), "year" => $year]; + $args = ["limit" => $config->get_int(IndexConfig::IMAGES), "year" => $year]; if ($event->page_matches("popular_by_day")) { $sql .= From f594e9066e29190b27cd0fbc09aa75684c7a4acf Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Fri, 16 Aug 2019 09:40:42 -0500 Subject: [PATCH 05/30] Added image flag --- ext/handle_flash/main.php | 1 + ext/handle_ico/main.php | 2 + ext/handle_mp3/main.php | 1 + ext/handle_pixel/main.php | 1 + ext/handle_svg/main.php | 1 + ext/handle_video/main.php | 1 + ext/media/config.php | 10 ++ ext/media/events.php | 58 ++++++++ ext/media/main.php | 263 ++++++++++++------------------------- ext/media/media_engine.php | 67 ++++++++++ 10 files changed, 228 insertions(+), 177 deletions(-) create mode 100644 ext/media/config.php create mode 100644 ext/media/events.php create mode 100644 ext/media/media_engine.php diff --git a/ext/handle_flash/main.php b/ext/handle_flash/main.php index 9b738ee6..fe63c723 100644 --- a/ext/handle_flash/main.php +++ b/ext/handle_flash/main.php @@ -13,6 +13,7 @@ class FlashFileHandler extends DataHandlerExtension if (!$info) { return null; } + $event->image = false; $event->width = $info[0]; $event->height = $info[1]; diff --git a/ext/handle_ico/main.php b/ext/handle_ico/main.php index 70d9b753..2975f529 100644 --- a/ext/handle_ico/main.php +++ b/ext/handle_ico/main.php @@ -11,6 +11,8 @@ class IcoFileHandler extends DataHandlerExtension $event->lossless = true; $event->video = false; $event->audio = false; + $event->image = ($event->ext!="ani"); + $fp = fopen($event->file_name, "r"); try { diff --git a/ext/handle_mp3/main.php b/ext/handle_mp3/main.php index 53987eea..2af95d19 100644 --- a/ext/handle_mp3/main.php +++ b/ext/handle_mp3/main.php @@ -9,6 +9,7 @@ class MP3FileHandler extends DataHandlerExtension $event->audio = true; $event->video = false; $event->lossless = false; + $event->image = false; break; } // TODO: Buff out audio format support, length scanning diff --git a/ext/handle_pixel/main.php b/ext/handle_pixel/main.php index 3016e8e3..31d38d53 100644 --- a/ext/handle_pixel/main.php +++ b/ext/handle_pixel/main.php @@ -29,6 +29,7 @@ class PixelFileHandler extends DataHandlerExtension $event->video = false; break; } + $event->image = !$event->video; $info = getimagesize($event->file_name); if (!$info) { diff --git a/ext/handle_svg/main.php b/ext/handle_svg/main.php index 4e8a173d..fc45626d 100644 --- a/ext/handle_svg/main.php +++ b/ext/handle_svg/main.php @@ -10,6 +10,7 @@ class SVGFileHandler extends DataHandlerExtension $event->lossless = true; $event->video = false; $event->audio = false; + $event->image = true; $msp = new MiniSVGParser($event->file_name); $event->width = $msp->width; diff --git a/ext/handle_video/main.php b/ext/handle_video/main.php index fbd98b65..d5220d31 100644 --- a/ext/handle_video/main.php +++ b/ext/handle_video/main.php @@ -38,6 +38,7 @@ class VideoFileHandler extends DataHandlerExtension { if (in_array($event->ext, self::SUPPORTED_EXT)) { $event->video = true; + $event->image = false; try { $data = Media::get_ffprobe_data($event->file_name); diff --git a/ext/media/config.php b/ext/media/config.php new file mode 100644 index 00000000..32814594 --- /dev/null +++ b/ext/media/config.php @@ -0,0 +1,10 @@ +engine = $engine; + $this->input_path = $input_path; + $this->input_type = $input_type; + $this->output_path = $output_path; + $this->target_height = $target_height; + $this->target_width = $target_width; + $this->target_format = $target_format; + $this->target_quality = $target_quality; + $this->minimize = $minimize; + $this->ignore_aspect_ratio = $ignore_aspect_ratio; + $this->allow_upscale = $allow_upscale; + } +} + +class MediaCheckPropertiesEvent extends Event +{ + public $file_name; + public $ext; + public $lossless = null; + public $audio = null; + public $video = null; + public $image = null; + public $length = null; + public $height = null; + public $width = null; + + public function __construct(string $file_name, string $ext) + { + $this->file_name = $file_name; + $this->ext = $ext; + } + +} diff --git a/ext/media/main.php b/ext/media/main.php index 71633497..8e399a01 100644 --- a/ext/media/main.php +++ b/ext/media/main.php @@ -1,149 +1,16 @@ [ - "gif", - "jpg", - "png", - "webp", - Media::WEBP_LOSSY, - ], - MediaEngine::IMAGICK => [ - "gif", - "jpg", - "png", - "webp", - Media::WEBP_LOSSY, - Media::WEBP_LOSSLESS, - ], - MediaEngine::FFMPEG => [ - "jpg", - "webp", - "png" - ] - ]; - public const INPUT_SUPPORT = [ - MediaEngine::GD => [ - "bmp", - "gif", - "jpg", - "png", - "webp", - Media::WEBP_LOSSY, - Media::WEBP_LOSSLESS - ], - MediaEngine::IMAGICK => [ - "bmp", - "gif", - "jpg", - "png", - "psd", - "tiff", - "webp", - Media::WEBP_LOSSY, - Media::WEBP_LOSSLESS, - "ico", - ], - MediaEngine::FFMPEG => [ - "avi", - "mkv", - "webm", - "mp4", - "mov", - "flv" - ] - ]; -} - class MediaException extends SCoreException { } -class MediaResizeEvent extends Event -{ - public $engine; - public $input_path; - public $input_type; - public $output_path; - public $target_format; - public $target_width; - public $target_height; - public $target_quality; - public $minimize; - public $ignore_aspect_ratio; - public $allow_upscale; - - public function __construct( - String $engine, - string $input_path, - string $input_type, - string $output_path, - int $target_width, - int $target_height, - bool $ignore_aspect_ratio = false, - string $target_format = null, - int $target_quality = 80, - bool $minimize = false, - bool $allow_upscale = true - ) { - assert(in_array($engine, MediaEngine::ALL)); - $this->engine = $engine; - $this->input_path = $input_path; - $this->input_type = $input_type; - $this->output_path = $output_path; - $this->target_height = $target_height; - $this->target_width = $target_width; - $this->target_format = $target_format; - $this->target_quality = $target_quality; - $this->minimize = $minimize; - $this->ignore_aspect_ratio = $ignore_aspect_ratio; - $this->allow_upscale = $allow_upscale; - } -} - -class MediaCheckPropertiesEvent extends Event -{ - public $file_name; - public $ext; - public $lossless = null; - public $audio = null; - public $video = null; - public $length = null; - public $height = null; - public $width = null; - - public function __construct(string $file_name, string $ext) - { - $this->file_name = $file_name; - $this->ext = $ext; - } -} - - class Media extends Extension { const WEBP_LOSSY = "webp-lossy"; @@ -211,41 +78,8 @@ class Media extends Extension $config->set_default_string(MediaConfig::CONVERT_PATH, 'convert'); - if ($config->get_int(MediaConfig::VERSION) < 1) { - $current_value = $config->get_string("thumb_ffmpeg_path"); - if (!empty($current_value)) { - $config->set_string(MediaConfig::FFMPEG_PATH, $current_value); - } elseif ($ffmpeg = shell_exec((PHP_OS == 'WINNT' ? 'where' : 'which') . ' ffmpeg')) { - //ffmpeg exists in PATH, check if it's executable, and if so, default to it instead of static - if (is_executable(strtok($ffmpeg, PHP_EOL))) { - $config->set_default_string(MediaConfig::FFMPEG_PATH, 'ffmpeg'); - } - } - - if ($ffprobe = shell_exec((PHP_OS == 'WINNT' ? 'where' : 'which') . ' ffprobe')) { - //ffprobe exists in PATH, check if it's executable, and if so, default to it instead of static - if (is_executable(strtok($ffprobe, PHP_EOL))) { - $config->set_default_string(MediaConfig::FFPROBE_PATH, 'ffprobe'); - } - } - - $current_value = $config->get_string("thumb_convert_path"); - if (!empty($current_value)) { - $config->set_string(MediaConfig::CONVERT_PATH, $current_value); - } elseif ($convert = shell_exec((PHP_OS == 'WINNT' ? 'where' : 'which') . ' convert')) { - //ffmpeg exists in PATH, check if it's executable, and if so, default to it instead of static - if (is_executable(strtok($convert, PHP_EOL))) { - $config->set_default_string(MediaConfig::CONVERT_PATH, 'convert'); - } - } - - $current_value = $config->get_int("thumb_mem_limit"); - if (!empty($current_value)) { - $config->set_int(MediaConfig::MEM_LIMIT, $current_value); - } - - $config->set_int(MediaConfig::VERSION, 1); - log_info("media", "extension installed"); + if ($config->get_int(MediaConfig::VERSION) < 2) { + $this->setup(); } } @@ -421,7 +255,7 @@ class Media extends Extension } - const CONTENT_SEARCH_TERM_REGEX = "/^content[=|:]((video)|(audio))$/i"; + const CONTENT_SEARCH_TERM_REGEX = "/^content[=|:]((video)|(audio)|(image)|(unknown))$/i"; public function onSearchTermParse(SearchTermParseEvent $event) @@ -430,8 +264,12 @@ class Media extends Extension $matches = []; if (preg_match(self::CONTENT_SEARCH_TERM_REGEX, $event->term, $matches)) { - $field = $matches[2]; - $event->add_querylet(new Querylet($database->scoreql_to_sql("$field = SCORE_BOOL_Y"))); + $field = $matches[1]; + if($field==="unknown") { + $event->add_querylet(new Querylet($database->scoreql_to_sql("video IS NULL OR audio IS NULL OR image IS NULL"))); + } else { + $event->add_querylet(new Querylet($database->scoreql_to_sql("$field = SCORE_BOOL_Y"))); + } } } @@ -485,8 +323,8 @@ class Media extends Extension $database->execute( "UPDATE images SET - lossless = :lossless, video = :video, audio = :audio, - height = :height, width = :width, + lossless = :lossless, video = :video, audio = :audio,image = :image, + height = :height, width = :width, length = :length WHERE hash = :hash", [ "hash" => $hash, @@ -494,6 +332,7 @@ class Media extends Extension "height" => $mcpe->height ?? 0, "lossless" => $database->scoresql_value_prepare($mcpe->lossless), "video" => $database->scoresql_value_prepare($mcpe->video), + "image" => $database->scoresql_value_prepare($mcpe->image), "audio" => $database->scoresql_value_prepare($mcpe->audio), "length" => $mcpe->length ] @@ -1154,4 +993,74 @@ class Media extends Extension log_debug('Media', "Getting video size with `$cmd`, returns $output -- $size[0], $size[1]"); return $size; } + + private function setup() + { + global $config, $database; + if ($config->get_int(MediaConfig::VERSION) < 1) { + $current_value = $config->get_string("thumb_ffmpeg_path"); + if (!empty($current_value)) { + $config->set_string(MediaConfig::FFMPEG_PATH, $current_value); + } elseif ($ffmpeg = shell_exec((PHP_OS == 'WINNT' ? 'where' : 'which') . ' ffmpeg')) { + //ffmpeg exists in PATH, check if it's executable, and if so, default to it instead of static + if (is_executable(strtok($ffmpeg, PHP_EOL))) { + $config->set_default_string(MediaConfig::FFMPEG_PATH, 'ffmpeg'); + } + } + + if ($ffprobe = shell_exec((PHP_OS == 'WINNT' ? 'where' : 'which') . ' ffprobe')) { + //ffprobe exists in PATH, check if it's executable, and if so, default to it instead of static + if (is_executable(strtok($ffprobe, PHP_EOL))) { + $config->set_default_string(MediaConfig::FFPROBE_PATH, 'ffprobe'); + } + } + + $current_value = $config->get_string("thumb_convert_path"); + if (!empty($current_value)) { + $config->set_string(MediaConfig::CONVERT_PATH, $current_value); + } elseif ($convert = shell_exec((PHP_OS == 'WINNT' ? 'where' : 'which') . ' convert')) { + //ffmpeg exists in PATH, check if it's executable, and if so, default to it instead of static + if (is_executable(strtok($convert, PHP_EOL))) { + $config->set_default_string(MediaConfig::CONVERT_PATH, 'convert'); + } + } + + $current_value = $config->get_int("thumb_mem_limit"); + if (!empty($current_value)) { + $config->set_int(MediaConfig::MEM_LIMIT, $current_value); + } + + $config->set_int(MediaConfig::VERSION, 1); + log_info("media", "extension installed"); + } + + if ($config->get_int(MediaConfig::VERSION) < 2) { + $database->execute($database->scoreql_to_sql( + "ALTER TABLE images ADD COLUMN image SCORE_BOOL NULL" + )); + + switch($database->get_driver_name()) { + case DatabaseDriver::PGSQL: + case DatabaseDriver::SQLITE: + $database->execute('CREATE INDEX images_image_idx ON images(image) WHERE image IS NOT NULL'); + break; + default: + $database->execute('CREATE INDEX images_image_idx ON images(image)'); + break; + } + + if ($database->get_driver_name()==DatabaseDriver::PGSQL) { // These updates can take a little bit + $database->execute("SET statement_timeout TO 300000;"); + } + + $database->commit(); // Each of these commands could hit a lot of data, combining them into one big transaction would not be a good idea. + + log_info("upgrade", "Setting predictable media values for known file types"); + $database->execute($database->scoreql_to_sql("UPDATE images SET image = SCORE_BOOL_N WHERE ext IN ('swf','mp3','ani','flv','mp4','m4v','ogv','webm')")); + $database->execute($database->scoreql_to_sql("UPDATE images SET image = SCORE_BOOL_Y WHERE ext IN ('jpg','jpeg''ico','cur','png')")); + + $config->set_int(MediaConfig::VERSION, 2); + log_info("media", "extension at version 2"); + } + } } diff --git a/ext/media/media_engine.php b/ext/media/media_engine.php new file mode 100644 index 00000000..28c753bb --- /dev/null +++ b/ext/media/media_engine.php @@ -0,0 +1,67 @@ + [ + "gif", + "jpg", + "png", + "webp", + Media::WEBP_LOSSY, + ], + MediaEngine::IMAGICK => [ + "gif", + "jpg", + "png", + "webp", + Media::WEBP_LOSSY, + Media::WEBP_LOSSLESS, + ], + MediaEngine::FFMPEG => [ + "jpg", + "webp", + "png" + ] + ]; + public const INPUT_SUPPORT = [ + MediaEngine::GD => [ + "bmp", + "gif", + "jpg", + "png", + "webp", + Media::WEBP_LOSSY, + Media::WEBP_LOSSLESS + ], + MediaEngine::IMAGICK => [ + "bmp", + "gif", + "jpg", + "png", + "psd", + "tiff", + "webp", + Media::WEBP_LOSSY, + Media::WEBP_LOSSLESS, + "ico", + ], + MediaEngine::FFMPEG => [ + "avi", + "mkv", + "webm", + "mp4", + "mov", + "flv" + ] + ]; +} From aa5c8c81e06cfe2493b86070b7a328adca998194 Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Thu, 10 Oct 2019 10:12:03 -0500 Subject: [PATCH 06/30] Added lower() to some tag lookups Removed a duplicate include line --- ext/danbooru_api/main.php | 4 ++-- ext/not_a_tag/main.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ext/danbooru_api/main.php b/ext/danbooru_api/main.php index aa0ec9a7..b7aa61ea 100644 --- a/ext/danbooru_api/main.php +++ b/ext/danbooru_api/main.php @@ -90,8 +90,8 @@ class DanbooruApi extends Extension } elseif (isset($_GET['name'])) { $namelist = explode(",", $_GET['name']); foreach ($namelist as $name) { - $sqlresult = $database->get_all( - "SELECT id,tag,count FROM tags WHERE tag = ?", + $sqlresult = $database->get_all($database->scoreql_to_sql( + "SELECT id,tag,count FROM tags WHERE SCORE_STRNORM(tag) = SCORE_STRNORM(?)"), [$name] ); foreach ($sqlresult as $row) { diff --git a/ext/not_a_tag/main.php b/ext/not_a_tag/main.php index cb59717c..c788077c 100644 --- a/ext/not_a_tag/main.php +++ b/ext/not_a_tag/main.php @@ -55,7 +55,7 @@ class NotATag extends Extension public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) { global $user; - if ($event->parent==="tags") { + if($event->parent==="tags") { if ($user->can(Permissions::BAN_IMAGE)) { $event->add_nav_link("untags", new Link('untag/list/1'), "UnTags"); } @@ -89,7 +89,7 @@ class NotATag extends Extension $page->set_redirect($_SERVER['HTTP_REFERER']); } elseif ($event->get_arg(0) == "remove") { if (isset($_POST['tag'])) { - $database->Execute("DELETE FROM untags WHERE tag = ?", [$_POST['tag']]); + $database->Execute($database->scoreql_to_sql("DELETE FROM untags WHERE SCORE_STRNORM(tag) = SCORE_STRNORM(?)"), [$_POST['tag']]); flash_message("Image ban removed"); $page->set_mode(PageMode::REDIRECT); From 04b17548930fc506515768c61f39c05854e81536 Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Thu, 10 Oct 2019 10:12:51 -0500 Subject: [PATCH 07/30] Fixed bulk add's KEY --- ext/bulk_add/info.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/bulk_add/info.php b/ext/bulk_add/info.php index 333bf0ba..f7624604 100644 --- a/ext/bulk_add/info.php +++ b/ext/bulk_add/info.php @@ -11,7 +11,7 @@ class BulkAddInfo extends ExtensionInfo { - public const KEY = "builk_add"; + public const KEY = "bulk_add"; public $key = self::KEY; public $name = "Bulk Add"; From 3a14857b409e0ef89cc3a32672c385885da19256 Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Thu, 10 Oct 2019 10:27:46 -0500 Subject: [PATCH 08/30] Consolidated tag sanitization functions Added more tag convenience functions --- core/imageboard/tag.php | 86 +++++++++++++++++++++++++++++++++-------- 1 file changed, 69 insertions(+), 17 deletions(-) diff --git a/core/imageboard/tag.php b/core/imageboard/tag.php index 7fa8b0b7..ae1146cd 100644 --- a/core/imageboard/tag.php +++ b/core/imageboard/tag.php @@ -29,23 +29,7 @@ class Tag $tags = explode(' ', trim($tags)); /* sanitise by removing invisible / dodgy characters */ - $tag_array = []; - foreach ($tags as $tag) { - $tag = preg_replace("/\s/", "", $tag); # whitespace - $tag = preg_replace('/\x20(\x0e|\x0f)/', '', $tag); # unicode RTL - $tag = preg_replace("/\.+/", ".", $tag); # strings of dots? - $tag = preg_replace("/^(\.+[\/\\\\])+/", "", $tag); # trailing slashes? - $tag = trim($tag, ", \t\n\r\0\x0B"); - - if (mb_strlen($tag, 'UTF-8') > 255) { - flash_message("The tag below is longer than 255 characters, please use a shorter tag.\n$tag\n"); - continue; - } - - if (!empty($tag)) { - $tag_array[] = $tag; - } - } + $tag_array = self::sanitize_array($tags); /* if user supplied a blank string, add "tagme" */ if (count($tag_array) === 0 && $tagme) { @@ -101,6 +85,74 @@ class Tag return $tag_array; } + public static function sanitize(string $tag): string + { + $tag = preg_replace("/\s/", "", $tag); # whitespace + $tag = preg_replace('/\x20(\x0e|\x0f)/', '', $tag); # unicode RTL + $tag = preg_replace("/\.+/", ".", $tag); # strings of dots? + $tag = preg_replace("/^(\.+[\/\\\\])+/", "", $tag); # trailing slashes? + $tag = trim($tag, ", \t\n\r\0\x0B"); + + if (mb_strlen($tag, 'UTF-8') > 255) { + throw new Exception("The tag below is longer than 255 characters, please use a shorter tag.\n$tag\n"); + } + return $tag; + } + + public static function compare(array $tags1, array $tags2): bool + { + if(count($tags1)!==count($tags2)) { + return false; + } + + $tags1 = array_map("strtolower",$tags1); + $tags2 = array_map("strtolower",$tags2); + natcasesort($tags1); + natcasesort($tags2); + + + for($i = 0; $i < count($tags1); $i++) { + if($tags1[$i]!==$tags2[$i]) { + var_dump($tags1); + var_dump($tags2); + return false; + } + } + return true; + } + + public static function get_diff_tags(array $source, array $remove): array + { + $before = array_map('strtolower', $source); + $remove = array_map('strtolower', $remove); + $after = []; + foreach ($before as $tag) { + if (!in_array($tag, $remove)) { + $after[] = $tag; + } + } + return $after; + } + + public static function sanitize_array(array $tags): array + { + $tag_array = []; + foreach ($tags as $tag) { + try { + $tag = Tag::sanitize($tag); + } catch(Exception $e) { + flash_message($e->getMessage()); + continue; + } + + if (!empty($tag)) { + $tag_array[] = $tag; + } + } + return $tag_array; + } + + public static function sqlify(string $term): string { global $database; From 4897063adc8cd34ded71a8d93f56857638c13044 Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Thu, 10 Oct 2019 10:28:10 -0500 Subject: [PATCH 09/30] Added trash link --- ext/trash/main.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ext/trash/main.php b/ext/trash/main.php index caef44aa..8d29dd62 100644 --- a/ext/trash/main.php +++ b/ext/trash/main.php @@ -60,6 +60,16 @@ class Trash extends Extension } } + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + global $user; + if($event->parent=="posts") { + if($user->can(Permissions::VIEW_TRASH)) { + $event->add_nav_link("posts_trash", new Link('/post/list/in%3Atrash/1'), "Trash",null, 60); + } + } + } + const SEARCH_REGEXP = "/^in:trash$/"; public function onSearchTermParse(SearchTermParseEvent $event) From 51563017c873f0548e183ba5d784a46c54cd9fc1 Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Thu, 10 Oct 2019 10:32:01 -0500 Subject: [PATCH 10/30] Transcode config constants migrated to own file, added enabled option for future feature --- ext/transcode/config.php | 11 +++++++++++ ext/transcode/main.php | 10 +--------- 2 files changed, 12 insertions(+), 9 deletions(-) create mode 100644 ext/transcode/config.php diff --git a/ext/transcode/config.php b/ext/transcode/config.php new file mode 100644 index 00000000..2146aba0 --- /dev/null +++ b/ext/transcode/config.php @@ -0,0 +1,11 @@ + Date: Thu, 10 Oct 2019 10:32:34 -0500 Subject: [PATCH 11/30] Added extension documentation link image --- .../baseline_open_in_new_black_18dp.png | Bin 0 -> 180 bytes ext/ext_manager/theme.php | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 ext/ext_manager/baseline_open_in_new_black_18dp.png diff --git a/ext/ext_manager/baseline_open_in_new_black_18dp.png b/ext/ext_manager/baseline_open_in_new_black_18dp.png new file mode 100644 index 0000000000000000000000000000000000000000..48a6da8e3fca58ba97a68bdd16d10cc21f4b9ba4 GIT binary patch literal 180 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|msy$sCLn;{8USwoza1d~~xL;^N z^p(Be%ow>^1R53QCTw))5=dMm(YA4c{f0Nm27hAQm0mks`QEXu*y@GbiH!TxbKQ1$ zY3x~|ZtZch%b=lOr_tj}K!WoOgUFD`M{8GG2#9GcoOQ-YLpg(|aKba?VliWN>nQJ{ dz(r55%QY?vI@dnqYBSIo44$rjF6*2UngB5%Lcjn3 literal 0 HcmV?d00001 diff --git a/ext/ext_manager/theme.php b/ext/ext_manager/theme.php index 27cc896b..173e2e56 100644 --- a/ext/ext_manager/theme.php +++ b/ext/ext_manager/theme.php @@ -37,7 +37,7 @@ class ExtManagerTheme extends Themelet //baseline_open_in_new_black_18dp.png $h_enabled_box = $editable ? "" : ""; - $h_docs = ($extension->documentation ? "â– " : ""); //TODO: A proper "docs" symbol would be preferred here. + $h_docs = ($extension->documentation ? "" : ""); //TODO: A proper "docs" symbol would be preferred here. $html .= " From 0a30ec6cfa1f62f2462e4e6714a828748b7d6587 Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Thu, 10 Oct 2019 10:34:37 -0500 Subject: [PATCH 12/30] Added favorite bulk actions --- ext/favorites/main.php | 49 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/ext/favorites/main.php b/ext/favorites/main.php index cd246b32..c213c283 100644 --- a/ext/favorites/main.php +++ b/ext/favorites/main.php @@ -167,6 +167,45 @@ class Favorites extends Extension } } + public function onBulkActionBlockBuilding(BulkActionBlockBuildingEvent $event) + { + global $user; + + if (!$user->is_anonymous()) { + $event->add_action("bulk_favorite", "Favorite"); + $event->add_action("bulk_unfavorite", "Un-Favorite"); + } + } + + public function onBulkAction(BulkActionEvent $event) + { + global $user; + + switch ($event->action) { + case "bulk_favorite": + if (!$user->is_anonymous()) { + $total = 0; + foreach ($event->items as $image) { + send_event(new FavoriteSetEvent($image->id, $user, true)); + $total++; + } + flash_message("Added $total items to favorites"); + } + break; + case "bulk_unfavorite": + if (!$user->is_anonymous()) { + $total = 0; + foreach ($event->items as $image) { + send_event(new FavoriteSetEvent($image->id, $user, false)); + $total++; + } + flash_message("Removed $total items from favorites"); + } + break; + } + } + + private function install() { global $database; @@ -203,10 +242,12 @@ class Favorites extends Extension { global $database; if ($do_set) { - $database->Execute( - "INSERT INTO user_favorites(image_id, user_id, created_at) VALUES(:image_id, :user_id, NOW())", - ["image_id"=>$image_id, "user_id"=>$user_id] - ); + if(!$database->exists("select 1 from user_favorites where image_id=:image_id and user_id=:user_id",["image_id"=>$image_id, "user_id"=>$user_id])) { + $database->Execute( + "INSERT INTO user_favorites(image_id, user_id, created_at) VALUES(:image_id, :user_id, NOW())", + ["image_id"=>$image_id, "user_id"=>$user_id] + ); + } } else { $database->Execute( "DELETE FROM user_favorites WHERE image_id = :image_id AND user_id = :user_id", From 9139bbfd0189132bc65a929ef6ba1dc49f732e43 Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Thu, 10 Oct 2019 10:39:42 -0500 Subject: [PATCH 13/30] Added another lower() to a tag lookup --- core/imageboard/image.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/imageboard/image.php b/core/imageboard/image.php index c268266e..c3ecd9fa 100644 --- a/core/imageboard/image.php +++ b/core/imageboard/image.php @@ -730,9 +730,9 @@ class Image "INSERT INTO tags(tag) VALUES (:tag)", ["tag"=>$tag] ); - $database->execute( + $database->execute($database->scoreql_to_sql( "INSERT INTO image_tags(image_id, tag_id) - VALUES(:id, (SELECT id FROM tags WHERE tag = :tag))", + VALUES(:id, (SELECT id FROM tags WHERE SCORE_STRNORM(tag) = SCORE_STRNORM(:tag)))"), ["id"=>$this->id, "tag"=>$tag] ); } else { From d1853ee1dbfcb208e908f971e0013cb70757f240 Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Thu, 10 Oct 2019 10:59:34 -0500 Subject: [PATCH 14/30] Added scoreql option to database functions to make using scoreql less verbose Added exists function to the database --- core/database.php | 69 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 14 deletions(-) diff --git a/core/database.php b/core/database.php index 3c06c5a3..c6ae69ab 100644 --- a/core/database.php +++ b/core/database.php @@ -178,9 +178,13 @@ class Database $this->dbtime += $dur; } - public function execute(string $query, array $args=[]): PDOStatement + public function execute(string $query, array $args=[], bool $scoreql = false): PDOStatement { try { + if($scoreql===true) { + $query = $this->scoreql_to_sql($query); + } + if (is_null($this->db)) { $this->connect_db(); } @@ -211,8 +215,12 @@ class Database /** * Execute an SQL query and return a 2D array. */ - public function get_all(string $query, array $args=[]): array + public function get_all(string $query, array $args=[], bool $scoreql = false): array { + if($scoreql===true) { + $query = $this->scoreql_to_sql($query); + } + $_start = microtime(true); $data = $this->execute($query, $args)->fetchAll(); $this->count_time("get_all", $_start, $query, $args); @@ -222,8 +230,11 @@ class Database /** * Execute an SQL query and return a iterable object for use with generators. */ - public function get_all_iterable(string $query, array $args=[]): PDOStatement + public function get_all_iterable(string $query, array $args=[], bool $scoreql = false): PDOStatement { + if($scoreql===true) { + $query = $this->scoreql_to_sql($query); + } $_start = microtime(true); $data = $this->execute($query, $args); $this->count_time("get_all_iterable", $_start, $query, $args); @@ -233,19 +244,40 @@ class Database /** * Execute an SQL query and return a single row. */ - public function get_row(string $query, array $args=[]): ?array + public function get_row(string $query, array $args=[], bool $scoreql = false): ?array { + if($scoreql===true) { + $query = $this->scoreql_to_sql($query); + } $_start = microtime(true); $row = $this->execute($query, $args)->fetch(); $this->count_time("get_row", $_start, $query, $args); return $row ? $row : null; } + + /** + * Execute an SQL query and return a boolean based on whether it returns a result + */ + public function exists(string $query, array $args=[], bool $scoreql = false): bool + { + if($scoreql===true) { + $query = $this->scoreql_to_sql($query); + } + $_start = microtime(true); + $result = $this->execute($query, $args); + $this->count_time("exists", $_start, $query, $args); + return $result->rowCount()>0; + } + /** * Execute an SQL query and return the first column of each row. */ - public function get_col(string $query, array $args=[]): array + public function get_col(string $query, array $args=[], bool $scoreql = false): array { + if($scoreql===true) { + $query = $this->scoreql_to_sql($query); + } $_start = microtime(true); $res = $this->execute($query, $args)->fetchAll(PDO::FETCH_COLUMN); $this->count_time("get_col", $_start, $query, $args); @@ -255,8 +287,11 @@ class Database /** * Execute an SQL query and return the first column of each row as a single iterable object. */ - public function get_col_iterable(string $query, array $args=[]): Generator + public function get_col_iterable(string $query, array $args=[], bool $scoreql = false): Generator { + if($scoreql===true) { + $query = $this->scoreql_to_sql($query); + } $_start = microtime(true); $stmt = $this->execute($query, $args); $this->count_time("get_col_iterable", $_start, $query, $args); @@ -268,8 +303,11 @@ class Database /** * Execute an SQL query and return the the first column => the second column. */ - public function get_pairs(string $query, array $args=[]): array + public function get_pairs(string $query, array $args=[], bool $scoreql = false): array { + if($scoreql===true) { + $query = $this->scoreql_to_sql($query); + } $_start = microtime(true); $res = $this->execute($query, $args)->fetchAll(PDO::FETCH_KEY_PAIR); $this->count_time("get_pairs", $_start, $query, $args); @@ -279,8 +317,11 @@ class Database /** * Execute an SQL query and return a single value. */ - public function get_one(string $query, array $args=[]) + public function get_one(string $query, array $args=[], bool $scoreql = false) { + if($scoreql===true) { + $query = $this->scoreql_to_sql($query); + } $_start = microtime(true); $row = $this->execute($query, $args)->fetch(); $this->count_time("get_one", $_start, $query, $args); @@ -354,7 +395,7 @@ class MockDatabase extends Database $this->responses = $responses; } - public function execute(string $query, array $params=[]): PDOStatement + public function execute(string $query, array $params=[], bool $scoreql = false): PDOStatement { log_debug( "mock-database", @@ -376,23 +417,23 @@ class MockDatabase extends Database return $this->responses[$this->query_id++]; } - public function get_all(string $query, array $args=[]): array + public function get_all(string $query, array $args=[], bool $scoreql = false): array { return $this->_execute($query, $args); } - public function get_row(string $query, array $args=[]): ?array + public function get_row(string $query, array $args=[], bool $scoreql = false): ?array { return $this->_execute($query, $args); } - public function get_col(string $query, array $args=[]): array + public function get_col(string $query, array $args=[], bool $scoreql = false): array { return $this->_execute($query, $args); } - public function get_pairs(string $query, array $args=[]): array + public function get_pairs(string $query, array $args=[], bool $scoreql = false): array { return $this->_execute($query, $args); } - public function get_one(string $query, array $args=[]) + public function get_one(string $query, array $args=[], bool $scoreql = false) { return $this->_execute($query, $args); } From 9907c02a115b5e41cec1bb340b27b0c45193c030 Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Thu, 10 Oct 2019 11:02:18 -0500 Subject: [PATCH 15/30] Resolved transaction issue --- ext/media/main.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ext/media/main.php b/ext/media/main.php index 8e399a01..1a9d674b 100644 --- a/ext/media/main.php +++ b/ext/media/main.php @@ -1053,14 +1053,17 @@ class Media extends Extension $database->execute("SET statement_timeout TO 300000;"); } - $database->commit(); // Each of these commands could hit a lot of data, combining them into one big transaction would not be a good idea. - + if ($database->transaction === true) { + $database->commit(); // Each of these commands could hit a lot of data, combining them into one big transaction would not be a good idea. + } log_info("upgrade", "Setting predictable media values for known file types"); $database->execute($database->scoreql_to_sql("UPDATE images SET image = SCORE_BOOL_N WHERE ext IN ('swf','mp3','ani','flv','mp4','m4v','ogv','webm')")); $database->execute($database->scoreql_to_sql("UPDATE images SET image = SCORE_BOOL_Y WHERE ext IN ('jpg','jpeg''ico','cur','png')")); $config->set_int(MediaConfig::VERSION, 2); log_info("media", "extension at version 2"); + + $database->beginTransaction(); } } } From 702f098ea6d1e3eef9e933ecd353b35c862e92c7 Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Mon, 14 Oct 2019 13:31:42 -0500 Subject: [PATCH 16/30] Added create_image permission check to upload menu code --- ext/upload/main.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ext/upload/main.php b/ext/upload/main.php index 356db988..25a0daf9 100644 --- a/ext/upload/main.php +++ b/ext/upload/main.php @@ -138,7 +138,10 @@ class Upload extends Extension public function onPageNavBuilding(PageNavBuildingEvent $event) { - $event->add_nav_link("upload", new Link('upload'), "Upload"); + global $user; + if ($user->can(Permissions::CREATE_IMAGE)) { + $event->add_nav_link("upload", new Link('upload'), "Upload"); + } } public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) From 3efa76c6a28d0dff6c9fbea4dce142a3e0dde095 Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Mon, 14 Oct 2019 13:31:12 -0500 Subject: [PATCH 17/30] Added set_timeout to database and engine --- core/database.php | 5 +++++ core/dbengine.php | 24 ++++++++++++++++++++++-- ext/media/main.php | 4 +--- ext/rating/main.php | 4 +--- ext/rule34/main.php | 4 +--- ext/upgrade/main.php | 4 +--- 6 files changed, 31 insertions(+), 14 deletions(-) diff --git a/core/database.php b/core/database.php index c6ae69ab..a68acdd3 100644 --- a/core/database.php +++ b/core/database.php @@ -178,6 +178,11 @@ class Database $this->dbtime += $dur; } + public function set_timeout(int $time): void + { + $this->engine->set_timeout($this->db, $time); + } + public function execute(string $query, array $args=[], bool $scoreql = false): PDOStatement { try { diff --git a/core/dbengine.php b/core/dbengine.php index 03b4b851..e72c734b 100644 --- a/core/dbengine.php +++ b/core/dbengine.php @@ -12,7 +12,7 @@ abstract class SCORE const ILIKE = "SCORE_ILIKE"; } -class DBEngine +abstract class DBEngine { /** @var null|string */ public $name = null; @@ -33,6 +33,8 @@ class DBEngine { return 'CREATE TABLE '.$name.' ('.$data.')'; } + + public abstract function set_timeout(PDO $db, int $time); } class MySQL extends DBEngine @@ -68,6 +70,13 @@ class MySQL extends DBEngine $ctes = "ENGINE=InnoDB DEFAULT CHARSET='utf8'"; return 'CREATE TABLE '.$name.' ('.$data.') '.$ctes; } + + public function set_timeout(PDO $db, int $time): void + { + // These only apply to read-only queries, which appears to be the best we can to mysql-wise + $db->exec("SET SESSION MAX_EXECUTION_TIME=".$time.";"); + } + } class PostgreSQL extends DBEngine @@ -87,7 +96,7 @@ class PostgreSQL extends DBEngine } else { $db->exec("SET application_name TO 'shimmie [local]';"); } - $db->exec("SET statement_timeout TO ".DATABASE_TIMEOUT.";"); + $this->set_timeout($db, DATABASE_TIMEOUT); } public function scoreql_to_sql(string $data): string @@ -109,6 +118,12 @@ class PostgreSQL extends DBEngine $data = $this->scoreql_to_sql($data); return "CREATE TABLE $name ($data)"; } + + public function set_timeout(PDO $db, int $time): void + { + $db->exec("SET statement_timeout TO ".$time.";"); + } + } // shimmie functions for export to sqlite @@ -213,4 +228,9 @@ class SQLite extends DBEngine $cols_redone = implode(", ", $cols); return "CREATE TABLE $name ($cols_redone); $extras"; } + + public function set_timeout(PDO $db, int $time): void + { + // There doesn't seem to be such a thing for SQLite, so it does nothing + } } diff --git a/ext/media/main.php b/ext/media/main.php index 1a9d674b..9c1eb5c0 100644 --- a/ext/media/main.php +++ b/ext/media/main.php @@ -1049,9 +1049,7 @@ class Media extends Extension break; } - if ($database->get_driver_name()==DatabaseDriver::PGSQL) { // These updates can take a little bit - $database->execute("SET statement_timeout TO 300000;"); - } + $database->set_timeout(300000); // These updates can take a little bit if ($database->transaction === true) { $database->commit(); // Each of these commands could hit a lot of data, combining them into one big transaction would not be a good idea. diff --git a/ext/rating/main.php b/ext/rating/main.php index aa18cabd..66778d91 100644 --- a/ext/rating/main.php +++ b/ext/rating/main.php @@ -578,9 +578,7 @@ class Ratings extends Extension break; } - if ($database->get_driver_name()==DatabaseDriver::PGSQL) { // These updates can take a little bit - $database->execute("SET statement_timeout TO 300000;"); - } + $database->set_timeout(300000); // These updates can take a little bit $database->execute("UPDATE images SET rating = :new WHERE rating = :old", ["new"=>'?', "old"=>'u' ]); diff --git a/ext/rule34/main.php b/ext/rule34/main.php index 1aa80d7d..f7e5a343 100644 --- a/ext/rule34/main.php +++ b/ext/rule34/main.php @@ -71,9 +71,7 @@ class Rule34 extends Extension { global $database, $page, $user; - if ($user->can(Permissions::DELETE_USER)) { // deleting users can take a while - $database->execute("SET statement_timeout TO ".(DATABASE_TIMEOUT+15000).";"); - } + $database->set_timeout(DATABASE_TIMEOUT+15000); // deleting users can take a while if (function_exists("sd_notify_watchdog")) { sd_notify_watchdog(); diff --git a/ext/upgrade/main.php b/ext/upgrade/main.php index 491cb183..0424f269 100644 --- a/ext/upgrade/main.php +++ b/ext/upgrade/main.php @@ -191,9 +191,7 @@ class Upgrade extends Extension break; } - if ($database->get_driver_name()==DatabaseDriver::PGSQL) { // These updates can take a little bit - $database->execute("SET statement_timeout TO 300000;"); - } + $database->set_timeout(300000); // These updates can take a little bit log_info("upgrade", "Setting index for ext column"); $database->execute('CREATE INDEX images_ext_idx ON images(ext)'); From ed8caa86bf71ff2a6c0968f8a67a635c8595b379 Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Tue, 15 Oct 2019 08:22:23 -0500 Subject: [PATCH 18/30] Fix for random issue --- core/imageboard/image.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/imageboard/image.php b/core/imageboard/image.php index c3ecd9fa..f5c84011 100644 --- a/core/imageboard/image.php +++ b/core/imageboard/image.php @@ -115,7 +115,7 @@ class Image if ($max < 1) { return null; } // From Issue #22 - opened by HungryFeline on May 30, 2011. - if ($max > $limit_range) { + if ($limit_range > 0 && $max > $limit_range) { $max = $limit_range; } $rand = mt_rand(0, $max-1); From c17c84f15f15f16cff044636df6e7aae9018e1df Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Tue, 15 Oct 2019 13:46:08 -0500 Subject: [PATCH 19/30] Fixed searching issues on event log page --- ext/log_db/main.php | 8 ++++---- ext/log_db/theme.php | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ext/log_db/main.php b/ext/log_db/main.php index 97958a15..c83b4dda 100644 --- a/ext/log_db/main.php +++ b/ext/log_db/main.php @@ -57,21 +57,21 @@ class LogDatabase extends Extension $args["time_end"] = $_GET["time-end"]; } if (!empty($_GET["module"])) { - $wheres[] = "section = :module"; + $wheres[] = $database->scoreql_to_sql("SCORE_STRNORM(section) = SCORE_STRNORM(:module)"); $args["module"] = $_GET["module"]; } if (!empty($_GET["user"])) { if ($database->get_driver_name() == DatabaseDriver::PGSQL) { if (preg_match("#\d+\.\d+\.\d+\.\d+(/\d+)?#", $_GET["user"])) { - $wheres[] = "(username = :user1 OR text(address) = :user2)"; + $wheres[] = $database->scoreql_to_sql("(SCORE_STRNORM(username) = SCORE_STRNORM(:user1) OR SCORE_STRNORM(text(address)) = SCORE_STRNORM(:user2))"); $args["user1"] = $_GET["user"]; $args["user2"] = $_GET["user"] . "/32"; } else { - $wheres[] = "lower(username) = lower(:user)"; + $wheres[] = $database->scoreql_to_sql("SCORE_STRNORM(username) = SCORE_STRNORM(:user)"); $args["user"] = $_GET["user"]; } } else { - $wheres[] = "(username = :user1 OR address = :user2)"; + $wheres[] = $database->scoreql_to_sql("(SCORE_STRNORM(username) = SCORE_STRNORM(:user1) OR SCORE_STRNORM(address) = SCORE_STRNORM(:user2))"); $args["user1"] = $_GET["user"]; $args["user2"] = $_GET["user"]; } diff --git a/ext/log_db/theme.php b/ext/log_db/theme.php index 8c1356fc..94d656b8 100644 --- a/ext/log_db/theme.php +++ b/ext/log_db/theme.php @@ -31,7 +31,7 @@ class LogDatabaseTheme extends Themelet - + ".make_form("log/view", "GET")." @@ -40,11 +40,11 @@ class LogDatabaseTheme extends Themelet @@ -53,7 +53,7 @@ class LogDatabaseTheme extends Themelet \n"; reset($events); // rewind to first element in array. - + foreach ($events as $event) { $c = $this->pri_to_col($event['priority']); $table .= ""; From 016fb6be654f6b27219894709b31dec5e5de8983 Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Thu, 10 Oct 2019 10:25:11 -0500 Subject: [PATCH 20/30] Small fixes and corrections --- core/polyfills.php | 3 ++- ext/rating/main.php | 4 ++-- ext/upload/main.php | 3 --- themes/danbooru2/ext_manager.theme.php | 2 +- themes/danbooru2/view.theme.php | 6 ++++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/polyfills.php b/core/polyfills.php index 87e739e3..c39ec13a 100644 --- a/core/polyfills.php +++ b/core/polyfills.php @@ -281,6 +281,7 @@ const MIME_TYPE_MAP = [ 'mpg' => 'video/mpeg', 'mpeg' => 'video/mpeg', 'mov' => 'video/quicktime', + 'flv' => 'video/x-flv', 'php' => 'text/x-php', 'mp4' => 'video/mp4', 'ogv' => 'video/ogg', @@ -502,7 +503,7 @@ function bool_escape($input): bool */ if (is_bool($input)) { return $input; - } elseif (is_int($input)) { + } elseif (is_numeric($input)) { return ($input === 1); } else { $value = filter_var($input, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); diff --git a/ext/rating/main.php b/ext/rating/main.php index 66778d91..2386c3b0 100644 --- a/ext/rating/main.php +++ b/ext/rating/main.php @@ -341,7 +341,7 @@ class Ratings extends Extension $old = $_POST["rating_old"]; $new = $_POST["rating_new"]; - if ($user->can("bulk_edit_image_rating")) { + if($user->can(Permissions::BULK_EDIT_IMAGE_RATING)) { $database->execute("UPDATE images SET rating = :new WHERE rating = :old", ["new"=>$new, "old"=>$old ]); } @@ -506,7 +506,7 @@ class Ratings extends Extension private function can_rate(): bool { global $user; - if ($user->can("edit_image_rating")) { + if ($user->can(Permissions::EDIT_IMAGE_RATING)) { return true; } return false; diff --git a/ext/upload/main.php b/ext/upload/main.php index 25a0daf9..9c7879ad 100644 --- a/ext/upload/main.php +++ b/ext/upload/main.php @@ -35,9 +35,6 @@ class DataUploadEvent extends Event assert(is_array($metadata["tags"])); assert(is_string($metadata["source"]) || is_null($metadata["source"])); - // DB limits to 64 char filenames - $metadata['filename'] = substr($metadata['filename'], 0, 63); - $this->metadata = $metadata; $this->set_tmpname($tmpname); diff --git a/themes/danbooru2/ext_manager.theme.php b/themes/danbooru2/ext_manager.theme.php index 247406c8..270ec929 100644 --- a/themes/danbooru2/ext_manager.theme.php +++ b/themes/danbooru2/ext_manager.theme.php @@ -8,7 +8,7 @@ class CustomExtManagerTheme extends ExtManagerTheme parent::display_table($page, $extensions, $editable); } - public function display_doc(Page $page, ExtensionInfo $info) + public function display_doc(Page $page, ExtensionManagerInfo $info) { $page->disable_left(); parent::display_doc($page, $info); diff --git a/themes/danbooru2/view.theme.php b/themes/danbooru2/view.theme.php index c655ecb6..89266795 100644 --- a/themes/danbooru2/view.theme.php +++ b/themes/danbooru2/view.theme.php @@ -51,8 +51,10 @@ class CustomViewImageTheme extends ViewImageTheme if ($image->rating == null || $image->rating == "?") { $image->rating = "?"; } - $h_rating = Ratings::rating_to_human($image->rating); - $html .= "
Rating: $h_rating"; + if (Extension::is_enabled(RatingsInfo::KEY)) { + $h_rating = Ratings::rating_to_human($image->rating); + $html .= "
Rating: $h_rating"; + } } return $html; From c2d6f1a5fa45621eb0af7de04c15dada8e9511fd Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Mon, 14 Oct 2019 13:35:33 -0500 Subject: [PATCH 21/30] New "Approval" extension --- ext/approval/info.php | 20 ++++ ext/approval/main.php | 204 +++++++++++++++++++++++++++++++++++++++++ ext/approval/theme.php | 41 +++++++++ 3 files changed, 265 insertions(+) create mode 100644 ext/approval/info.php create mode 100644 ext/approval/main.php create mode 100644 ext/approval/theme.php diff --git a/ext/approval/info.php b/ext/approval/info.php new file mode 100644 index 00000000..e07d1341 --- /dev/null +++ b/ext/approval/info.php @@ -0,0 +1,20 @@ + + * Description: Provides "Trash" or "Recycle Bin"-type functionality, storing delete images for later recovery + * Documentation: + */ + +class ApprovalInfo extends ExtensionInfo +{ + public const KEY = "approval"; + + public $key = self::KEY; + public $name = "Approval"; + public $authors = ["Matthew Barbour"=>"matthew@darkholme.net"]; + public $license = self::LICENSE_WTFPL; + public $description = "Adds an approval step to the upload/import process."; + public $db_support = [DatabaseDriver::MYSQL, DatabaseDriver::PGSQL]; +} diff --git a/ext/approval/main.php b/ext/approval/main.php new file mode 100644 index 00000000..496ea73e --- /dev/null +++ b/ext/approval/main.php @@ -0,0 +1,204 @@ +set_default_bool(ApprovalConfig::IMAGES, false); + $config->set_default_bool(ApprovalConfig::COMMENTS, false); + + if ($config->get_int(ApprovalConfig::VERSION) < 1) { + $this->install(); + } + } + + public function onPageRequest(PageRequestEvent $event) + { + global $page, $user; + + if ($event->page_matches("approve_image") && $user->can(Permissions::APPROVE_IMAGE)) { + // 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 SCoreException("Can not approve image: No valid Image ID given."); + } + + self::approve_image($image_id); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("post/view/".$image_id)); + } + } + + public function onAdminBuilding(AdminBuildingEvent $event) + { + $this->theme->display_admin_form(); + } + + public function onAdminAction(AdminActionEvent $event) + { + global $database, $user; + + $action = $event->action; + $event->redirect = true; + if($action==="approval") { + $approval_action = $_POST["approval_action"]; + switch ($approval_action) { + case "approve_all": + $database->set_timeout(300000); // These updates can take a little bit + $database->execute($database->scoreql_to_sql( + "UPDATE images SET approved = SCORE_BOOL_Y, approved_by_id = :approved_by_id WHERE approved = SCORE_BOOL_N"), + ["approved_by_id"=>$user->id] + ); + break; + case "de_approve_all": + $database->set_timeout(300000); // These updates can take a little bit + $database->execute($database->scoreql_to_sql( + "UPDATE images SET approved = SCORE_BOOL_N, approved_by_id = NULL WHERE approved = SCORE_BOOL_Y")); + break; + default: + + break; + } + } + } + + public function onDisplayingImage(DisplayingImageEvent $event) + { + global $user, $page; + + if ($event->image->approved===false && !$user->can(Permissions::APPROVE_IMAGE)) { + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("post/list")); + } + } + + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + global $user; + if($event->parent=="posts") { + if($user->can(Permissions::APPROVE_IMAGE)) { + $event->add_nav_link("posts_unapproved", new Link('/post/list/approved%3Ano/1'), "Pending Approval",null, 60); + } + } + } + + + const SEARCH_REGEXP = "/^approved:(yes|no)/"; + public function onSearchTermParse(SearchTermParseEvent $event) + { + global $user, $database; + + $matches = []; + + if (is_null($event->term) && $this->no_approval_query($event->context)) { + $event->add_querylet(new Querylet($database->scoreql_to_sql("approved = SCORE_BOOL_Y "))); + } + + + if (preg_match(self::SEARCH_REGEXP, strtolower($event->term), $matches)) { + if ($user->can(Permissions::APPROVE_IMAGE)&&$matches[1]=="no") { + $event->add_querylet(new Querylet($database->scoreql_to_sql("approved = SCORE_BOOL_N "))); + } else { + $event->add_querylet(new Querylet($database->scoreql_to_sql("approved = SCORE_BOOL_Y "))); + } + } + } + + public function onHelpPageBuilding(HelpPageBuildingEvent $event) + { + global $user; + if ($event->key===HelpPages::SEARCH) { + if ($user->can(Permissions::APPROVE_IMAGE)) { + $block = new Block(); + $block->header = "Approval"; + $block->body = $this->theme->get_help_html(); + $event->add_block($block); + } + } + } + + + private function no_approval_query(array $context): bool + { + foreach ($context as $term) { + if (preg_match(self::SEARCH_REGEXP, $term)) { + return false; + } + } + return true; + } + + public static function approve_image($image_id) + { + global $database, $user; + + $database->execute($database->scoreql_to_sql( + "UPDATE images SET approved = SCORE_BOOL_Y, approved_by_id = :approved_by_id WHERE id = :id AND approved = SCORE_BOOL_N"), + ["approved_by_id"=>$user->id, "id"=>$image_id] + ); + } + public function onImageAdminBlockBuilding(ImageAdminBlockBuildingEvent $event) + { + global $user; + if ($event->image->approved===false && $user->can(Permissions::APPROVE_IMAGE)) { + $event->add_part($this->theme->get_image_admin_html($event->image->id)); + } + } + + public function onBulkActionBlockBuilding(BulkActionBlockBuildingEvent $event) + { + global $user; + + if ($user->can(Permissions::APPROVE_IMAGE)&&in_array("approved:no", $event->search_terms)) { + $event->add_action("bulk_approve_image", "Approve", "a"); + } + } + + public function onBulkAction(BulkActionEvent $event) + { + global $user; + + switch ($event->action) { + case "bulk_approve_image": + if ($user->can(Permissions::APPROVE_IMAGE)) { + $total = 0; + foreach ($event->items as $image) { + self::approve_image($image->id); + $total++; + } + flash_message("Approved $total items"); + } + break; + } + } + + + private function install() + { + global $database, $config; + + if ($config->get_int(ApprovalConfig::VERSION) < 1) { + $database->Execute($database->scoreql_to_sql( + "ALTER TABLE images ADD COLUMN approved SCORE_BOOL NOT NULL DEFAULT SCORE_BOOL_N" + )); + $database->Execute($database->scoreql_to_sql( + "ALTER TABLE images ADD COLUMN approved_by_id INTEGER NULL" + )); + + $database->Execute("CREATE INDEX images_approved_idx ON images(approved)"); + $config->set_int(ApprovalConfig::VERSION, 1); + } + } +} diff --git a/ext/approval/theme.php b/ext/approval/theme.php new file mode 100644 index 00000000..bb55a646 --- /dev/null +++ b/ext/approval/theme.php @@ -0,0 +1,41 @@ + + + + "; + + return $html; + } + + + public function get_help_html() + { + return '

Search for images that are approved/not approved.

+
+
approved:yes
+

Returns images that have been approved.

+
+
+
approved:no
+

Returns images that have not been approved.

+
+ '; + } + + public function display_admin_form() + { + global $page; + $html = make_form(make_link("admin/approval"), "POST"); + $html .= "
"; + $html .= ""; + $html .= "\n"; + $page->add_block(new Block("Approval", $html)); + } +} From 2b46ede09849aa84b6c3f566824c0ea6060998cd Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Mon, 14 Oct 2019 13:43:49 -0500 Subject: [PATCH 22/30] approval permissions --- core/permissions.php | 3 +++ core/userclass.php | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/core/permissions.php b/core/permissions.php index e546236b..66b92b7c 100644 --- a/core/permissions.php +++ b/core/permissions.php @@ -81,4 +81,7 @@ abstract class Permissions public const POOLS_ADMIN = "pools_admin"; public const TIPS_ADMIN = "tips_admin"; public const CRON_ADMIN = "cron_admin"; + public const APPROVE_IMAGE = "approve_image"; + public const APPROVE_COMMENT = "approve_comment"; + } diff --git a/core/userclass.php b/core/userclass.php index 2207fa63..f474d154 100644 --- a/core/userclass.php +++ b/core/userclass.php @@ -151,6 +151,9 @@ new UserClass("base", null, [ Permissions::POOLS_ADMIN => false, Permissions::TIPS_ADMIN => false, Permissions::CRON_ADMIN => false, + + Permissions::APPROVE_IMAGE => false, + Permissions::APPROVE_COMMENT => false, ]); new UserClass("anonymous", "base", [ @@ -228,6 +231,8 @@ new UserClass("admin", "base", [ Permissions::POOLS_ADMIN => true, Permissions::TIPS_ADMIN => true, Permissions::CRON_ADMIN => true, + Permissions::APPROVE_IMAGE => true, + Permissions::APPROVE_COMMENT => true, ]); new UserClass("hellbanned", "user", [ From 5f89420fabaac7d9b42f99c2782e80fa57122dd2 Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Mon, 14 Oct 2019 14:40:15 -0500 Subject: [PATCH 23/30] Approval enable option --- ext/approval/main.php | 37 ++++++++++++++++++++++--------------- ext/approval/theme.php | 8 ++++++++ 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/ext/approval/main.php b/ext/approval/main.php index 496ea73e..48f067a6 100644 --- a/ext/approval/main.php +++ b/ext/approval/main.php @@ -41,6 +41,11 @@ class Approval extends Extension } } + public function onSetupBuilding(SetupBuildingEvent $event) + { + $this->theme->display_admin_block($event); + } + public function onAdminBuilding(AdminBuildingEvent $event) { $this->theme->display_admin_form(); @@ -98,21 +103,23 @@ class Approval extends Extension const SEARCH_REGEXP = "/^approved:(yes|no)/"; public function onSearchTermParse(SearchTermParseEvent $event) { - global $user, $database; + global $user, $database, $config; - $matches = []; + if($config->get_bool(ApprovalConfig::IMAGES)) { + $matches = []; - if (is_null($event->term) && $this->no_approval_query($event->context)) { - $event->add_querylet(new Querylet($database->scoreql_to_sql("approved = SCORE_BOOL_Y "))); - } - - - if (preg_match(self::SEARCH_REGEXP, strtolower($event->term), $matches)) { - if ($user->can(Permissions::APPROVE_IMAGE)&&$matches[1]=="no") { - $event->add_querylet(new Querylet($database->scoreql_to_sql("approved = SCORE_BOOL_N "))); - } else { + if (is_null($event->term) && $this->no_approval_query($event->context)) { $event->add_querylet(new Querylet($database->scoreql_to_sql("approved = SCORE_BOOL_Y "))); } + + + if (preg_match(self::SEARCH_REGEXP, strtolower($event->term), $matches)) { + if ($user->can(Permissions::APPROVE_IMAGE) && $matches[1] == "no") { + $event->add_querylet(new Querylet($database->scoreql_to_sql("approved = SCORE_BOOL_N "))); + } else { + $event->add_querylet(new Querylet($database->scoreql_to_sql("approved = SCORE_BOOL_Y "))); + } + } } } @@ -151,17 +158,17 @@ class Approval extends Extension } public function onImageAdminBlockBuilding(ImageAdminBlockBuildingEvent $event) { - global $user; - if ($event->image->approved===false && $user->can(Permissions::APPROVE_IMAGE)) { + global $user, $config; + if ($event->image->approved===false && $user->can(Permissions::APPROVE_IMAGE) && $config->get_bool(ApprovalConfig::IMAGES)) { $event->add_part($this->theme->get_image_admin_html($event->image->id)); } } public function onBulkActionBlockBuilding(BulkActionBlockBuildingEvent $event) { - global $user; + global $user, $config; - if ($user->can(Permissions::APPROVE_IMAGE)&&in_array("approved:no", $event->search_terms)) { + if ($user->can(Permissions::APPROVE_IMAGE)&&in_array("approved:no", $event->search_terms)&& $config->get_bool(ApprovalConfig::IMAGES)) { $event->add_action("bulk_approve_image", "Approve", "a"); } } diff --git a/ext/approval/theme.php b/ext/approval/theme.php index bb55a646..5c807f8c 100644 --- a/ext/approval/theme.php +++ b/ext/approval/theme.php @@ -29,9 +29,17 @@ class ApprovalTheme extends Themelet '; } + public function display_admin_block(SetupBuildingEvent $event) + { + $sb = new SetupBlock("Approval"); + $sb->add_bool_option(ApprovalConfig::IMAGES, "Images: "); + $event->panel->add_block($sb); + } + public function display_admin_form() { global $page; + $html = make_form(make_link("admin/approval"), "POST"); $html .= "
"; $html .= ""; From 4dfb2761ab86c4deaa2b894d66934fe270294839 Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Mon, 14 Oct 2019 14:46:42 -0500 Subject: [PATCH 24/30] More approval enable option consequences --- ext/approval/main.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ext/approval/main.php b/ext/approval/main.php index 48f067a6..58428b54 100644 --- a/ext/approval/main.php +++ b/ext/approval/main.php @@ -48,6 +48,8 @@ class Approval extends Extension public function onAdminBuilding(AdminBuildingEvent $event) { + global $config; + $this->theme->display_admin_form(); } @@ -81,9 +83,9 @@ class Approval extends Extension public function onDisplayingImage(DisplayingImageEvent $event) { - global $user, $page; + global $user, $page, $config; - if ($event->image->approved===false && !$user->can(Permissions::APPROVE_IMAGE)) { + if ( $config->get_bool(ApprovalConfig::IMAGES) && $event->image->approved===false && !$user->can(Permissions::APPROVE_IMAGE)) { $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/list")); } @@ -125,9 +127,9 @@ class Approval extends Extension public function onHelpPageBuilding(HelpPageBuildingEvent $event) { - global $user; + global $user, $config; if ($event->key===HelpPages::SEARCH) { - if ($user->can(Permissions::APPROVE_IMAGE)) { + if ($user->can(Permissions::APPROVE_IMAGE) && $config->get_bool(ApprovalConfig::IMAGES)) { $block = new Block(); $block->header = "Approval"; $block->body = $this->theme->get_help_html(); From 1565b8570bc2773932068d636d97e35d5febab57 Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Fri, 1 Nov 2019 23:45:28 -0500 Subject: [PATCH 25/30] Added disapproving controls to approval extension --- ext/approval/main.php | 50 +++++++++++++++++++++++++++++++++++++----- ext/approval/theme.php | 19 +++++++++++----- 2 files changed, 59 insertions(+), 10 deletions(-) diff --git a/ext/approval/main.php b/ext/approval/main.php index 58428b54..05e7b426 100644 --- a/ext/approval/main.php +++ b/ext/approval/main.php @@ -37,6 +37,21 @@ class Approval extends Extension self::approve_image($image_id); $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("post/view/" . $image_id)); + } + + if ($event->page_matches("disapprove_image") && $user->can(Permissions::APPROVE_IMAGE)) { + // 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 SCoreException("Can not disapprove image: No valid Image ID given."); + } + + self::disapprove_image($image_id); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/view/".$image_id)); } } @@ -69,7 +84,7 @@ class Approval extends Extension ["approved_by_id"=>$user->id] ); break; - case "de_approve_all": + case "disapprove_all": $database->set_timeout(300000); // These updates can take a little bit $database->execute($database->scoreql_to_sql( "UPDATE images SET approved = SCORE_BOOL_N, approved_by_id = NULL WHERE approved = SCORE_BOOL_Y")); @@ -158,11 +173,22 @@ class Approval extends Extension ["approved_by_id"=>$user->id, "id"=>$image_id] ); } + + public static function disapprove_image($image_id) + { + global $database, $user; + + $database->execute($database->scoreql_to_sql( + "UPDATE images SET approved = SCORE_BOOL_N, approved_by_id = NULL WHERE id = :id AND approved = SCORE_BOOL_Y"), + ["id"=>$image_id] + ); + } + public function onImageAdminBlockBuilding(ImageAdminBlockBuildingEvent $event) { global $user, $config; - if ($event->image->approved===false && $user->can(Permissions::APPROVE_IMAGE) && $config->get_bool(ApprovalConfig::IMAGES)) { - $event->add_part($this->theme->get_image_admin_html($event->image->id)); + if($user->can(Permissions::APPROVE_IMAGE) && $config->get_bool(ApprovalConfig::IMAGES)) { + $event->add_part($this->theme->get_image_admin_html($event->image)); } } @@ -170,8 +196,12 @@ class Approval extends Extension { global $user, $config; - if ($user->can(Permissions::APPROVE_IMAGE)&&in_array("approved:no", $event->search_terms)&& $config->get_bool(ApprovalConfig::IMAGES)) { - $event->add_action("bulk_approve_image", "Approve", "a"); + if ($user->can(Permissions::APPROVE_IMAGE)&& $config->get_bool(ApprovalConfig::IMAGES)) { + if(in_array("approved:no", $event->search_terms)) { + $event->add_action("bulk_approve_image", "Approve", "a"); + } else { + $event->add_action("bulk_disapprove_image", "Disapprove"); + } } } @@ -190,6 +220,16 @@ class Approval extends Extension flash_message("Approved $total items"); } break; + case "bulk_disapprove_image": + if ($user->can(Permissions::APPROVE_IMAGE)) { + $total = 0; + foreach ($event->items as $image) { + self::disapprove_image($image->id); + $total++; + } + flash_message("Disapproved $total items"); + } + break; } } diff --git a/ext/approval/theme.php b/ext/approval/theme.php index 5c807f8c..0879d1b1 100644 --- a/ext/approval/theme.php +++ b/ext/approval/theme.php @@ -2,14 +2,23 @@ class ApprovalTheme extends Themelet { - public function get_image_admin_html(int $image_id) + public function get_image_admin_html(Image $image) { - $html = " - ".make_form(make_link('approve_image/'.$image_id), 'POST')." - + if($image->approved===true) { + $html = " + ".make_form(make_link('disapprove_image/'.$image->id), 'POST')." + + + + "; + } else { + $html = " + ".make_form(make_link('approve_image/'.$image->id), 'POST')." + "; + } return $html; } @@ -42,7 +51,7 @@ class ApprovalTheme extends Themelet $html = make_form(make_link("admin/approval"), "POST"); $html .= "
"; - $html .= ""; + $html .= ""; $html .= "\n"; $page->add_block(new Block("Approval", $html)); } From 6e320a090e2b8214391761576861b18ed8739c25 Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Fri, 1 Nov 2019 23:42:11 -0500 Subject: [PATCH 26/30] Better help page nav system integration --- ext/help_pages/main.php | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/ext/help_pages/main.php b/ext/help_pages/main.php index ac7f4cf1..90206d00 100644 --- a/ext/help_pages/main.php +++ b/ext/help_pages/main.php @@ -33,22 +33,40 @@ class HelpPages extends Extension { public const SEARCH = "search"; + private $pages; + + private function get_pages(): array + { + if($this->pages==null) { + $e = new HelpPageListBuildingEvent(); + send_event($e); + $this->pages = $e->pages; + } + return $this->pages; + } + public function onPageRequest(PageRequestEvent $event) { global $page; + $pages = $this->get_pages(); + if ($event->page_matches("help")) { - $e = new HelpPageListBuildingEvent(); - send_event($e); - $page->set_mode(PageMode::PAGE); + if ($event->count_args() == 0) { - $this->theme->display_list_page($e->pages); + $name = array_key_first($pages); + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(make_link("help/".$name)); + return; } else { + $page->set_mode(PageMode::PAGE); $name = $event->get_arg(0); $title = $name; - if (array_key_exists($name, $e->pages)) { - $title = $e->pages[$name]; + if(array_key_exists($name, $pages)) { + $title = $pages[$name]; + } else { + return; } $this->theme->display_help_page($title); @@ -77,6 +95,16 @@ class HelpPages extends Extension $event->add_nav_link("help", new Link('help'), "Help"); } + public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) + { + if($event->parent=="help") { + $pages = $this->get_pages(); + foreach ($pages as $key=>$value) { + $event->add_nav_link("help_".$key, new Link('help/'.$key),$value); + } + } + } + public function onUserBlockBuilding(UserBlockBuildingEvent $event) { $event->add_link("Help", make_link("help")); From 6b22f6da3f95e912a0887fbfc00dc79a7e5b2c0e Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Fri, 1 Nov 2019 23:52:57 -0500 Subject: [PATCH 27/30] Cleanup --- core/polyfills.php | 1 - ext/approval/info.php | 7 ------- 2 files changed, 8 deletions(-) diff --git a/core/polyfills.php b/core/polyfills.php index c39ec13a..b5ec84c8 100644 --- a/core/polyfills.php +++ b/core/polyfills.php @@ -281,7 +281,6 @@ const MIME_TYPE_MAP = [ 'mpg' => 'video/mpeg', 'mpeg' => 'video/mpeg', 'mov' => 'video/quicktime', - 'flv' => 'video/x-flv', 'php' => 'text/x-php', 'mp4' => 'video/mp4', 'ogv' => 'video/ogg', diff --git a/ext/approval/info.php b/ext/approval/info.php index e07d1341..c2af31cd 100644 --- a/ext/approval/info.php +++ b/ext/approval/info.php @@ -1,12 +1,5 @@ - * Description: Provides "Trash" or "Recycle Bin"-type functionality, storing delete images for later recovery - * Documentation: - */ - class ApprovalInfo extends ExtensionInfo { public const KEY = "approval"; From 55c68540037d2e66909106cb60f05b9950381357 Mon Sep 17 00:00:00 2001 From: Shish Date: Sat, 2 Nov 2019 19:57:34 +0000 Subject: [PATCH 28/30] formatting --- core/database.php | 18 ++++++++--------- core/dbengine.php | 4 +--- core/imageboard/image.php | 8 +++++--- core/imageboard/tag.php | 12 +++++------ core/permissions.php | 1 - core/util.php | 13 +++++++----- ext/approval/main.php | 37 ++++++++++++++++++++-------------- ext/approval/theme.php | 2 +- ext/artists/main.php | 2 +- ext/bulk_remove/main.php | 2 +- ext/cron_uploader/config.php | 1 - ext/cron_uploader/main.php | 34 ++++++++++++++++--------------- ext/cron_uploader/theme.php | 24 +++++++++++++--------- ext/danbooru_api/main.php | 6 ++++-- ext/downtime/theme.php | 2 +- ext/favorites/main.php | 2 +- ext/forum/main.php | 4 ++-- ext/help_pages/main.php | 10 ++++----- ext/home/theme.php | 2 +- ext/media/config.php | 1 - ext/media/events.php | 22 +++++++++++--------- ext/media/main.php | 8 ++++---- ext/not_a_tag/main.php | 2 +- ext/ouroboros_api/main.php | 2 +- ext/pools/main.php | 2 +- ext/rating/main.php | 2 +- ext/trash/main.php | 6 +++--- ext/upload/main.php | 3 +++ themes/material/home.theme.php | 2 +- 29 files changed, 128 insertions(+), 106 deletions(-) diff --git a/core/database.php b/core/database.php index a68acdd3..535548a7 100644 --- a/core/database.php +++ b/core/database.php @@ -186,7 +186,7 @@ class Database public function execute(string $query, array $args=[], bool $scoreql = false): PDOStatement { try { - if($scoreql===true) { + if ($scoreql===true) { $query = $this->scoreql_to_sql($query); } @@ -222,7 +222,7 @@ class Database */ public function get_all(string $query, array $args=[], bool $scoreql = false): array { - if($scoreql===true) { + if ($scoreql===true) { $query = $this->scoreql_to_sql($query); } @@ -237,7 +237,7 @@ class Database */ public function get_all_iterable(string $query, array $args=[], bool $scoreql = false): PDOStatement { - if($scoreql===true) { + if ($scoreql===true) { $query = $this->scoreql_to_sql($query); } $_start = microtime(true); @@ -251,7 +251,7 @@ class Database */ public function get_row(string $query, array $args=[], bool $scoreql = false): ?array { - if($scoreql===true) { + if ($scoreql===true) { $query = $this->scoreql_to_sql($query); } $_start = microtime(true); @@ -266,7 +266,7 @@ class Database */ public function exists(string $query, array $args=[], bool $scoreql = false): bool { - if($scoreql===true) { + if ($scoreql===true) { $query = $this->scoreql_to_sql($query); } $_start = microtime(true); @@ -280,7 +280,7 @@ class Database */ public function get_col(string $query, array $args=[], bool $scoreql = false): array { - if($scoreql===true) { + if ($scoreql===true) { $query = $this->scoreql_to_sql($query); } $_start = microtime(true); @@ -294,7 +294,7 @@ class Database */ public function get_col_iterable(string $query, array $args=[], bool $scoreql = false): Generator { - if($scoreql===true) { + if ($scoreql===true) { $query = $this->scoreql_to_sql($query); } $_start = microtime(true); @@ -310,7 +310,7 @@ class Database */ public function get_pairs(string $query, array $args=[], bool $scoreql = false): array { - if($scoreql===true) { + if ($scoreql===true) { $query = $this->scoreql_to_sql($query); } $_start = microtime(true); @@ -324,7 +324,7 @@ class Database */ public function get_one(string $query, array $args=[], bool $scoreql = false) { - if($scoreql===true) { + if ($scoreql===true) { $query = $this->scoreql_to_sql($query); } $_start = microtime(true); diff --git a/core/dbengine.php b/core/dbengine.php index e72c734b..86b1a9d6 100644 --- a/core/dbengine.php +++ b/core/dbengine.php @@ -34,7 +34,7 @@ abstract class DBEngine return 'CREATE TABLE '.$name.' ('.$data.')'; } - public abstract function set_timeout(PDO $db, int $time); + abstract public function set_timeout(PDO $db, int $time); } class MySQL extends DBEngine @@ -76,7 +76,6 @@ class MySQL extends DBEngine // These only apply to read-only queries, which appears to be the best we can to mysql-wise $db->exec("SET SESSION MAX_EXECUTION_TIME=".$time.";"); } - } class PostgreSQL extends DBEngine @@ -123,7 +122,6 @@ class PostgreSQL extends DBEngine { $db->exec("SET statement_timeout TO ".$time.";"); } - } // shimmie functions for export to sqlite diff --git a/core/imageboard/image.php b/core/imageboard/image.php index f5c84011..7a66ec04 100644 --- a/core/imageboard/image.php +++ b/core/imageboard/image.php @@ -151,7 +151,7 @@ class Image if (!$result) { $querylet = Image::build_search_querylet($tag_conditions, $img_conditions); $querylet->append(new Querylet(" ORDER BY ".(Image::$order_sql ?: "images.".$config->get_string(IndexConfig::ORDER)))); - if($limit!=null) { + if ($limit!=null) { $querylet->append(new Querylet(" LIMIT :limit ", ["limit" => $limit])); $querylet->append(new Querylet(" OFFSET :offset ", ["offset"=>$start])); } @@ -730,9 +730,11 @@ class Image "INSERT INTO tags(tag) VALUES (:tag)", ["tag"=>$tag] ); - $database->execute($database->scoreql_to_sql( + $database->execute( + $database->scoreql_to_sql( "INSERT INTO image_tags(image_id, tag_id) - VALUES(:id, (SELECT id FROM tags WHERE SCORE_STRNORM(tag) = SCORE_STRNORM(:tag)))"), + VALUES(:id, (SELECT id FROM tags WHERE SCORE_STRNORM(tag) = SCORE_STRNORM(:tag)))" + ), ["id"=>$this->id, "tag"=>$tag] ); } else { diff --git a/core/imageboard/tag.php b/core/imageboard/tag.php index ae1146cd..0deeeef7 100644 --- a/core/imageboard/tag.php +++ b/core/imageboard/tag.php @@ -101,18 +101,18 @@ class Tag public static function compare(array $tags1, array $tags2): bool { - if(count($tags1)!==count($tags2)) { + if (count($tags1)!==count($tags2)) { return false; } - $tags1 = array_map("strtolower",$tags1); - $tags2 = array_map("strtolower",$tags2); + $tags1 = array_map("strtolower", $tags1); + $tags2 = array_map("strtolower", $tags2); natcasesort($tags1); natcasesort($tags2); - for($i = 0; $i < count($tags1); $i++) { - if($tags1[$i]!==$tags2[$i]) { + for ($i = 0; $i < count($tags1); $i++) { + if ($tags1[$i]!==$tags2[$i]) { var_dump($tags1); var_dump($tags2); return false; @@ -140,7 +140,7 @@ class Tag foreach ($tags as $tag) { try { $tag = Tag::sanitize($tag); - } catch(Exception $e) { + } catch (Exception $e) { flash_message($e->getMessage()); continue; } diff --git a/core/permissions.php b/core/permissions.php index 66b92b7c..84eb292e 100644 --- a/core/permissions.php +++ b/core/permissions.php @@ -83,5 +83,4 @@ abstract class Permissions public const CRON_ADMIN = "cron_admin"; public const APPROVE_IMAGE = "approve_image"; public const APPROVE_COMMENT = "approve_comment"; - } diff --git a/core/util.php b/core/util.php index b79a2238..44f05c6c 100644 --- a/core/util.php +++ b/core/util.php @@ -352,16 +352,18 @@ function join_url(string $base, string ...$paths) function get_dir_contents(string $dir): array { - if(empty($dir)) { + if (empty($dir)) { throw new Exception("dir required"); } - if(!is_dir($dir)) { + if (!is_dir($dir)) { return []; } $results = array_diff( scandir( - $dir), - ['..', '.']); + $dir + ), + ['..', '.'] + ); return $results; } @@ -378,7 +380,8 @@ function scan_dir(string $path): array $path, FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO | - FilesystemIterator::SKIP_DOTS); + FilesystemIterator::SKIP_DOTS + ); foreach (new RecursiveIteratorIterator($ite) as $filename => $cur) { try { $filesize = $cur->getSize(); diff --git a/ext/approval/main.php b/ext/approval/main.php index 05e7b426..f012b2e0 100644 --- a/ext/approval/main.php +++ b/ext/approval/main.php @@ -74,20 +74,23 @@ class Approval extends Extension $action = $event->action; $event->redirect = true; - if($action==="approval") { + if ($action==="approval") { $approval_action = $_POST["approval_action"]; switch ($approval_action) { case "approve_all": $database->set_timeout(300000); // These updates can take a little bit - $database->execute($database->scoreql_to_sql( - "UPDATE images SET approved = SCORE_BOOL_Y, approved_by_id = :approved_by_id WHERE approved = SCORE_BOOL_N"), + $database->execute( + $database->scoreql_to_sql( + "UPDATE images SET approved = SCORE_BOOL_Y, approved_by_id = :approved_by_id WHERE approved = SCORE_BOOL_N" + ), ["approved_by_id"=>$user->id] ); break; case "disapprove_all": $database->set_timeout(300000); // These updates can take a little bit $database->execute($database->scoreql_to_sql( - "UPDATE images SET approved = SCORE_BOOL_N, approved_by_id = NULL WHERE approved = SCORE_BOOL_Y")); + "UPDATE images SET approved = SCORE_BOOL_N, approved_by_id = NULL WHERE approved = SCORE_BOOL_Y" + )); break; default: @@ -100,7 +103,7 @@ class Approval extends Extension { global $user, $page, $config; - if ( $config->get_bool(ApprovalConfig::IMAGES) && $event->image->approved===false && !$user->can(Permissions::APPROVE_IMAGE)) { + if ($config->get_bool(ApprovalConfig::IMAGES) && $event->image->approved===false && !$user->can(Permissions::APPROVE_IMAGE)) { $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/list")); } @@ -109,9 +112,9 @@ class Approval extends Extension public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) { global $user; - if($event->parent=="posts") { - if($user->can(Permissions::APPROVE_IMAGE)) { - $event->add_nav_link("posts_unapproved", new Link('/post/list/approved%3Ano/1'), "Pending Approval",null, 60); + if ($event->parent=="posts") { + if ($user->can(Permissions::APPROVE_IMAGE)) { + $event->add_nav_link("posts_unapproved", new Link('/post/list/approved%3Ano/1'), "Pending Approval", null, 60); } } } @@ -122,7 +125,7 @@ class Approval extends Extension { global $user, $database, $config; - if($config->get_bool(ApprovalConfig::IMAGES)) { + if ($config->get_bool(ApprovalConfig::IMAGES)) { $matches = []; if (is_null($event->term) && $this->no_approval_query($event->context)) { @@ -168,8 +171,10 @@ class Approval extends Extension { global $database, $user; - $database->execute($database->scoreql_to_sql( - "UPDATE images SET approved = SCORE_BOOL_Y, approved_by_id = :approved_by_id WHERE id = :id AND approved = SCORE_BOOL_N"), + $database->execute( + $database->scoreql_to_sql( + "UPDATE images SET approved = SCORE_BOOL_Y, approved_by_id = :approved_by_id WHERE id = :id AND approved = SCORE_BOOL_N" + ), ["approved_by_id"=>$user->id, "id"=>$image_id] ); } @@ -178,8 +183,10 @@ class Approval extends Extension { global $database, $user; - $database->execute($database->scoreql_to_sql( - "UPDATE images SET approved = SCORE_BOOL_N, approved_by_id = NULL WHERE id = :id AND approved = SCORE_BOOL_Y"), + $database->execute( + $database->scoreql_to_sql( + "UPDATE images SET approved = SCORE_BOOL_N, approved_by_id = NULL WHERE id = :id AND approved = SCORE_BOOL_Y" + ), ["id"=>$image_id] ); } @@ -187,7 +194,7 @@ class Approval extends Extension public function onImageAdminBlockBuilding(ImageAdminBlockBuildingEvent $event) { global $user, $config; - if($user->can(Permissions::APPROVE_IMAGE) && $config->get_bool(ApprovalConfig::IMAGES)) { + if ($user->can(Permissions::APPROVE_IMAGE) && $config->get_bool(ApprovalConfig::IMAGES)) { $event->add_part($this->theme->get_image_admin_html($event->image)); } } @@ -197,7 +204,7 @@ class Approval extends Extension global $user, $config; if ($user->can(Permissions::APPROVE_IMAGE)&& $config->get_bool(ApprovalConfig::IMAGES)) { - if(in_array("approved:no", $event->search_terms)) { + if (in_array("approved:no", $event->search_terms)) { $event->add_action("bulk_approve_image", "Approve", "a"); } else { $event->add_action("bulk_disapprove_image", "Disapprove"); diff --git a/ext/approval/theme.php b/ext/approval/theme.php index 0879d1b1..b7ca5b23 100644 --- a/ext/approval/theme.php +++ b/ext/approval/theme.php @@ -4,7 +4,7 @@ class ApprovalTheme extends Themelet { public function get_image_admin_html(Image $image) { - if($image->approved===true) { + if ($image->approved===true) { $html = " ".make_form(make_link('disapprove_image/'.$image->id), 'POST')." diff --git a/ext/artists/main.php b/ext/artists/main.php index e0a4cf7e..2fbd3500 100644 --- a/ext/artists/main.php +++ b/ext/artists/main.php @@ -905,7 +905,7 @@ class Artists extends Extension $pageNumber * $artistsPerPage , $artistsPerPage ] - ); + ); $number_of_listings = count($listing); diff --git a/ext/bulk_remove/main.php b/ext/bulk_remove/main.php index 1d2517b3..50ea8edb 100644 --- a/ext/bulk_remove/main.php +++ b/ext/bulk_remove/main.php @@ -123,7 +123,7 @@ class BulkRemove extends Extension $page->add_block(new Block( "Bulk Remove Error", "Please use Board Admin to use bulk remove." - )); + )); } // diff --git a/ext/cron_uploader/config.php b/ext/cron_uploader/config.php index c749d635..aa6637dc 100644 --- a/ext/cron_uploader/config.php +++ b/ext/cron_uploader/config.php @@ -22,7 +22,6 @@ abstract class CronUploaderConfig $config->set_string(self::KEY, $upload_key); } - } public static function get_user(): int diff --git a/ext/cron_uploader/main.php b/ext/cron_uploader/main.php index 38ff3e8c..49f4f171 100644 --- a/ext/cron_uploader/main.php +++ b/ext/cron_uploader/main.php @@ -22,7 +22,7 @@ class CronUploader extends Extension public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) { - if($event->parent=="system") { + if ($event->parent=="system") { $event->add_nav_link("cron_docs", new Link('cron_upload'), "Cron Upload"); } } @@ -58,7 +58,7 @@ class CronUploader extends Extension $sb->add_int_option(CronUploaderConfig::COUNT, "Upload per run", true); $sb->add_text_option(CronUploaderConfig::DIR, "Root dir", true); $sb->add_text_option(CronUploaderConfig::KEY, "Key", true); - $sb->add_choice_option(CronUploaderConfig::USER, $users,"User", true); + $sb->add_choice_option(CronUploaderConfig::USER, $users, "User", true); $sb->end_table(); $sb->add_label("Read the documentation for cron setup instructions."); @@ -130,7 +130,7 @@ class CronUploader extends Extension $results = get_dir_contents($stage_dir); if (count($results) == 0) { - if(rmdir($stage_dir)===false) { + if (rmdir($stage_dir)===false) { flash_message("Nothing to stage from $folder, cannot remove folder"); } else { flash_message("Nothing to stage from $folder, removing folder"); @@ -203,24 +203,29 @@ class CronUploader extends Extension } $this->theme->display_documentation( - $running, $queue_dirinfo, $uploaded_dirinfo, $failed_dirinfo, - $this->get_cron_cmd(), $this->get_cron_url(), $logs + $running, + $queue_dirinfo, + $uploaded_dirinfo, + $failed_dirinfo, + $this->get_cron_cmd(), + $this->get_cron_url(), + $logs ); } - function get_queue_dir() + public function get_queue_dir() { $dir = CronUploaderConfig::get_dir(); return join_path($dir, self::QUEUE_DIR); } - function get_uploaded_dir() + public function get_uploaded_dir() { $dir = CronUploaderConfig::get_dir(); return join_path($dir, self::UPLOADED_DIR); } - function get_failed_dir() + public function get_failed_dir() { $dir = CronUploaderConfig::get_dir(); return join_path($dir, self::FAILED_DIR); @@ -262,7 +267,7 @@ class CronUploader extends Extension throw new SCoreException("Cron upload key incorrect"); } $user_id = CronUploaderConfig::get_user(); - if(empty($user_id)) { + if (empty($user_id)) { throw new SCoreException("Cron upload user not set"); } $user = User::by_id($user_id); @@ -329,8 +334,6 @@ class CronUploader extends Extension $this->move_uploaded($img[0], $img[1], $output_subdir, true); $this->log_message(SCORE_LOG_ERROR, "(" . gettype($e) . ") " . $e->getMessage()); $this->log_message(SCORE_LOG_ERROR, $e->getTraceAsString()); - - } } @@ -348,14 +351,13 @@ class CronUploader extends Extension flock($lockfile, LOCK_UN); fclose($lockfile); } - } private function move_uploaded(string $path, string $filename, string $output_subdir, bool $corrupt = false) { $relativeDir = dirname(substr($path, strlen(CronUploaderConfig::get_dir()) + 7)); - if($relativeDir==".") { + if ($relativeDir==".") { $relativeDir = ""; } @@ -424,10 +426,11 @@ class CronUploader extends Extension private const PARTIAL_DOWNLOAD_EXTENSIONS = ['crdownload','part']; - private function is_skippable_file(string $path) { + private function is_skippable_file(string $path) + { $info = pathinfo($path); - if(in_array(strtolower($info['extension']),self::PARTIAL_DOWNLOAD_EXTENSIONS)) { + if (in_array(strtolower($info['extension']), self::PARTIAL_DOWNLOAD_EXTENSIONS)) { return true; } @@ -499,4 +502,3 @@ class CronUploader extends Extension $page->set_data(implode("\r\n", $this->output_buffer)); } } - diff --git a/ext/cron_uploader/theme.php b/ext/cron_uploader/theme.php index 8c438d23..0b53dbf8 100644 --- a/ext/cron_uploader/theme.php +++ b/ext/cron_uploader/theme.php @@ -2,9 +2,15 @@ class CronUploaderTheme extends Themelet { - public function display_documentation(bool $running, array $queue_dirinfo, array $uploaded_dirinfo, array $failed_dirinfo, - string $cron_cmd, string $cron_url, ?array $log_entries) - { + public function display_documentation( + bool $running, + array $queue_dirinfo, + array $uploaded_dirinfo, + array $failed_dirinfo, + string $cron_cmd, + string $cron_url, + ?array $log_entries + ) { global $page; @@ -51,7 +57,7 @@ class CronUploaderTheme extends Themelet
When you create the cron job, you choose when to upload new images. "; - $usage_html = "Upload your images you want to be uploaded to the queue directory using your FTP client or other means. + $usage_html = "Upload your images you want to be uploaded to the queue directory using your FTP client or other means.
({$queue_dirinfo['path']})
  1. Any sub-folders will be turned into tags.
  2. @@ -81,9 +87,9 @@ class CronUploaderTheme extends Themelet $page->add_block($block_install); $page->add_block($block_usage); - if(!empty($log_entries)) { + if (!empty($log_entries)) { $log_html = "
TimeModuleUserMessage

"; - foreach($log_entries as $entry) { + foreach ($log_entries as $entry) { $log_html .= ""; } $log_html .= "
{$entry["date_sent"]}{$entry["message"]}
"; @@ -111,13 +117,13 @@ class CronUploaderTheme extends Themelet $html .= ""; $html .= ""; - $html .= make_form(make_link("admin/cron_uploader_clear_queue"), "POST",false,"","return confirm('Are you sure you want to delete everything in the queue folder?');") + $html .= make_form(make_link("admin/cron_uploader_clear_queue"), "POST", false, "", "return confirm('Are you sure you want to delete everything in the queue folder?');") ."
" ."
"; - $html .= make_form(make_link("admin/cron_uploader_clear_uploaded"), "POST",false,"","return confirm('Are you sure you want to delete everything in the uploaded folder?');") + $html .= make_form(make_link("admin/cron_uploader_clear_uploaded"), "POST", false, "", "return confirm('Are you sure you want to delete everything in the uploaded folder?');") ."
" ."
"; - $html .= make_form(make_link("admin/cron_uploader_clear_failed"), "POST",false,"","return confirm('Are you sure you want to delete everything in the failed folder?');") + $html .= make_form(make_link("admin/cron_uploader_clear_failed"), "POST", false, "", "return confirm('Are you sure you want to delete everything in the failed folder?');") ."
" ."
"; $html .= "\n"; diff --git a/ext/danbooru_api/main.php b/ext/danbooru_api/main.php index b7aa61ea..dfbce69a 100644 --- a/ext/danbooru_api/main.php +++ b/ext/danbooru_api/main.php @@ -90,8 +90,10 @@ class DanbooruApi extends Extension } elseif (isset($_GET['name'])) { $namelist = explode(",", $_GET['name']); foreach ($namelist as $name) { - $sqlresult = $database->get_all($database->scoreql_to_sql( - "SELECT id,tag,count FROM tags WHERE SCORE_STRNORM(tag) = SCORE_STRNORM(?)"), + $sqlresult = $database->get_all( + $database->scoreql_to_sql( + "SELECT id,tag,count FROM tags WHERE SCORE_STRNORM(tag) = SCORE_STRNORM(?)" + ), [$name] ); foreach ($sqlresult as $row) { diff --git a/ext/downtime/theme.php b/ext/downtime/theme.php index 99c4cffc..1399dbbb 100644 --- a/ext/downtime/theme.php +++ b/ext/downtime/theme.php @@ -66,6 +66,6 @@ class DowntimeTheme extends Themelet EOD -); + ); } } diff --git a/ext/favorites/main.php b/ext/favorites/main.php index c213c283..66200eaf 100644 --- a/ext/favorites/main.php +++ b/ext/favorites/main.php @@ -242,7 +242,7 @@ class Favorites extends Extension { global $database; if ($do_set) { - if(!$database->exists("select 1 from user_favorites where image_id=:image_id and user_id=:user_id",["image_id"=>$image_id, "user_id"=>$user_id])) { + if (!$database->exists("select 1 from user_favorites where image_id=:image_id and user_id=:user_id", ["image_id"=>$image_id, "user_id"=>$user_id])) { $database->Execute( "INSERT INTO user_favorites(image_id, user_id, created_at) VALUES(:image_id, :user_id, NOW())", ["image_id"=>$image_id, "user_id"=>$user_id] diff --git a/ext/forum/main.php b/ext/forum/main.php index e4c60df4..a1c5d410 100644 --- a/ext/forum/main.php +++ b/ext/forum/main.php @@ -269,7 +269,7 @@ class Forum extends Extension "GROUP BY f.id, f.sticky, f.title, f.date, u.name, u.email, u.class ". "ORDER BY f.sticky ASC, f.uptodate DESC LIMIT :limit OFFSET :offset", ["limit"=>$threadsPerPage, "offset"=>$pageNumber * $threadsPerPage] - ); + ); $this->theme->display_thread_list($page, $threads, $showAdminOptions, $pageNumber + 1, $totalPages); } @@ -302,7 +302,7 @@ class Forum extends Extension "ORDER BY p.date ASC ". "LIMIT :limit OFFSET :offset", ["thread_id"=>$threadID, "offset"=>$pageNumber * $postsPerPage, "limit"=>$postsPerPage] - ); + ); $this->theme->display_thread($posts, $showAdminOptions, $threadTitle, $threadID, $pageNumber + 1, $totalPages); } diff --git a/ext/help_pages/main.php b/ext/help_pages/main.php index 90206d00..8238f875 100644 --- a/ext/help_pages/main.php +++ b/ext/help_pages/main.php @@ -37,7 +37,7 @@ class HelpPages extends Extension private function get_pages(): array { - if($this->pages==null) { + if ($this->pages==null) { $e = new HelpPageListBuildingEvent(); send_event($e); $this->pages = $e->pages; @@ -52,8 +52,6 @@ class HelpPages extends Extension $pages = $this->get_pages(); if ($event->page_matches("help")) { - - if ($event->count_args() == 0) { $name = array_key_first($pages); $page->set_mode(PageMode::REDIRECT); @@ -63,7 +61,7 @@ class HelpPages extends Extension $page->set_mode(PageMode::PAGE); $name = $event->get_arg(0); $title = $name; - if(array_key_exists($name, $pages)) { + if (array_key_exists($name, $pages)) { $title = $pages[$name]; } else { return; @@ -97,10 +95,10 @@ class HelpPages extends Extension public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) { - if($event->parent=="help") { + if ($event->parent=="help") { $pages = $this->get_pages(); foreach ($pages as $key=>$value) { - $event->add_nav_link("help_".$key, new Link('help/'.$key),$value); + $event->add_nav_link("help_".$key, new Link('help/'.$key), $value); } } } diff --git a/ext/home/theme.php b/ext/home/theme.php index 8dfc666d..d0ec1f2d 100644 --- a/ext/home/theme.php +++ b/ext/home/theme.php @@ -22,7 +22,7 @@ class HomeTheme extends Themelet EOD -); + ); } public function build_body(string $sitename, string $main_links, string $main_text, string $contact_link, $num_comma, string $counter_text) diff --git a/ext/media/config.php b/ext/media/config.php index 32814594..99a18aab 100644 --- a/ext/media/config.php +++ b/ext/media/config.php @@ -6,5 +6,4 @@ abstract class MediaConfig const CONVERT_PATH = "media_convert_path"; const VERSION = "ext_media_version"; const MEM_LIMIT = 'media_mem_limit'; - } diff --git a/ext/media/events.php b/ext/media/events.php index d996e43e..d33afa97 100644 --- a/ext/media/events.php +++ b/ext/media/events.php @@ -14,14 +14,19 @@ class MediaResizeEvent extends Event public $ignore_aspect_ratio; public $allow_upscale; - public function __construct(String $engine, string $input_path, string $input_type, string $output_path, - int $target_width, int $target_height, - bool $ignore_aspect_ratio = false, - string $target_format = null, - int $target_quality = 80, - bool $minimize = false, - bool $allow_upscale = true) - { + public function __construct( + String $engine, + string $input_path, + string $input_type, + string $output_path, + int $target_width, + int $target_height, + bool $ignore_aspect_ratio = false, + string $target_format = null, + int $target_quality = 80, + bool $minimize = false, + bool $allow_upscale = true + ) { assert(in_array($engine, MediaEngine::ALL)); $this->engine = $engine; $this->input_path = $input_path; @@ -54,5 +59,4 @@ class MediaCheckPropertiesEvent extends Event $this->file_name = $file_name; $this->ext = $ext; } - } diff --git a/ext/media/main.php b/ext/media/main.php index 9c1eb5c0..25f2ddde 100644 --- a/ext/media/main.php +++ b/ext/media/main.php @@ -265,7 +265,7 @@ class Media extends Extension $matches = []; if (preg_match(self::CONTENT_SEARCH_TERM_REGEX, $event->term, $matches)) { $field = $matches[1]; - if($field==="unknown") { + if ($field==="unknown") { $event->add_querylet(new Querylet($database->scoreql_to_sql("video IS NULL OR audio IS NULL OR image IS NULL"))); } else { $event->add_querylet(new Querylet($database->scoreql_to_sql("$field = SCORE_BOOL_Y"))); @@ -814,7 +814,7 @@ class Media extends Extension $new_height, $width, $height - ) === false) { + ) === false) { throw new MediaException("Unable to copy resized image data to new image"); } @@ -1039,7 +1039,7 @@ class Media extends Extension "ALTER TABLE images ADD COLUMN image SCORE_BOOL NULL" )); - switch($database->get_driver_name()) { + switch ($database->get_driver_name()) { case DatabaseDriver::PGSQL: case DatabaseDriver::SQLITE: $database->execute('CREATE INDEX images_image_idx ON images(image) WHERE image IS NOT NULL'); @@ -1052,7 +1052,7 @@ class Media extends Extension $database->set_timeout(300000); // These updates can take a little bit if ($database->transaction === true) { - $database->commit(); // Each of these commands could hit a lot of data, combining them into one big transaction would not be a good idea. + $database->commit(); // Each of these commands could hit a lot of data, combining them into one big transaction would not be a good idea. } log_info("upgrade", "Setting predictable media values for known file types"); $database->execute($database->scoreql_to_sql("UPDATE images SET image = SCORE_BOOL_N WHERE ext IN ('swf','mp3','ani','flv','mp4','m4v','ogv','webm')")); diff --git a/ext/not_a_tag/main.php b/ext/not_a_tag/main.php index c788077c..83004f49 100644 --- a/ext/not_a_tag/main.php +++ b/ext/not_a_tag/main.php @@ -55,7 +55,7 @@ class NotATag extends Extension public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) { global $user; - if($event->parent==="tags") { + if ($event->parent==="tags") { if ($user->can(Permissions::BAN_IMAGE)) { $event->add_nav_link("untags", new Link('untag/list/1'), "UnTags"); } diff --git a/ext/ouroboros_api/main.php b/ext/ouroboros_api/main.php index dfc4aa5c..4766950b 100644 --- a/ext/ouroboros_api/main.php +++ b/ext/ouroboros_api/main.php @@ -472,7 +472,7 @@ class OuroborosAPI extends Extension if (empty($post->file) && !empty($post->file_url) && filter_var( $post->file_url, FILTER_VALIDATE_URL - ) !== false + ) !== false ) { // Transload from source $meta['file'] = tempnam('/tmp', 'shimmie_transload_' . $config->get_string('transload_engine')); diff --git a/ext/pools/main.php b/ext/pools/main.php index 15e36c99..6205a8f2 100644 --- a/ext/pools/main.php +++ b/ext/pools/main.php @@ -818,7 +818,7 @@ class Pools extends Extension SELECT COUNT(*) FROM pool_images p $query", ["pid" => $poolID] - ) / $imagesPerPage); + ) / $imagesPerPage); diff --git a/ext/rating/main.php b/ext/rating/main.php index 2386c3b0..c939b00b 100644 --- a/ext/rating/main.php +++ b/ext/rating/main.php @@ -341,7 +341,7 @@ class Ratings extends Extension $old = $_POST["rating_old"]; $new = $_POST["rating_new"]; - if($user->can(Permissions::BULK_EDIT_IMAGE_RATING)) { + if ($user->can(Permissions::BULK_EDIT_IMAGE_RATING)) { $database->execute("UPDATE images SET rating = :new WHERE rating = :old", ["new"=>$new, "old"=>$old ]); } diff --git a/ext/trash/main.php b/ext/trash/main.php index 8d29dd62..d3772a68 100644 --- a/ext/trash/main.php +++ b/ext/trash/main.php @@ -63,9 +63,9 @@ class Trash extends Extension public function onPageSubNavBuilding(PageSubNavBuildingEvent $event) { global $user; - if($event->parent=="posts") { - if($user->can(Permissions::VIEW_TRASH)) { - $event->add_nav_link("posts_trash", new Link('/post/list/in%3Atrash/1'), "Trash",null, 60); + if ($event->parent=="posts") { + if ($user->can(Permissions::VIEW_TRASH)) { + $event->add_nav_link("posts_trash", new Link('/post/list/in%3Atrash/1'), "Trash", null, 60); } } } diff --git a/ext/upload/main.php b/ext/upload/main.php index 9c7879ad..25a0daf9 100644 --- a/ext/upload/main.php +++ b/ext/upload/main.php @@ -35,6 +35,9 @@ class DataUploadEvent extends Event assert(is_array($metadata["tags"])); assert(is_string($metadata["source"]) || is_null($metadata["source"])); + // DB limits to 64 char filenames + $metadata['filename'] = substr($metadata['filename'], 0, 63); + $this->metadata = $metadata; $this->set_tmpname($tmpname); diff --git a/themes/material/home.theme.php b/themes/material/home.theme.php index ada70b17..c878d3c2 100644 --- a/themes/material/home.theme.php +++ b/themes/material/home.theme.php @@ -25,7 +25,7 @@ class CustomHomeTheme extends HomeTheme EOD -); + ); } public function build_body(string $sitename, string $main_links, string $main_text, string $contact_link, $num_comma, string $counter_text) From b568933f45f1b69e28a8e1ab1c25f3858e572cc9 Mon Sep 17 00:00:00 2001 From: Shish Date: Sat, 2 Nov 2019 20:19:09 +0000 Subject: [PATCH 29/30] remove extension metadata comments (we have metadata objects now) --- ext/admin/info.php | 10 - ext/alias_editor/info.php | 9 - ext/arrowkey_navigation/info.php | 10 +- ext/artists/info.php | 9 - ext/autocomplete/info.php | 6 - ext/ban_words/info.php | 10 - ext/bbcode/info.php | 8 - ext/blocks/info.php | 8 - ext/blotter/info.php | 6 - ext/browser_search/info.php | 12 -- ext/bulk_actions/info.php | 10 - ext/bulk_add/info.php | 11 +- ext/bulk_add_csv/info.php | 10 - ext/bulk_remove/info.php | 9 - ext/comment/info.php | 10 - ext/custom_html_headers/info.php | 9 - ext/danbooru_api/info.php | 8 - ext/downtime/info.php | 10 - ext/emoticons/info.php | 10 - ext/et/info.php | 8 - ext/ext_manager/info.php | 10 - ext/favorites/info.php | 8 - ext/featured/info.php | 10 - ext/forum/info.php | 9 - ext/google_analytics/info.php | 9 - ext/handle_404/info.php | 8 - ext/handle_archive/info.php | 8 - ext/handle_flash/info.php | 7 - ext/handle_ico/info.php | 6 - ext/handle_mp3/info.php | 6 - ext/handle_pixel/info.php | 7 - ext/handle_static/info.php | 9 - ext/handle_svg/info.php | 7 - ext/handle_video/info.php | 9 - ext/help_pages/info.php | 6 - ext/holiday/info.php | 7 - ext/home/info.php | 10 - ext/image/info.php | 9 - ext/image_hash_ban/info.php | 10 - ext/image_hash_ban/theme.php | 10 - ext/image_view_counter/info.php | 9 - ext/index/info.php | 302 +++++++++++++++---------------- ext/ipban/info.php | 10 - ext/link_image/info.php | 29 ++- ext/link_image/readme.txt | 82 --------- ext/livefeed/info.php | 9 - ext/log_db/info.php | 8 - ext/log_logstash/info.php | 8 - ext/log_net/info.php | 8 - ext/mail/info.php | 8 - ext/media/info.php | 6 - ext/not_a_tag/info.php | 7 - ext/notes/info.php | 8 - ext/numeric_score/info.php | 9 - ext/oekaki/info.php | 6 - ext/ouroboros_api/info.php | 10 - ext/pm/info.php | 9 - ext/pm_triggers/info.php | 7 - ext/pools/info.php | 8 - ext/post_titles/info.php | 6 - ext/qr_code/info.php | 6 +- ext/random_image/info.php | 10 - ext/random_list/info.php | 10 - ext/rating/info.php | 9 - ext/regen_thumb/info.php | 8 - ext/relationships/info.php | 7 - ext/report_image/info.php | 10 - ext/report_image/theme.php | 10 - ext/res_limit/info.php | 7 - ext/resize/info.php | 7 - ext/rotate/info.php | 7 - ext/rss_comments/info.php | 8 - ext/rss_images/info.php | 7 - ext/rule34/info.php | 9 - ext/setup/info.php | 7 - ext/shimmie_api/info.php | 9 - ext/site_description/info.php | 10 - ext/sitemap/info.php | 10 - ext/source_history/info.php | 6 - ext/statsd/info.php | 10 - ext/system/info.php | 6 - ext/tag_categories/info.php | 6 - ext/tag_edit/info.php | 7 - ext/tag_editcloud/info.php | 8 - ext/tag_history/info.php | 6 - ext/tag_history/theme.php | 11 +- ext/tag_list/info.php | 7 - ext/tagger/info.php | 7 - ext/tips/info.php | 10 - ext/transcode/info.php | 8 - ext/trash/info.php | 7 - ext/update/info.php | 8 - ext/upgrade/info.php | 8 - ext/upload/info.php | 7 - ext/user/info.php | 6 - ext/user_config/info.php | 7 - ext/varnish/info.php | 8 - ext/view/info.php | 7 - ext/wiki/info.php | 9 - ext/word_filter/info.php | 8 - 100 files changed, 176 insertions(+), 1039 deletions(-) delete mode 100644 ext/link_image/readme.txt diff --git a/ext/admin/info.php b/ext/admin/info.php index 84db9927..bdaafa4a 100644 --- a/ext/admin/info.php +++ b/ext/admin/info.php @@ -1,15 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Description: Various things to make admins' lives easier - * Documentation: - - */ - class AdminPageInfo extends ExtensionInfo { public const KEY = "admin"; diff --git a/ext/alias_editor/info.php b/ext/alias_editor/info.php index 4990ac6d..b846b815 100644 --- a/ext/alias_editor/info.php +++ b/ext/alias_editor/info.php @@ -1,14 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Description: Edit the alias list - * Documentation: - */ - class AliasEditorInfo extends ExtensionInfo { public const KEY = "alias_editor"; diff --git a/ext/arrowkey_navigation/info.php b/ext/arrowkey_navigation/info.php index ee6b88f2..4d0a2f38 100644 --- a/ext/arrowkey_navigation/info.php +++ b/ext/arrowkey_navigation/info.php @@ -1,13 +1,5 @@ - * Link: http://www.drudexsoftware.com/ - * License: GPLv2 - * Description: Allows viewers no navigate between images using the left & right arrow keys. - * Documentation: - * Simply enable this extention in the extention manager to enable arrow key navigation. - */ + class ArrowkeyNavigationInfo extends ExtensionInfo { public const KEY = "arrowkey_navigation"; diff --git a/ext/artists/info.php b/ext/artists/info.php index 5da88896..efdc77a9 100644 --- a/ext/artists/info.php +++ b/ext/artists/info.php @@ -1,14 +1,5 @@ - * Alpha - * License: GPLv2 - * Description: Simple artists extension - * Documentation: - * - */ class ArtistsInfo extends ExtensionInfo { public const KEY = "artists"; diff --git a/ext/autocomplete/info.php b/ext/autocomplete/info.php index 3d420496..259ab70b 100644 --- a/ext/autocomplete/info.php +++ b/ext/autocomplete/info.php @@ -1,11 +1,5 @@ - * Description: Adds autocomplete to search & tagging. - */ - class AutoCompleteInfo extends ExtensionInfo { public const KEY = "autocomplete"; diff --git a/ext/ban_words/info.php b/ext/ban_words/info.php index 6b56c045..b816b89c 100644 --- a/ext/ban_words/info.php +++ b/ext/ban_words/info.php @@ -1,15 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Description: For stopping spam and other comment abuse - * Documentation: - * - */ - class BanWordsInfo extends ExtensionInfo { public const KEY = "ban_words"; diff --git a/ext/bbcode/info.php b/ext/bbcode/info.php index 06798aab..d97ae411 100644 --- a/ext/bbcode/info.php +++ b/ext/bbcode/info.php @@ -1,13 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Description: Turns BBCode into HTML - */ - class BBCodeInfo extends ExtensionInfo { public const KEY = "bbcode"; diff --git a/ext/blocks/info.php b/ext/blocks/info.php index 23d24604..2bf68f2b 100644 --- a/ext/blocks/info.php +++ b/ext/blocks/info.php @@ -1,13 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Description: Add HTML to some space (News, Ads, etc) - */ - class BlocksInfo extends ExtensionInfo { public const KEY = "blocks"; diff --git a/ext/blotter/info.php b/ext/blotter/info.php index d03891ec..7fab798c 100644 --- a/ext/blotter/info.php +++ b/ext/blotter/info.php @@ -1,11 +1,5 @@ [http://seemslegit.com/] - * License: GPLv2 - * Description: - */ class BlotterInfo extends ExtensionInfo { public const KEY = "blotter"; diff --git a/ext/browser_search/info.php b/ext/browser_search/info.php index ba353e4c..34360c5b 100644 --- a/ext/browser_search/info.php +++ b/ext/browser_search/info.php @@ -1,17 +1,5 @@ - * Some code (and lots of help) by Artanis (Erik Youngren ) from the 'tagger' extention - Used with permission - * Link: http://atravelinggeek.com/ - * License: GPLv2 - * Description: Allows the user to add a browser 'plugin' to search the site with real-time suggestions - * Version: 0.1c, October 26, 2007 - * Documentation: - * - */ - class BrowserSearchInfo extends ExtensionInfo { public const KEY = "browser_search"; diff --git a/ext/bulk_actions/info.php b/ext/bulk_actions/info.php index 00c66576..76158a76 100644 --- a/ext/bulk_actions/info.php +++ b/ext/bulk_actions/info.php @@ -1,15 +1,5 @@ , contributions by Shish and Agasa. - */ - - class BulkActionsInfo extends ExtensionInfo { public const KEY = "bulk_actions"; diff --git a/ext/bulk_add/info.php b/ext/bulk_add/info.php index f7624604..1d25d373 100644 --- a/ext/bulk_add/info.php +++ b/ext/bulk_add/info.php @@ -1,14 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Description: Bulk add server-side images - * Documentation: - */ - class BulkAddInfo extends ExtensionInfo { public const KEY = "bulk_add"; @@ -20,7 +11,7 @@ class BulkAddInfo extends ExtensionInfo public $license = self::LICENSE_GPLV2; public $description = "Bulk add server-side images"; public $documentation = -" Upload the images into a new directory via ftp or similar, go to +"Upload the images into a new directory via ftp or similar, go to shimmie's admin page and put that directory in the bulk add box. If there are subdirectories, they get used as tags (eg if you upload into /home/bob/uploads/holiday/2008/ and point diff --git a/ext/bulk_add_csv/info.php b/ext/bulk_add_csv/info.php index a2e6af69..30a407eb 100644 --- a/ext/bulk_add_csv/info.php +++ b/ext/bulk_add_csv/info.php @@ -1,15 +1,5 @@ - * License: GPLv2 - * Description: Bulk add server-side images with metadata from CSV file - * Documentation: - * - * - */ - class BulkAddCSVInfo extends ExtensionInfo { public const KEY = "bulk_add_csv"; diff --git a/ext/bulk_remove/info.php b/ext/bulk_remove/info.php index 7f90b825..6a48ee2b 100644 --- a/ext/bulk_remove/info.php +++ b/ext/bulk_remove/info.php @@ -1,14 +1,5 @@ - * Link: http://www.drudexsoftware.com/ - * License: GPLv2 - * Description: Allows admin to delete many images at once through Board Admin. - * Documentation: - * - */ class BulkRemoveInfo extends ExtensionInfo { public const KEY = "bulk_remove"; diff --git a/ext/comment/info.php b/ext/comment/info.php index 600d1eab..38191656 100644 --- a/ext/comment/info.php +++ b/ext/comment/info.php @@ -1,15 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Description: Allow users to make comments on images - * Documentation: - * Formatting is done with the standard formatting API (normally BBCode) - */ - class CommentListInfo extends ExtensionInfo { public const KEY = "comment"; diff --git a/ext/custom_html_headers/info.php b/ext/custom_html_headers/info.php index 5ac483d3..617ce791 100644 --- a/ext/custom_html_headers/info.php +++ b/ext/custom_html_headers/info.php @@ -1,14 +1,5 @@ - * Link: http://www.drudexsoftware.com - * License: GPLv2 - * Description: Allows admins to modify & set custom <head> content - * Documentation: - * - */ class CustomHtmlHeadersInfo extends ExtensionInfo { public const KEY = "custom_html_headers"; diff --git a/ext/danbooru_api/info.php b/ext/danbooru_api/info.php index 89047d3b..fd68c229 100644 --- a/ext/danbooru_api/info.php +++ b/ext/danbooru_api/info.php @@ -1,13 +1,5 @@ -Description: Allow Danbooru apps like Danbooru Uploader for Firefox to communicate with Shimmie -Documentation: - -*/ - class DanbooruApiInfo extends ExtensionInfo { public const KEY = "danbooru_api"; diff --git a/ext/downtime/info.php b/ext/downtime/info.php index fd8df943..671af143 100644 --- a/ext/downtime/info.php +++ b/ext/downtime/info.php @@ -1,15 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Description: Show a "down for maintenance" page - * Documentation: - * - */ - class DowntimeInfo extends ExtensionInfo { public const KEY = "downtime"; diff --git a/ext/emoticons/info.php b/ext/emoticons/info.php index 8c19165d..e2f44cdd 100644 --- a/ext/emoticons/info.php +++ b/ext/emoticons/info.php @@ -1,15 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Description: Lets users use graphical smilies - * Documentation: - * - */ - class EmoticonsInfo extends ExtensionInfo { public const KEY = "emoticons"; diff --git a/ext/et/info.php b/ext/et/info.php index 3245f10c..297647aa 100644 --- a/ext/et/info.php +++ b/ext/et/info.php @@ -1,13 +1,5 @@ - * License: GPLv2 - * Description: Show various bits of system information - * Documentation: - */ - class ETInfo extends ExtensionInfo { public const KEY = "et"; diff --git a/ext/ext_manager/info.php b/ext/ext_manager/info.php index 80ade6e9..6c979d5e 100644 --- a/ext/ext_manager/info.php +++ b/ext/ext_manager/info.php @@ -1,15 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Visibility: admin - * Description: A thing for point & click extension management - * Documentation: - */ - class ExtManagerInfo extends ExtensionInfo { public const KEY = "ext_manager"; diff --git a/ext/favorites/info.php b/ext/favorites/info.php index 0e49b8d1..7d6ab844 100644 --- a/ext/favorites/info.php +++ b/ext/favorites/info.php @@ -1,13 +1,5 @@ - * License: GPLv2 - * Description: Allow users to favorite images - * Documentation: - */ - class FavoritesInfo extends ExtensionInfo { public const KEY = "favorites"; diff --git a/ext/featured/info.php b/ext/featured/info.php index b28277e1..c677f582 100644 --- a/ext/featured/info.php +++ b/ext/featured/info.php @@ -1,15 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Description: Bring a specific image to the users' attentions - * Documentation: - * - */ - class FeaturedInfo extends ExtensionInfo { public const KEY = "featured"; diff --git a/ext/forum/info.php b/ext/forum/info.php index 5671e8b2..a7d5a72d 100644 --- a/ext/forum/info.php +++ b/ext/forum/info.php @@ -1,14 +1,5 @@ - * Alpha - * License: GPLv2 - * Description: Rough forum extension - * Documentation: - */ - class ForumInfo extends ExtensionInfo { public const KEY = "dorum"; diff --git a/ext/google_analytics/info.php b/ext/google_analytics/info.php index a62cc880..f81d4fde 100644 --- a/ext/google_analytics/info.php +++ b/ext/google_analytics/info.php @@ -1,14 +1,5 @@ - * Link: http://drudexsoftware.com - * License: GPLv2 - * Description: Integrates Google Analytics tracking - * Documentation: - * - */ class GoogleAnalyticsInfo extends ExtensionInfo { public const KEY = "google_analytics"; diff --git a/ext/handle_404/info.php b/ext/handle_404/info.php index f18367c8..f32d74cd 100644 --- a/ext/handle_404/info.php +++ b/ext/handle_404/info.php @@ -1,13 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Visibility: admin - * Description: If no other extension puts anything onto the page, show 404 - */ class Handle404Info extends ExtensionInfo { public const KEY = "handle_404"; diff --git a/ext/handle_archive/info.php b/ext/handle_archive/info.php index 174e18d3..078d2001 100644 --- a/ext/handle_archive/info.php +++ b/ext/handle_archive/info.php @@ -1,13 +1,5 @@ - * Description: Allow users to upload archives (zip, etc) - * Documentation: - * - */ - class ArchiveFileHandlerInfo extends ExtensionInfo { public const KEY = "handle_archive"; diff --git a/ext/handle_flash/info.php b/ext/handle_flash/info.php index 9d997aaa..642cf64c 100644 --- a/ext/handle_flash/info.php +++ b/ext/handle_flash/info.php @@ -1,12 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * Description: Handle Flash files. - */ - class FlashFileHandlerInfo extends ExtensionInfo { public const KEY = "handle_flash"; diff --git a/ext/handle_ico/info.php b/ext/handle_ico/info.php index 64ba9984..90419d79 100644 --- a/ext/handle_ico/info.php +++ b/ext/handle_ico/info.php @@ -1,11 +1,5 @@ - * Description: Handle windows icons - */ - class IcoFileHandlerInfo extends ExtensionInfo { public const KEY = "handle_ico"; diff --git a/ext/handle_mp3/info.php b/ext/handle_mp3/info.php index df17f2ad..9bf9093b 100644 --- a/ext/handle_mp3/info.php +++ b/ext/handle_mp3/info.php @@ -1,11 +1,5 @@ - * Description: Handle MP3 files - */ - class MP3FileHandlerInfo extends ExtensionInfo { public const KEY = "handle_mp3"; diff --git a/ext/handle_pixel/info.php b/ext/handle_pixel/info.php index 2dc2d17c..03095f7c 100644 --- a/ext/handle_pixel/info.php +++ b/ext/handle_pixel/info.php @@ -1,12 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * Description: Handle JPEG, PNG, GIF, WEBP, etc files - */ - class PixelFileHandlerInfo extends ExtensionInfo { public const KEY = "handle_pixel"; diff --git a/ext/handle_static/info.php b/ext/handle_static/info.php index 1ba6ea9c..14a61a34 100644 --- a/ext/handle_static/info.php +++ b/ext/handle_static/info.php @@ -1,14 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Visibility: admin - * Description: If Shimmie can't handle a request, check static files ($theme/static/$filename, then ext/handle_static/static/$filename) - */ - class HandleStaticInfo extends ExtensionInfo { public const KEY = "handle_static"; diff --git a/ext/handle_svg/info.php b/ext/handle_svg/info.php index 68e59cb8..50acfdce 100644 --- a/ext/handle_svg/info.php +++ b/ext/handle_svg/info.php @@ -1,12 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * Description: Handle static SVG files. - */ - class SVGFileHandlerInfo extends ExtensionInfo { public const KEY = "handle_svg"; diff --git a/ext/handle_video/info.php b/ext/handle_video/info.php index 52c357c3..7c7ad713 100644 --- a/ext/handle_video/info.php +++ b/ext/handle_video/info.php @@ -1,14 +1,5 @@ - * Modified By: Shish , jgen , im-mi - * License: GPLv2 - * Description: Handle FLV, MP4, OGV and WEBM video files. - * Documentation: - */ - class VideoFileHandlerInfo extends ExtensionInfo { public const KEY = "handle_video"; diff --git a/ext/help_pages/info.php b/ext/help_pages/info.php index 58845be2..1375ef51 100644 --- a/ext/help_pages/info.php +++ b/ext/help_pages/info.php @@ -1,11 +1,5 @@ - * Description: Provides documentation screens - */ - class HelpPagesInfo extends ExtensionInfo { public const KEY = "help_pages"; diff --git a/ext/holiday/info.php b/ext/holiday/info.php index 92bcd521..6f291436 100644 --- a/ext/holiday/info.php +++ b/ext/holiday/info.php @@ -1,12 +1,5 @@ - * Link: http://www.codeanimu.net - * License: GPLv2 - * Description: Use an additional stylesheet on certain holidays. - */ class HolidayInfo extends ExtensionInfo { public const KEY = "holiday"; diff --git a/ext/home/info.php b/ext/home/info.php index 4d248371..84087de8 100644 --- a/ext/home/info.php +++ b/ext/home/info.php @@ -1,15 +1,5 @@ -* License: GPLv2 -* Visibility: admin -* Description: Displays a front page with logo, search box and image count -* Documentation: -* -*/ - class HomeInfo extends ExtensionInfo { public const KEY = "home"; diff --git a/ext/image/info.php b/ext/image/info.php index 8dee38fd..30ad53bd 100644 --- a/ext/image/info.php +++ b/ext/image/info.php @@ -1,14 +1,5 @@ - * Modified by: jgen - * Link: http://code.shishnet.org/shimmie2/ - * Description: Handle the image database - * Visibility: admin - */ - class ImageIOInfo extends ExtensionInfo { public const KEY = "image"; diff --git a/ext/image_hash_ban/info.php b/ext/image_hash_ban/info.php index d165286f..a3080331 100644 --- a/ext/image_hash_ban/info.php +++ b/ext/image_hash_ban/info.php @@ -1,15 +1,5 @@ - * Link: http://atravelinggeek.com/ - * License: GPLv2 - * Description: Ban images based on their hash - * Based on the ResolutionLimit and IPban extensions by Shish - * Version 0.1, October 21, 2007 - */ - class ImageBanInfo extends ExtensionInfo { public const KEY = "image_hash_ban"; diff --git a/ext/image_hash_ban/theme.php b/ext/image_hash_ban/theme.php index 53bf6139..5a3afd99 100644 --- a/ext/image_hash_ban/theme.php +++ b/ext/image_hash_ban/theme.php @@ -1,14 +1,4 @@ - * Link: http://atravelinggeek.com/ - * License: GPLv2 - * Description: Ban images based on their hash - * Based on the ResolutionLimit and IPban extensions by Shish - * Version 0.1 - * October 21, 2007 - */ class ImageBanTheme extends Themelet { diff --git a/ext/image_view_counter/info.php b/ext/image_view_counter/info.php index 2cea0069..e9dede91 100644 --- a/ext/image_view_counter/info.php +++ b/ext/image_view_counter/info.php @@ -1,14 +1,5 @@ - * Link: http://www.drudexsoftware.com/ - * License: GPLv2 - * Description: Tracks & displays how many times an image is viewed - * Documentation: - * - */ class ImageViewCounterInfo extends ExtensionInfo { public const KEY = "image_view_counter"; diff --git a/ext/index/info.php b/ext/index/info.php index 9987f569..6f46c2ef 100644 --- a/ext/index/info.php +++ b/ext/index/info.php @@ -1,160 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Description: Show a list of uploaded images - * Documentation: - * Here is a list of the search methods available out of the box; - * Shimmie extensions may provide other filters: - *
    - *
  • by tag, eg - *
      - *
    • cat - *
    • pie - *
    • somethi* -- wildcards are supported - *
    - *
  • size (=, <, >, <=, >=) width x height, eg - *
      - *
    • size=1024x768 -- a specific wallpaper size - *
    • size>=500x500 -- no small images - *
    • size<1000x1000 -- no large images - *
    - *
  • width (=, <, >, <=, >=) width, eg - *
      - *
    • width=1024 -- find images with 1024 width - *
    • width>2000 -- find images bigger than 2000 width - *
    - *
  • height (=, <, >, <=, >=) height, eg - *
      - *
    • height=768 -- find images with 768 height - *
    • height>1000 -- find images bigger than 1000 height - *
    - *
  • ratio (=, <, >, <=, >=) width : height, eg - *
      - *
    • ratio=4:3, ratio=16:9 -- standard wallpaper - *
    • ratio=1:1 -- square images - *
    • ratio<1:1 -- tall images - *
    • ratio>1:1 -- wide images - *
    - *
  • filesize (=, <, >, <=, >=) size, eg - *
      - *
    • filesize>1024 -- no images under 1KB - *
    • filesize<=3MB -- shorthand filesizes are supported too - *
    - *
  • id (=, <, >, <=, >=) number, eg - *
      - *
    • id<20 -- search only the first few images - *
    • id>=500 -- search later images - *
    - *
  • user=Username & poster=Username, eg - *
      - *
    • user=Shish -- find all of Shish's posts - *
    • poster=Shish -- same as above - *
    - *
  • user_id=userID & poster_id=userID, eg - *
      - *
    • user_id=2 -- find all posts by user id 2 - *
    • poster_id=2 -- same as above - *
    - *
  • hash=md5sum & md5=md5sum, eg - *
      - *
    • hash=bf5b59173f16b6937a4021713dbfaa72 -- find the "Taiga want up!" image - *
    • md5=bf5b59173f16b6937a4021713dbfaa72 -- same as above - *
    - *
  • filetype=type & ext=type, eg - *
      - *
    • filetype=png -- find all PNG images - *
    • ext=png -- same as above - *
    - *
  • filename=blah & name=blah, eg - *
      - *
    • filename=kitten -- find all images with "kitten" in the original filename - *
    • name=kitten -- same as above - *
    - *
  • posted (=, <, >, <=, >=) date, eg - *
      - *
    • posted>=2009-12-25 posted<=2010-01-01 -- find images posted between christmas and new year - *
    - *
  • tags (=, <, >, <=, >=) count, eg - *
      - *
    • tags=1 -- search for images with only 1 tag - *
    • tags>=10 -- search for images with 10 or more tags - *
    • tags<25 -- search for images with less than 25 tags - *
    - *
  • source=(URL, any, none) eg - *
      - *
    • source=http://example.com -- find all images with "http://example.com" in the source - *
    • source=any -- find all images with a source - *
    • source=none -- find all images without a source - *
    - *
  • order=(id, width, height, filesize, filename)_(ASC, DESC), eg - *
      - *
    • order=width -- find all images sorted from highest > lowest width - *
    • order=filesize_asc -- find all images sorted from lowest > highest filesize - *
    - *
  • order=random_####, eg - *
      - *
    • order=random_8547 -- find all images sorted randomly using 8547 as a seed - *
    - *
- *

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. - *

Metatags can be followed by ":" rather than "=" if you prefer. - *
I.E: "posted:2014-01-01", "id:>=500" etc. - *

Some search methods provided by extensions: - *

    - *
  • Numeric Score - *
      - *
    • score (=, <, >, <=, >=) number -- seach by score - *
    • upvoted_by=Username -- search for a user's likes - *
    • downvoted_by=Username -- search for a user's dislikes - *
    • upvoted_by_id=UserID -- search for a user's likes by user ID - *
    • downvoted_by_id=UserID -- search for a user's dislikes by user ID - *
    • order=score_(ASC, DESC) -- find all images sorted from by score - *
    - *
  • Image Rating - *
      - *
    • rating=se -- find safe and explicit images, ignore questionable and unknown - *
    - *
  • Favorites - *
      - *
    • favorites (=, <, >, <=, >=) number -- search for images favourited a certain number of times - *
    • favourited_by=Username -- search for a user's choices by username - *
    • favorited_by_userno=UserID -- search for a user's choice by userID - *
    - *
  • Notes - *
      - *
    • notes (=, <, >, <=, >=) number -- search by the number of notes an image has - *
    • notes_by=Username -- search for images containing notes created by username - *
    • notes_by_userno=UserID -- search for images containing notes created by userID - *
    - *
  • Artists - *
      - *
    • author=ArtistName -- search for images by artist - *
    - *
  • Image Comments - *
      - *
    • comments (=, <, >, <=, >=) number -- search for images by number of comments - *
    • commented_by=Username -- search for images containing user's comments by username - *
    • commented_by_userno=UserID -- search for images containing user's comments by userID - *
    - *
  • Pools - *
      - *
    • pool=(PoolID, any, none) -- search for images in a pool by PoolID. - *
    • pool_by_name=PoolName -- search for images in a pool by PoolName. underscores are replaced with spaces - *
    - *
  • Post Relationships - *
      - *
    • parent=(parentID, any, none) -- search for images by parentID / if they have, do not have a parent - *
    • child=(any, none) -- search for images which have, or do not have children - *
    - *
- */ - class IndexInfo extends ExtensionInfo { public const KEY = "index"; @@ -166,4 +11,151 @@ class IndexInfo extends ExtensionInfo public $license = self::LICENSE_GPLV2; public $description = "Show a list of uploaded images"; public $core = true; + public $documentation = "Here is a list of the search methods available out of the box; +Shimmie extensions may provide other filters: +
    +
  • by tag, eg +
      +
    • cat +
    • pie +
    • somethi* -- wildcards are supported +
    +
  • size (=, <, >, <=, >=) width x height, eg +
      +
    • size=1024x768 -- a specific wallpaper size +
    • size>=500x500 -- no small images +
    • size<1000x1000 -- no large images +
    +
  • width (=, <, >, <=, >=) width, eg +
      +
    • width=1024 -- find images with 1024 width +
    • width>2000 -- find images bigger than 2000 width +
    +
  • height (=, <, >, <=, >=) height, eg +
      +
    • height=768 -- find images with 768 height +
    • height>1000 -- find images bigger than 1000 height +
    +
  • ratio (=, <, >, <=, >=) width : height, eg +
      +
    • ratio=4:3, ratio=16:9 -- standard wallpaper +
    • ratio=1:1 -- square images +
    • ratio<1:1 -- tall images +
    • ratio>1:1 -- wide images +
    +
  • filesize (=, <, >, <=, >=) size, eg +
      +
    • filesize>1024 -- no images under 1KB +
    • filesize<=3MB -- shorthand filesizes are supported too +
    +
  • id (=, <, >, <=, >=) number, eg +
      +
    • id<20 -- search only the first few images +
    • id>=500 -- search later images +
    +
  • user=Username & poster=Username, eg +
      +
    • user=Shish -- find all of Shish's posts +
    • poster=Shish -- same as above +
    +
  • user_id=userID & poster_id=userID, eg +
      +
    • user_id=2 -- find all posts by user id 2 +
    • poster_id=2 -- same as above +
    +
  • hash=md5sum & md5=md5sum, eg +
      +
    • hash=bf5b59173f16b6937a4021713dbfaa72 -- find the \"Taiga want up!\" image +
    • md5=bf5b59173f16b6937a4021713dbfaa72 -- same as above +
    +
  • filetype=type & ext=type, eg +
      +
    • filetype=png -- find all PNG images +
    • ext=png -- same as above +
    +
  • filename=blah & name=blah, eg +
      +
    • filename=kitten -- find all images with \"kitten\" in the original filename +
    • name=kitten -- same as above +
    +
  • posted (=, <, >, <=, >=) date, eg +
      +
    • posted>=2009-12-25 posted<=2010-01-01 -- find images posted between christmas and new year +
    +
  • tags (=, <, >, <=, >=) count, eg +
      +
    • tags=1 -- search for images with only 1 tag +
    • tags>=10 -- search for images with 10 or more tags +
    • tags<25 -- search for images with less than 25 tags +
    +
  • source=(URL, any, none) eg +
      +
    • source=http://example.com -- find all images with \"http://example.com\" in the source +
    • source=any -- find all images with a source +
    • source=none -- find all images without a source +
    +
  • order=(id, width, height, filesize, filename)_(ASC, DESC), eg +
      +
    • order=width -- find all images sorted from highest > lowest width +
    • order=filesize_asc -- find all images sorted from lowest > highest filesize +
    +
  • order=random_####, eg +
      +
    • order=random_8547 -- find all images sorted randomly using 8547 as a seed +
    +
+

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. +

Metatags can be followed by \":\" rather than \"=\" if you prefer. +
I.E: \"posted:2014-01-01\", \"id:>=500\" etc. +

Some search methods provided by extensions: +

    +
  • Numeric Score +
      +
    • score (=, <, >, <=, >=) number -- seach by score +
    • upvoted_by=Username -- search for a user's likes +
    • downvoted_by=Username -- search for a user's dislikes +
    • upvoted_by_id=UserID -- search for a user's likes by user ID +
    • downvoted_by_id=UserID -- search for a user's dislikes by user ID +
    • order=score_(ASC, DESC) -- find all images sorted from by score +
    +
  • Image Rating +
      +
    • rating=se -- find safe and explicit images, ignore questionable and unknown +
    +
  • Favorites +
      +
    • favorites (=, <, >, <=, >=) number -- search for images favourited a certain number of times +
    • favourited_by=Username -- search for a user's choices by username +
    • favorited_by_userno=UserID -- search for a user's choice by userID +
    +
  • Notes +
      +
    • notes (=, <, >, <=, >=) number -- search by the number of notes an image has +
    • notes_by=Username -- search for images containing notes created by username +
    • notes_by_userno=UserID -- search for images containing notes created by userID +
    +
  • Artists +
      +
    • author=ArtistName -- search for images by artist +
    +
  • Image Comments +
      +
    • comments (=, <, >, <=, >=) number -- search for images by number of comments +
    • commented_by=Username -- search for images containing user's comments by username +
    • commented_by_userno=UserID -- search for images containing user's comments by userID +
    +
  • Pools +
      +
    • pool=(PoolID, any, none) -- search for images in a pool by PoolID. +
    • pool_by_name=PoolName -- search for images in a pool by PoolName. underscores are replaced with spaces +
    +
  • Post Relationships +
      +
    • parent=(parentID, any, none) -- search for images by parentID / if they have, do not have a parent +
    • child=(any, none) -- search for images which have, or do not have children +
    +
+"; } diff --git a/ext/ipban/info.php b/ext/ipban/info.php index 83e595f8..92605d22 100644 --- a/ext/ipban/info.php +++ b/ext/ipban/info.php @@ -1,15 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Description: Ban IP addresses - * Documentation: - * - */ - class IPBanInfo extends ExtensionInfo { public const KEY = "ipban"; diff --git a/ext/link_image/info.php b/ext/link_image/info.php index cbc46255..1e97c2bc 100644 --- a/ext/link_image/info.php +++ b/ext/link_image/info.php @@ -1,11 +1,5 @@ - * Description: Show various forms of link to each image, for copy & paste - */ - class LinkImageInfo extends ExtensionInfo { public const KEY = "link_image"; @@ -14,4 +8,27 @@ class LinkImageInfo extends ExtensionInfo public $name = "Link to Image"; public $authors = ["Artanis"=>"artanis.00@gmail.com"]; public $description = "Show various forms of link to each image, for copy & paste"; + public $license = self::LICENSE_GPLV2; + public $documentation = "There is one option in Board Config: Text Link Format. +It takes the following arguments as well as plain text. + +
+|| arguments    || replacement                      ||
+|| \$id          || The image ID.                    ||
+|| \$hash        || The MD5 hash of the image.       ||
+|| \$tags        || The image's tag list.            ||
+|| \$base        || The base HREF as set in Config.  ||
+|| \$ext         || The image's extension.           ||
+|| \$size        || The image's display size.        ||
+|| \$filesize    || The image's size in KB.          ||
+|| \$filename    || The image's original filename.   ||
+|| \$title       || The site title as set in Config. ||
+
+ +

Link to Image will default this option to '\$title - \$id (\$ext \$size \$filesize)'. + +

To reset to the default, simply clear the current setting. Link to Image +will then fill in the default value after the save. + +

To leave the setting blank for any reason, leave a space (' ') in it."; } diff --git a/ext/link_image/readme.txt b/ext/link_image/readme.txt deleted file mode 100644 index 6051103a..00000000 --- a/ext/link_image/readme.txt +++ /dev/null @@ -1,82 +0,0 @@ -Link to Image adds BBCode and HTML link codes to the image view. Offers code for a customizable text link, thumbnail links, and full image inline. - -Author: Erik Youngren - -License: GPLv2 - -Submit a Bug Report or Suggestion for Link to Image: - * http://trac.shishnet.org/shimmie2/newticket?owner=artanis.00@gmail.com&component=third%20party%20extensions&keywords=link_to_image - -= Use = -There is one option in Board Config: Text Link Format. -It takes the following arguments as well as plain text. -|| arguments || replacement || -|| $id || The image ID. || -|| $hash || The MD5 hash of the image. || -|| $tags || The image's tag list. || -|| $base || The base HREF as set in Config. || -|| $ext || The image's extension. || -|| $size || The image's display size. || -|| $filesize || The image's size in KB. || -|| $filename || The image's original filename. || -|| $title || The site title as set in Config. || -Link to Image will default this option to '$title - $id ($ext $size $filesize)'. -To reset to the default, simply clear the current setting. Link to Image will then fill in the default value after the save. - -To leave the setting blank for any reason, leave a space (' ') in it. - -= Install = - 1. Copy the folder {{{contrib/link_image/}}} to {{{ext/}}}. - 2. In the Config panel, make sure Base URL is set (you may as well set Data URL while you're there, if you haven't already.) - 3. Make sure Image Link, Thumb Link, and Short Link all contain the full path ("http://" and onward,) either by using $base or plain text. Link to Image will not be able to retrieve the correct paths without these variables. - -= Change Log = -== Version 0.3.0 == - * Moved Link to Image over to the official theme engine. This functions basically the same as what the prototype was, but it's more thought out and nicer. - * Cleaned up the insides a bit. - -== Version 0.2.0 == - * Changed the HTML generation to use a prototype theme engine. All HTML generation is now contained within {{{link_image.html.php}}}, which may be copied to the current theme folder and edited from there. - -== Version 0.1.4 - 20070510 == - * Style changes. - * Added output containing only the locations of the thumb, image and post. - * Added a link to wikipedia's HTML page, just as BBCode has a wikipedia link. - -== Version 0.1.3b - 20070509 == - * Renamed style.css to _style.css to avoid the auto loader. - -== Version 0.1.3 - 20070508 == - * Created Readme.txt - * Merged 0.1.2 into 0.1.2b - * Removed uneeded documentation from main.php - * Rewrote the css to be unique. Previously used CSS I wrote for elsewhere. Styled to reduce space consumption. - * Added code to insert the CSS import. - * Updated Nice URLs to allow access to the /ext/ folder. (Why is my stylesheet returning HTML instead of CSS?) - * First SVN update. - -== Version 0.1.2b - 20070507 == -(fairly simultaneous with 0.1.2) - * shish: - * Updated to new extension format - * Created folder link_image in trunk/contrib - * Renamed link_image.ext.php to main.php and moved to /link_image/ - * Created style.css {{{ /* 404'd :|*/ }}}. - * Documentation (different from mine.) - * Changed add_text_option() and added add_label() in SetupBuildingEvent because I was using an edited version of the function that shish didn't know about. It was a wonder that didn't throw massive errors. - * Published on SVN. - -== Version 0.1.2 - 20070506 == - * Textboxes now select-all when they gain focus. - * Commenting and documentation. - -== Version 0.1.1 - 20070506 == - * Fixed HTML thumbnail link code. (image tag was being html_escaped twice, resulting in "$gt;" and "<" from the first escape becoming "&gt;" and "&lt;") It turns out that html_escape was completely unnecessary, all I had to do was replace the single-quotes around the attributes with escaped double-quotes ('\"'.) - -== Version 0.1.0 - 20070506 == - * Release. - -= Links = - * http://trac.shishnet.org/shimmie2/wiki/Contrib/Extensions/LinkToImage - Home - * http://forum.shishnet.org/viewtopic.php?p=153 - Discussion - * http://trac.shishnet.org/shimmie2/browser/trunk/contrib/link_image - Shimmie2 Trac SVN diff --git a/ext/livefeed/info.php b/ext/livefeed/info.php index 5aeb4ea4..e5a888fc 100644 --- a/ext/livefeed/info.php +++ b/ext/livefeed/info.php @@ -1,14 +1,5 @@ -* License: GPLv2 -* Visibility: admin -* Description: Logs user-safe (no IPs) data to a UDP socket, eg IRCCat -* Documentation: -*/ - class LiveFeedInfo extends ExtensionInfo { public const KEY = "livefeed"; diff --git a/ext/log_db/info.php b/ext/log_db/info.php index 0757b4df..177cef81 100644 --- a/ext/log_db/info.php +++ b/ext/log_db/info.php @@ -1,13 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * Description: Keep a record of SCore events (in the database). - * Visibility: admin - */ - class LogDatabaseInfo extends ExtensionInfo { public const KEY = "log_db"; diff --git a/ext/log_logstash/info.php b/ext/log_logstash/info.php index 6f35d526..d3413048 100644 --- a/ext/log_logstash/info.php +++ b/ext/log_logstash/info.php @@ -1,13 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * Description: Send log events to a network port. - * Visibility: admin - */ - class LogLogstashInfo extends ExtensionInfo { public const KEY = "log_logstash"; diff --git a/ext/log_net/info.php b/ext/log_net/info.php index a053a994..7aa660d5 100644 --- a/ext/log_net/info.php +++ b/ext/log_net/info.php @@ -1,13 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * Description: Send log events to a network port. - * Visibility: admin - */ - class LogNetInfo extends ExtensionInfo { public const KEY = "log_net"; diff --git a/ext/mail/info.php b/ext/mail/info.php index bb370eae..b5c1044d 100644 --- a/ext/mail/info.php +++ b/ext/mail/info.php @@ -1,13 +1,5 @@ - * Link: http://seemslegit.com - * License: GPLv2 - * Description: Provides an interface for sending and receiving mail. - */ - class MailInfo extends ExtensionInfo { public const KEY = "mail"; diff --git a/ext/media/info.php b/ext/media/info.php index abafffbe..3a514557 100644 --- a/ext/media/info.php +++ b/ext/media/info.php @@ -1,11 +1,5 @@ - * Description: Provides common functions and settings used for media operations. - */ - class MediaInfo extends ExtensionInfo { public const KEY = "media"; diff --git a/ext/not_a_tag/info.php b/ext/not_a_tag/info.php index ddd97f82..4f4224c7 100644 --- a/ext/not_a_tag/info.php +++ b/ext/not_a_tag/info.php @@ -1,12 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Description: Redirect users to the rules if they use bad tags - */ class NotATagInfo extends ExtensionInfo { public const KEY = "not_a_tag"; diff --git a/ext/notes/info.php b/ext/notes/info.php index 9296b7b8..fcb6d4e9 100644 --- a/ext/notes/info.php +++ b/ext/notes/info.php @@ -1,13 +1,5 @@ - * License: GPLv2 - * Description: Annotate images - * Documentation: - */ - class NotesInfo extends ExtensionInfo { public const KEY = "notes"; diff --git a/ext/numeric_score/info.php b/ext/numeric_score/info.php index ca2b77ab..bd7ffa27 100644 --- a/ext/numeric_score/info.php +++ b/ext/numeric_score/info.php @@ -1,14 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Description: Allow users to score images - * Documentation: - */ - class NumericScoreInfo extends ExtensionInfo { public const KEY = "numeric_score"; diff --git a/ext/oekaki/info.php b/ext/oekaki/info.php index 2600bf7f..99ec45b7 100644 --- a/ext/oekaki/info.php +++ b/ext/oekaki/info.php @@ -1,11 +1,5 @@ - * Description: Ouroboros-like API for Shimmie - * Version: 0.2 - * Documentation: - * - */ - - class OuroborosAPIInfo extends ExtensionInfo { public const KEY = "ouroboros_api"; diff --git a/ext/pm/info.php b/ext/pm/info.php index 795ee31f..93986fca 100644 --- a/ext/pm/info.php +++ b/ext/pm/info.php @@ -1,14 +1,5 @@ - * License: GPLv2 - * Description: Allow users to send messages to eachother - * Documentation: - * - */ - class PrivMsgInfo extends ExtensionInfo { public const KEY = "pm"; diff --git a/ext/pm_triggers/info.php b/ext/pm_triggers/info.php index d36ca3b5..1fd356c1 100644 --- a/ext/pm_triggers/info.php +++ b/ext/pm_triggers/info.php @@ -1,12 +1,5 @@ - * License: GPLv2 - * Description: Send PMs in response to certain events (eg image deletion) - */ - class PMTriggerInfo extends ExtensionInfo { public const KEY = "pm_triggers"; diff --git a/ext/pools/info.php b/ext/pools/info.php index 5acf4629..2cfa72d6 100644 --- a/ext/pools/info.php +++ b/ext/pools/info.php @@ -1,13 +1,5 @@ , jgen , Daku - * License: GPLv2 - * Description: Allow users to create groups of images and order them. - * Documentation: - */ - class PoolsInfo extends ExtensionInfo { public const KEY = "pools"; diff --git a/ext/post_titles/info.php b/ext/post_titles/info.php index 208cf231..87c22267 100644 --- a/ext/post_titles/info.php +++ b/ext/post_titles/info.php @@ -1,11 +1,5 @@ - * Description: Add titles to media posts - */ - class PostTitlesInfo extends ExtensionInfo { public const KEY = "post_titles"; diff --git a/ext/qr_code/info.php b/ext/qr_code/info.php index f8fe2f5e..d97d9c11 100644 --- a/ext/qr_code/info.php +++ b/ext/qr_code/info.php @@ -1,9 +1,5 @@ [http://seemslegit.com] - * Description: - */ + class QRImageInfo extends ExtensionInfo { public const KEY = "qr_code"; diff --git a/ext/random_image/info.php b/ext/random_image/info.php index 3143f883..389f52a1 100644 --- a/ext/random_image/info.php +++ b/ext/random_image/info.php @@ -1,15 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Description: Do things with a random image - * Documentation: - * - */ - class RandomImageInfo extends ExtensionInfo { public const KEY = "random_image"; diff --git a/ext/random_list/info.php b/ext/random_list/info.php index f7d9dd12..226619af 100644 --- a/ext/random_list/info.php +++ b/ext/random_list/info.php @@ -1,15 +1,5 @@ - * Link: http://www.drudexsoftware.com - * License: GPLv2 - * Description: Allows displaying a page with random images - * Documentation: - * - */ - class RandomListInfo extends ExtensionInfo { public const KEY = "random_list"; diff --git a/ext/rating/info.php b/ext/rating/info.php index c53335ef..529b9b2a 100644 --- a/ext/rating/info.php +++ b/ext/rating/info.php @@ -1,14 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Description: Allow users to rate images "safe", "questionable" or "explicit" - * Documentation: - */ - class RatingsInfo extends ExtensionInfo { public const KEY = "rating"; diff --git a/ext/regen_thumb/info.php b/ext/regen_thumb/info.php index 8f272915..86075141 100644 --- a/ext/regen_thumb/info.php +++ b/ext/regen_thumb/info.php @@ -1,13 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Description: - * Documentation: - */ class RegenThumbInfo extends ExtensionInfo { public const KEY = "regen_thumb"; diff --git a/ext/relationships/info.php b/ext/relationships/info.php index 941e202b..024b5c5b 100644 --- a/ext/relationships/info.php +++ b/ext/relationships/info.php @@ -1,12 +1,5 @@ - * License: GPLv2 - * Description: Allow posts to have relationships (parent/child). - */ - class RelationshipsInfo extends ExtensionInfo { public const KEY = "relationships"; diff --git a/ext/report_image/info.php b/ext/report_image/info.php index 937f0a6e..4477fbb9 100644 --- a/ext/report_image/info.php +++ b/ext/report_image/info.php @@ -1,15 +1,5 @@ - * Link: http://atravelinggeek.com/ - * License: GPLv2 - * Description: Report images as dupes/illegal/etc - * Version 0.3a - See changelog in main.php - * November 06, 2007 - */ - class ReportImageInfo extends ExtensionInfo { public const KEY = "report_image"; diff --git a/ext/report_image/theme.php b/ext/report_image/theme.php index f4de5934..6c34178a 100644 --- a/ext/report_image/theme.php +++ b/ext/report_image/theme.php @@ -1,15 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Description: Allows the admin to set min / max image dimensions - */ class ResolutionLimitInfo extends ExtensionInfo { public const KEY = "res_limit"; diff --git a/ext/resize/info.php b/ext/resize/info.php index 72ea0bd1..326eafe3 100644 --- a/ext/resize/info.php +++ b/ext/resize/info.php @@ -1,16 +1,9 @@ - * Description: Allows admins to resize images. - * License: GPLv2 - * Version: 0.1 * Notice: * The image resize and resample code is based off of the "smart_resize_image" * function copyright 2008 Maxim Chernyak, released under a MIT-style license. - * Documentation: - * This extension allows admins to resize images. */ class ResizeImageInfo extends ExtensionInfo diff --git a/ext/rotate/info.php b/ext/rotate/info.php index de7bb471..b10e4ad0 100644 --- a/ext/rotate/info.php +++ b/ext/rotate/info.php @@ -1,16 +1,9 @@ / Agasa - * Description: Allows admins to rotate images. - * License: GPLv2 - * Version: 0.1 * Notice: * The image resize and resample code is based off of the "smart_resize_image" * function copyright 2008 Maxim Chernyak, released under a MIT-style license. - * Documentation: - * This extension allows admins to rotate images. */ class RotateImageInfo extends ExtensionInfo diff --git a/ext/rss_comments/info.php b/ext/rss_comments/info.php index f6074f62..a69d58b0 100644 --- a/ext/rss_comments/info.php +++ b/ext/rss_comments/info.php @@ -1,13 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Description: Self explanatory - */ - class RSSCommentsInfo extends ExtensionInfo { public const KEY = "rss_comments"; diff --git a/ext/rss_images/info.php b/ext/rss_images/info.php index 33f814ed..bc58134c 100644 --- a/ext/rss_images/info.php +++ b/ext/rss_images/info.php @@ -1,12 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Description: Self explanatory - */ class RSSImagesInfo extends ExtensionInfo { public const KEY = "rss_images"; diff --git a/ext/rule34/info.php b/ext/rule34/info.php index 606e9607..11988432 100644 --- a/ext/rule34/info.php +++ b/ext/rule34/info.php @@ -1,14 +1,5 @@ - * License: GPLv2 - * Description: Extra site-specific bits - * Documentation: - * - */ - class Rule34Info extends ExtensionInfo { public const KEY = "rule34"; diff --git a/ext/setup/info.php b/ext/setup/info.php index 03fb0774..7fa3e5ef 100644 --- a/ext/setup/info.php +++ b/ext/setup/info.php @@ -1,12 +1,5 @@ - * Description: A JSON interface to shimmie data [WARNING] - * Documentation: - * - */ - - class ShimmieApiInfo extends ExtensionInfo { public const KEY = "shimmie_api"; diff --git a/ext/site_description/info.php b/ext/site_description/info.php index 2bbc25e7..7a5da7bc 100644 --- a/ext/site_description/info.php +++ b/ext/site_description/info.php @@ -1,15 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Visibility: admin - * Description: A description for search engines - * Documentation: - * - */ class SiteDescriptionInfo extends ExtensionInfo { public const KEY = "site_description"; diff --git a/ext/sitemap/info.php b/ext/sitemap/info.php index 3cee3e3a..5f7cb12e 100644 --- a/ext/sitemap/info.php +++ b/ext/sitemap/info.php @@ -1,15 +1,5 @@ - * Author: Drudex Software - * Link: http://drudexsoftware.com - * License: GPLv2 - * Description: Sitemap with caching & advanced priorities - * Documentation: - */ - class XMLSitemapInfo extends ExtensionInfo { public const KEY = "sitemap"; diff --git a/ext/source_history/info.php b/ext/source_history/info.php index cce9a369..07784147 100644 --- a/ext/source_history/info.php +++ b/ext/source_history/info.php @@ -1,11 +1,5 @@ -* License: GPLv2 -* Visibility: admin -* Description: Sends Shimmie stats to a StatsD server -* Documentation: -* -*/ - class StatsDInterfaceInfo extends ExtensionInfo { public const KEY = "statsd"; diff --git a/ext/system/info.php b/ext/system/info.php index 7f32847f..04ed13d3 100644 --- a/ext/system/info.php +++ b/ext/system/info.php @@ -1,11 +1,5 @@ - * Description: Provides system screen - */ - class SystemInfo extends ExtensionInfo { public const KEY = "system"; diff --git a/ext/tag_categories/info.php b/ext/tag_categories/info.php index 7c3ebe1c..4b382754 100644 --- a/ext/tag_categories/info.php +++ b/ext/tag_categories/info.php @@ -1,11 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * Description: Let tags be split into 'categories', like Danbooru's tagging - */ class TagCategoriesInfo extends ExtensionInfo { public const KEY = "tag_categories"; diff --git a/ext/tag_edit/info.php b/ext/tag_edit/info.php index d19e1f45..4fb4fdd8 100644 --- a/ext/tag_edit/info.php +++ b/ext/tag_edit/info.php @@ -1,12 +1,5 @@ , modified by jgen - * Description: Keep a record of tag changes, and allows you to revert changes. - */ - class TagHistoryInfo extends ExtensionInfo { public const KEY = "tag_history"; diff --git a/ext/tag_history/theme.php b/ext/tag_history/theme.php index 099b8215..353901bb 100644 --- a/ext/tag_history/theme.php +++ b/ext/tag_history/theme.php @@ -1,9 +1,4 @@ , modified by jgen - */ - class TagHistoryTheme extends Themelet { private $messages = []; @@ -117,11 +112,11 @@ class TagHistoryTheme extends Themelet public function display_admin_block(string $validation_msg='') { global $page; - + if (!empty($validation_msg)) { $validation_msg = '
'. $validation_msg .''; } - + $html = ' Revert tag changes by a specific IP address or username, optionally limited to recent changes. '.$validation_msg.' @@ -137,7 +132,7 @@ class TagHistoryTheme extends Themelet "; $page->add_block(new Block("Mass Tag Revert", $html)); } - + /* * Show a standard page for results to be put into */ diff --git a/ext/tag_list/info.php b/ext/tag_list/info.php index a44adfe3..a3fa78f2 100644 --- a/ext/tag_list/info.php +++ b/ext/tag_list/info.php @@ -1,12 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * Description: Show the tags in various ways - */ - class TagListInfo extends ExtensionInfo { public const KEY = "tag_list"; diff --git a/ext/tagger/info.php b/ext/tagger/info.php index b240b70b..79d975b4 100644 --- a/ext/tagger/info.php +++ b/ext/tagger/info.php @@ -1,12 +1,5 @@ - * Do not remove this notice. - */ - class TaggerInfo extends ExtensionInfo { public const KEY = "tagger"; diff --git a/ext/tips/info.php b/ext/tips/info.php index acacf98e..f5822c7c 100644 --- a/ext/tips/info.php +++ b/ext/tips/info.php @@ -1,15 +1,5 @@ - * License: GPLv2 - * Description: Show a random line of text in the subheader space - * Documentation: - * Formatting is done with HTML - */ - - class TipsInfo extends ExtensionInfo { public const KEY = "tips"; diff --git a/ext/transcode/info.php b/ext/transcode/info.php index 5ed63862..ceb6f9f9 100644 --- a/ext/transcode/info.php +++ b/ext/transcode/info.php @@ -1,13 +1,5 @@ - * Description: Allows admins to automatically and manually transcode images. - * Documentation: - * - */ - class TranscodeImageInfo extends ExtensionInfo { public const KEY = "transcode"; diff --git a/ext/trash/info.php b/ext/trash/info.php index a4991f36..87d1c7eb 100644 --- a/ext/trash/info.php +++ b/ext/trash/info.php @@ -1,12 +1,5 @@ - * Description: Provides "Trash" or "Recycle Bin"-type functionality, storing delete images for later recovery - * Documentation: - */ - class TrashInfo extends ExtensionInfo { public const KEY = "trash"; diff --git a/ext/update/info.php b/ext/update/info.php index 979bcbab..9e3631b3 100644 --- a/ext/update/info.php +++ b/ext/update/info.php @@ -1,13 +1,5 @@ - * Link: http://www.codeanimu.net - * License: GPLv2 - * Description: Shimmie updater! (Requires admin panel extension & transload engine (cURL/fopen/Wget)) - */ - class UpdateInfo extends ExtensionInfo { public const KEY = "update"; diff --git a/ext/upgrade/info.php b/ext/upgrade/info.php index 6ece153b..8432ccb6 100644 --- a/ext/upgrade/info.php +++ b/ext/upgrade/info.php @@ -1,13 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * Description: Keeps things happy behind the scenes - * Visibility: admin - */ - class UpgradeInfo extends ExtensionInfo { public const KEY = "upgrade"; diff --git a/ext/upload/info.php b/ext/upload/info.php index c14ae1d3..b8e18692 100644 --- a/ext/upload/info.php +++ b/ext/upload/info.php @@ -1,12 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * Description: Allows people to upload files to the website - */ - class UploadInfo extends ExtensionInfo { public const KEY = "upload"; diff --git a/ext/user/info.php b/ext/user/info.php index f8b5943e..04664feb 100644 --- a/ext/user/info.php +++ b/ext/user/info.php @@ -1,11 +1,5 @@ - * Description: Provides system-wide support for user-specific settings - * Visibility: admin - */ - class UserConfigInfo extends ExtensionInfo { public const KEY = "user_config"; diff --git a/ext/varnish/info.php b/ext/varnish/info.php index eacaa0cd..4c0c575d 100644 --- a/ext/varnish/info.php +++ b/ext/varnish/info.php @@ -1,13 +1,5 @@ -* License: GPLv2 -* Visibility: admin -* Description: Sends PURGE requests when a /post/view is updated -*/ - class VarnishPurgerInfo extends ExtensionInfo { public const KEY = "varnish"; diff --git a/ext/view/info.php b/ext/view/info.php index a8e9cc81..55253ddf 100644 --- a/ext/view/info.php +++ b/ext/view/info.php @@ -1,12 +1,5 @@ - * License: GPLv2 - * Description: A simple wiki, for those who don't want the hugeness of mediawiki - * Documentation: - * - */ - class WikiInfo extends ExtensionInfo { public const KEY = "wiki"; diff --git a/ext/word_filter/info.php b/ext/word_filter/info.php index 89b76079..8575ef98 100644 --- a/ext/word_filter/info.php +++ b/ext/word_filter/info.php @@ -1,13 +1,5 @@ - * Link: http://code.shishnet.org/shimmie2/ - * License: GPLv2 - * Description: Simple search and replace - */ - class WordFilterInfo extends ExtensionInfo { public const KEY = "word_filter"; From ac5546c6efc44719b4923774ca5cc96b2508f7c8 Mon Sep 17 00:00:00 2001 From: Shish Date: Sun, 3 Nov 2019 16:22:59 +0000 Subject: [PATCH 30/30] remove more old comments --- core/_install.php | 32 +++++++++++++++----------------- ext/comment/main.php | 6 ------ ext/image/main.php | 9 +-------- ext/image_hash_ban/main.php | 6 ++---- ext/ipban/main.php | 13 +++---------- ext/setup/main.php | 23 +++++------------------ ext/tag_list/main.php | 11 ++--------- ext/upload/main.php | 3 --- ext/user/main.php | 10 +++------- ext/user/theme.php | 1 - ext/wiki/main.php | 2 -- 11 files changed, 31 insertions(+), 85 deletions(-) diff --git a/core/_install.php b/core/_install.php index a37553da..3f799d46 100644 --- a/core/_install.php +++ b/core/_install.php @@ -74,8 +74,7 @@ if (is_readable("data/config/shimmie.conf.php")) { do_install(); -// utilities {{{ - // TODO: Can some of these be pushed into "core/???.inc.php" ? +// TODO: Can some of these be pushed into "core/???.inc.php" ? function check_gd_version(): int { @@ -99,10 +98,9 @@ function check_im_version(): int return (empty($convert_check) ? 0 : 1); } -// }}} function do_install() -{ // {{{ +{ if (file_exists("data/config/auto_install.conf.php")) { require_once "data/config/auto_install.conf.php"; } elseif (@$_POST["database_type"] == DatabaseDriver::SQLITE) { @@ -118,10 +116,10 @@ function do_install() define("CACHE_DSN", null); define("DATABASE_KA", true); install_process(); -} // }}} +} function ask_questions() -{ // {{{ +{ $warnings = []; $errors = []; @@ -232,21 +230,21 @@ function ask_questions() EOD; -} // }}} +} /** * This is where the install really takes place. */ function install_process() -{ // {{{ +{ build_dirs(); create_tables(); insert_defaults(); write_config(); -} // }}} +} function create_tables() -{ // {{{ +{ try { $db = new Database(); @@ -331,10 +329,10 @@ EOD; } catch (Exception $e) { handle_db_errors(false, "An unknown error occurred while trying to insert data into the database.", $e->getMessage(), 4); } -} // }}} +} function insert_defaults() -{ // {{{ +{ try { $db = new Database(); @@ -350,10 +348,10 @@ function insert_defaults() } catch (Exception $e) { handle_db_errors(false, "An unknown error occurred while trying to insert data into the database.", $e->getMessage(), 6); } -} // }}} +} function build_dirs() -{ // {{{ +{ $data_exists = file_exists("data") || mkdir("data"); $data_writable = is_writable("data") || chmod("data", 0755); @@ -373,10 +371,10 @@ function build_dirs() "; exit(7); } -} // }}} +} function write_config() -{ // {{{ +{ $file_content = '<' . '?php' . "\n" . "define('DATABASE_DSN', '".DATABASE_DSN."');\n" . '?' . '>'; @@ -417,7 +415,7 @@ EOD; EOD; } echo "\n"; -} // }}} +} function handle_db_errors(bool $isPDO, string $errorMessage1, string $errorMessage2, int $exitCode) { diff --git a/ext/comment/main.php b/ext/comment/main.php index 3791ea00..8dca6983 100644 --- a/ext/comment/main.php +++ b/ext/comment/main.php @@ -367,7 +367,6 @@ class CommentList extends Extension } } - // page building {{{ private function build_page(int $current_page) { global $cache, $database, $user; @@ -417,9 +416,7 @@ class CommentList extends Extension $this->theme->display_comment_list($images, $current_page, $total_pages, $user->can(Permissions::CREATE_COMMENT)); } - // }}} - // get comments {{{ /** * #return Comment[] */ @@ -488,9 +485,7 @@ class CommentList extends Extension ORDER BY comments.id ASC ", ["image_id"=>$image_id]); } - // }}} - // add / remove / edit comments {{{ private function is_comment_limit_hit(): bool { global $config, $database; @@ -651,5 +646,4 @@ class CommentList extends Extension throw new CommentPostingException("Akismet thinks that your comment is spam. Try rewriting the comment, or logging in."); } } - // }}} } diff --git a/ext/image/main.php b/ext/image/main.php index 2dc8f72b..941e7492 100644 --- a/ext/image/main.php +++ b/ext/image/main.php @@ -159,8 +159,6 @@ class ImageIO extends Extension $event->panel->add_block($sb); } - - // add image {{{ private function add_image(ImageAdditionEvent $event) { global $user, $database, $config; @@ -237,9 +235,7 @@ class ImageIO extends Extension log_warning("add_image", "Error while running update_image_media_properties: ".$e->getMessage()); } } - // }}} end add - // fetch image {{{ private function send_file(int $image_id, string $type) { global $config; @@ -298,9 +294,7 @@ class ImageIO extends Extension )); } } - // }}} end fetch - // replace image {{{ private function replace_image(int $id, Image $image) { global $database; @@ -362,5 +356,4 @@ class ImageIO extends Extension log_info("image", "Replaced Image #{$id} with ({$image->hash})"); } - // }}} end replace -} // end of class ImageIO +} diff --git a/ext/image_hash_ban/main.php b/ext/image_hash_ban/main.php index 33ff65d5..0617b503 100644 --- a/ext/image_hash_ban/main.php +++ b/ext/image_hash_ban/main.php @@ -1,6 +1,5 @@ hash = $hash; } } -// }}} -// AddImageHashBanEvent {{{ + class AddImageHashBanEvent extends Event { public $hash; @@ -23,7 +21,7 @@ class AddImageHashBanEvent extends Event $this->reason = $reason; } } -// }}} + class ImageBan extends Extension { public function onInitExt(InitExtEvent $event) diff --git a/ext/ipban/main.php b/ext/ipban/main.php index 52b92fd9..9ebcca21 100644 --- a/ext/ipban/main.php +++ b/ext/ipban/main.php @@ -1,6 +1,5 @@ id = $id; } } -// }}} -// AddIPBanEvent {{{ + class AddIPBanEvent extends Event { public $ip; @@ -25,7 +23,6 @@ class AddIPBanEvent extends Event $this->end = trim($end); } } -// }}} class IPBan extends Extension { @@ -131,7 +128,6 @@ class IPBan extends Extension } } - // installer {{{ protected function install() { global $database; @@ -209,8 +205,7 @@ class IPBan extends Extension $config->set_int("ext_ipban_version", 8); } } - // }}} - // deal with banned person {{{ + private function check_ip_ban() { $remote = $_SERVER['REMOTE_ADDR']; @@ -266,8 +261,7 @@ class IPBan extends Extension log_error("ipban", "block($remote) called but no bans matched"); exit; } - // }}} - // database {{{ + private function get_bans() { global $database; @@ -328,5 +322,4 @@ class IPBan extends Extension $cache->set("ip_bans_sorted", $sorted, 600); return $sorted; } - // }}} } diff --git a/ext/setup/main.php b/ext/setup/main.php index 676442fe..12e4ea6b 100644 --- a/ext/setup/main.php +++ b/ext/setup/main.php @@ -2,8 +2,7 @@ include_once "config.php"; -/* ConfigSaveEvent {{{ - * +/* * Sent when the setup screen's 'set' button has been * activated; new config options are in $_POST */ @@ -17,9 +16,8 @@ class ConfigSaveEvent extends Event $this->config = $config; } } -// }}} -/* SetupBuildingEvent {{{ - * + +/* * Sent when the setup page is ready to be added to */ class SetupBuildingEvent extends Event @@ -32,10 +30,7 @@ class SetupBuildingEvent extends Event $this->panel = $panel; } } -// }}} -/* SetupPanel {{{ - * - */ + class SetupPanel { /** @var SetupBlock[] */ @@ -46,10 +41,7 @@ class SetupPanel $this->blocks[] = $block; } } -// }}} -/* SetupBlock {{{ - * - */ + class SetupBlock extends Block { /** @var string */ @@ -57,8 +49,6 @@ class SetupBlock extends Block /** @var string */ public $body; - - public function __construct(string $title) { $this->header = $title; @@ -134,8 +124,6 @@ class SetupBlock extends Block $this->end_table_header_cell(); } - - private function format_option(string $name, $html, ?string $label, bool $table_row) { if ($table_row) { @@ -274,7 +262,6 @@ class SetupBlock extends Block $this->format_option($name, $html, $label, $table_row); } } -// }}} class Setup extends Extension { diff --git a/ext/tag_list/main.php b/ext/tag_list/main.php index 24bdb92a..0b0f1b93 100644 --- a/ext/tag_list/main.php +++ b/ext/tag_list/main.php @@ -159,8 +159,7 @@ class TagList extends Extension $sb->end_table(); $event->panel->add_block($sb); } - // }}} - // misc {{{ + private function tag_link(string $tag): string { $u_tag = url_escape($tag); @@ -253,8 +252,6 @@ class TagList extends Extension return $html; } - // }}} - // maps {{{ private function build_navigation(): string { @@ -453,8 +450,7 @@ class TagList extends Extension return $html; } - // }}} - // blocks {{{ + private function add_related_block(Page $page, Image $image): void { global $database, $config; @@ -653,7 +649,4 @@ class TagList extends Extension return $related_tags; } } - - - // }}} } diff --git a/ext/upload/main.php b/ext/upload/main.php index 25a0daf9..9bc90995 100644 --- a/ext/upload/main.php +++ b/ext/upload/main.php @@ -291,8 +291,6 @@ class Upload extends Extension return $tags; } - // do things {{{ - /** * Returns a descriptive error message for the specified PHP error code. * @@ -475,5 +473,4 @@ class Upload extends Extension return $ok; } - // }}} } diff --git a/ext/user/main.php b/ext/user/main.php index 71e62d1f..7905c16f 100644 --- a/ext/user/main.php +++ b/ext/user/main.php @@ -339,8 +339,7 @@ class UserPage extends Extension $this->theme->display_user_block($page, $user, $ubbe->parts); } } - // }}} - // Things done *with* the user {{{ + private function page_login($name, $pass) { global $config, $page; @@ -490,8 +489,7 @@ class UserPage extends Extension '/' ); } - //}}} - // Things done *to* the user {{{ + private function user_can_edit_user(User $a, User $b): bool { if ($a->is_anonymous()) { @@ -581,8 +579,7 @@ class UserPage extends Extension $this->redirect_to_user($duser); } } - // }}} - // ips {{{ + private function count_upload_ips(User $duser): array { global $database; @@ -683,5 +680,4 @@ class UserPage extends Extension $page->set_redirect(make_link("post/list")); } } - // }}} } diff --git a/ext/user/theme.php b/ext/user/theme.php index 06ebc887..3c41641d 100644 --- a/ext/user/theme.php +++ b/ext/user/theme.php @@ -339,7 +339,6 @@ class UserPageTheme extends Themelet } return $html; } - // }}} public function get_help_html() { diff --git a/ext/wiki/main.php b/ext/wiki/main.php index 189a7797..d52b3059 100644 --- a/ext/wiki/main.php +++ b/ext/wiki/main.php @@ -265,7 +265,6 @@ class Wiki extends Extension return new WikiPage($row); } - // php-diff {{{ /** Diff implemented in pure php, written from scratch. Copyright (C) 2003 Daniel Unterberger @@ -502,5 +501,4 @@ class Wiki extends Extension throw new Exception("stat needs to be =, + or -"); } } - // }}} }