示例#1
0
 public function form_edit($movie_id)
 {
     $movie = ORM::factory("item", $movie_id);
     access::required("view", $movie);
     access::required("edit", $movie);
     print movie::get_edit_form($movie);
 }
示例#2
0
 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";
 }
示例#3
0
 /**
  * Create a merged list of all allowed photo and movie extensions.
  */
 static function get_extensions()
 {
     $extensions = legal_file::get_photo_extensions();
     if (movie::find_ffmpeg()) {
         $extensions = array_merge($extensions, legal_file::get_movie_extensions());
     }
     return $extensions;
 }
示例#4
0
 protected function buildDomainObject($row)
 {
     $movie = new movie();
     $movie->setId($row['mov_id']);
     $movie->setTitle($row['mov_title']);
     $movie->setDescriptionShort($row['mov_description_short']);
     $movie->setDescriptionLong($row['mov_description_long']);
     $movie->setDirector($row['mov_director']);
     $movie->setYear($row['mov_year']);
     $movie->setImage($row['mov_image']);
     if (array_key_exists('cat_id', $row)) {
         $categoryId = $row['cat_id'];
         $category = $this->categoryDAO->find($categoryId);
         $movie->setCategory($category);
     }
     return $movie;
 }
示例#5
0
 public function create_movie_creates_reasonable_slug_test()
 {
     $rand = rand();
     $root = ORM::factory("item", 1);
     $album = album::create($root, $rand, $rand, $rand);
     $movie = movie::create($album, MODPATH . "gallery/tests/test.flv", "This (is) my file%name.flv", $rand, $rand);
     $this->assert_equal("This-is-my-file-name", $movie->slug);
 }
示例#6
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");
     }
     $movie_info = movie::getmoviesize($filename);
     // 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());
     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;
 }
示例#7
0
 public function render()
 {
     $v = new View("form_uploadify.html");
     $v->album = $this->data["album"];
     $v->script_data = $this->data["script_data"];
     $v->simultaneous_upload_limit = module::get_var("gallery", "simultaneous_upload_limit");
     $v->movies_allowed = (bool) movie::find_ffmpeg();
     $v->suhosin_session_encrypt = (bool) ini_get("suhosin.session.encrypt");
     return $v;
 }
示例#8
0
 public function create_movie_shouldnt_allow_names_with_trailing_periods_test()
 {
     $rand = rand();
     $root = ORM::factory("item", 1);
     try {
         $movie = movie::create($root, MODPATH . "gallery/tests/test.jpg", "{$rand}.jpg.", $rand, $rand);
     } catch (Exception $e) {
         $this->assert_equal("@todo NAME_CANNOT_END_IN_PERIOD", $e->getMessage());
         return;
     }
     $this->assert_true(false, "Shouldn't create a movie with trailing . in the name");
 }
示例#9
0
 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("server_add", $parent);
             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}";
                 if (in_array($extension, array("flv", "mp4"))) {
                     $movie = movie::create($parent, $source_path, $name, $name, null, user::active()->id);
                 } else {
                     $photo = photo::create($parent, $source_path, $name, $name, 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"];
 }
示例#10
0
 private function _print_view($form)
 {
     list($ffmpeg_version, $ffmpeg_date) = movie::get_ffmpeg_version();
     $ffmpeg_version = $ffmpeg_date ? "{$ffmpeg_version} ({$ffmpeg_date})" : $ffmpeg_version;
     $ffmpeg_path = movie::find_ffmpeg();
     $ffmpeg_dir = substr($ffmpeg_path, 0, strrpos($ffmpeg_path, "/"));
     $view = new Admin_View("admin.html");
     $view->page_title = t("Movies settings");
     $view->content = new View("admin_movies.html");
     $view->content->form = $form;
     $view->content->ffmpeg_dir = $ffmpeg_dir;
     $view->content->ffmpeg_version = $ffmpeg_version;
     print $view;
 }
示例#11
0
 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");
     }
 }
 static function get_movie_time($item)
 {
     $ffmpeg = movie::find_ffmpeg();
     if (empty($ffmpeg)) {
         return t("00:00");
     }
     $cmd = escapeshellcmd($ffmpeg) . " -i " . escapeshellarg($item->file_path()) . " 2>&1";
     $result = `{$cmd}`;
     if (preg_match("/Duration: (\\d+):(\\d+):(\\d+\\.\\d+)/", $result, $regs)) {
         return 3600 * $regs[1] + 60 * $regs[2] + $regs[3];
     } else {
         if (preg_match("/duration.*?:.*?(\\d+)/", $result, $regs)) {
             return $regs[1];
         } else {
             return '00';
         }
     }
 }
