diff options
Diffstat (limited to 'modules/server_add')
-rw-r--r-- | modules/server_add/controllers/admin_server_add.php | 14 | ||||
-rw-r--r-- | modules/server_add/controllers/server_add.php | 388 | ||||
-rw-r--r-- | modules/server_add/helpers/server_add.php | 15 | ||||
-rw-r--r-- | modules/server_add/helpers/server_add_event.php (renamed from modules/server_add/helpers/server_add_menu.php) | 8 | ||||
-rw-r--r-- | modules/server_add/helpers/server_add_installer.php | 30 | ||||
-rw-r--r-- | modules/server_add/helpers/server_add_task.php | 85 | ||||
-rw-r--r-- | modules/server_add/helpers/server_add_theme.php | 8 | ||||
-rw-r--r-- | modules/server_add/js/server_add.js | 229 | ||||
-rw-r--r-- | modules/server_add/models/server_add_file.php | 21 | ||||
-rw-r--r-- | modules/server_add/module.info | 6 | ||||
-rw-r--r-- | modules/server_add/views/admin_server_add.html.php | 2 | ||||
-rw-r--r-- | modules/server_add/views/server_add_tree.html.php | 53 | ||||
-rw-r--r-- | modules/server_add/views/server_add_tree_dialog.html.php | 59 |
13 files changed, 396 insertions, 522 deletions
diff --git a/modules/server_add/controllers/admin_server_add.php b/modules/server_add/controllers/admin_server_add.php index a30215b8..30109f42 100644 --- a/modules/server_add/controllers/admin_server_add.php +++ b/modules/server_add/controllers/admin_server_add.php @@ -38,10 +38,7 @@ class Admin_Server_Add_Controller extends Admin_Controller { $path = $form->add_path->path->value; $paths[$path] = 1; module::set_var("server_add", "authorized_paths", serialize($paths)); - $form->add_path->inputs->path->value = ""; - message::success(t("Added path %path", array("path" => p::clean($path)))); - server_add::check_config($paths); url::redirect("admin/server_add"); } else { @@ -61,11 +58,12 @@ class Admin_Server_Add_Controller extends Admin_Controller { $path = $this->input->get("path"); $paths = unserialize(module::get_var("server_add", "authorized_paths")); - unset($paths[$path]); - message::success(t("Removed path %path", array("path" => p::clean($path)))); - module::set_var("server_add", "authorized_paths", serialize($paths)); - server_add::check_config($paths); - + if (isset($paths[$path])) { + unset($paths[$path]); + message::success(t("Removed path %path", array("path" => p::clean($path)))); + module::set_var("server_add", "authorized_paths", serialize($paths)); + server_add::check_config($paths); + } url::redirect("admin/server_add"); } diff --git a/modules/server_add/controllers/server_add.php b/modules/server_add/controllers/server_add.php index 05ea5058..bfb96506 100644 --- a/modules/server_add/controllers/server_add.php +++ b/modules/server_add/controllers/server_add.php @@ -17,258 +17,244 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Server_Add_Controller extends Controller { - public function index($id) { +class Server_Add_Controller extends Admin_Controller { + public function browse($id) { $paths = unserialize(module::get_var("server_add", "authorized_paths")); - - if (!user::active()->admin) { - access::forbidden(); + foreach (array_keys($paths) as $path) { + $files[] = $path; } $item = ORM::factory("item", $id); $view = new View("server_add_tree_dialog.html"); - $view->action = url::abs_site("__ARGS__/{$id}__TASK_ID__?csrf=" . access::csrf_token()); - $view->parents = $item->parents(); - $view->album_title = $item->title; - - $tree = new View("server_add_tree.html"); - $tree->data = array(); - $tree->checked = false; - $tree->tree_id = "tree_$id"; - foreach (array_keys($paths) as $path) { - $tree->data[$path] = array("path" => $path, "is_dir" => true); - } - $view->tree = $tree->__toString(); + $view->item = $item; + $view->tree = new View("server_add_tree.html"); + $view->tree->files = $files; + $view->tree->parents = array(); print $view; } public function children() { - if (!user::active()->admin) { - access::forbidden(); - } + $path = $this->input->get("path"); - $paths = unserialize(module::get_var("server_add", "authorized_paths")); - $path_valid = false; - $path = $this->input->post("path"); - $checked = $this->input->post("checked") == "true"; + $tree = new View("server_add_tree.html"); + $tree->files = array(); + $tree->parents = array(); - foreach (array_keys($paths) as $valid_path) { - if ($path_valid = strpos($path, $valid_path) === 0) { - break; + // Make a tree with the parents back up to the authorized path, and all the children under the + // current path. + if (server_add::is_valid_path($path)) { + $tree->parents[] = $path; + while (server_add::is_valid_path(dirname($tree->parents[0]))) { + array_unshift($tree->parents, dirname($tree->parents[0])); } - } - if (empty($path_valid)) { - throw new Exception("@todo BAD_PATH"); - } - if (!is_readable($path) || is_link($path)) { - kohana::show_404(); - } + foreach (glob("$path/*") as $file) { + if (!is_readable($file)) { + continue; + } + if (!is_dir($file)) { + $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION)); + if (!in_array($ext, array("gif", "jpeg", "jpg", "png", "flv", "mp4"))) { + continue; + } + } - $tree = new View("server_add_tree.html"); - $tree->data = $this->_get_children($path); - $tree->checked = $checked; - $tree->tree_id = "tree_" . md5($path); + $tree->files[] = $file; + } + } else { + // Missing or invalid path; print out the list of authorized path + $paths = unserialize(module::get_var("server_add", "authorized_paths")); + foreach (array_keys($paths) as $path) { + $tree->files[] = $path; + } + } print $tree; } - function start($id) { - if (!user::active()->admin) { - access::forbidden(); - } + /** + * Begin the task of adding photos. + */ + public function start() { access::verify_csrf(); + $item = ORM::factory("item", Input::instance()->get("item_id")); - $item = ORM::factory("item", $id); - $paths = unserialize(module::get_var("server_add", "authorized_paths")); - $input_files = $this->input->post("path"); - $collapsed = $this->input->post("collapsed"); - $files = array(); - $total_count = 0; - foreach (array_keys($paths) as $valid_path) { - $path_length = strlen($valid_path); - foreach ($input_files as $key => $path) { - if (!empty($path)) { - if ($valid_path != $path && strpos($path, $valid_path) === 0) { - $relative_path = substr(dirname($path), $path_length); - $name = basename($path); - $files[$valid_path][] = array("path" => $relative_path, - "parent_id" => $id, "name" => basename($path), - "type" => is_dir($path) ? "album" : "file"); - $total_count++; - } - if ($collapsed[$key] === "true") { - $total_count += $this->_select_children($id, $valid_path, $path, $files[$valid_path]); - } - unset($input_files[$key]); - unset($collapsed[$key]); - } + foreach (Input::instance()->post("paths") as $path) { + if (server_add::is_valid_path($path)) { + $paths[] = array($path, null); } } - if ($total_count == 0) { - print json_encode(array("result" => "success", - "url" => "", - "task" => array( - "id" => -1, "done" => 1, "percent_complete" => 100, - "status" => t("No eligible files, import cancelled")))); - return; - } - $task_def = Task_Definition::factory() - ->callback("server_add_task::add_from_server") + ->callback("Server_Add_Controller::add") ->description(t("Add photos or movies from the local server")) ->name(t("Add from server")); - $task = task::create($task_def, array("item_id" => $id, "next_path" => 0, "files" => $files, - "counter" => 0, "position" => 0, "total" => $total_count)); + $task = task::create($task_def, array("item_id" => $item->id, "queue" => $paths)); - batch::start(); - print json_encode(array("result" => "started", - "url" => url::site("server_add/add_photo/{$task->id}?csrf=" . - access::csrf_token()), - "task" => array( - "id" => $task->id, - "percent_complete" => $task->percent_complete, - "status" => $task->status, - "done" => $task->done))); + print json_encode( + array("result" => "started", + "status" => $task->status, + "url" => url::site("server_add/run/$task->id?csrf=" . access::csrf_token()))); } - function add_photo($task_id) { - if (!user::active()->admin) { - access::forbidden(); - } + /** + * Run the task of adding photos + */ + function run($task_id) { access::verify_csrf(); - $task = task::run($task_id); - // @todo the task is already run... its a little late to check the access - if (!$task->loaded || $task->owner_id != user::active()->id) { - access::forbidden(); - } - - if ($task->done) { - switch ($task->state) { - case "success": - message::success(t("Add from server completed")); - break; - - case "error": - message::warning(t("Add from server completed with errors")); - break; - } - print json_encode(array("result" => "success", - "task" => array( - "id" => $task->id, - "percent_complete" => $task->percent_complete, - "status" => $task->status, - "done" => $task->done))); - - } else { - print json_encode(array("result" => "in_progress", - "task" => array( - "id" => $task->id, - "percent_complete" => $task->percent_complete, - "status" => $task->status, - "done" => $task->done))); - } - } - - public function finish($id, $task_id) { - if (!user::active()->admin) { - access::forbidden(); - } - access::verify_csrf(); $task = ORM::factory("task", $task_id); - if (!$task->loaded || $task->owner_id != user::active()->id) { access::forbidden(); } - if (!$task->done) { - message::warning(t("Add from server was cancelled prior to completion")); - } - - batch::stop(); - print json_encode(array("result" => "success")); + $task = task::run($task_id); + print json_encode(array("done" => $task->done, + "status" => $task->status, + "percent_complete" => $task->percent_complete)); } - public function pause($id, $task_id) { - if (!user::active()->admin) { - access::forbidden(); - } - access::verify_csrf(); - $task = ORM::factory("task", $task_id); - if (!$task->loaded || $task->owner_id != user::active()->id) { - access::forbidden(); - } + /** + * This is the task code that adds photos and albums. It first examines all the target files + * and creates a set of Server_Add_File_Models, then runs through the list of models and adds + * them one at a time. + */ + static function add($task) { + $mode = $task->get("mode", "init"); + $start = microtime(true); - message::warning(t("Add from server was cancelled prior to completion")); - batch::stop(); - print json_encode(array("result" => "success")); - } + switch ($mode) { + case "init": + $task->set("mode", "build-file-list"); + $task->percent_complete = 0; + $task->status = t("Starting up"); + batch::start(); + break; - private function _select_children($id, $valid_path, $path, &$files) { - $count = 0; - $children = new RecursiveIteratorIterator( - new RecursiveDirectoryIterator($path), - RecursiveIteratorIterator::SELF_FIRST); + case "build-file-list": // 0% to 10% + // We can't fit an arbitrary number of paths in a task, so store them in a separate table. + // Don't use an iterator here because we can't get enough control over it when we're dealing + // with a deep hierarchy and we don't want to go over our time quota. The queue is in the + // form [path, parent_id] where the parent_id refers to another Server_Add_File_Model. We + // have this extra level of abstraction because we don't know its Item_Model id yet. + $queue = $task->get("queue"); + while ($queue && microtime(true) - $start < 0.5) { + list($file, $parent_entry_id) = array_shift($queue); + $entry = ORM::factory("server_add_file"); + $entry->task_id = $task->id; + $entry->file = $file; + $entry->parent_id = $parent_entry_id; + $entry->save(); - $path_length = strlen($valid_path); - foreach($children as $name => $file){ - if ($file->isLink()) { - continue; - } - $filename = $file->getFilename(); - if ($filename[0] != ".") { - if ($file->isDir()) { - $relative_path = substr(dirname($file->getPathname()), $path_length); - $files[] = array("path" => $relative_path, - "parent_id" => $id, "name" => $filename, "type" => "album"); - $count++; - } else { - $extension = strtolower(substr(strrchr($filename, '.'), 1)); - if ($file->isReadable() && - in_array($extension, array("gif", "jpeg", "jpg", "png", "flv", "mp4"))) { - $relative_path = substr(dirname($file->getPathname()), $path_length); - $files[] = array("path" => $relative_path, - "parent_id" => $id, "name" => $filename, "type" => "file"); - $count++; + foreach (glob("$file/*") as $child) { + if (is_dir($child)) { + $queue[] = array($child, $entry->id); + } else { + $ext = strtolower(pathinfo($child, PATHINFO_EXTENSION)); + if (in_array($ext, array("gif", "jpeg", "jpg", "png", "flv", "mp4")) && + filesize($child) > 0) { + $child_entry = ORM::factory("server_add_file"); + $child_entry->task_id = $task->id; + $child_entry->file = $child; + $child_entry->parent_id = $entry->id; + $child_entry->save(); + } } } } - } + // We have no idea how long this can take because we have no idea how deep the tree + // hierarchy rabbit hole goes. Leave ourselves room here for 100 iterations and don't go + // over 10% in percent_complete. + $task->set("queue", $queue); + $task->percent_complete = min($task->percent_complete + 0.1, 10); + $task->status = t2("Found one file", "Found %count files", + Database::instance() + ->where("task_id", $task->id) + ->count_records("server_add_files")); - return $count; - } + if (!$queue) { + $task->set("mode", "add-files"); + $task->set( + "total_files", database::instance()->count_records( + "server_add_files", array("task_id" => $task->id))); + $task->percent_complete = 10; + } + break; + + case "add-files": // 10% to 100% + $completed_files = $task->get("completed_files", 0); + $total_files = $task->get("total_files"); - private function _get_children($path) { - $directory_list = $file_list = array(); - $files = new DirectoryIterator($path); - foreach ($files as $file) { - if ($file->isDot() || $file->isLink()) { - continue; + // Ordering by id ensures that we add them in the order that we created the entries, which + // will create albums first. Ignore entries which already have an Item_Model attached, + // they're done. + $entries = ORM::factory("server_add_file") + ->where("task_id", $task->id) + ->where("item_id", null) + ->orderby("id", "ASC") + ->limit(10) + ->find_all(); + if ($entries->count() == 0) { + // Out of entries, we're done. + $task->set("mode", "done"); } - $filename = $file->getFilename(); - if ($filename[0] != ".") { - if ($file->isDir()) { - $directory_list[$filename] = array("path" => $file->getPathname(), "is_dir" => true); + + $owner_id = user::active()->id; + foreach ($entries as $entry) { + if (microtime(true) - $start > 0.5) { + break; + } + + // Look up the parent item for this entry. By now it should exist, but if none was + // specified, then this belongs as a child of the current item. + $parent_entry = ORM::factory("server_add_file", $entry->parent_id); + if (!$parent_entry->loaded) { + $parent = ORM::factory("item", $task->get("item_id")); } else { - $extension = strtolower(substr(strrchr($filename, '.'), 1)); - if ($file->isReadable() && - in_array($extension, array("gif", "jpeg", "jpg", "png", "flv", "mp4"))) { - $file_list[$filename] = array("path" => $file->getPathname(), "is_dir" => false); + $parent = ORM::factory("item", $parent_entry->item_id); + } + + $name = basename($entry->file); + $title = item::convert_filename_to_title($name); + if (is_dir($entry->file)) { + $album = album::create($parent, $name, $title, null, $owner_id); + $entry->item_id = $album->id; + } else { + $extension = strtolower(pathinfo($name, PATHINFO_EXTENSION)); + if (in_array($extension, array("gif", "png", "jpg", "jpeg"))) { + $photo = photo::create($parent, $entry->file, $name, $title, null, $owner_id); + $entry->item_id = $photo->id; + } else if (in_array($extension, array("flv", "mp4"))) { + $movie = movie::create($parent, $entry->file, $name, $title, null, $owner_id); + $entry->item_id = $movie->id; + } else { + // This should never happen, because we don't add stuff to the list that we can't + // process. But just in, case.. set this to a non-null value so that we skip this + // entry. + $entry->item_id = 0; + $task->log("Skipping unknown file type: $entry->file"); } } - } - } - ksort($directory_list); - ksort($file_list); + $completed_files++; + $entry->save(); + } + $task->set("completed_files", $completed_files); + $task->status = t("Adding photos / albums (%completed of %total)", + array("completed" => $completed_files, + "total" => $total_files)); + $task->percent_complete = 10 + 100 * ($completed_files / $total_files); + break; - // We can't use array_merge here because if a file name is numeric, it will - // get renumbered, so lets do it ourselves - foreach ($file_list as $file => $fileinfo) { - $directory_list[$file] = $fileinfo; + case "done": + batch::stop(); + $task->done = true; + $task->state = "success"; + $task->percent_complete = 100; + ORM::factory("server_add_file")->where("task_id", $task->id)->delete_all(); + message::info(t2("Successfully added one photo / album", + "Successfully added %count photos / albums", + $task->get("completed_files"))); } - return $directory_list; } -}
\ No newline at end of file +} diff --git a/modules/server_add/helpers/server_add.php b/modules/server_add/helpers/server_add.php index f75a09d2..74f51ad9 100644 --- a/modules/server_add/helpers/server_add.php +++ b/modules/server_add/helpers/server_add.php @@ -31,4 +31,19 @@ class server_add_Core { site_status::clear("server_add_configuration"); } } + + static function is_valid_path($path) { + if (!is_readable($path) || is_link($path)) { + return false; + } + + $authorized_paths = unserialize(module::get_var("server_add", "authorized_paths")); + foreach (array_keys($authorized_paths) as $valid_path) { + if (strpos($path, $valid_path) === 0) { + return true; + } + } + + return false; + } } diff --git a/modules/server_add/helpers/server_add_menu.php b/modules/server_add/helpers/server_add_event.php index 23878913..b53e72d1 100644 --- a/modules/server_add/helpers/server_add_menu.php +++ b/modules/server_add/helpers/server_add_event.php @@ -17,8 +17,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class server_add_menu_Core { - static function admin($menu, $theme) { +class server_add_event_Core { + static function admin_menu($menu, $theme) { $menu->get("settings_menu") ->append(Menu::factory("link") ->id("server_add") @@ -26,7 +26,7 @@ class server_add_menu_Core { ->url(url::site("admin/server_add"))); } - static function site($menu, $theme) { + static function site_menu($menu, $theme) { $item = $theme->item(); $paths = unserialize(module::get_var("server_add", "authorized_paths")); @@ -38,7 +38,7 @@ class server_add_menu_Core { $server_add = Menu::factory("dialog") ->id("server_add") ->label(t("Add from server")) - ->url(url::site("server_add/index/$item->id")); + ->url(url::site("server_add/browse/$item->id")); $add_photos_item = $menu->get("add_photos_item"); $add_photos_menu = $menu->get("add_photos_menu"); diff --git a/modules/server_add/helpers/server_add_installer.php b/modules/server_add/helpers/server_add_installer.php index c9d92e69..c3c1572d 100644 --- a/modules/server_add/helpers/server_add_installer.php +++ b/modules/server_add/helpers/server_add_installer.php @@ -19,10 +19,38 @@ */ class server_add_installer { static function install() { - module::set_version("server_add", 1); + $db = Database::instance(); + $db->query("CREATE TABLE {server_add_files} ( + `id` int(9) NOT NULL auto_increment, + `file` varchar(255) NOT NULL, + `item_id` int(9), + `parent_id` int(9), + `task_id` int(9) NOT NULL, + PRIMARY KEY (`id`)) + DEFAULT CHARSET=utf8;"); + module::set_version("server_add", 3); server_add::check_config(); } + static function upgrade($version) { + $db = Database::instance(); + if ($version == 1) { + $db->query("CREATE TABLE {server_add_files} ( + `id` int(9) NOT NULL auto_increment, + `task_id` int(9) NOT NULL, + `file` varchar(255) NOT NULL, + PRIMARY KEY (`id`)) + DEFAULT CHARSET=utf8;"); + module::set_version("server_add", $version = 2); + } + + if ($version == 2) { + $db->query("ALTER TABLE {server_add_files} ADD COLUMN `item_id` int(9)"); + $db->query("ALTER TABLE {server_add_files} ADD COLUMN `parent_id` int(9)"); + module::set_version("server_add", $version = 3); + } + } + static function deactivate() { site_status::clear("server_add_configuration"); } diff --git a/modules/server_add/helpers/server_add_task.php b/modules/server_add/helpers/server_add_task.php deleted file mode 100644 index 0482b47c..00000000 --- a/modules/server_add/helpers/server_add_task.php +++ /dev/null @@ -1,85 +0,0 @@ -<?php defined("SYSPATH") or die("No direct script access."); -/** - * Gallery - a web based photo album viewer and editor - * Copyright (C) 2000-2009 Bharat Mediratta - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. - */ -class server_add_task_Core { - static function available_tasks() { - // Return empty array so nothing appears in the maintenance screen - return array(); - } - - static function add_from_server($task) { - $context = unserialize($task->context); - try { - $paths = array_keys(unserialize(module::get_var("server_add", "authorized_paths"))); - $path = $paths[$context["next_path"]]; - if (!empty($context["files"][$path])) { - $file = $context["files"][$path][$context["position"]]; - $parent = ORM::factory("item", $file["parent_id"]); - access::required("add", $parent); - if (!$parent->is_album()) { - throw new Exception("@todo BAD_ALBUM"); - } - - $name = $file["name"]; - if ($file["type"] == "album") { - $album = ORM::factory("item") - ->where("name", $name) - ->where("parent_id", $parent->id) - ->find(); - if (!$album->loaded) { - $album = album::create($parent, $name, $name, null, user::active()->id); - } - // Now that we have a new album. Go through the remaining files to import and change the - // parent_id of any file that has the same relative path as this album's path. - $album_path = "{$file['path']}/$name"; - for ($idx = $context["position"] + 1; $idx < count($context["files"][$path]); $idx++) { - if (strpos($context["files"][$path][$idx]["path"], $album_path) === 0) { - $context["files"][$path][$idx]["parent_id"] = $album->id; - } - } - } else { - $extension = strtolower(substr(strrchr($name, '.'), 1)); - $source_path = "$path{$file['path']}/$name"; - $title = item::convert_filename_to_title($name); - if (in_array($extension, array("flv", "mp4"))) { - $movie = movie::create($parent, $source_path, $name, $title, - null, user::active()->id); - } else { - $photo = photo::create($parent, $source_path, $name, $title, - null, user::active()->id); - } - } - - $context["counter"]++; - if (++$context["position"] >= count($context["files"][$path])) { - $context["next_path"]++; - $context["position"] = 0; - } - } else { - $context["next_path"]++; - } - } catch(Exception $e) { - $context["errors"][$path] = $e->getMessage(); - } - $task->context = serialize($context); - $task->state = "success"; - $task->percent_complete = ($context["counter"] / (float)$context["total"]) * 100; - $task->done = $context["counter"] == (float)$context["total"]; - } -}
\ No newline at end of file diff --git a/modules/server_add/helpers/server_add_theme.php b/modules/server_add/helpers/server_add_theme.php index 02f99690..2ba2e167 100644 --- a/modules/server_add/helpers/server_add_theme.php +++ b/modules/server_add/helpers/server_add_theme.php @@ -20,20 +20,20 @@ class server_add_theme_Core { static function head($theme) { if (user::active()->admin) { - $theme->script("modules/server_add/js/server_add.js"); + $theme->script("server_add.js"); } } static function admin_head($theme) { $head = array(); if (strpos(Router::$current_uri, "admin/server_add") !== false) { - $theme->css("lib/jquery.autocomplete.css"); + $theme->css("jquery.autocomplete.css"); $base = url::site("__ARGS__"); $csrf = access::csrf_token(); $head[] = "<script> var base_url = \"$base\"; var csrf = \"$csrf\";</script>"; - $theme->script("lib/jquery.autocomplete.js"); - $theme->script("modules/server_add/js/admin.js"); + $theme->script("jquery.autocomplete.js"); + $theme->script("admin.js"); } return implode("\n", $head); diff --git a/modules/server_add/js/server_add.js b/modules/server_add/js/server_add.js index e2526dbe..fbd61dcc 100644 --- a/modules/server_add/js/server_add.js +++ b/modules/server_add/js/server_add.js @@ -1,205 +1,62 @@ -var paused = false; -var task = null; - -$("#gServerAdd").ready(function() { - init_server_add_form(); -}); - -function init_server_add_form() { - $("#gServerAdd #gServerAddButton").click(function(event) { - do_add(this, event); - }); - $("#gServerAdd #gServerPauseButton").click(function(event) { - event.preventDefault(); - paused = true; - }); - $(".gProgressBar").progressbar(); - $("#gServerAddTree ul").css("display", "block"); - $("#gServerAdd form").bind("form_closing", function(target) { - if (task != null && !task.done) { - $.ajax({async: false, - success: function(data, textStatus) { - document.location.reload(); - }, - dataType: "json", - type: "POST", - url: get_url("server_add/pause", task.id) - }); - } else { - document.location.reload(); - } - }); - set_click_events(); -} - -function set_click_events() { - $(".ui-icon").unbind("click"); - $(":checkbox").unbind("click"); - $(".ui-icon").click(function(event) { - open_close_branch(this, event); - }); - - $("input[type=checkbox]").click(function(event) { - checkbox_click(this); - }); -} - -function open_close_branch(icon, event) { - var parent = icon.parentNode; - var closed = $(icon).hasClass("ui-icon-plus"); - var children = $(parent).find(".gCheckboxTree"); - - if (closed) { - if (children.length == 0) { - load_children(icon); - } else { - toggle_branch("open", icon); - } +/** + * Manage file selection state. + */ +function select_file(li) { + $(li).toggleClass("selected"); + if ($("#gServerAdd span.selected").length) { + $("#gServerAddAddButton").enable(true).removeClass("ui-state-disabled"); } else { - toggle_branch("close", icon); + $("#gServerAddAddButton").enable(false).addClass("ui-state-disabled"); } } -function toggle_branch(direction, icon) { - var parent = icon.parentNode; - var branch = $(parent).children(".gServerAddChildren"); - $(branch).slideToggle("fast", function() { - if (direction == "open") { - $(icon).addClass("ui-icon-minus"); - $(icon).removeClass("ui-icon-plus"); - $(parent).removeClass("gCollapsed"); - } else { - $(icon).addClass("ui-icon-plus"); - $(icon).removeClass("ui-icon-minus"); +/** + * Load a new directory + */ +function open_dir(path) { + $.ajax({ + url: GET_CHILDREN_URL.replace("__PATH__", path), + success: function(data, textStatus) { + $("#gServerAddTree").html(data); } }); } -function get_url(uri, task_id) { - var url = $("#gServerAdd form").attr("action"); - url = url.replace("__ARGS__", uri); - url = url.replace("__TASK_ID__", !task_id ? "" : "/" + task_id); - return url; -} - -function checkbox_click(checkbox) { - var parent = $(checkbox).parents("li").get(0); - var checked = $(checkbox).attr("checked"); - if (!$(parent).hasClass("gCollapsed")) { - $(parent).find(".gCheckboxTree input[type=checkbox]").attr("checked", checked); - } - var checkboxes = $("#gServerAdd :checkbox[checked]"); - $("#gServerAdd form :submit").attr("disabled", checkboxes.length == 0); -} - -function load_children(icon) { - $("#gDialog").addClass("gDialogLoadingLarge"); - var parent = icon.parentNode; - var checkbox = $(parent).find("input[type=checkbox]"); - var parms = "&path=" + $(checkbox).attr("value"); - parms += "&checked=" + $(checkbox).is(":checked"); - parms += "&collapsed=" + $(parent).hasClass("gCollapsed"); +function start_add() { + var paths = []; + $.each($("#gServerAdd span.selected"), function () { + paths.push($(this).attr("file")); + }); - $.ajax({success: function(data, textStatus) { - $(parent).children(".gServerAddChildren").html(data); - set_click_events(); - $("#gDialog").removeClass("gDialogLoadingLarge"); - toggle_branch("open", icon); - }, - data: parms, - dataType: "html", - type: "POST", - url: get_url("server_add/children") + $.ajax({ + url: START_URL, + type: "POST", + async: false, + data: { "paths[]": paths }, + dataType: "json", + success: function(data, textStatus) { + $("#gStatus").html(data.status); + $("#gServerAdd .gProgressBar").progressbar("value", data.percent_complete); + setTimeout(function() { run_add(data.url); }, 0); + } }); + return false; } -function do_add(submit, event) { - event.preventDefault(); - - $("#gServerAdd #gServerAddButton").hide(); - $("#gServerAdd #gServerPauseButton").show(); - - var parms = ""; - if (!paused) { - $(".gProgressBar").progressbar("value", 0); - $(".gProgressBar").css("visibility", "visible"); - var check_list = $("#gServerAdd :checkbox[checked]"); - - var paths = ""; - var collapsed = ""; - $.each(check_list, function () { - var parent = $(this).parents("li")[0]; - paths += "&path[]=" + this.value; - collapsed += "&collapsed[]=" + $(parent).hasClass("gCollapsed"); - }); - parms = paths + collapsed; - } - paused = false; - - $.ajax({async: false, - data: parms, +function run_add(url) { + $.ajax({ + url: url, + async: false, dataType: "json", success: function(data, textStatus) { - var done = data.task.done; - if (done) { - task = null; - $("body").append("<div id='gNoFilesDialog'>" + data.task.status + "</div>"); - - $("#gNoFilesDialog").dialog({modal: true, - autoOpen: true, - title: FILE_IMPORT_WARNING}); - $(".gProgressBar").css("visibility", "hidden"); - $("#gServerAdd #gServerAddButton").show(); - $("#gServerAdd #gServerPauseButton").hide(); - return; - } - task = data.task; - var url = data.url; - while (!done && !paused) { - $.ajax({async: false, - success: function(data, textStatus) { - $(".gProgressBar").progressbar("value", data.task.percent_complete); - done = data.task.done; - }, - error: function(XMLHttpRequest, textStatus, errorThrown) { - paused = true; - display_upload_error(XMLHttpRequest.responseText); - }, - dataType: "json", - type: "POST", - url: url - }); - } - if (!paused) { - $.ajax({async: false, - success: function(data, textStatus) { - document.location.reload(); - }, - dataType: "json", - type: "POST", - url: get_url("server_add/finish", task.id) - }); + $("#gStatus").html(data.status); + $("#gServerAdd .gProgressBar").progressbar("value", data.percent_complete); + if (data.done) { + $("#gServerAddProgress").slideUp(); } else { - $("#gServerAdd #gServerAddButton").show(); - $("#gServerAdd #gServerPauseButton").hide(); + setTimeout(function() { run_add(url); }, 0); } - }, - type: "POST", - url: get_url("server_add/start") + } }); - - return false; -} - -function display_upload_error(error) { - $("body").append("<div id=\"gServerAddError\" title=\"" + FATAL_ERROR + "\">" + error + "</div>"); - $("#gServerAddError").dialog({ - autoOpen: true, - autoResize: false, - modal: true, - resizable: true, - width: 610, - height: $("#gDialog").height() - }); } diff --git a/modules/server_add/models/server_add_file.php b/modules/server_add/models/server_add_file.php new file mode 100644 index 00000000..8b1ed924 --- /dev/null +++ b/modules/server_add/models/server_add_file.php @@ -0,0 +1,21 @@ +<?php defined("SYSPATH") or die("No direct script access."); +/** + * Gallery - a web based photo album viewer and editor + * Copyright (C) 2000-2009 Bharat Mediratta + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ +class Server_Add_File_Model extends ORM { +} diff --git a/modules/server_add/module.info b/modules/server_add/module.info index 04e2b2ba..23acab94 100644 --- a/modules/server_add/module.info +++ b/modules/server_add/module.info @@ -1,3 +1,3 @@ -name = Server Add -description = Allows authorized users to load images directly from your web server -version = 1 +name = "Server Add" +description = "Allows authorized users to load images directly from your web server" +version = 3 diff --git a/modules/server_add/views/admin_server_add.html.php b/modules/server_add/views/admin_server_add.html.php index 588a9fca..30ab3536 100644 --- a/modules/server_add/views/admin_server_add.html.php +++ b/modules/server_add/views/admin_server_add.html.php @@ -11,7 +11,7 @@ <ul id="gPathList"> <? foreach ($paths as $id => $path): ?> <li class="ui-icon-left"> - <a href="<?= url::site("admin/server_add/remove_path?path=$path&csrf=$csrf") ?>" + <a href="<?= url::site("admin/server_add/remove_path?path=$path&csrf=$csrf") ?>" id="icon_<?= $id?>" class="gRemoveDir ui-icon ui-icon-trash"> X diff --git a/modules/server_add/views/server_add_tree.html.php b/modules/server_add/views/server_add_tree.html.php index 33047fb3..254a9da0 100644 --- a/modules/server_add/views/server_add_tree.html.php +++ b/modules/server_add/views/server_add_tree.html.php @@ -1,14 +1,41 @@ <?php defined("SYSPATH") or die("No direct script access.") ?> -<script type="text/javascript"> -</script> -<ul id="<?= $tree_id ?>" class="gCheckboxTree"> - <? foreach ($data as $file => $file_info): ?> - <li class="<?= empty($file_info["is_dir"]) ? "gFile" : "gDirectory gCollapsed ui-icon-left" ?>"> - <? if (!empty($file_info["is_dir"])): ?> - <span class="ui-icon ui-icon-plus"></span> - <? endif ?> - <label> <?= form::checkbox("checkbox[]", p::clean($file_info["path"]), $checked) . " " . p::clean($file) ?> </label> - <div class="gServerAddChildren" style="display: none"></div> - </li> - <? endforeach ?> -</ul> +<li class="ui-icon-left"> + <span class="ui-icon ui-icon-folder-open"></span> + <span ondblclick="open_dir('')"> + <?= t("All") ?> + </span> + <ul> + + <? foreach ($parents as $dir): ?> + <li class="ui-icon-left"> + <span class="ui-icon ui-icon-folder-open"></span> + <span ondblclick="open_dir('<?= $dir ?>')"> + <?= basename($dir) ?> + </span> + <ul> + <? endforeach ?> + + <? foreach ($files as $file): ?> + <li class="ui-icon-left"> + <span class="ui-icon <?= is_dir($file) ? "ui-icon-folder-collapsed" : "ui-icon-document" ?>"></span> + <span onclick="select_file(this)" + <? if (is_dir($file)): ?> + ondblclick="open_dir($(this).attr('file'))" + <? endif ?> + file="<?= $file ?>" + > + <?= p::clean(basename($file)) ?> + </span> + </li> + <? endforeach ?> + <? if (!$files): ?> + <li> <i> <?= t("empty") ?> </i> </li> + <? endif ?> + + <? foreach ($parents as $dir): ?> + </ul> + </li> + <? endforeach ?> + + </ul> +</li> diff --git a/modules/server_add/views/server_add_tree_dialog.html.php b/modules/server_add/views/server_add_tree_dialog.html.php index 8b296987..431635f8 100644 --- a/modules/server_add/views/server_add_tree_dialog.html.php +++ b/modules/server_add/views/server_add_tree_dialog.html.php @@ -1,30 +1,57 @@ <?php defined("SYSPATH") or die("No direct script access.") ?> -<script> - var FATAL_ERROR = "<?= t("Fatal Error") ?>"; - var FILE_IMPORT_WARNING = "<?= t("Add from server warning") ?>"; - $("#gServerAdd").ready(function() { - init_server_add_form(); - }); +<script type="text/javascript"> + var GET_CHILDREN_URL = "<?= url::site("server_add/children?path=__PATH__") ?>"; + var START_URL = "<?= url::site("server_add/start?item_id={$item->id}&csrf=$csrf") ?>"; </script> + <div id="gServerAdd"> - <h1 style="display: none;"><?= t("Add Photos to '%title'", array("title" => p::clean($album_title))) ?></h1> + <h1 style="display: none;"><?= t("Add Photos to '%title'", array("title" => p::purify($item->title))) ?></h1> <p id="gDescription"><?= t("Photos will be added to album:") ?></p> <ul class="gBreadcrumbs"> - <? foreach ($parents as $parent): ?> - <li><?= p::clean($parent->title) ?></li> + <? foreach ($item->parents() as $parent): ?> + <li> + <?= p::purify($parent->title) ?> + </li> <? endforeach ?> - <li class="active"><?= p::clean($album_title) ?></li> + <li class="active"> + <?= p::purify($item->title) ?> + </li> </ul> - <?= form::open($action, array("method" => "post")) ?> - <div id="gServerAddTree" > + <ul id="gServerAddTree" class="gCheckboxTree"> <?= $tree ?> + </ul> + + <div id="gServerAddProgress" style="display: none"> + <div class="gProgressBar"></div> + <div id="gStatus"></div> </div> + <span> - <?= form::submit(array("id" => "gServerPauseButton", "name" => "add", "disabled" => true, "class" => "submit", "style" => "display:none"), t("Pause")) ?> - <?= form::submit(array("id" => "gServerAddButton", "name" => "add", "disabled" => true, "class" => "submit"), t("Add")) ?> + <button id="gServerAddAddButton" class="ui-state-default ui-state-disabled ui-corner-all" + disabled="disabled"> + <?= t("Add") ?> + </button> + + <button id="gServerCloseButton" class="ui-state-default ui-corner-all"> + <?= t("Close") ?> + </button> </span> - <?= form::close() ?> - <div class="gProgressBar" style="visibility: hidden" ></div> + + <script type="text/javascript"> + $("#gServerAddAddButton").ready(function() { + $("#gServerAddAddButton").click(function(event) { + event.preventDefault(); + $("#gServerAdd .gProgressBar"). + progressbar(). + progressbar("value", 0); + $("#gServerAddProgress").slideDown("fast", function() { start_add() }); + }); + $("#gServerCloseButton").click(function(event) { + $("#gDialog").dialog("close"); + }); + }); + </script> + </div> |