public function add_photo($id) { $album = ORM::factory("item", $id); access::required("view", $album); access::required("add", $album); access::verify_csrf(); $file_validation = new Validation($_FILES); $file_validation->add_rules("Filedata", "upload::valid", "upload::type[gif,jpg,png,flv,mp4]"); if ($file_validation->validate()) { // SimpleUploader.swf does not yet call /start directly, so simulate it here for now. if (!batch::in_progress()) { batch::start(); } $temp_filename = upload::save("Filedata"); try { $name = substr(basename($temp_filename), 10); // Skip unique identifier Kohana adds $title = item::convert_filename_to_title($name); $path_info = pathinfo($temp_filename); if (array_key_exists("extension", $path_info) && in_array(strtolower($path_info["extension"]), array("flv", "mp4"))) { $movie = movie::create($album, $temp_filename, $name, $title); log::success("content", t("Added a movie"), html::anchor("movies/{$movie->id}", t("view movie"))); } else { $photo = photo::create($album, $temp_filename, $name, $title); log::success("content", t("Added a photo"), html::anchor("photos/{$photo->id}", t("view photo"))); } } catch (Exception $e) { unlink($temp_filename); throw $e; } unlink($temp_filename); } print "File Received"; }
public function createFile($name, $data = null) { try { access::required("view", $this->item); access::required("add", $this->item); } catch (Kohana_404_Exception $e) { throw new Sabre_DAV_Exception_Forbidden("Access denied"); } if (substr($name, 0, 1) == ".") { return true; } try { $tempfile = tempnam(TMPPATH, "dav"); $target = fopen($tempfile, "wb"); stream_copy_to_stream($data, $target); fclose($target); $item = ORM::factory("item"); $item->name = $name; $item->title = item::convert_filename_to_title($item->name); $item->description = ""; $item->parent_id = $this->item->id; $item->set_data_file($tempfile); $item->type = "photo"; $item->save(); } catch (Exception $e) { unlink($tempfile); throw $e; } }
public function add_photo($id) { $album = ORM::factory("item", $id); access::required("view", $album); access::required("add", $album); access::verify_csrf(); // The Flash uploader not call /start directly, so simulate it here for now. if (!batch::in_progress()) { batch::start(); } $form = $this->_get_add_form($album); // Uploadify adds its own field to the form, so validate that separately. $file_validation = new Validation($_FILES); $file_validation->add_rules("Filedata", "upload::valid", "upload::required", "upload::type[" . implode(",", legal_file::get_extensions()) . "]"); if ($form->validate() && $file_validation->validate()) { $temp_filename = upload::save("Filedata"); Event::add("system.shutdown", create_function("", "unlink(\"{$temp_filename}\");")); try { $item = ORM::factory("item"); $item->name = substr(basename($temp_filename), 10); // Skip unique identifier Kohana adds $item->title = item::convert_filename_to_title($item->name); $item->parent_id = $album->id; $item->set_data_file($temp_filename); // Remove double extensions from the filename - they'll be disallowed in the model but if // we don't do it here then it'll result in a failed upload. $item->name = legal_file::smash_extensions($item->name); $path_info = @pathinfo($temp_filename); if (array_key_exists("extension", $path_info) && in_array(strtolower($path_info["extension"]), legal_file::get_movie_extensions())) { $item->type = "movie"; $item->save(); log::success("content", t("Added a movie"), html::anchor("movies/{$item->id}", t("view movie"))); } else { $item->type = "photo"; $item->save(); log::success("content", t("Added a photo"), html::anchor("photos/{$item->id}", t("view photo"))); } module::event("add_photos_form_completed", $item, $form); } catch (Exception $e) { // The Flash uploader has no good way of reporting complex errors, so just keep it simple. Kohana_Log::add("error", $e->getMessage() . "\n" . $e->getTraceAsString()); // Ugh. I hate to use instanceof, But this beats catching the exception separately since // we mostly want to treat it the same way as all other exceptions if ($e instanceof ORM_Validation_Exception) { Kohana_Log::add("error", "Validation errors: " . print_r($e->validation->errors(), 1)); } header("HTTP/1.1 500 Internal Server Error"); print "ERROR: " . $e->getMessage(); return; } print "FILEID: {$item->id}"; } else { header("HTTP/1.1 400 Bad Request"); print "ERROR: " . t("Invalid upload"); } }
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"] / (double) $context["total"] * 100; $task->done = $context["counter"] == (double) $context["total"]; }
public function add_photo($id) { $album = ORM::factory("item", $id); access::required("view", $album); access::required("add", $album); access::verify_csrf(); $file_validation = new Validation($_FILES); $file_validation->add_rules("Filedata", "upload::valid", "upload::required", "upload::type[gif,jpg,jpeg,png,flv,mp4]"); if ($file_validation->validate()) { // SimpleUploader.swf does not yet call /start directly, so simulate it here for now. if (!batch::in_progress()) { batch::start(); } $temp_filename = upload::save("Filedata"); try { $name = substr(basename($temp_filename), 10); // Skip unique identifier Kohana adds $title = item::convert_filename_to_title($name); $path_info = @pathinfo($temp_filename); if (array_key_exists("extension", $path_info) && in_array(strtolower($path_info["extension"]), array("flv", "mp4"))) { $item = movie::create($album, $temp_filename, $name, $title); log::success("content", t("Added a movie"), html::anchor("movies/{$item->id}", t("view movie"))); } else { $item = photo::create($album, $temp_filename, $name, $title); log::success("content", t("Added a photo"), html::anchor("photos/{$item->id}", t("view photo"))); } // We currently have no way of showing errors if validation fails, so only call our event // handlers if validation passes. $form = $this->_get_add_form($album); if ($form->validate()) { module::event("add_photos_form_completed", $item, $form); } } catch (Exception $e) { Kohana_Log::add("alert", $e->__toString()); if (file_exists($temp_filename)) { unlink($temp_filename); } header("HTTP/1.1 500 Internal Server Error"); print "ERROR: " . $e->getMessage(); return; } unlink($temp_filename); print "FILEID: {$item->id}"; } else { header("HTTP/1.1 400 Bad Request"); print "ERROR: " . t("Invalid Upload"); } }
public function add_photo($id) { access::verify_csrf(); $album = ORM::factory("item", $id); access::required("view", $album); access::required("add", $album); try { $name = $_REQUEST["filename"]; $body = @file_get_contents('php://input'); //$stream = http_get_request_body(); $directory = Kohana::config('upload.directory', TRUE); // Make sure the directory ends with a slash $directory = str_replace('\\', '/', $directory); $directory = rtrim($directory, '/') . '/'; if (!is_dir($directory) and Kohana::config('upload.create_directories') === TRUE) { // Create the upload directory mkdir($directory, 0777, TRUE); } if (!is_writable($directory)) { throw new Kohana_Exception('upload.not_writable', $directory); } $temp_filename = $directory . $name; $file = fopen($temp_filename, 'w'); fwrite($file, $body); fclose($file); $item = ORM::factory("item"); $item->name = basename($temp_filename); // Skip unique identifier Kohana adds $item->title = item::convert_filename_to_title($item->name); $item->parent_id = $album->id; $item->set_data_file($temp_filename); $path_info = @pathinfo($temp_filename); if (array_key_exists("extension", $path_info) && in_array(strtolower($path_info["extension"]), array("flv", "mp4"))) { $item->type = "movie"; $item->save(); log::success("content", t("Added a movie"), html::anchor("movies/{$item->id}", t("view movie"))); } else { $item->type = "photo"; $item->save(); log::success("content", t("Added a photo"), html::anchor("photos/{$item->id}", t("view photo"))); } } catch (Exception $e) { Kohana::log("alert", $e->__toString()); if (file_exists($temp_filename)) { unlink($temp_filename); } throw new Kohana_Exception('Problem creating file.' . $e->__toString()); } unlink($temp_filename); print json_encode(self::child_json_encode($item)); }
public function convert_filename_to_title_test() { $this->assert_equal("foo", item::convert_filename_to_title("foo.jpg")); $this->assert_equal("foo.bar", item::convert_filename_to_title("foo.bar.jpg")); }
/** * 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); switch ($mode) { case "init": $task->set("mode", "build-file-list"); $task->percent_complete = 0; $task->status = t("Starting up"); batch::start(); break; 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(); 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"))) { $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")); 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"); // 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"); } $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 { $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}"); } } } $completed_files++; $entry->save(); } $task->set("completed_files", $completed_files); $task->status = t("Adding photos and albums (%completed of %total)", array("completed" => $completed_files, "total" => $total_files)); $task->percent_complete = 10 + 100 * ($completed_files / $total_files); break; 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", "Successfully added %count photos and albums", $task->get("completed_files"))); } }
static function cron() { $owner_id = 2; $debug = !empty($_SERVER['argv']) && isset($_SERVER['argv'][1]) && $_SERVER['argv'][1] == "debug"; // Login as Admin $debug and print "Starting user session\n"; $session = Session::instance(); $session->delete("user"); auth::login(IdentityProvider::instance()->admin_user()); // check if some folders are still unprocessed from previous run $entry = ORM::factory("folder_sync_entry")->where("is_directory", "=", 1)->where("checked", "=", 0)->order_by("id", "ASC")->find(); if (!$entry->loaded()) { $debug and print "Adding default folders\n"; $paths = unserialize(module::get_var("folder_sync", "authorized_paths")); foreach (array_keys($paths) as $path) { if (folder_sync::is_valid_path($path)) { $path = rtrim($path, "/"); $debug and print " * {$path}\n"; $entry = ORM::factory("folder_sync_entry")->where("is_directory", "=", 1)->where("path", "=", $path)->find(); if ($entry && $entry->loaded()) { $entry->checked = 0; $entry->save(); } else { $entry = ORM::factory("folder_sync_entry"); $entry->path = $path; $entry->is_directory = 1; $entry->parent_id = null; $entry->item_id = module::get_var("folder_sync", "destination_album_id", 1); $entry->md5 = ''; $entry->save(); } } } } // Scan and add files $debug and print "Starting the loop\n"; $done = false; $limit = 500; while (!$done && $limit > 0) { $debug and print "Loop started: Limit = {$limit}\n"; $entry = ORM::factory("folder_sync_entry")->where("is_directory", "=", 1)->where("checked", "=", 0)->order_by("id", "ASC")->find(); if ($entry->loaded()) { // get the parrent $parent = ORM::factory("item", $entry->item_id); if (!$parent->loaded()) { $debug and print "Deleting entry #{$entry->id} pointing to missing item #{$entry->item_id}\n"; //$entry->delete(); //continue; } $debug and print "Scanning folder: {$entry->path}\n"; $child_paths = glob(preg_quote($entry->path) . "/*"); if (!$child_paths) { $child_paths = glob("{$entry->path}/*"); } foreach ($child_paths as $child_path) { $name = basename($child_path); $title = item::convert_filename_to_title($name); $debug and print "Found {$child_path}..."; if (is_dir($child_path)) { $debug and print "folder\n"; $entry_exists = ORM::factory("folder_sync_entry")->where("is_directory", "=", 1)->where("path", "=", $child_path)->find(); if ($entry_exists && $entry_exists->loaded()) { $debug and print "Folder is already imported, marked to re-sync.\n"; $entry_exists->checked = 0; $entry_exists->save(); } else { $debug and print "Adding new folder.\n"; $album = ORM::factory("item"); $album->type = "album"; $album->parent_id = $parent->id; $album->name = $name; $album->title = $title; $album->owner_id = $owner_id; $album->sort_order = $parent->sort_order; $album->sort_column = $parent->sort_column; $album->save(); $child_entry = ORM::factory("folder_sync_entry"); $child_entry->path = $child_path; $child_entry->parent_id = $entry->id; $child_entry->item_id = $album->id; $child_entry->is_directory = 1; $child_entry->md5 = ""; $child_entry->save(); } } else { $debug and print "file\n"; $ext = strtolower(pathinfo($child_path, PATHINFO_EXTENSION)); if (!in_array($ext, legal_file::get_extensions()) || !filesize($child_path)) { // Not importable, skip it. $debug and print "File is incompatible. Skipping.\n"; continue; } // check if file was already imported $entry_exists = ORM::factory("folder_sync_entry")->where("is_directory", "=", 0)->where("path", "=", $child_path)->find(); if ($entry_exists && $entry_exists->loaded()) { $debug and print "Image is already imported..."; if (empty($entry_exists->added) || empty($entry_exists->md5) || $entry_exists->added != filemtime($child_path) || $entry_exists->md5 != md5_file($child_path)) { $item = ORM::factory("item", $entry_exists->item_id); if ($item->loaded()) { $item->set_data_file($child_path); $debug and print "updating.\n"; try { $item->save(); } catch (ORM_Validation_Exception $e) { print "Error saving the image (ID = {$item->id}) with the new data file.\n"; exit; } } else { $debug and print "deleting.\n"; $entry_exists->delete(); } } else { $debug and print "skipping.\n"; } // since it's an update, don't count too much towards the limit $limit -= 0.25; } else { if (in_array($ext, legal_file::get_photo_extensions())) { $debug and print "Adding new photo.\n"; $item = ORM::factory("item"); $item->type = "photo"; $item->parent_id = $parent->id; $item->set_data_file($child_path); $item->name = $name; $item->title = $title; $item->owner_id = $owner_id; $item->save(); } else { if (in_array($ext, legal_file::get_movie_extensions())) { $debug and print "Adding new video.\n"; $item = ORM::factory("item"); $item->type = "movie"; $item->parent_id = $parent->id; $item->set_data_file($child_path); $item->name = $name; $item->title = $title; $item->owner_id = $owner_id; $item->save(); } } $entry_exists = ORM::factory("folder_sync_entry"); $entry_exists->path = $child_path; $entry_exists->parent_id = $entry->id; // null if the parent was a staging dir $entry_exists->is_directory = 0; $entry_exists->md5 = md5_file($child_path); $entry_exists->added = filemtime($child_path); $entry_exists->item_id = $item->id; $entry_exists->save(); $limit--; } } // Did we hit the limit? if ($limit <= 0) { $debug and print "Reached the limit. Exiting.\n"; exit; } } // We've processed this entry unless we reached a limit. if ($limit > 0) { $entry->checked = 1; $entry->save(); } } else { $done = true; $debug and print "All folders are processed. Exiting.\n"; } } // process deletes if (module::get_var("folder_sync", "process_deletes", false)) { $entries = ORM::factory("folder_sync_entry")->order_by("id", "ASC")->find_all(); foreach ($entries as $entry) { if (!file_exists($entry->path) && $entry->item_id > 1) { $item = ORM::factory("item", $entry->item_id); if ($item->loaded()) { $item->delete(); } } } } exit; }
/** * This is the task code that adds photos and albums. It first examines all the target files * and creates a set of Server_Add_Entry_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); switch ($mode) { case "init": $task->set("mode", "build-file-list"); $task->set("dirs_scanned", 0); $task->percent_complete = 0; $task->status = t("Starting up"); batch::start(); break; 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. $paths = unserialize(module::get_var("server_add", "authorized_paths")); $dirs_scanned = $task->get("dirs_scanned"); while (microtime(true) - $start < 0.5) { // Process every directory that doesn't yet have a parent id, these are the // paths that we're importing. $entry = ORM::factory("server_add_entry")->where("task_id", "=", $task->id)->where("is_directory", "=", 1)->where("checked", "=", 0)->order_by("id", "ASC")->find(); if ($entry->loaded()) { $child_paths = glob(preg_quote($entry->path) . "/*"); if (!$child_paths) { $child_paths = glob("{$entry->path}/*"); } foreach ($child_paths as $child_path) { if (!is_dir($child_path)) { $ext = strtolower(pathinfo($child_path, PATHINFO_EXTENSION)); if (!legal_file::get_extensions($ext) || !filesize($child_path)) { // Not importable, skip it. continue; } } $child_entry = ORM::factory("server_add_entry"); $child_entry->task_id = $task->id; $child_entry->path = $child_path; $child_entry->parent_id = $entry->id; // null if the parent was a staging dir $child_entry->is_directory = is_dir($child_path); $child_entry->save(); } // We've processed this entry, mark it as done. $entry->checked = 1; $entry->save(); $dirs_scanned++; } } // 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("dirs_scanned", $dirs_scanned); $task->percent_complete = min($task->percent_complete + 0.1, 10); $task->status = t2("Scanned one directory", "Scanned %count directories", $dirs_scanned); if (!$entry->loaded()) { $task->set("mode", "add-files"); $task->set("total_files", ORM::factory("server_add_entry")->where("task_id", "=", $task->id)->count_all()); $task->percent_complete = 10; } break; case "add-files": // 10% to 100% $completed_files = $task->get("completed_files", 0); $total_files = $task->get("total_files"); // 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_entry")->where("task_id", "=", $task->id)->where("item_id", "IS", null)->order_by("id", "ASC")->limit(10)->find_all(); if ($entries->count() == 0) { // Out of entries, we're done. $task->set("mode", "done"); } $owner_id = identity::active_user()->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_entry", $entry->parent_id); if (!$parent_entry->loaded()) { $parent = ORM::factory("item", $task->get("item_id")); } else { $parent = ORM::factory("item", $parent_entry->item_id); } $name = basename($entry->path); $title = item::convert_filename_to_title($name); if ($entry->is_directory) { $album = ORM::factory("item"); $album->type = "album"; $album->parent_id = $parent->id; $album->name = $name; $album->title = $title; $album->owner_id = $owner_id; $album->sort_order = $parent->sort_order; $album->sort_column = $parent->sort_column; $album->save(); $entry->item_id = $album->id; } else { try { $extension = strtolower(pathinfo($name, PATHINFO_EXTENSION)); if (legal_file::get_photo_extensions($extension)) { $photo = ORM::factory("item"); $photo->type = "photo"; $photo->parent_id = $parent->id; $photo->set_data_file($entry->path); $photo->name = $name; $photo->title = $title; $photo->owner_id = $owner_id; $photo->save(); $entry->item_id = $photo->id; } else { if (legal_file::get_movie_extensions($extension)) { $movie = ORM::factory("item"); $movie->type = "movie"; $movie->parent_id = $parent->id; $movie->set_data_file($entry->path); $movie->name = $name; $movie->title = $title; $movie->owner_id = $owner_id; $movie->save(); $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->path}"); } } } catch (Exception $e) { // This can happen if a photo file is invalid, like a BMP masquerading as a .jpg $entry->item_id = 0; $task->log("Skipping invalid file: {$entry->path}"); } } $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 = $total_files ? 10 + 100 * ($completed_files / $total_files) : 100; break; case "done": batch::stop(); $task->done = true; $task->state = "success"; $task->percent_complete = 100; ORM::factory("server_add_entry")->where("task_id", "=", $task->id)->delete_all(); message::info(t2("Successfully added one photo / album", "Successfully added %count photos / albums", $task->get("completed_files"))); } }
/** * Add photo or movie from upload. Once we have a valid file, this generates an item model * from it. It returns the item model on success, and throws an exception and adds log entries * on failure. * @TODO: consider moving this to a common controller which is extended by various uploaders. * * @param int parent album id * @param string temp file path (analogous to $_FILES[...]["tmp_name"]) * @param string filename (analogous to $_FILES[...]["name"]) * @return object new item model */ private function _add_item($album_id, $tmp_name, $name) { $extension = pathinfo($name, PATHINFO_EXTENSION); try { $item = ORM::factory("item"); $item->name = $name; $item->title = item::convert_filename_to_title($name); $item->parent_id = $album_id; $item->set_data_file($tmp_name); if (!$extension) { throw new Exception(t("Uploaded file has no extension")); } else { if (legal_file::get_photo_extensions($extension)) { $item->type = "photo"; $item->save(); log::success("content", t("Added a photo"), html::anchor("photos/{$item->id}", t("view photo"))); } else { if (movie::allow_uploads() && legal_file::get_movie_extensions($extension)) { $item->type = "movie"; $item->save(); log::success("content", t("Added a movie"), html::anchor("movies/{$item->id}", t("view movie"))); } else { throw new Exception(t("Uploaded file has illegal extension")); } } } } catch (Exception $e) { // Log errors then re-throw exception. Kohana_Log::add("error", $e->getMessage() . "\n" . $e->getTraceAsString()); // If we have a validation error, add an additional log entry. if ($e instanceof ORM_Validation_Exception) { Kohana_Log::add("error", "Validation errors: " . print_r($e->validation->errors(), 1)); } throw $e; } return $item; }
public function add($id) { $album = ORM::factory("item", $id); access::required("view", $album); access::required("add", $album); access::verify_csrf(); $form = $this->_get_add_form($album); if ($form->validate()) { batch::start(); $count = 0; $added_a_movie = false; $added_a_photo = false; foreach (array("file1", "file2", "file3") as $key) { if ($form->add_photos->{$key}->value == "") { continue; } try { $temp_filename = $form->add_photos->{$key}->value; $item = ORM::factory("item"); $item->name = basename($temp_filename); $item->title = item::convert_filename_to_title($item->name); $item->parent_id = $album->id; $item->set_data_file($temp_filename); $path_info = @pathinfo($temp_filename); if (array_key_exists("extension", $path_info) && in_array(strtolower($path_info["extension"]), array("flv", "mp4", "m4v"))) { $item->type = "movie"; $item->save(); $added_a_movie = true; log::success("content", t("Added a movie"), html::anchor("movies/{$item->id}", t("view movie"))); } else { $item->type = "photo"; $item->save(); $added_a_photo = true; log::success("content", t("Added a photo"), html::anchor("photos/{$item->id}", t("view photo"))); } $count++; module::event("add_photos_form_completed", $item, $form); } catch (Exception $e) { // Lame error handling for now. Just record the exception and move on Kohana_Log::add("error", $e->getMessage() . "\n" . $e->getTraceAsString()); // Ugh. I hate to use instanceof, But this beats catching the exception separately since // we mostly want to treat it the same way as all other exceptions if ($e instanceof ORM_Validation_Exception) { Kohana_Log::add("error", "Validation errors: " . print_r($e->validation->errors(), 1)); } } if (file_exists($temp_filename)) { unlink($temp_filename); } } batch::stop(); if ($count) { if ($added_a_photo && $added_a_movie) { message::success(t("Added %count photos and movies", array("count" => $count))); } else { if ($added_a_photo) { message::success(t2("Added one photo", "Added %count photos", $count)); } else { message::success(t2("Added one movie", "Added %count movies", $count)); } } } json::reply(array("result" => "success")); } else { json::reply(array("result" => "error", "html" => (string) $form)); } // Override the application/json mime type. The dialog based HTML uploader uses an iframe to // buffer the reply, and on some browsers (Firefox 3.6) it does not know what to do with the // JSON that it gets back so it puts up a dialog asking the user what to do with it. So force // the encoding type back to HTML for the iframe. // See: http://jquery.malsup.com/form/#file-upload header("Content-Type: text/html; charset=" . Kohana::CHARSET); }
/** * 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); switch ($mode) { case "init": $task->set("mode", "build-file-list"); $task->percent_complete = 0; $task->status = t("Starting up"); batch::start(); break; 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"); $paths = unserialize(module::get_var("videos", "authorized_paths")); while ($queue && microtime(true) - $start < 0.5) { list($file, $parent_entry_id) = array_shift($queue); // Ignore the staging directories as directories to be imported. if (empty($paths[$file])) { $entry = ORM::factory("videos_file"); $entry->task_id = $task->id; $entry->file = $file; $entry->parent_id = $parent_entry_id; $entry->save(); $entry_id = $entry->id; } else { $entry_id = null; } $file = preg_quote($file); 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", "m4v")) && if (in_array($ext, unserialize(module::get_var("videos", "allowed_extensions"))) && filesize($child) > 0) { $child_entry = ORM::factory("videos_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", ORM::factory("videos_file")->where("task_id", "=", $task->id)->count_all()); if (!$queue) { $task->set("mode", "add-files"); $task->set("total_files", ORM::factory("videos_file")->where("task_id", "=", $task->id)->count_all()); $task->percent_complete = 10; } break; case "add-files": // 10% to 100% $completed_files = $task->get("completed_files", 0); $total_files = $task->get("total_files"); // 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("videos_file")->where("task_id", "=", $task->id)->where("item_id", "IS", null)->order_by("id", "ASC")->limit(10)->find_all(); if ($entries->count() == 0) { // Out of entries, we're done. $task->set("mode", "done"); } $owner_id = identity::active_user()->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("videos_file", $entry->parent_id); if (!$parent_entry->loaded()) { $parent = ORM::factory("item", $task->get("item_id")); } else { $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 = ORM::factory("item"); $album->type = "album"; $album->parent_id = $parent->id; $album->name = $name; $album->title = $title; $album->owner_id = $owner_id; $album->save(); $entry->item_id = $album->id; } else { try { $extension = strtolower(pathinfo($name, PATHINFO_EXTENSION)); if (in_array($extension, unserialize(module::get_var("videos", "allowed_extensions")))) { $movie = ORM::factory("item"); $movie->type = "movie"; $movie->parent_id = $parent->id; $movie->set_data_file($entry->file); $movie->name = $name; $movie->title = $title; $movie->owner_id = $owner_id; $movie->save(); $entry->item_id = $movie->id; $items_video = ORM::factory("items_video"); $items_video->item_id = $movie->id; $items_video->save(); if (file_exists($entry->file . ".flv")) { copy($entry->file . ".flv", $movie->resize_path() . ".flv"); list($vid_width, $vid_height, $mime_type) = movie::get_file_metadata($entry->file . ".flv"); $movie->height = $vid_height; $movie->width = $vid_width; $movie->save(); } } 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}"); } } catch (Exception $e) { // This can happen if a photo file is invalid, like a BMP masquerading as a .jpg $entry->item_id = 0; $task->log("Skipping invalid file: {$entry->file}"); } } $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 = $total_files ? 10 + 100 * ($completed_files / $total_files) : 100; break; case "done": batch::stop(); $task->done = true; $task->state = "success"; $task->percent_complete = 100; db::build()->delete("videos_files")->where("task_id", "=", $task->id)->execute(); message::info(t2("Successfully added one file", "Successfully added %count files", $task->get("completed_files"))); } }
public function get_item_title($item, $allowbbcode = FALSE, $limit_title_length = 0) { if (!$item) { return ""; } if ($item->is_album()) { $title = $item->title; } else { switch ($this->title_source) { case "description": $title = $item->description; break; case "no-filename": $title = $item->title; $filename = $item->name; if (strcasecmp($title, $filename) == 0) { $title = ""; } else { if (defined('PATHINFO_FILENAME')) { $filename = pathinfo($filename, PATHINFO_FILENAME); } elseif (strstr($item->filename, '.')) { $filename = substr($filename, 0, strrpos($filename, '.')); } if (strcasecmp($title, $filename) == 0) { $title = ""; } else { $filename = item::convert_filename_to_title($filename); // Normalize filename to title format if (strcasecmp($title, $filename) == 0) { $title = ""; } } } break; default: $title = $item->title; break; } } $title = html::purify($title); if ($allowbbcode) { $title = $this->bb2html($title, 1); } else { $title = $this->bb2html($title, 2); } if ($limit_title_length) { $title = text::limit_chars($title, $limit_title_length); } if ($title === "") { $title = t(ucfirst($item->type)) . " " . $item->id; } return $title; }