示例#13
0
文件: movie.php 项目: JasonWiki/docs
 /**
  * Return the width, height, mime_type and extension of the given movie file.
  */
 static function get_file_metadata($file_path)
 {
     $ffmpeg = movie::find_ffmpeg();
     if (empty($ffmpeg)) {
         throw new Exception("@todo MISSING_FFMPEG");
     }
     $cmd = escapeshellcmd($ffmpeg) . " -i " . escapeshellarg($file_path) . " 2>&1";
     $result = `{$cmd}`;
     if (preg_match("/Stream.*?Video:.*?, (\\d+)x(\\d+)/", $result, $regs)) {
         list($width, $height) = array($regs[1], $regs[2]);
     } else {
         list($width, $height) = array(0, 0);
     }
     $pi = pathinfo($file_path);
     $extension = isset($pi["extension"]) ? $pi["extension"] : "flv";
     // No extension?  Assume FLV.
     $mime_type = in_array(strtolower($extension), array("mp4", "m4v")) ? "video/mp4" : "video/x-flv";
     return array($width, $height, $mime_type, $extension);
 }
示例#14
0
 public function render()
 {
     $v = new View("form_uploadify.html");
     $v->album = $this->data["album"];
     $v->script_data = $this->data["script_data"];
     $v->simultaneous_upload_limit = module::get_var("gallery", "simultaneous_upload_limit");
     $v->movies_allowed = movie::allow_uploads();
     $v->extensions = legal_file::get_filters();
     $v->suhosin_session_encrypt = (bool) ini_get("suhosin.session.encrypt");
     list($toolkit_max_filesize_bytes, $toolkit_max_filesize) = graphics::max_filesize();
     $upload_max_filesize = trim(ini_get("upload_max_filesize"));
     $upload_max_filesize_bytes = num::convert_to_bytes($upload_max_filesize);
     if ($upload_max_filesize_bytes < $toolkit_max_filesize_bytes) {
         $v->size_limit_bytes = $upload_max_filesize_bytes;
         $v->size_limit = $upload_max_filesize;
     } else {
         $v->size_limit_bytes = $toolkit_max_filesize_bytes;
         $v->size_limit = $toolkit_max_filesize;
     }
     return $v;
 }
示例#15
0
require_once 'config.php';
require_once 'common/defaults.php';
require_once 'common/class.database.php';
function print_f($array = array())
{
    echo '<pre>';
    print_r($array);
    echo '</pre>';
}
// Custom auto loader
function admin_autoloader($class)
{
    include_once ABSPATH . 'classes/class.' . $class . '.php';
}
spl_autoload_register('admin_autoloader');
$id = isset($_GET['id']) ? $_GET['id'] : NULL;
$start = isset($_GET['start']) ? $_GET['start'] : NULL;
$end = isset($_GET['end']) ? $_GET['end'] : NULL;
$movie = new movie();
//$data = $movie->get_service_movies($id,$_GET['status'],$_GET['start'],$_GET['end']);
//print_f($results);
// if ($results) {
// 	foreach($results as $res){
// 		print_f($res);
// 	}
// }
header('Content-Type: application/json');
echo json_encode($movie->get_service_movies($id, $_GET['status'], $start, $end));
?>

	
示例#16
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;
     }
 }
示例#17
0
 /**
  * Create a merged list of all allowed photo and movie extensions.
  *
  * @param string $extension (opt.) - return true if allowed; if not given, return complete array
  */
 static function get_extensions($extension = null)
 {
     $extensions = legal_file::get_photo_extensions();
     if (movie::allow_uploads()) {
         $extensions = array_merge($extensions, legal_file::get_movie_extensions());
     }
     if ($extension) {
         // return true if in array, false if not
         return in_array(strtolower($extension), $extensions);
     } else {
         // return complete array
         return $extensions;
     }
 }
