diff --git a/ext/bulk_add_csv/main.php b/ext/bulk_add_csv/main.php new file mode 100644 index 00000000..cc5f4df7 --- /dev/null +++ b/ext/bulk_add_csv/main.php @@ -0,0 +1,132 @@ + + * License: GPLv2 + * Description: Bulk add server-side images with metadata from CSV file + * Documentation: + * Modification of "Bulk Add" by Shish.

+ * Adds images from a CSV with the four following values:
+ * "/path/to/image.jpg","space separated tags","source","rating (s, q, or e)"
+ * e.g. "/tmp/cat.png","shish oekaki","shimmie.shishnet.org/v2/post/view/3051","s"

+ * Any value but the first may be omitted, but there must be four values per line.
+ * e.g. "/why/not/try/bulk_add.jpg","","",""

+ * Useful for importing tagged images without having to do database manipulation.
+ *

Note: requires "Admin Controls" and optionally "Image Ratings" to be enabled

+ * + */ + +class BulkAddCSV extends Extension { + public function onPageRequest(PageRequestEvent $event) { + global $page, $user; + if($event->page_matches("bulk_add_csv")) { + if($user->is_admin() && $user->check_auth_token() && isset($_POST['csv'])) { + set_time_limit(0); + $this->add_csv($_POST['csv']); + $this->theme->display_upload_results($page); + } + } + } + + public function onCommand(CommandEvent $event) { + if($event->cmd == "help") { + print " bulk-add-csv [/path/to.csv]\n"; + print " Import this .csv file (refer to documentation)\n\n"; + } + if($event->cmd == "bulk-add-csv") { + global $user; + + //Nag until CLI is admin by default + if (!$user->is_admin()) { + print "Not running as an admin, which can cause problems.\n"; + print "Please add the parameter: -u admin_username"; + } elseif(count($event->args) == 1) { + $this->add_csv($event->args[0]); + } + } + } + + public function onAdminBuilding(AdminBuildingEvent $event) { + $this->theme->display_admin_block(); + } + + /** + * Generate the necessary DataUploadEvent for a given image and tags. + */ + private function add_image($tmpname, $filename, $tags, $source, $rating) { + assert(file_exists($tmpname)); + + $pathinfo = pathinfo($filename); + if(!array_key_exists('extension', $pathinfo)) { + throw new UploadException("File has no extension"); + } + $metadata['filename'] = $pathinfo['basename']; + $metadata['extension'] = $pathinfo['extension']; + $metadata['tags'] = $tags; + $metadata['source'] = $source; + $event = new DataUploadEvent($tmpname, $metadata); + send_event($event); + if($event->image_id == -1) { + throw new UploadException("File type not recognised"); + } elseif(class_exists("RatingSetEvent") && in_array($rating, array("s", "q", "e"))) { + $ratingevent = new RatingSetEvent(Image::by_id($event->image_id), $rating); + send_event($ratingevent); + } + } + + private function add_csv(/*string*/ $csvfile) { + global $page; + + if(!file_exists($csvfile)) { + $this->theme->add_status("Error", "$csvfile not found"); + return; + } + if (!is_file($csvfile) || strtolower(substr($csvfile, -4)) != ".csv") { + $this->theme->add_status("Error", "$csvfile doesn't appear to be a csv file"); + return; + } + + $linenum = 1; + $list = ""; + $csvhandle = fopen($csvfile, "r"); + + while (($csvdata = fgetcsv($csvhandle, 0, ",")) !== FALSE) { + if(count($csvdata) != 4) { + if(strlen($list) > 0) { + $this->theme->add_status("Error", "Encountered malformed data. Line $linenum $csvfile
".$list); + fclose($csvhandle); + return; + } else { + $this->theme->add_status("Error", "Encountered malformed data. Line $linenum $csvfile
Check here for the expected format"); + fclose($csvhandle); + return; + } + } + $fullpath = $csvdata[0]; + $tags = trim($csvdata[1]); + $source = $csvdata[2]; + $rating = $csvdata[3]; + $pathinfo = pathinfo($fullpath); + $shortpath = $pathinfo["basename"]; + $list .= "
".html_escape("$shortpath (".str_replace(" ", ", ", $tags).")... "); + if (file_exists($csvdata[0]) && is_file($csvdata[0])) { + try{ + $this->add_image($fullpath, $pathinfo["basename"], $tags, $source, $rating); + $list .= "ok\n"; + } + catch(Exception $ex) { + $list .= "failed:
". $ex->getMessage(); + } + } else { + $list .= "failed:
File doesn't exist ".html_escape($csvdata[0]); + } + $linenum += 1; + } + + if(strlen($list) > 0) { + $this->theme->add_status("Adding $csvfile", $list); + } + fclose($csvhandle); + } +} +?> diff --git a/ext/bulk_add_csv/theme.php b/ext/bulk_add_csv/theme.php new file mode 100644 index 00000000..dfff459b --- /dev/null +++ b/ext/bulk_add_csv/theme.php @@ -0,0 +1,44 @@ +set_title("Adding images from csv"); + $page->set_heading("Adding images from csv"); + $page->add_block(new NavBlock()); + foreach($this->messages as $block) { + $page->add_block($block); + } + } + + /* + * Add a section to the admin page. This should contain a form which + * links to bulk_add_csv with POST[csv] set to the name of a server-side + * csv file + */ + public function display_admin_block() { + global $page, $user; + $html = " + Add images from a csv. Images will be tagged and have their + source and rating set (if \"Image Ratings\" is enabled) +
Specify the absolute or relative path to a local .csv file. Check here for the expected format. + +

".make_form(make_link("bulk_add_csv"))." + + + +
CSV
+ + "; + $page->add_block(new Block("Bulk Add CSV", $html)); + } + + public function add_status($title, $body) { + $this->messages[] = new Block($title, $body); + } +} +?>