Пример #1
0
 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);
 }
Пример #2
0
 /**
  * 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");
     }
 }
Пример #3
0
 /**
  * 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);
     }
 }
Пример #4
0
 /**
  * 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);
     }
 }
Пример #5
0
 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);
 }
Пример #6
0
 /**
  * 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;
 }
Пример #7
0
 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}")));
 }
Пример #8
0
 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);
         }
     }
 }
Пример #9
0
 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());
     }
 }
Пример #10
0
 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"));
 }
Пример #11
0
 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"));
 }
Пример #12
0
 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));
     }
 }
Пример #13
0
 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));
     }
 }
Пример #14
0
 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);
 }
Пример #15
0
 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));
 }
Пример #16
0
 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();
     }
 }
Пример #17
0
 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);
     }
 }
Пример #18
0
 /**
  * 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;
 }
Пример #19
0
 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;
 }
Пример #20
0
 /**
  * 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);
         }
     }
 }
Пример #21
0
 /**
  * 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);
     }
 }
Пример #22
0
 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();
 }
Пример #23
0
 /**
  * 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;
 }
Пример #24
0
 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));
     }
 }
Пример #25
0
 /**
  * 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())));
         }
     }
 }
Пример #26
0
 /**
  * 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;
     }
 }
Пример #27
0
 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);
 }
Пример #28
0
 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);
 }
Пример #29
0
 /**
  * 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;
 }