示例#18
0
 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);
         $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")));
         }
     } catch (Exception $e) {
         Kohana::log("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 json_encode(self::child_json_encode($item));
 }
示例#19
0
文件: item.php 项目: Joe7/gallery3
 /**
  * Make sure that the data file is well formed (it exists and isn't empty).
  */
 public function valid_data_file(Validation $v, $field)
 {
     if (!is_file($this->data_file)) {
         $v->add_error("name", "bad_data_file_path");
     } else {
         if (filesize($this->data_file) == 0) {
             $v->add_error("name", "empty_data_file");
         }
     }
     if ($this->loaded()) {
         if ($this->is_photo()) {
             list($a, $b, $mime_type) = photo::get_file_metadata($this->data_file);
         } else {
             if ($this->is_movie()) {
                 list($a, $b, $mime_type) = movie::get_file_metadata($this->data_file);
             }
         }
         if ($mime_type != $this->mime_type) {
             $v->add_error("name", "cant_change_mime_type");
         }
     }
 }
示例#20
0
 /**
  * Return the width, height, mime_type, extension and duration of the given movie file.
  * Metadata is first generated using ffmpeg (or set to defaults if it fails),
  * then can be modified by other modules using movie_get_file_metadata events.
  *
  * This function and its use cases are symmetric to those of photo::get_file_metadata.
  *
  * @param  string $file_path
  * @return array  array($width, $height, $mime_type, $extension, $duration)
  *
  * Use cases in detail:
  *   Input is standard movie type (flv/mp4/m4v)
  *     -> return metadata from ffmpeg
  *   Input is *not* standard movie type that is supported by ffmpeg (e.g. avi, mts...)
  *     -> return metadata from ffmpeg
  *   Input is *not* standard movie type that is *not* supported by ffmpeg but is legal
  *     -> return zero width, height, and duration; mime type and extension according to legal_file
  *   Input is illegal, unidentifiable, unreadable, or does not exist
  *     -> throw exception
  * Note: movie_get_file_metadata events can change any of the above cases (except the last one).
  */
 static function get_file_metadata($file_path)
 {
     if (!is_readable($file_path)) {
         throw new Exception("@todo UNREADABLE_FILE");
     }
     $metadata = new stdClass();
     $ffmpeg = movie::find_ffmpeg();
     if (!empty($ffmpeg)) {
         // ffmpeg found - use it to get width, height, and duration.
         $cmd = escapeshellcmd($ffmpeg) . " -i " . escapeshellarg($file_path) . " 2>&1";
         $result = `{$cmd}`;
         if (preg_match("/Stream.*?Video:.*?, (\\d+)x(\\d+)/", $result, $matches_res)) {
             if (preg_match("/Stream.*?Video:.*? \\[.*?DAR (\\d+):(\\d+).*?\\]/", $result, $matches_dar) && $matches_dar[1] >= 1 && $matches_dar[2] >= 1) {
                 // DAR is defined - determine width based on height and DAR
                 // (should always be int, but adding round to be sure)
                 $matches_res[1] = round($matches_res[2] * $matches_dar[1] / $matches_dar[2]);
             }
             list($metadata->width, $metadata->height) = array($matches_res[1], $matches_res[2]);
         } else {
             list($metadata->width, $metadata->height) = array(0, 0);
         }
         if (preg_match("/Duration: (\\d+:\\d+:\\d+\\.\\d+)/", $result, $matches)) {
             $metadata->duration = movie::hhmmssdd_to_seconds($matches[1]);
         } else {
             if (preg_match("/duration.*?:.*?(\\d+)/", $result, $matches)) {
                 $metadata->duration = $matches[1];
             } else {
                 $metadata->duration = 0;
             }
         }
     } else {
         // ffmpeg not found - set width, height, and duration to zero.
         $metadata->width = 0;
         $metadata->height = 0;
         $metadata->duration = 0;
     }
     $extension = pathinfo($file_path, PATHINFO_EXTENSION);
     if (!$extension || !($metadata->mime_type = legal_file::get_movie_types_by_extension($extension))) {
         // Extension is empty or illegal.
         $metadata->extension = null;
         $metadata->mime_type = null;
     } else {
         // Extension is legal (and mime is already set above).
         $metadata->extension = strtolower($extension);
     }
     // Run movie_get_file_metadata events which can modify the class.
     module::event("movie_get_file_metadata", $file_path, $metadata);
     // If the post-events results are invalid, throw an exception.  Note that, unlike photos, having
     // zero width and height isn't considered invalid (as is the case when FFmpeg isn't installed).
     if (!$metadata->mime_type || !$metadata->extension || $metadata->mime_type != legal_file::get_movie_types_by_extension($metadata->extension)) {
         throw new Exception("@todo ILLEGAL_OR_UNINDENTIFIABLE_FILE");
     }
     return array($metadata->width, $metadata->height, $metadata->mime_type, $metadata->extension, $metadata->duration);
 }
示例#21
0
 /**
  * Handle any business logic necessary to create or modify an item.
  * @see ORM::save()
  *
  * @return ORM Item_Model
  */
 public function save()
 {
     $significant_changes = $this->changed;
     unset($significant_changes["view_count"]);
     unset($significant_changes["relative_url_cache"]);
     unset($significant_changes["relative_path_cache"]);
     if (!empty($this->changed) && $significant_changes || isset($this->data_file)) {
         $this->updated = time();
         if (!$this->loaded()) {
             // Create a new item.
             module::event("item_before_create", $this);
             // Set a weight if it's missing.  We don't do this in the constructor because it's not a
             // simple assignment.
             if (empty($this->weight)) {
                 $this->weight = item::get_max_weight();
             }
             // Make an url friendly slug from the name, if necessary
             if (empty($this->slug)) {
                 $this->slug = item::convert_filename_to_slug(pathinfo($this->name, PATHINFO_FILENAME));
                 // If the filename is all invalid characters, then the slug may be empty here.  Pick a
                 // random value.
                 if (empty($this->slug)) {
                     $this->slug = (string) rand(1000, 9999);
                 }
             }
             // Get the width, height and mime type from our data file for photos and movies.
             if ($this->is_photo() || $this->is_movie()) {
                 if ($this->is_photo()) {
                     list($this->width, $this->height, $this->mime_type, $extension) = photo::get_file_metadata($this->data_file);
                 } else {
                     if ($this->is_movie()) {
                         list($this->width, $this->height, $this->mime_type, $extension) = movie::get_file_metadata($this->data_file);
                     }
                 }
                 // Force an extension onto the name if necessary
                 $pi = pathinfo($this->data_file);
                 if (empty($pi["extension"])) {
                     $this->name = "{$this->name}.{$extension}";
                 }
             }
             $this->_randomize_name_or_slug_on_conflict();
             parent::save();
             // Build our url caches, then save again.  We have to do this after it's already been
             // saved once because we use only information from the database to build the paths.  If we
             // could depend on a save happening later we could defer this 2nd save.
             $this->_build_relative_caches();
             parent::save();
             // Take any actions that we can only do once all our paths are set correctly after saving.
             switch ($this->type) {
                 case "album":
                     mkdir($this->file_path());
                     mkdir(dirname($this->thumb_path()));
                     mkdir(dirname($this->resize_path()));
                     break;
                 case "photo":
                 case "movie":
                     // The thumb or resize may already exist in the case where a movie and a photo generate
                     // a thumbnail of the same name (eg, foo.flv movie and foo.jpg photo will generate
                     // foo.jpg thumbnail).  If that happens, randomize and save again.
                     if (file_exists($this->resize_path()) || file_exists($this->thumb_path())) {
                         $pi = pathinfo($this->name);
                         $this->name = $pi["filename"] . "-" . random::int() . "." . $pi["extension"];
                         parent::save();
                     }
                     copy($this->data_file, $this->file_path());
                     break;
             }
             // This will almost definitely trigger another save, so put it at the end so that we're
             // tail recursive.  Null out the data file variable first, otherwise the next save will
             // trigger an item_updated_data_file event.
             $this->data_file = null;
             module::event("item_created", $this);
         } else {
             // Update an existing item
             module::event("item_before_update", $item);
             // If any significant fields have changed, load up a copy of the original item and
             // keep it around.
             $original = ORM::factory("item", $this->id);
             // Preserve the extension of the data file. Many helpers, (e.g. ImageMagick), assume
             // the MIME type from the extension. So when we adopt the new data file, it's important
             // to adopt the new extension. That ensures that the item's extension is always
             // appropriate for its data. We don't try to preserve the name of the data file, though,
             // because the name is typically a temporary randomly-generated name.
             if (isset($this->data_file)) {
                 $extension = pathinfo($this->data_file, PATHINFO_EXTENSION);
                 $new_name = pathinfo($this->name, PATHINFO_FILENAME) . ".{$extension}";
                 if (!empty($extension) && strcmp($this->name, $new_name)) {
                     $this->name = $new_name;
                 }
                 if ($this->is_photo()) {
                     list($this->width, $this->height, $this->mime_type, $extension) = photo::get_file_metadata($this->data_file);
                 } else {
                     if ($this->is_movie()) {
                         list($this->width, $this->height, $this->mime_type, $extension) = movie::get_file_metadata($this->data_file);
                     }
                 }
             }
             if (array_intersect($this->changed, array("parent_id", "name", "slug"))) {
                 $original->_build_relative_caches();
                 $this->relative_path_cache = null;
                 $this->relative_url_cache = null;
             }
             $this->_randomize_name_or_slug_on_conflict();
             parent::save();
             // Now update the filesystem and any database caches if there were significant value
             // changes.  If anything past this point fails, then we'll have an inconsistent database
             // so this code should be as robust as we can make it.
             // Update the MPTT pointers, if necessary.  We have to do this before we generate any
             // cached paths!
             if ($original->parent_id != $this->parent_id) {
                 parent::move_to($this->parent());
             }
             if ($original->parent_id != $this->parent_id || $original->name != $this->name) {
                 $this->_build_relative_caches();
                 // If there is a data file, then we want to preserve both the old data and the new data.
                 // (Third-party event handlers would like access to both). The old data file will be
                 // accessible via the $original item, and the new one via $this item. But in that case,
                 // we don't want to rename the original as below, because the old data would end up being
                 // clobbered by the new data file. Also, the rename isn't necessary, because the new item
                 // data is coming from the data file anyway. So we only perform the rename if there isn't
                 // a data file. Another way to solve this would be to copy the original file rather than
                 // conditionally rename it, but a copy would cost far more than the rename.
                 if (!isset($this->data_file)) {
                     @rename($original->file_path(), $this->file_path());
                 }
                 // Move all of the items associated data files
                 if ($this->is_album()) {
                     @rename(dirname($original->resize_path()), dirname($this->resize_path()));
                     @rename(dirname($original->thumb_path()), dirname($this->thumb_path()));
                 } else {
                     @rename($original->resize_path(), $this->resize_path());
                     @rename($original->thumb_path(), $this->thumb_path());
                 }
                 if ($original->parent_id != $this->parent_id) {
                     // This will result in 2 events since we'll still fire the item_updated event below
                     module::event("item_moved", $this, $original->parent());
                 }
             }
             // Changing the name, slug or parent ripples downwards
             if ($this->is_album() && ($original->name != $this->name || $original->slug != $this->slug || $original->parent_id != $this->parent_id)) {
                 db::build()->update("items")->set("relative_url_cache", null)->set("relative_path_cache", null)->where("left_ptr", ">", $this->left_ptr)->where("right_ptr", "<", $this->right_ptr)->execute();
             }
             // Replace the data file, if requested.
             if ($this->data_file && ($this->is_photo() || $this->is_movie())) {
                 copy($this->data_file, $this->file_path());
                 // Get the width, height and mime type from our data file for photos and movies.
                 if ($this->is_photo()) {
                     list($this->width, $this->height) = photo::get_file_metadata($this->file_path());
                 } else {
                     if ($this->is_movie()) {
                         list($this->width, $this->height) = movie::get_file_metadata($this->file_path());
                     }
                 }
                 $this->thumb_dirty = 1;
                 $this->resize_dirty = 1;
             }
             module::event("item_updated", $original, $this);
             if ($this->data_file) {
                 // Null out the data file variable here, otherwise this event will trigger another
                 // save() which will think that we're doing another file move.
                 $this->data_file = null;
                 if ($original->file_path() != $this->file_path()) {
                     @unlink($original->file_path());
                 }
                 module::event("item_updated_data_file", $this);
             }
         }
     } else {
         if (!empty($this->changed)) {
             // Insignificant changes only.  Don't fire events or do any special checking to try to keep
             // this lightweight.
             parent::save();
         }
     }
     return $this;
 }
示例#22
0
 /**
  * Rebuild the thumb and resize for the given item.
  * @param Item_Model $item
  */
 static function generate($item)
 {
     if ($item->is_album()) {
         if (!($cover = $item->album_cover())) {
             // This album has no cover; there's nothing to generate.  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://gallery.menalto.com/node/96926
             if ($item->album_cover_item_id) {
                 $item->album_cover_item_id = null;
                 $item->save();
             }
             return;
         }
         $input_file = $cover->file_path();
         $input_item = $cover;
     } else {
         $input_file = $item->file_path();
         $input_item = $item;
     }
     if ($item->thumb_dirty) {
         $ops["thumb"] = $item->thumb_path();
     }
     if ($item->resize_dirty && !$item->is_album() && !$item->is_movie()) {
         $ops["resize"] = $item->resize_path();
     }
     if (empty($ops)) {
         $item->thumb_dirty = 0;
         $item->resize_dirty = 0;
         $item->save();
         return;
     }
     try {
         foreach ($ops as $target => $output_file) {
             if ($input_item->is_movie()) {
                 // Convert the movie filename to a JPG first, delete anything that might already be there
                 $output_file = legal_file::change_extension($output_file, "jpg");
                 unlink($output_file);
                 // 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", $input_file, $output_file, $movie_options_wrapper, $input_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($input_file, $output_file, $movie_options_wrapper->movie_options);
                     } catch (Exception $e) {
                         // Didn't work, likely because of MISSING_FFMPEG - copy missing_movie instead
                         copy(MODPATH . "gallery/images/missing_movie.jpg", $output_file);
                     }
                 }
                 $working_file = $output_file;
             } else {
                 $working_file = $input_file;
             }
             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;
             }
         }
         if (!empty($ops["thumb"])) {
             if (file_exists($item->thumb_path())) {
                 $item->thumb_dirty = 0;
             } else {
                 copy(MODPATH . "gallery/images/missing_photo.png", $item->thumb_path());
             }
             $dims = getimagesize($item->thumb_path());
             $item->thumb_width = $dims[0];
             $item->thumb_height = $dims[1];
         }
         if (!empty($ops["resize"])) {
             if (file_exists($item->resize_path())) {
                 $item->resize_dirty = 0;
             } else {
                 copy(MODPATH . "gallery/images/missing_photo.png", $item->resize_path());
             }
             $dims = getimagesize($item->resize_path());
             $item->resize_width = $dims[0];
             $item->resize_height = $dims[1];
         }
         $item->save();
     } catch (Exception $e) {
         // Something went wrong rebuilding the image.  Leave it dirty and move on.
         // @todo we should handle this better.
         Kohana_Log::add("error", "Caught exception rebuilding image: {$item->title}\n" . $e->getMessage() . "\n" . $e->getTraceAsString());
         throw $e;
     }
 }
