static function item_created($item) { // Only works on photos if (!$item->is_photo()) { return; } // Locate jhead if (!is_file($path = exec('which jhead'))) { // @todo throw an exception ? Kohana::log('error', 'jhead is not installed'); } $binary = str_replace('\\', '/', realpath(dirname($path))); $binary .= '/jhead'; $binary .= PHP_SHLIB_SUFFIX === 'dll' ? '.exe' : ''; if (!is_file($binary)) { // @todo throw an exception ? Kohana::log('error', 'Unable to locate jhead binary'); } // Invoke jhead if ($error = exec(escapeshellcmd($binary) . ' -q -autorot ' . $item->file_path())) { // @todo throw an exception ? Kohana::log('error', 'Error during execution of jhead'); } // Update item $image_info = getimagesize($item->file_path()); $item->width = $image_info[0]; $item->height = $image_info[1]; $item->resize_dirty = 1; $item->thumb_dirty = 1; $item->save(); graphics::generate($item); }
/** * Task that rebuilds all dirty images. * @param Task_Model the task */ static function rebuild_dirty_images($task) { $result = graphics::find_dirty_images_query(); $remaining = $result->count(); $completed = $task->get("completed", 0); $i = 0; foreach ($result as $row) { $item = ORM::factory("item", $row->id); if ($item->loaded) { graphics::generate($item); } $completed++; $remaining--; if (++$i == 2) { break; } } $task->status = t2("Updated: 1 image. Total: %total_count.", "Updated: %count images. Total: %total_count.", $completed, array("total_count" => $remaining + $completed)); if ($completed + $remaining > 0) { $task->percent_complete = (int) (100 * $completed / ($completed + $remaining)); } else { $task->percent_complete = 100; } $task->set("completed", $completed); if ($remaining == 0) { $task->done = true; $task->state = "success"; site_status::clear("graphics_dirty"); } }
/** * Task that rebuilds all dirty images. * @param Task_Model the task */ static function rebuild_dirty_images($task) { $errors = array(); try { $result = graphics::find_dirty_images_query()->select("id")->execute(); $total_count = $task->get("total_count", $result->count()); $mode = $task->get("mode", "init"); if ($mode == "init") { $task->set("total_count", $total_count); $task->set("mode", "process"); batch::start(); } $completed = $task->get("completed", 0); $ignored = $task->get("ignored", array()); $i = 0; foreach ($result as $row) { if (array_key_exists($row->id, $ignored)) { continue; } $item = ORM::factory("item", $row->id); if ($item->loaded()) { try { graphics::generate($item); $completed++; $errors[] = t("Successfully rebuilt images for '%title'", array("title" => html::purify($item->title))); } catch (Exception $e) { $errors[] = t("Unable to rebuild images for '%title'", array("title" => html::purify($item->title))); $errors[] = (string) $e; $ignored[$item->id] = 1; } } if (++$i == 2) { break; } } $task->status = t2("Updated: 1 image. Total: %total_count.", "Updated: %count images. Total: %total_count.", $completed, array("total_count" => $total_count)); if ($completed < $total_count) { $task->percent_complete = (int) (100 * ($completed + count($ignored)) / $total_count); } else { $task->percent_complete = 100; } $task->set("completed", $completed); $task->set("ignored", $ignored); if ($task->percent_complete == 100) { $task->done = true; $task->state = "success"; batch::stop(); site_status::clear("graphics_dirty"); } } catch (Exception $e) { Kohana_Log::add("error", (string) $e); $task->done = true; $task->state = "error"; $task->status = $e->getMessage(); $errors[] = (string) $e; } if ($errors) { $task->log($errors); } }
/** * Task that rebuilds all dirty images. * @param Task_Model the task */ static function rebuild_dirty_images($task) { $errors = array(); try { $result = graphics::find_dirty_images_query(); $completed = $task->get("completed", 0); $ignored = $task->get("ignored", array()); $remaining = $result->count() - count($ignored); $i = 0; foreach ($result as $row) { if (array_key_exists($row->id, $ignored)) { continue; } $item = ORM::factory("item", $row->id); if ($item->loaded) { try { graphics::generate($item); $ignored[$item->id] = 1; $errors[] = t("Successfully rebuilt images for '%title'", array("title" => html::purify($item->title))); } catch (Exception $e) { $errors[] = t("Unable to rebuild images for '%title'", array("title" => html::purify($item->title))); $errors[] = $e->__toString(); } } $completed++; $remaining--; if (++$i == 2) { break; } } $task->status = t2("Updated: 1 image. Total: %total_count.", "Updated: %count images. Total: %total_count.", $completed, array("total_count" => $remaining + $completed)); if ($completed + $remaining > 0) { $task->percent_complete = (int) (100 * $completed / ($completed + $remaining)); } else { $task->percent_complete = 100; } $task->set("completed", $completed); $task->set("ignored", $ignored); if ($remaining == 0) { $task->done = true; $task->state = "success"; site_status::clear("graphics_dirty"); } } catch (Exception $e) { $task->done = true; $task->state = "error"; $task->status = $e->getMessage(); $errors[] = $e->__toString(); } if ($errors) { $task->log($errors); } }
static function remove_album_cover($album) { access::required("edit", $album); @unlink($album->thumb_path()); model_cache::clear("item", $album->album_cover_item_id); $album->album_cover_item_id = null; $album->thumb_width = 0; $album->thumb_height = 0; $album->thumb_dirty = 1; $album->save(); graphics::generate($album); }
/** * Create a new photo. * @param integer $parent_id id of parent album * @param string $filename path to the photo file on disk * @param string $name the filename to use for this photo in the album * @param integer $title the title of the new photo * @param string $description (optional) the longer description of this photo * @return Item_Model */ static function create($parent, $filename, $name, $title, $description = null, $owner_id = null) { if (!$parent->loaded || $parent->type != "album") { throw new Exception("@todo INVALID_PARENT"); } if (!is_file($filename)) { throw new Exception("@todo MISSING_IMAGE_FILE"); } if (!($image_info = getimagesize($filename))) { throw new Exception("@todo INVALID_IMAGE_FILE"); } // Force an extension onto the name $pi = pathinfo($name); if (empty($pi["extension"])) { $pi["extension"] = image_type_to_extension($image_info[2], false); $name .= "." . $pi["extension"]; } $photo = ORM::factory("item"); $photo->type = "photo"; $photo->title = $title; $photo->description = $description; $photo->name = $name; $photo->owner_id = $owner_id; $photo->width = $image_info[0]; $photo->height = $image_info[1]; $photo->mime_type = empty($image_info['mime']) ? "application/unknown" : $image_info['mime']; $photo->thumb_dirty = 1; $photo->resize_dirty = 1; // Randomize the name if there's a conflict while (ORM::Factory("item")->where("parent_id", $parent->id)->where("name", $photo->name)->find()->id) { // @todo Improve this. Random numbers are not user friendly $photo->name = rand() . "." . $pi["extension"]; } // This saves the photo $photo->add_to_parent($parent); copy($filename, $photo->file_path()); module::event("item_created", $photo); // Build our thumbnail/resizes graphics::generate($photo); // If the parent has no cover item, make this it. $parent = $photo->parent(); if ($parent->album_cover_item_id == null) { $parent->album_cover_item_id = $photo->id; $parent->save(); graphics::generate($parent); } return $photo; }
public function save($source_id) { access::verify_csrf(); $source = ORM::factory("item", $source_id); access::required("edit", $source); $target = ORM::factory("item", $this->input->post("target_id")); access::required("edit", $target); $source->move_to($target); // If the target has no cover item, make this it. if ($target->album_cover_item_id == null) { $target->album_cover_item_id = $source->type == "album" ? $source->album_cover_item_id : $source->id; $target->save(); graphics::generate($target); } print json_encode(array("result" => "success", "location" => url::site("albums/{$target->id}"))); }
static function item_created($item) { access::add_item($item); if ($item->is_photo() || $item->is_movie()) { // Build our thumbnail/resizes. try { graphics::generate($item); } catch (Exception $e) { log::error("graphics", t("Couldn't create a thumbnail or resize for %item_title", array("item_title" => $item->title)), html::anchor($item->abs_url(), t("details"))); Kohana_Log::add("error", $e->getMessage() . "\n" . $e->getTraceAsString()); } // If the parent has no cover item, make this it. $parent = $item->parent(); if (access::can("edit", $parent) && $parent->album_cover_item_id == null) { item::make_album_cover($item); } } }
public function restore($id) { // Allow the user to restore the original photo. // Make sure the current user has suficient access to view and edit the item. $item = ORM::factory("item", $id); access::required("view", $item); access::required("edit", $item); // Figure out where the original was stashed at. $original_image = VARPATH . "original/" . str_replace(VARPATH . "albums/", "", $item->file_path()); // Make sure the current item is a photo and that an original exists. if ($item->is_photo() && file_exists($original_image)) { // Delete the modified version of the photo. @unlink($item->file_path()); // Copy the original image back over, display an error message if the copy fails. if (@rename($original_image, $item->file_path())) { // Re-generate the items resize and thumbnail. $item_data = model_cache::get("item", $id); $item_data->resize_dirty = 1; $item_data->thumb_dirty = 1; $item_data->save(); graphics::generate($item_data); // If the item is the thumbnail for the parent album, // fix the parent's thumbnail as well. $parent = $item_data->parent(); if ($parent->album_cover_item_id == $item_data->id) { copy($item_data->thumb_path(), $parent->thumb_path()); $parent->thumb_width = $item_data->thumb_width; $parent->thumb_height = $item_data->thumb_height; $parent->save(); } // Display a success message and redirect to the items page. message::success(t("Your original image has been restored.")); url::redirect($item->url()); } else { // Display an error message if the copy failed. message::error(t("Image restore failed!")); url::redirect($item->url()); } } else { // Display an error message if there is not an original photo. message::error(t("Image restore failed!")); url::redirect($item->url()); } }
public function make_album_cover($id) { access::verify_csrf(); $item = ORM::factory("item", $id); access::required("edit", $item); $parent = $item->parent(); access::required("edit", $parent); if ($item->type == "photo") { $parent->album_cover_item_id = $item->id; } else { if ($item->type == "album") { $parent->album_cover_item_id = $item->album_cover_item_id; } } $parent->thumb_dirty = 1; $parent->save(); graphics::generate($parent); print json_encode(array("result" => "success")); }
public function save($source_id) { access::verify_csrf(); $source = ORM::factory("item", $source_id); $target = ORM::factory("item", Input::instance()->post("target_id")); access::required("view", $source); access::required("view", $target); access::required("edit", $target); model_cache::clear(); $target->album_cover_item_id = $source->is_album() ? $source->album_cover_item_id : $source->id; $target->thumb_dirty = 1; $target->save(); graphics::generate($target); $grand_parent = $target->parent(); if ($grand_parent && access::can("edit", $grand_parent) && $grand_parent->album_cover_item_id == null) { item::make_album_cover($target); } $msg = t("Made <b>%title</b> album's cover for <b>%album</b>", array("title" => html::purify($source->title), "album" => html::purify($target->title))); message::success($msg); json::reply(array("result" => "success")); }
public function rotate($id, $dir) { access::verify_csrf(); $item = ORM::factory("item", $id); if (!$item->loaded) { return ""; } $degrees = 0; switch ($dir) { case "ccw": $degrees = -90; break; case "cw": $degrees = 90; break; } if ($degrees) { graphics::rotate($item->file_path(), $item->file_path(), array("degrees" => $degrees)); list($item->width, $item->height) = getimagesize($item->file_path()); $item->resize_dirty = 1; $item->thumb_dirty = 1; $item->save(); graphics::generate($item); $parent = $item->parent(); if ($parent->album_cover_item_id == $item->id) { copy($item->thumb_path(), $parent->thumb_path()); $parent->thumb_width = $item->thumb_width; $parent->thumb_height = $item->thumb_height; $parent->save(); } } if (Input::instance()->get("page_type") == "album") { print json_encode(array("src" => $item->thumb_url() . "?rnd=" . rand(), "width" => $item->thumb_width, "height" => $item->thumb_height)); } else { print json_encode(array("src" => $item->resize_url() . "?rnd=" . rand(), "width" => $item->resize_width, "height" => $item->resize_height)); } }
public function rotate($id, $dir) { access::verify_csrf(); $item = model_cache::get("item", $id); access::required("view", $item); access::required("edit", $item); $degrees = 0; switch ($dir) { case "ccw": $degrees = -90; break; case "cw": $degrees = 90; break; } if ($degrees) { gallery_graphics::rotate($item->file_path(), $item->file_path(), array("degrees" => $degrees)); list($item->width, $item->height) = getimagesize($item->file_path()); $item->resize_dirty = 1; $item->thumb_dirty = 1; $item->save(); graphics::generate($item); $parent = $item->parent(); // @todo: this is an inadequate way to regenerate the parent's thumbnail after rotation. if ($parent->album_cover_item_id == $item->id) { copy($item->thumb_path(), $parent->thumb_path()); $parent->thumb_width = $item->thumb_width; $parent->thumb_height = $item->thumb_height; $parent->save(); } } if (Input::instance()->get("page_type") == "collection") { print json_encode(array("src" => $item->thumb_url() . "?rnd=" . rand(), "width" => $item->thumb_width, "height" => $item->thumb_height)); } else { print json_encode(array("src" => $item->resize_url() . "?rnd=" . rand(), "width" => $item->resize_width, "height" => $item->resize_height)); } }
static function remove_album_cover($album) { access::required("view", $album); access::required("edit", $album); model_cache::clear(); $album->album_cover_item_id = null; $album->save(); graphics::generate($album); }
public function rotate($id, $dir) { access::verify_csrf(); $item = model_cache::get("item", $id); access::required("view", $item); access::required("edit", $item); $degrees = 0; switch ($dir) { case "ccw": $degrees = -90; break; case "cw": $degrees = 90; break; } if ($degrees) { gallery_graphics::rotate($item->file_path(), $item->file_path(), array("degrees" => $degrees)); list($item->width, $item->height) = getimagesize($item->file_path()); $item->resize_dirty = 1; $item->thumb_dirty = 1; $item->save(); graphics::generate($item); $parent = $item->parent(); if ($parent->album_cover_item_id == $item->id) { copy($item->thumb_path(), $parent->thumb_path()); $parent->thumb_width = $item->thumb_width; $parent->thumb_height = $item->thumb_height; $parent->save(); } } print json_encode(self::child_json_encode($item)); }
static function item_updated_data_file($item) { graphics::generate($item); // Update any places where this is the album cover foreach (ORM::factory("item")->where("album_cover_item_id", "=", $item->id)->find_all() as $target) { copy($item->thumb_path(), $target->thumb_path()); $target->thumb_width = $item->thumb_width; $target->thumb_height = $item->thumb_height; $target->save(); } }
static function item_updated_data_file($item) { graphics::generate($item); // Update any places where this is the album cover foreach (ORM::factory("item")->where("album_cover_item_id", "=", $item->id)->find_all() as $target) { $target->thumb_dirty = 1; $target->save(); graphics::generate($target); } }
/** * Create a new photo. * @param integer $parent_id id of parent album * @param string $filename path to the photo file on disk * @param string $name the filename to use for this photo in the album * @param integer $title the title of the new photo * @param string $description (optional) the longer description of this photo * @return Item_Model */ static function create($parent, $filename, $name, $title, $description = null, $owner_id = null) { if (!$parent->loaded || !$parent->is_album()) { throw new Exception("@todo INVALID_PARENT"); } if (!is_file($filename)) { throw new Exception("@todo MISSING_IMAGE_FILE"); } if (strpos($name, "/")) { throw new Exception("@todo NAME_CANNOT_CONTAIN_SLASH"); } // We don't allow trailing periods as a security measure // ref: http://dev.kohanaphp.com/issues/684 if (rtrim($name, ".") != $name) { throw new Exception("@todo NAME_CANNOT_END_IN_PERIOD"); } if (filesize($filename) == 0) { throw new Exception("@todo EMPTY_INPUT_FILE"); } $image_info = getimagesize($filename); // Force an extension onto the name $pi = pathinfo($filename); if (empty($pi["extension"])) { $pi["extension"] = image_type_to_extension($image_info[2], false); $name .= "." . $pi["extension"]; } $photo = ORM::factory("item"); $photo->type = "photo"; $photo->title = $title; $photo->description = $description; $photo->name = $name; $photo->owner_id = $owner_id ? $owner_id : user::active(); $photo->width = $image_info[0]; $photo->height = $image_info[1]; $photo->mime_type = empty($image_info['mime']) ? "application/unknown" : $image_info['mime']; $photo->thumb_dirty = 1; $photo->resize_dirty = 1; $photo->sort_column = "weight"; $photo->rand_key = (double) mt_rand() / (double) mt_getrandmax(); // Randomize the name if there's a conflict while (ORM::factory("item")->where("parent_id", $parent->id)->where("name", $photo->name)->find()->id) { // @todo Improve this. Random numbers are not user friendly $photo->name = rand() . "." . $pi["extension"]; } // This saves the photo $photo->add_to_parent($parent); /* * If the thumb or resize already exists then rename it. We need to do this after the save * because the resize_path and thumb_path both call relative_path which caches the * path. Before add_to_parent the relative path will be incorrect. */ if (file_exists($photo->resize_path()) || file_exists($photo->thumb_path())) { $photo->name = $pi["filename"] . "-" . rand() . "." . $pi["extension"]; $photo->save(); } copy($filename, $photo->file_path()); // @todo: publish this from inside Item_Model::save() when we refactor to the point where // there's only one save() happening here. module::event("item_created", $photo); // Build our thumbnail/resizes. If we fail to build thumbnail/resize we assume that the image // is bad in some way and discard it. try { graphics::generate($photo); } catch (Exception $e) { $photo->delete(); throw $e; } // If the parent has no cover item, make this it. if (access::can("edit", $parent) && $parent->album_cover_item_id == null) { item::make_album_cover($photo); } return $photo; }
public function p_rotate($item, $dir) { $degrees = 0; switch ($dir) { case "ccw": $degrees = -90; break; case "cw": $degrees = 90; break; } if ($degrees) { gallery_graphics::rotate($item->file_path(), $item->file_path(), array("degrees" => $degrees)); list($item->width, $item->height) = getimagesize($item->file_path()); $item->resize_dirty = 1; $item->thumb_dirty = 1; $item->save(); graphics::generate($item); $parent = $item->parent(); if ($parent->album_cover_item_id == $item->id) { copy($item->thumb_path(), $parent->thumb_path()); $parent->thumb_width = $item->thumb_width; $parent->thumb_height = $item->thumb_height; $parent->save(); } } return $item; }
/** * Set the highlight properly for a single album */ static function set_album_highlight(&$queue) { // Dequeue the current album and enqueue its children list($g2_album_id, $children) = each($queue); unset($queue[$g2_album_id]); foreach ($children as $key => $value) { $queue[$key] = $value; } $g3_album_id = self::map($g2_album_id); if (!$g3_album_id) { return t("Album with id: %id not imported", array("id" => $g3_album_id)); } $table = g2(GalleryCoreApi::fetchThumbnailsByItemIds(array($g2_album_id))); if (isset($table[$g2_album_id])) { // Backtrack the source id to an item $g2_source = $table[$g2_album_id]; while (GalleryUtilities::isA($g2_source, "GalleryDerivative")) { $g2_source = g2(GalleryCoreApi::loadEntitiesById($g2_source->getDerivativeSourceId())); } $item_id = self::map($g2_source->getId()); if ($item_id) { $item = ORM::factory("item", $item_id); $g2_album = ORM::factory("item", $g3_album_id); $g2_album->album_cover_item_id = $item->id; $g2_album->thumb_dirty = 1; $g2_album->view_count = g2(GalleryCoreApi::fetchItemViewCount($g2_album_id)); $g2_album->save(); graphics::generate($g2_album); } } }
/** * Task that rebuilds all dirty images. * @param Task_Model the task */ static function rebuild_dirty_images($task) { $errors = array(); try { // Choose the dirty images in a random order so that if we run this task multiple times // concurrently each task is rebuilding different images simultaneously. $result = graphics::find_dirty_images_query()->select("id")->select(db::expr("RAND() as r"))->order_by("r", "ASC")->execute(); $total_count = $task->get("total_count", $result->count()); $mode = $task->get("mode", "init"); if ($mode == "init") { $task->set("total_count", $total_count); $task->set("mode", "process"); batch::start(); } $completed = $task->get("completed", 0); $ignored = $task->get("ignored", array()); $i = 0; // If there's no work left to do, skip to the end. This can happen if we resume a task long // after the work got done in some other task. if (!$result->count()) { $completed = $total_count; } foreach ($result as $row) { if (array_key_exists($row->id, $ignored)) { continue; } $item = ORM::factory("item", $row->id); if ($item->loaded()) { try { graphics::generate($item); $completed++; $errors[] = t("Successfully rebuilt images for '%title'", array("title" => html::purify($item->title))); } catch (Exception $e) { $errors[] = t("Unable to rebuild images for '%title'", array("title" => html::purify($item->title))); $errors[] = (string) $e; $ignored[$item->id] = 1; } } if (++$i == 2) { break; } } $task->status = t2("Updated: 1 image. Total: %total_count.", "Updated: %count images. Total: %total_count.", $completed, array("total_count" => $total_count)); if ($completed < $total_count) { $task->percent_complete = (int) (100 * ($completed + count($ignored)) / $total_count); } else { $task->percent_complete = 100; } $task->set("completed", $completed); $task->set("ignored", $ignored); if ($task->percent_complete == 100) { $task->done = true; $task->state = "success"; batch::stop(); site_status::clear("graphics_dirty"); } } catch (Exception $e) { Kohana_Log::add("error", (string) $e); $task->done = true; $task->state = "error"; $task->status = $e->getMessage(); $errors[] = (string) $e; } if ($errors) { $task->log($errors); } }
static function do_embossing($id, $image_id, $overlay_id) { $gravity = module::get_var('emboss', 'gravity'); $transparency = module::get_var('emboss', 'transparency'); $item = ORM::factory('item')->where('id', '=', $image_id)->find(); $path = $item->file_path() . $name; $orig = str_replace(VARPATH . 'albums/', VARPATH . 'originals/', $path); @unlink($path); if ($overlay_id < 0) { log::info('emboss', 'Remove embossing from ' . $item->name); @copy($orig, $path); } else { $overlay = ORM::factory('emboss_overlay')->where('id', '=', $overlay_id)->find(); $overlay_path = VARPATH . 'modules/emboss/' . $overlay->name; $opts['file'] = $overlay_path; $opts['position'] = $gravity; $opts['transparency'] = 100 - $transparency; log::info('emboss', 'Embossing ' . $item->name . ' with ' . $overlay->name); gallery_graphics::composite($orig, $path, $opts); } $item->thumb_dirty = 1; $item->resize_dirty = 1; $item->save(); graphics::generate($item); db::build()->update('emboss_mappings')->where('id', '=', $id)->set('cur_overlay_id', $overlay_id)->set('cur_gravity', $gravity)->set('cur_transparency', $transparency)->execute(); }
/** * Create a new movie. * @param integer $parent_id id of parent album * @param string $filename path to the photo file on disk * @param string $name the filename to use for this photo in the album * @param integer $title the title of the new photo * @param string $description (optional) the longer description of this photo * @return Item_Model */ static function create($parent, $filename, $name, $title, $description = null, $owner_id = null) { if (!$parent->loaded || !$parent->is_album()) { throw new Exception("@todo INVALID_PARENT"); } if (!is_file($filename)) { throw new Exception("@todo MISSING_MOVIE_FILE"); } if (strpos($name, "/")) { throw new Exception("@todo NAME_CANNOT_CONTAIN_SLASH"); } // We don't allow trailing periods as a security measure // ref: http://dev.kohanaphp.com/issues/684 if (rtrim($name, ".") != $name) { throw new Exception("@todo NAME_CANNOT_END_IN_PERIOD"); } try { $movie_info = movie::getmoviesize($filename); } catch (Exception $e) { // Assuming this is MISSING_FFMPEG for now $movie_info = getimagesize(MODPATH . "gallery/images/missing_movie.png"); } // Force an extension onto the name $pi = pathinfo($filename); if (empty($pi["extension"])) { $pi["extension"] = image_type_to_extension($movie_info[2], false); $name .= "." . $pi["extension"]; } $movie = ORM::factory("item"); $movie->type = "movie"; $movie->title = $title; $movie->description = $description; $movie->name = $name; $movie->owner_id = $owner_id ? $owner_id : user::active(); $movie->width = $movie_info[0]; $movie->height = $movie_info[1]; $movie->mime_type = strtolower($pi["extension"]) == "mp4" ? "video/mp4" : "video/x-flv"; $movie->thumb_dirty = 1; $movie->resize_dirty = 1; $movie->sort_column = "weight"; $movie->rand_key = (double) mt_rand() / (double) mt_getrandmax(); // Randomize the name if there's a conflict while (ORM::factory("item")->where("parent_id", $parent->id)->where("name", $movie->name)->find()->id) { // @todo Improve this. Random numbers are not user friendly $movie->name = rand() . "." . $pi["extension"]; } // This saves the photo $movie->add_to_parent($parent); // If the thumb or resize already exists then rename it if (file_exists($movie->resize_path()) || file_exists($movie->thumb_path())) { $movie->name = $pi["filename"] . "-" . rand() . "." . $pi["extension"]; $movie->save(); } copy($filename, $movie->file_path()); // @todo: publish this from inside Item_Model::save() when we refactor to the point where // there's only one save() happening here. module::event("item_created", $movie); // Build our thumbnail graphics::generate($movie); // If the parent has no cover item, make this it. if (access::can("edit", $parent) && $parent->album_cover_item_id == null) { item::make_album_cover($movie); } return $movie; }
public function make_tag_album_cover($id, $tag_id, $album_id) { if (!identity::active_user()->admin) { message::error(t("You do not have sufficient privileges to do this")); url::redirect("tag_albums/show/" . $id . "/" . $tag_id . "/" . $album_id . "/" . urlencode($item->name)); } $item = ORM::factory("item", $id); if ($album_id > 0 && $tag_id == 0) { // If we are dealing with a dynamic album, set it's thumbnail to this pics. // Based on modules/gallery/helpers/item.php $album_tags = ORM::factory("tags_album_id")->where("id", "=", $album_id)->find_all(); if (count($album_tags) > 0) { $parent = ORM::factory("item", $album_tags[0]->album_id); $parent->album_cover_item_id = $item->id; $parent->thumb_dirty = 1; graphics::generate($parent); $parent->save(); $grand_parent = $parent->parent(); if ($grand_parent && access::can("edit", $grand_parent) && $grand_parent->album_cover_item_id == null) { item::make_album_cover($parent); } } message::success(t("Made " . $item->title . " this album's cover")); url::redirect("tag_albums/show/" . $id . "/" . $tag_id . "/" . $album_id . "/" . urlencode($item->name)); } else { // If setting a thumbnail for an auto-generated all tags->tag album. $record = ORM::factory("tags_album_tag_cover")->where("tag_id", "=", $tag_id)->find(); if (!$record->loaded()) { $record->tag_id = $tag_id; } $record->photo_id = $id; $record->save(); message::success(t("Made " . $item->title . " this album's cover")); url::redirect("tag_albums/show/" . $id . "/" . $tag_id . "/" . $album_id . "/" . urlencode($item->name)); } }
/** * Set the highlight properly for a single album */ static function set_album_highlight(&$queue) { // Dequeue the current album and enqueue its children list($g2_album_id, $children) = each($queue); unset($queue[$g2_album_id]); if (!empty($children)) { foreach ($children as $key => $value) { $queue[$key] = $value; } } $messages = array(); $g3_album_id = self::map($g2_album_id); if (!$g3_album_id) { return t("Album with id: %id not imported", array("id" => $g3_album_id)); } $table = g2(GalleryCoreApi::fetchThumbnailsByItemIds(array($g2_album_id))); if (isset($table[$g2_album_id])) { // Backtrack the source id to an item $orig_g2_source = $g2_source = $table[$g2_album_id]; while (GalleryUtilities::isA($g2_source, "GalleryDerivative")) { $g2_source = g2(GalleryCoreApi::loadEntitiesById($g2_source->getDerivativeSourceId())); } $item_id = self::map($g2_source->getId()); if ($item_id) { $item = ORM::factory("item", $item_id); $g3_album = ORM::factory("item", $g3_album_id); $g3_album->album_cover_item_id = $item->id; $g3_album->thumb_dirty = 1; try { $g3_album->view_count = (int) g2(GalleryCoreApi::fetchItemViewCount($g2_album_id)); } catch (Exception $e) { $g3_album->view_count = 0; } try { $g3_album->save(); graphics::generate($g3_album); } catch (Exception $e) { return (string) new G2_Import_Exception(t("Failed to generate an album highlight for album '%name'.", array("name" => $g3_album->name)), $e); } self::set_map($orig_g2_source->getId(), $g3_album->id, "thumbnail", self::g2_url(array("view" => "core.DownloadItem", "itemId" => $orig_g2_source->getId()))); } } }
/** * Rebuild the thumb and resize for the given item. * @param Item_Model $item */ static function generate($item) { if ($item->thumb_dirty) { $ops["thumb"] = $item->thumb_path(); } if ($item->resize_dirty && $item->is_photo()) { $ops["resize"] = $item->resize_path(); } try { foreach ($ops as $target => $output_file) { $working_file = $item->file_path(); // Delete anything that might already be there @unlink($output_file); switch ($item->type) { case "movie": // Run movie_extract_frame events, which can either: // - generate an output file, bypassing the ffmpeg-based movie::extract_frame // - add to the options sent to movie::extract_frame (e.g. change frame extract time, // add de-interlacing arguments to ffmpeg... see movie helper for more info) // Note that the args are similar to those of the events in gallery_graphics $movie_options_wrapper = new stdClass(); $movie_options_wrapper->movie_options = array(); module::event("movie_extract_frame", $working_file, $output_file, $movie_options_wrapper, $item); // If no output_file generated by events, run movie::extract_frame with movie_options clearstatcache(); if (@filesize($output_file) == 0) { try { movie::extract_frame($working_file, $output_file, $movie_options_wrapper->movie_options); // If we're here, we know ffmpeg is installed and the movie is valid. Because the // user may not always have had ffmpeg installed, the movie's width, height, and // mime type may need updating. Let's use this opportunity to make sure they're // correct. It's not optimal to do it at this low level, but it's not trivial to find // these cases quickly in an upgrade script. list($width, $height, $mime_type) = movie::get_file_metadata($working_file); // Only set them if they need updating to avoid marking them as "changed" if ($item->width != $width || $item->height != $height || $item->mime_type != $mime_type) { $item->width = $width; $item->height = $height; $item->mime_type = $mime_type; } } catch (Exception $e) { // Didn't work, likely because of MISSING_FFMPEG - use placeholder graphics::_replace_image_with_placeholder($item, $target); break; } } $working_file = $output_file; case "photo": // Run the graphics rules (for both movies and photos) foreach (self::_get_rules($target) as $rule) { $args = array($working_file, $output_file, unserialize($rule->args), $item); call_user_func_array($rule->operation, $args); $working_file = $output_file; } break; case "album": if (!($cover = $item->album_cover())) { // This album has no cover; copy its placeholder image. Because of an old bug, it's // possible that there's an album cover item id that points to an invalid item. In that // case, just null out the album cover item id. It's not optimal to do that at this low // level, but it's not trivial to find these cases quickly in an upgrade script and if we // don't do this, the album may be permanently marked as "needs rebuilding" // // ref: http://sourceforge.net/apps/trac/gallery/ticket/1172 // http://galleryproject.org/node/96926 if ($item->album_cover_item_id) { $item->album_cover_item_id = null; $item->save(); } graphics::_replace_image_with_placeholder($item, $target); break; } if ($cover->thumb_dirty) { graphics::generate($cover); } if (!$cover->thumb_dirty) { // Make the album cover from the cover item's thumb. Run gallery_graphics::resize with // null options and it will figure out if this is a direct copy or conversion to jpg. $working_file = $cover->thumb_path(); gallery_graphics::resize($working_file, $output_file, null, $item); } break; } } if (!empty($ops["thumb"])) { if (file_exists($item->thumb_path())) { $item->thumb_dirty = 0; } else { Kohana_Log::add("error", "Failed to rebuild thumb image: {$item->title}"); graphics::_replace_image_with_placeholder($item, "thumb"); } } if (!empty($ops["resize"])) { if (file_exists($item->resize_path())) { $item->resize_dirty = 0; } else { Kohana_Log::add("error", "Failed to rebuild resize image: {$item->title}"); graphics::_replace_image_with_placeholder($item, "resize"); } } graphics::_update_item_dimensions($item); $item->save(); } catch (Exception $e) { // Something went wrong rebuilding the image. Replace with the placeholder images, // leave it dirty and move on. Kohana_Log::add("error", "Caught exception rebuilding images: {$item->title}\n" . $e->getMessage() . "\n" . $e->getTraceAsString()); if ($item->is_photo()) { graphics::_replace_image_with_placeholder($item, "resize"); } graphics::_replace_image_with_placeholder($item, "thumb"); try { graphics::_update_item_dimensions($item); } catch (Exception $e) { // Looks like get_file_metadata couldn't identify our placeholders. We should never get // here, but in the odd case we do, we need to do something. Let's put in hardcoded values. if ($item->is_photo()) { list($item->resize_width, $item->resize_height) = array(200, 200); } list($item->thumb_width, $item->thumb_height) = array(200, 200); } $item->save(); throw $e; } }
public function generate_album_cover_from_bad_photo_test() { $album = test::random_album(); $photo = test::random_photo($album); $album->reload(); // At this point, the photo is valid and has a valid resize and thumb. Make it garble. file_put_contents($photo->file_path(), test::lorem_ipsum(200)); // Regenerate album from garbled photo. $photo->thumb_dirty = 1; $photo->save(); $album->thumb_dirty = 1; try { graphics::generate($album); $this->assert_true(false, "Shouldn't get here"); } catch (Exception $e) { // Exception expected } // Check that the image got replaced with a missing image placeholder $this->assert_same(file_get_contents(MODPATH . "gallery/images/missing_photo.jpg"), file_get_contents($album->thumb_path())); // Check that the items table got updated with new metadata $this->assert_equal(array(200, 200), array($album->thumb_width, $album->thumb_height)); // Check that the images are marked as dirty $this->assert_equal(1, $album->thumb_dirty); }
private static function _do_rotation($item, $degrees) { // This code is copied from Quick_Controller::rotate graphics::rotate($item->file_path(), $item->file_path(), array("degrees" => $degrees)); list($item->width, $item->height) = getimagesize($item->file_path()); $item->resize_dirty = 1; $item->thumb_dirty = 1; $item->save(); graphics::generate($item); $parent = $item->parent(); if ($parent->album_cover_item_id == $item->id) { copy($item->thumb_path(), $parent->thumb_path()); $parent->thumb_width = $item->thumb_width; $parent->thumb_height = $item->thumb_height; $parent->save(); } list($height, $width) = $item->scale_dimensions(90); $margin_top = (90 - $height) / 20; return array("src" => $item->thumb_url() . "?rnd=" . rand(), "id" => $item->id, "marginTop" => "{$margin_top}em", "width" => $width, "height" => $height); }
/** * Set the highlight properly for a single album */ static function set_album_highlight(&$queue) { $messages = array(); if (count($queue) == 0) { $messages[] = t('Empty highlights queue'); return $messages; } $item = array_shift($queue); if (substr($item, -10) == '.highlight') { $item = substr($item, 0, strlen($item) - 10); } g1_import::debug(t('Now importing highlight %item', array('item' => $item))); // Item names come in as Level:FolderX/ItemX $pos = strpos($item, ':'); if ($pos === false) { $messages[] = t('Invalid item %item', array('item' => $item)); return $messages; } $item = substr($item, $pos + 1); // Item names come in as FolderX/ItemX $pos = strrpos($item, '/'); if ($pos === false) { $messages[] = t('Invalid item %item', array('item' => $item)); return $messages; } // Get ItemX into g1_item $g1_item = substr($item, $pos + 1); // Get FolderX into g1_item $g1_album = substr($item, 0, $pos); if (self::map($g1_album, '', 'highlight')) { return $messages; } $album_id = self::map($g1_album, '', 'album'); if (!$album_id) { $messages[] = t('Album %name not found', array('name' => $g1_album)); return $messages; } $item_id = self::map($g1_album, $g1_item, 'item'); if (!$item_id) { $item_id = self::map($g1_item, '', 'album'); } if (!$item_id) { $messages[] = t('Item/Album %name not found', array('name' => $item)); return $messages; } $album = ORM::factory('item', $album_id); $album->album_cover_item_id = $item_id; $album->thumb_dirty = 1; try { $album->save(); graphics::generate($album); g1_import::debug(t('Added highlight %item to %album', array('item' => $item, 'album' => $album->name))); } catch (Exception $e) { $messages[] = (string) new G1_Import_Exception(t("Failed to generate an album highlight for album '%name'.", array('name' => $album->name)), $e); return $messages; } $album_id = self::map($g1_album, '', 'album'); self::set_map($album_id, $g1_album, '', 'highlight'); g1_import::debug(t('Added highlight %item to %album', array('item' => $item, 'album' => $album->name))); return $messages; }