public function movie_thumbnails_are_jpgs_test()
 {
     $movie = test::random_movie();
     $name = legal_file::change_extension($movie->name, "jpg");
     $_SERVER["REQUEST_URI"] = url::file("var/thumbs/{$name}");
     $controller = new File_Proxy_Controller();
     $this->assert_same($movie->thumb_path(), $controller->__call("", array()));
 }
 public function change_extension_path_containing_dots_test()
 {
     $this->assert_equal("/website/foo.com/VID_20120513_105421.jpg", legal_file::change_extension("/website/foo.com/VID_20120513_105421.mp4", "jpg"));
 }
Exemple #3
0
 /**
  * album: http://example.com/gallery3/var/resizes/album1/.thumb.jpg
  * photo: http://example.com/gallery3/var/albums/album1/photo.thumb.jpg
  */
 public function thumb_url($full_uri = false)
 {
     $cache_buster = $this->_cache_buster($this->thumb_path());
     $relative_path = "var/thumbs/" . $this->relative_path();
     $base = $full_uri ? url::abs_file($relative_path) : url::file($relative_path);
     if ($this->is_photo()) {
         return $base . $cache_buster;
     } else {
         if ($this->is_album()) {
             return $base . "/.album.jpg" . $cache_buster;
         } else {
             if ($this->is_movie()) {
                 // Replace the extension with jpg
                 $base = legal_file::change_extension($base, "jpg");
                 return $base . $cache_buster;
             }
         }
     }
 }