示例#23
0
 public function get_file_metadata_with_valid_extension_but_illegal_file_contents_test()
 {
     copy(MODPATH . "gallery/tests/Photo_Helper_Test.php", TMPPATH . "test_php_with_flv_extension.flv");
     // Since mime type and extension are based solely on the filename, this is considered valid.
     // Of course, FFmpeg cannot extract width, height, or duration from the file.  Note that this
     // isn't a really a security problem, since the filename doesn't have a php extension and
     // therefore will never be executed.
     $this->assert_equal(array(0, 0, "video/x-flv", "flv", 0), movie::get_file_metadata(TMPPATH . "test_php_with_flv_extension.flv"));
     unlink(TMPPATH . "test_php_with_flv_extension.flv");
 }
示例#24
0
 /**
  *  @see REST_Controller::_form_edit($resource)
  */
 public function _form_edit($movie)
 {
     access::required("view", $movie);
     access::required("edit", $movie);
     print movie::get_edit_form($movie);
 }
示例#25
0
 /**
  * Process the data file info.  Get its metadata and extension.
  * If valid, use it to sanitize the item name and update the
  * width, height, and mime type.
  */
 private function _process_data_file_info()
 {
     try {
         if ($this->is_photo()) {
             list($this->width, $this->height, $this->mime_type, $extension) = photo::get_file_metadata($this->data_file);
         } else {
             if ($this->is_movie()) {
                 list($this->width, $this->height, $this->mime_type, $extension) = movie::get_file_metadata($this->data_file);
             } else {
                 // Albums don't have data files.
                 $this->data_file = null;
                 return;
             }
         }
         // Sanitize the name based on the idenified extension, but only set $this->name if different
         // to ensure it isn't unnecessarily marked as "changed"
         $name = legal_file::sanitize_filename($this->name, $extension, $this->type);
         if ($this->name != $name) {
             $this->name = $name;
         }
         // Data file valid - make sure the flag is reset to false.
         $this->data_file_error = false;
     } catch (Exception $e) {
         // Data file invalid - set the flag so it's reported during item validation.
         $this->data_file_error = true;
     }
 }
