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