Exemple #4
0
 public function add()
 {
     access::verify_csrf();
     $form = watermark::get_add_form();
     if ($form->validate()) {
         $file = $_POST["file"];
         $pathinfo = pathinfo($file);
         // Forge prefixes files with "uploadfile-xxxxxxx" for uniqueness
         $name = preg_replace("/uploadfile-[^-]+-(.*)/", '$1', $pathinfo["basename"]);
         $name = legal_file::smash_extensions($name);
         if (!($image_info = getimagesize($file)) || !in_array($image_info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) {
             message::error(t("Unable to identify this image file"));
             @unlink($file);
             return;
         }
         if (!in_array($pathinfo["extension"], legal_file::get_photo_extensions())) {
             switch ($image_info[2]) {
                 case IMAGETYPE_GIF:
                     $name = legal_file::change_extension($name, "gif");
                     break;
                 case IMAGETYPE_JPEG:
                     $name = legal_file::change_extension($name, "jpg");
                     break;
                 case IMAGETYPE_PNG:
                     $name = legal_file::change_extension($name, "png");
                     break;
             }
         }
         rename($file, VARPATH . "modules/watermark/{$name}");
         module::set_var("watermark", "name", $name);
         module::set_var("watermark", "width", $image_info[0]);
         module::set_var("watermark", "height", $image_info[1]);
         module::set_var("watermark", "mime_type", $image_info["mime"]);
         module::set_var("watermark", "position", $form->add_watermark->position->value);
         module::set_var("watermark", "transparency", $form->add_watermark->transparency->value);
         $this->_update_graphics_rules();
         @unlink($file);
         message::success(t("Watermark saved"));
         log::success("watermark", t("Watermark saved"));
         json::reply(array("result" => "success", "location" => url::site("admin/watermarks")));
     } else {
         // rawurlencode the results because the JS code that uploads the file buffers it in an
         // iframe which entitizes the HTML and makes it difficult for the JS to process.  If we url
         // encode it now, it passes through cleanly.  See ticket #797.
         json::reply(array("result" => "error", "html" => rawurlencode((string) $form)));
     }
     // Override the application/json mime type.  The dialog based HTML uploader uses an iframe to
     // buffer the reply, and on some browsers (Firefox 3.6) it does not know what to do with the
     // JSON that it gets back so it puts up a dialog asking the user what to do with it.  So force
     // the encoding type back to HTML for the iframe.
     // See: http://jquery.malsup.com/form/#file-upload
     header("Content-Type: text/html; charset=" . Kohana::CHARSET);
 }
 /**
  * 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;
     }
 }
Exemple #6
0
 /**
  * Sanitize a filename for a given type (given as "photo" or "movie") and a target file format
  * (given as an extension).  This returns a completely legal and valid filename,
  * or throws an exception if the type or extension given is invalid or illegal.  It tries to
  * maintain the filename's original extension even if it's not identical to the given extension
  * (e.g. don't change "JPG" or "jpeg" to "jpg").
  *
  * Note: it is not okay if the extension given is legal but does not match the type (e.g. if
  * extension is "mp4" and type is "photo", it will throw an exception)
  *
  * @param  string $filename  (with no directory)
  * @param  string $extension (can be uppercase or lowercase)
  * @param  string $type      (as "photo" or "movie")
  * @return string sanitized filename (or null if bad extension argument)
  */
 static function sanitize_filename($filename, $extension, $type)
 {
     // Check if the type is valid - if so, get the mime types of the
     // original and target extensions; if not, throw an exception.
     $original_extension = pathinfo($filename, PATHINFO_EXTENSION);
     switch ($type) {
         case "photo":
             $mime_type = legal_file::get_photo_types_by_extension($extension);
             $original_mime_type = legal_file::get_photo_types_by_extension($original_extension);
             break;
         case "movie":
             $mime_type = legal_file::get_movie_types_by_extension($extension);
             $original_mime_type = legal_file::get_movie_types_by_extension($original_extension);
             break;
         default:
             throw new Exception("@todo INVALID_TYPE");
     }
     // Check if the target extension is blank or invalid - if so, throw an exception.
     if (!$extension || !$mime_type) {
         throw new Exception("@todo ILLEGAL_EXTENSION");
     }
     // Check if the mime types of the original and target extensions match - if not, fix it.
     if (!$original_extension || $mime_type != $original_mime_type) {
         $filename = legal_file::change_extension($filename, $extension);
     }
     // It should be a filename without a directory - remove all slashes (and backslashes).
     $filename = str_replace("/", "_", $filename);
     $filename = str_replace("\\", "_", $filename);
     // Remove extra dots from the filename.  This will also remove extraneous underscores.
     $filename = legal_file::smash_extensions($filename);
     // It's possible that the filename has no base (e.g. ".jpg") - if so, give it a generic one.
     if (empty($filename) || substr($filename, 0, 1) == ".") {
         $filename = $type . $filename;
         // e.g. "photo.jpg" or "movie.mp4"
     }
     return $filename;
 }
 public function find_by_path_with_flv_test()
 {
     $parent = test::random_album();
     $flv = test::random_movie($parent);
     $flv_path = "{$parent->name}/{$flv->name}";
     $jpg_path = legal_file::change_extension($flv_path, "jpg");
     // Check normal operation.
     $this->assert_equal($flv->id, item::find_by_path($flv_path, "albums")->id);
     $this->assert_equal($flv->id, item::find_by_path($jpg_path, "thumbs")->id);
     $this->assert_equal($flv->id, item::find_by_path($flv_path)->id);
     // Check that we don't get false positives.
     $this->assert_equal(null, item::find_by_path($jpg_path, "albums")->id);
     $this->assert_equal(null, item::find_by_path($flv_path, "thumbs")->id);
     $this->assert_equal(null, item::find_by_path($jpg_path)->id);
     // Check normal operation without relative path cache.
     self::_remove_relative_path_caches();
     $this->assert_equal($flv->id, item::find_by_path($flv_path, "albums")->id);
     self::_remove_relative_path_caches();
     $this->assert_equal($flv->id, item::find_by_path($jpg_path, "thumbs")->id);
     self::_remove_relative_path_caches();
     $this->assert_equal($flv->id, item::find_by_path($flv_path)->id);
     // Check that we don't get false positives without relative path cache.
     self::_remove_relative_path_caches();
     $this->assert_equal(null, item::find_by_path($jpg_path, "albums")->id);
     $this->assert_equal(null, item::find_by_path($flv_path, "thumbs")->id);
     $this->assert_equal(null, item::find_by_path($jpg_path)->id);
 }
 /**
  * the main optimize function
  *
  * the function arguments are the same format as other graphics rules.  the only "option" is $target, hence why it's renamed in the function def.
  *
  * NOTE: unlike other graphics transformations, this only uses the output file!  if it isn't already there, we don't do anything.
  * among other things, this means that the original, full-size images are never touched.
  */
 static function optimize($input_file, $output_file, $target, $item = null)
 {
     // see if output file exists and is writable
     if (is_writable($output_file)) {
         // see if input is a supported file type.  if not, return without doing anything.
         $image_info = getimagesize($input_file);
         // [0]=w, [1]=h, [2]=type (1=GIF, 2=JPG, 3=PNG)
         switch ($image_info[2]) {
             case 1:
                 $type_old = "gif";
                 $convert = module::get_var("image_optimizer", "convert_" . $target . "_gif");
                 break;
             case 2:
                 $type_old = "jpg";
                 $convert = 0;
                 // no conversion possible here...
                 break;
             case 3:
                 $type_old = "png";
                 $convert = module::get_var("image_optimizer", "convert_" . $target . "_png");
                 break;
             default:
                 // not a supported file type
                 return;
         }
     } else {
         // file doesn't exist or isn't writable
         return;
     }
     // set new file type
     $type = $convert ? $convert : $type_old;
     // convert image type (if applicable).  this isn't necessarily lossless.
     if ($convert) {
         $output_file_new = legal_file::change_extension($output_file, $type);
         // perform conversion using standard Gallery toolkit (GD/ImageMagick/GraphicsMagick)
         // note: if input was a GIF, this will kill animation
         $image = Image::factory($output_file)->quality(module::get_var("gallery", "image_quality"))->save($output_file_new);
         // if filenames are different, move the new on top of the old
         if ($output_file != $output_file_new) {
             /**
              * HACK ALERT!  Gallery3 is still broken with regard to treating thumb/resizes with proper extensions.  This doesn't try to fix that.
              *   Normal Gallery setup:
              *     photo thumb -> keep photo type, keep photo extension
              *     album thumb -> keep source photo thumb type, change extension to jpg (i.e. ".album.jpg" even for png/gif)
              * Also, missing_photo.png is similarly altered...
              *
              * Anyway, to avoid many rewrites of core functions (and not-easily-reversible database changes), this module also forces the extension to stay the same.
              *   With image optimizer conversion:
              *     photo thumb -> change type, keep photo extension (i.e. "photo.png" photo becomes "photo.png" thumb even if type has changed)
              *     album thumb -> keep source photo thumb type, change extension to jpg (i.e. ".album.jpg" even for png/gif)
              */
             rename($output_file_new, $output_file);
         }
     }
     // get module variables
     $configstatus = module::get_var("image_optimizer", "configstatus_" . $type);
     $path = module::get_var("image_optimizer", "path_" . $type);
     $opt = module::get_var("image_optimizer", "optlevel_" . $target . "_" . $type);
     $meta = module::get_var("image_optimizer", "metastrip_" . $target);
     $prog = module::get_var("image_optimizer", "progressive_" . $target);
     // make sure the toolkit is configured correctly and we want to use it - if not, return without doing anything.
     if ($configstatus) {
         if (!$prog && !$meta && !$opt) {
             // nothing to do!
             return;
         }
     } else {
         // not configured correctly
         return;
     }
     /**
      * do the actual optimization
      */
     // set parameters
     switch ($type) {
         case "jpg":
             $exec_args = $opt ? " -optimize" : "";
             $exec_args .= $meta ? " -copy none" : " -copy all";
             $exec_args .= $prog ? " -progressive" : "";
             $exec_args .= " -outfile ";
             break;
         case "png":
             $exec_args = $opt ? " -o" . $opt : "";
             $exec_args .= $meta ? " -strip all" : "";
             $exec_args .= $prog ? " -i 1" : "";
             $exec_args .= " -quiet -out ";
             break;
         case "gif":
             $exec_args = $opt ? " --optimize=3" : "";
             // levels 1 and 2 don't really help us
             $exec_args .= $meta ? " --no-comments --no-extensions --no-names" : " --same-comments --same-extensions --same-names";
             $exec_args .= $prog ? " --interlace" : " --same-interlace";
             $exec_args .= " --careful --output ";
             break;
     }
     // run it - from output_file to tmp_file.
     $tmp_file = image_optimizer::make_temp_name($output_file);
     exec(escapeshellcmd($path) . $exec_args . escapeshellarg($tmp_file) . " " . escapeshellarg($output_file), $exec_output, $exec_status);
     if ($exec_status || !filesize($tmp_file)) {
         // either a blank/nonexistant file or an error - do nothing to the output, but log an error and delete the temp (if any)
         Kohana_Log::add("error", "image_optimizer optimization failed on " . $output_file);
         unlink($tmp_file);
     } else {
         // worked - move temp to output
         rename($tmp_file, $output_file);
     }
 }
Exemple #9
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 to a JPG first
                 $output_file = legal_file::change_extension($output_file, "jpg");
                 try {
                     movie::extract_frame($input_file, $output_file);
                 } catch (Exception $e) {
                     // Assuming this is MISSING_FFMPEG for now
                     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;
     }
 }
 public function change_extension_path_containing_dots_and_non_standard_chars_test()
 {
     $this->assert_equal("/j'écris@un#nom/bizarre(mais quand.même/ça_passe.jpg", legal_file::change_extension("/j'écris@un#nom/bizarre(mais quand.même/ça_passe.\$ÇÀ@€#_", "jpg"));
 }