示例#26
0
 /**
  * Handle any business logic necessary to create or modify an item.
  * @see ORM::save()
  *
  * @return ORM Item_Model
  */
 public function save()
 {
     $significant_changes = $this->changed;
     unset($significant_changes["view_count"]);
     unset($significant_changes["relative_url_cache"]);
     unset($significant_changes["relative_path_cache"]);
     if (!empty($this->changed) && $significant_changes) {
         $this->updated = time();
         if (!$this->loaded()) {
             // Create a new item.
             // Set a weight if it's missing.  We don't do this in the constructor because it's not a
             // simple assignment.
             if (empty($this->weight)) {
                 $this->weight = item::get_max_weight();
             }
             // Make an url friendly slug from the name, if necessary
             if (empty($this->slug)) {
                 $tmp = pathinfo($this->name, PATHINFO_FILENAME);
                 $tmp = preg_replace("/[^A-Za-z0-9-_]+/", "-", $tmp);
                 $this->slug = trim($tmp, "-");
             }
             // Get the width, height and mime type from our data file for photos and movies.
             if ($this->is_movie() || $this->is_photo()) {
                 $pi = pathinfo($this->data_file);
                 if ($this->is_photo()) {
                     $image_info = getimagesize($this->data_file);
                     $this->width = $image_info[0];
                     $this->height = $image_info[1];
                     $this->mime_type = $image_info["mime"];
                     // Force an extension onto the name if necessary
                     if (empty($pi["extension"])) {
                         $pi["extension"] = image_type_to_extension($image_info[2], false);
                         $this->name .= "." . $pi["extension"];
                     }
                 } else {
                     list($this->width, $this->height) = movie::getmoviesize($this->data_file);
                     // No extension?  Assume FLV.
                     if (empty($pi["extension"])) {
                         $pi["extension"] = "flv";
                         $this->name .= "." . $pi["extension"];
                     }
                     $this->mime_type = strtolower($pi["extension"]) == "mp4" ? "video/mp4" : "video/x-flv";
                 }
             }
             // Randomize the name or slug if there's a conflict.  Preserve the extension.
             // @todo Improve this.  Random numbers are not user friendly
             $base_name = pathinfo($this->name, PATHINFO_FILENAME);
             $base_ext = pathinfo($this->name, PATHINFO_EXTENSION);
             $base_slug = $this->slug;
             while (ORM::factory("item")->where("parent_id", "=", $this->parent_id)->and_open()->where("name", "=", $this->name)->or_where("slug", "=", $this->slug)->close()->find()->id) {
                 $rand = rand();
                 if ($base_ext) {
                     $this->name = "{$base_name}-{$rand}.{$base_ext}";
                 } else {
                     $this->name = "{$base_name}-{$rand}";
                 }
                 $this->slug = "{$base_slug}-{$rand}";
             }
             parent::save();
             // Build our url caches, then save again.  We have to do this after it's already been
             // saved once because we use only information from the database to build the paths.  If we
             // could depend on a save happening later we could defer this 2nd save.
             $this->_build_relative_caches();
             parent::save();
             // Take any actions that we can only do once all our paths are set correctly after saving.
             switch ($this->type) {
                 case "album":
                     mkdir($this->file_path());
                     mkdir(dirname($this->thumb_path()));
                     mkdir(dirname($this->resize_path()));
                     break;
                 case "photo":
                 case "movie":
                     // The thumb or resize may already exist in the case where a movie and a photo generate
                     // a thumbnail of the same name (eg, foo.flv movie and foo.jpg photo will generate
                     // foo.jpg thumbnail).  If that happens, randomize and save again.
                     if (file_exists($this->resize_path()) || file_exists($this->thumb_path())) {
                         $pi = pathinfo($this->name);
                         $this->name = $pi["filename"] . "-" . rand() . "." . $pi["extension"];
                         parent::save();
                     }
                     copy($this->data_file, $this->file_path());
                     break;
             }
             // This will almost definitely trigger another save, so put it at the end so that we're
             // tail recursive.
             module::event("item_created", $this);
         } else {
             // Update an existing item
             // If any significant fields have changed, load up a copy of the original item and
             // keep it around.
             $original = ORM::factory("item", $this->id);
             if (array_intersect($this->changed, array("parent_id", "name", "slug"))) {
                 $original->_build_relative_caches();
                 $this->relative_path_cache = null;
                 $this->relative_url_cache = null;
             }
             parent::save();
             // Now update the filesystem and any database caches if there were significant value
             // changes.  If anything past this point fails, then we'll have an inconsistent database
             // so this code should be as robust as we can make it.
             // Update the MPTT pointers, if necessary.  We have to do this before we generate any
             // cached paths!
             if ($original->parent_id != $this->parent_id) {
                 parent::move_to($this->parent());
             }
             if ($original->parent_id != $this->parent_id || $original->name != $this->name) {
                 // Move all of the items associated data files
                 @rename($original->file_path(), $this->file_path());
                 if ($this->is_album()) {
                     @rename(dirname($original->resize_path()), dirname($this->resize_path()));
                     @rename(dirname($original->thumb_path()), dirname($this->thumb_path()));
                 } else {
                     @rename($original->resize_path(), $this->resize_path());
                     @rename($original->thumb_path(), $this->thumb_path());
                 }
                 if ($original->parent_id != $this->parent_id) {
                     // This will result in 2 events since we'll still fire the item_updated event below
                     module::event("item_moved", $this, $original->parent());
                 }
             }
             // Changing the name, slug or parent ripples downwards
             if ($this->is_album() && ($original->name != $this->name || $original->slug != $this->slug || $original->parent_id != $this->parent_id)) {
                 db::build()->update("items")->set("relative_url_cache", null)->set("relative_path_cache", null)->where("left_ptr", ">", $this->left_ptr)->where("right_ptr", "<", $this->right_ptr)->execute();
             }
             module::event("item_updated", $original, $this);
         }
     } else {
         if (!empty($this->changed)) {
             // Insignificant changes only.  Don't fire events or do any special checking to try to keep
             // this lightweight.
             parent::save();
         }
     }
     return $this;
 }
示例#27
0
 /**
  * Import a single photo or movie.
  */
 static function import_item(&$queue)
 {
     $g2_item_id = array_shift($queue);
     if (self::map($g2_item_id)) {
         return t("Item with id: %id already imported, skipping", array("id" => $g2_item_id));
     }
     try {
         self::$current_g2_item = $g2_item = g2(GalleryCoreApi::loadEntitiesById($g2_item_id));
         $g2_path = g2($g2_item->fetchPath());
     } catch (Exception $e) {
         return t("Failed to import Gallery 2 item with id: %id\n%exception", array("id" => $g2_item_id, "exception" => $e->__toString()));
     }
     $parent = ORM::factory("item", self::map($g2_item->getParentId()));
     $g2_type = $g2_item->getEntityType();
     $corrupt = 0;
     if (!file_exists($g2_path)) {
         // If the Gallery 2 source image isn't available, this operation is going to fail.  That can
         // happen in cases where there's corruption in the source Gallery 2.  In that case, fall
         // back on using a broken image.  It's important that we import *something* otherwise
         // anything that refers to this item in Gallery 2 will have a dangling pointer in Gallery 3
         //
         // Note that this will change movies to be photos, if there's a broken movie.  Hopefully
         // this case is rare enough that we don't need to take any heroic action here.
         g2_import::log(t("%path missing in import; replacing it with a placeholder", array("path" => $g2_path)));
         $g2_path = MODPATH . "g2_import/data/broken-image.gif";
         $g2_type = "GalleryPhotoItem";
         $corrupt = 1;
     }
     $message = array();
     switch ($g2_type) {
         case "GalleryPhotoItem":
             if (!in_array($g2_item->getMimeType(), array("image/jpeg", "image/gif", "image/png"))) {
                 Kohana::log("alert", "{$g2_path} is an unsupported image type; using a placeholder gif");
                 $message[] = t("'%path' is an unsupported image type, using a placeholder", array("path" => $g2_path));
                 $g2_path = MODPATH . "g2_import/data/broken-image.gif";
                 $corrupt = 1;
             }
             try {
                 $item = photo::create($parent, $g2_path, $g2_item->getPathComponent(), self::_decode_html_special_chars($g2_item->getTitle()), self::_decode_html_special_chars(self::extract_description($g2_item)), self::map($g2_item->getOwnerId()));
             } catch (Exception $e) {
                 Kohana::log("alert", "Corrupt image {$g2_path}\n" . $e->__toString());
                 $message[] = t("Corrupt image '%path'", array("path" => $g2_path));
                 $message[] = $e->__toString();
                 $corrupt = 1;
             }
             break;
         case "GalleryMovieItem":
             // @todo we should transcode other types into FLV
             if (in_array($g2_item->getMimeType(), array("video/mp4", "video/x-flv"))) {
                 try {
                     $item = movie::create($parent, $g2_path, $g2_item->getPathComponent(), self::_decode_html_special_chars($g2_item->getTitle()), self::_decode_html_special_chars(self::extract_description($g2_item)), self::map($g2_item->getOwnerId()));
                 } catch (Exception $e) {
                     Kohana::log("alert", "Corrupt movie {$g2_path}\n" . $e->__toString());
                     $message[] = t("Corrupt movie '%path'", array("path" => $g2_path));
                     $message[] = $e->__toString();
                     $corrupt = 1;
                 }
             } else {
                 Kohana::log("alert", "{$g2_path} is an unsupported movie type");
                 $message[] = t("'%path' is an unsupported movie type", array("path" => $g2_path));
                 $corrupt = 1;
             }
             break;
         default:
             // Ignore
             break;
     }
     if (!empty($item)) {
         self::import_keywords_as_tags($g2_item->getKeywords(), $item);
     }
     if (isset($item)) {
         self::set_map($g2_item_id, $item->id);
         $item->view_count = g2(GalleryCoreApi::fetchItemViewCount($g2_item_id));
         $item->save();
     }
     if ($corrupt) {
         $url_generator = $GLOBALS["gallery"]->getUrlGenerator();
         // @todo we need a more persistent warning
         $g2_item_url = $url_generator->generateUrl(array("itemId" => $g2_item->getId()));
         // Why oh why did I ever approve the session id placeholder idea in G2?
         $g2_item_url = str_replace('&amp;g2_GALLERYSID=TMP_SESSION_ID_DI_NOISSES_PMT', '', $g2_item_url);
         if (!empty($item)) {
             $message[] = t("<a href=\"%g2_url\">%title</a> from Gallery 2 could not be processed; " . "(imported as <a href=\"%g3_url\">%title</a>)", array("g2_url" => $g2_item_url, "g3_url" => $item->url(), "title" => $g2_item->getTitle()));
         } else {
             $message[] = t("<a href=\"%g2_url\">%title</a> from Gallery 2 could not be processed", array("g2_url" => $g2_item_url, "title" => $g2_item->getTitle()));
         }
     }
     self::$current_g2_item = null;
     return $message;
 }
示例#28
0
 public function form_edit($id)
 {
     $item = model_cache::get("item", $id);
     access::required("view", $item);
     access::required("edit", $item);
     switch ($item->type) {
         case "album":
             $form = album::get_edit_form($item);
             break;
         case "photo":
             $form = photo::get_edit_form($item);
             break;
         case "movie":
             $form = movie::get_edit_form($item);
             break;
     }
     // Pass on the source item where this form was generated, so we have an idea where to return to.
     $form->hidden("from_id")->value((int) Input::instance()->get("from_id", 0));
     print $form;
 }
示例#29
0
 /**
  * Rebuild the thumb and resize for the given item.
  * @param Item_Model $item
  * @return true on successful generation
  */
 static function generate($item)
 {
     if ($item->is_album()) {
         if (!($cover = $item->album_cover())) {
             return false;
         }
         $input_file = $cover->file_path();
         $input_item = $cover;
     } else {
         $input_file = $item->file_path();
         $input_item = $item;
     }
     if ($item->thumb_dirty) {
         $ops["thumb"] = $item->thumb_path();
     }
     if ($item->resize_dirty && !$item->is_album() && !$item->is_movie()) {
         $ops["resize"] = $item->resize_path();
     }
     if (empty($ops)) {
         $item->thumb_dirty = 0;
         $item->resize_dirty = 0;
         $item->save();
         return true;
     }
     try {
         foreach ($ops as $target => $output_file) {
             if ($input_item->is_movie()) {
                 // Convert the movie to a JPG first
                 $output_file = preg_replace("/...\$/", "jpg", $output_file);
                 try {
                     movie::extract_frame($input_file, $output_file);
                 } catch (Exception $e) {
                     // Assuming this is MISSING_FFMPEG for now
                     copy(MODPATH . "gallery/images/missing_movie.png", $output_file);
                 }
                 $working_file = $output_file;
             } else {
                 $working_file = $input_file;
             }
             foreach (ORM::factory("graphics_rule")->where("target", $target)->where("active", true)->orderby("priority", "asc")->find_all() as $rule) {
                 $args = array($working_file, $output_file, unserialize($rule->args));
                 call_user_func_array(array("graphics", $rule->operation), $args);
                 $working_file = $output_file;
             }
         }
         if (!empty($ops["thumb"])) {
             $dims = getimagesize($item->thumb_path());
             $item->thumb_width = $dims[0];
             $item->thumb_height = $dims[1];
             $item->thumb_dirty = 0;
         }
         if (!empty($ops["resize"])) {
             $dims = getimagesize($item->resize_path());
             $item->resize_width = $dims[0];
             $item->resize_height = $dims[1];
             $item->resize_dirty = 0;
         }
         $item->save();
     } catch (Exception $e) {
         // Something went wrong rebuilding the image.  Leave it dirty and move on.
         // @todo we should handle this better.
         Kohana::log("error", "Caught exception rebuilding image: {$item->title}\n" . $e->getMessage() . "\n" . $e->getTraceAsString());
         return false;
     }
     return true;
 }
示例#30
0
 /**
  * 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")));
     }
 }