From 0312d1b071bd4434ddb3f82888b0323da6bf3732 Mon Sep 17 00:00:00 2001 From: shadlaws Date: Fri, 8 Feb 2013 13:51:41 +0100 Subject: #1994 - Make get_file_metadata throw an exception if photo or movie is unidentifiable/illegal. - photo & movie helpers: modified to throw exceptions when file is known to be unidentifiable/illegal. - item model: revised to work with exceptions and be more explicit when the data file is invalid. - item model: removed duplicate get_file_metadata call for updated items. - admin_watermarks controller: revised to work with exceptions (really cleans up logic here). - graphics helper: revised to handle invalid placeholders (a nearly-impossible corner case, but still...). - photo & movie helper tests: revised to work with exceptions, added new tests for illegal files with valid extensions. - item model tests: revised to work with exceptions, added new tests for illegal files with valid extensions. --- modules/gallery/helpers/movie.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'modules/gallery/helpers/movie.php') diff --git a/modules/gallery/helpers/movie.php b/modules/gallery/helpers/movie.php index 6844771b..d4b907a2 100644 --- a/modules/gallery/helpers/movie.php +++ b/modules/gallery/helpers/movie.php @@ -192,8 +192,16 @@ class movie_Core { $metadata->extension = strtolower($extension); } - // Run movie_get_file_metadata events which can modify the class, then return results. + // 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); } -- cgit v1.2.3 From 27be4ae6064b8609a641f4bf239999d5a8ec2c60 Mon Sep 17 00:00:00 2001 From: shadlaws Date: Sun, 10 Feb 2013 10:10:44 +0100 Subject: Follow-on to 0312d1b071bd4434ddb3f82888b0323da6bf3732 for #1994. - Updated function comments to match revisions. - No functional changes. --- modules/gallery/helpers/movie.php | 4 +--- modules/gallery/helpers/photo.php | 6 ++---- 2 files changed, 3 insertions(+), 7 deletions(-) (limited to 'modules/gallery/helpers/movie.php') diff --git a/modules/gallery/helpers/movie.php b/modules/gallery/helpers/movie.php index d4b907a2..637d8ac0 100644 --- a/modules/gallery/helpers/movie.php +++ b/modules/gallery/helpers/movie.php @@ -138,9 +138,7 @@ class movie_Core { * -> 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 *not* standard movie type that is *not* supported by ffmpeg and is *not* legal - * -> return zero width, height, and duration; null mime type and extension - * Input is not readable or does not exist + * 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). */ diff --git a/modules/gallery/helpers/photo.php b/modules/gallery/helpers/photo.php index 2d32f0d3..004cc7c4 100644 --- a/modules/gallery/helpers/photo.php +++ b/modules/gallery/helpers/photo.php @@ -94,10 +94,8 @@ class photo_Core { * Input is *not* standard photo type that is supported by getimagesize (e.g. tif, bmp...) * -> return metadata from getimagesize() * Input is *not* standard photo type that is *not* supported by getimagesize but is legal - * -> return zero width and height, mime type and extension according to legal_file - * Input is *not* standard photo type that is *not* supported by getimagesize and is *not* legal - * -> return zero width and height, null mime type and extension - * Input is not readable or does not exist + * -> return metadata if found by photo_get_file_metadata events + * Input is illegal, unidentifiable, unreadable, or does not exist * -> throw exception * Note: photo_get_file_metadata events can change any of the above cases (except the last one). */ -- cgit v1.2.3 From 0a2670a19ab121fe6970f2fcdf1864cb452a76c1 Mon Sep 17 00:00:00 2001 From: shadlaws Date: Tue, 12 Feb 2013 00:30:30 +0100 Subject: #1988 - Add movie_allow_uploads option ("always", "never", or "autodetect"). - gallery_installer, module.info, install.sql - add movie_allow_uploads variable - movie::allow_uploads (new) - return true if movie_allow_uploads is "always" or "autodetect" and FFmpeg found, false otherwise - legal_file - use movie::allow_uploads instead of movie::find_ffmpeg - Form_Uploadify - use movie::allow_uploads instead of movie::find_ffmpeg --- installer/install.sql | 5 +++-- modules/gallery/helpers/gallery_installer.php | 8 ++++++++ modules/gallery/helpers/legal_file.php | 4 ++-- modules/gallery/helpers/movie.php | 25 +++++++++++++++++++++++++ modules/gallery/libraries/Form_Uploadify.php | 2 +- modules/gallery/module.info | 2 +- 6 files changed, 40 insertions(+), 6 deletions(-) (limited to 'modules/gallery/helpers/movie.php') diff --git a/installer/install.sql b/installer/install.sql index 4097d51e..b89d6b9b 100644 --- a/installer/install.sql +++ b/installer/install.sql @@ -245,7 +245,7 @@ CREATE TABLE {modules} ( KEY `weight` (`weight`) ) AUTO_INCREMENT=10 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -INSERT INTO {modules} VALUES (1,1,'gallery',55,1); +INSERT INTO {modules} VALUES (1,1,'gallery',56,1); INSERT INTO {modules} VALUES (2,1,'user',4,2); INSERT INTO {modules} VALUES (3,1,'comment',7,3); INSERT INTO {modules} VALUES (4,1,'organize',4,4); @@ -383,7 +383,7 @@ CREATE TABLE {vars} ( `value` text, PRIMARY KEY (`id`), UNIQUE KEY `module_name` (`module_name`,`name`) -) AUTO_INCREMENT=46 DEFAULT CHARSET=utf8; +) AUTO_INCREMENT=47 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; INSERT INTO {vars} VALUES (NULL,'gallery','active_site_theme','wind'); INSERT INTO {vars} VALUES (NULL,'gallery','active_admin_theme','admin_wind'); @@ -417,6 +417,7 @@ INSERT INTO {vars} VALUES (NULL,'gallery','extra_binary_paths','/usr/local/bin:/ INSERT INTO {vars} VALUES (NULL,'gallery','timezone',NULL); INSERT INTO {vars} VALUES (NULL,'gallery','lock_timeout','1'); INSERT INTO {vars} VALUES (NULL,'gallery','movie_extract_frame_time','3'); +INSERT INTO {vars} VALUES (NULL,'gallery','movie_allow_uploads','autodetect'); INSERT INTO {vars} VALUES (NULL,'gallery','blocks_site_sidebar','a:4:{i:10;a:2:{i:0;s:7:\"gallery\";i:1;s:8:\"language\";}i:11;a:2:{i:0;s:4:\"info\";i:1;s:8:\"metadata\";}i:12;a:2:{i:0;s:3:\"rss\";i:1;s:9:\"rss_feeds\";}i:13;a:2:{i:0;s:3:\"tag\";i:1;s:3:\"tag\";}}'); INSERT INTO {vars} VALUES (NULL,'gallery','identity_provider','user'); INSERT INTO {vars} VALUES (NULL,'user','minimum_password_length','5'); diff --git a/modules/gallery/helpers/gallery_installer.php b/modules/gallery/helpers/gallery_installer.php index 7f10cdee..051a66cf 100644 --- a/modules/gallery/helpers/gallery_installer.php +++ b/modules/gallery/helpers/gallery_installer.php @@ -315,6 +315,7 @@ class gallery_installer { module::set_var("gallery", "timezone", null); module::set_var("gallery", "lock_timeout", 1); module::set_var("gallery", "movie_extract_frame_time", 3); + module::set_var("gallery", "movie_allow_uploads", "autodetect"); } static function upgrade($version) { @@ -789,6 +790,13 @@ class gallery_installer { module::set_version("gallery", $version = 55); } + if ($version == 55) { + // In v56, we added the ability to change the default behavior regarding movie uploads. It + // can be set to "always", "never", or "autodetect" to match the previous behavior where they + // are allowed only if FFmpeg is found. + module::set_var("gallery", "movie_allow_uploads", "autodetect"); + module::set_version("gallery", $version = 56); + } } static function uninstall() { diff --git a/modules/gallery/helpers/legal_file.php b/modules/gallery/helpers/legal_file.php index ef588ceb..debd1e6d 100644 --- a/modules/gallery/helpers/legal_file.php +++ b/modules/gallery/helpers/legal_file.php @@ -98,7 +98,7 @@ class legal_file_Core { */ static function get_types_by_extension($extension=null) { $types_by_extension = legal_file::get_photo_types_by_extension(); - if (movie::find_ffmpeg()) { + if (movie::allow_uploads()) { $types_by_extension = array_merge($types_by_extension, legal_file::get_movie_types_by_extension()); } @@ -165,7 +165,7 @@ class legal_file_Core { */ static function get_extensions($extension=null) { $extensions = legal_file::get_photo_extensions(); - if (movie::find_ffmpeg()) { + if (movie::allow_uploads()) { $extensions = array_merge($extensions, legal_file::get_movie_extensions()); } if ($extension) { diff --git a/modules/gallery/helpers/movie.php b/modules/gallery/helpers/movie.php index d4b907a2..eda478c7 100644 --- a/modules/gallery/helpers/movie.php +++ b/modules/gallery/helpers/movie.php @@ -24,6 +24,8 @@ * Note: by design, this class does not do any permission checking. */ class movie_Core { + private static $allow_uploads; + static function get_edit_form($movie) { $form = new Forge("movies/update/$movie->id", "", "post", array("id" => "g-edit-movie-form")); $form->hidden("from_id")->value($movie->id); @@ -109,6 +111,29 @@ class movie_Core { } } + /** + * Return true if movie uploads are allowed, false if not. This is based on the + * "movie_allow_uploads" Gallery variable as well as whether or not ffmpeg is found. + */ + static function allow_uploads() { + if (empty(self::$allow_uploads)) { + // Refresh ffmpeg settings + $ffmpeg = movie::find_ffmpeg(); + switch (module::get_var("gallery", "movie_allow_uploads", "autodetect")) { + case "always": + self::$allow_uploads = true; + break; + case "never": + self::$allow_uploads = false; + break; + default: + self::$allow_uploads = !empty($ffmpeg); + break; + } + } + return self::$allow_uploads; + } + /** * Return the path to the ffmpeg binary if one exists and is executable, or null. */ diff --git a/modules/gallery/libraries/Form_Uploadify.php b/modules/gallery/libraries/Form_Uploadify.php index 56793c69..1e58018d 100644 --- a/modules/gallery/libraries/Form_Uploadify.php +++ b/modules/gallery/libraries/Form_Uploadify.php @@ -46,7 +46,7 @@ class Form_Uploadify_Core extends Form_Input { $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->movies_allowed = movie::allow_uploads(); $v->extensions = legal_file::get_filters(); $v->suhosin_session_encrypt = (bool) ini_get("suhosin.session.encrypt"); diff --git a/modules/gallery/module.info b/modules/gallery/module.info index d79a5077..2383ec3c 100644 --- a/modules/gallery/module.info +++ b/modules/gallery/module.info @@ -1,6 +1,6 @@ name = "Gallery 3" description = "Gallery core application" -version = 55 +version = 56 author_name = "Gallery Team" author_url = "http://codex.galleryproject.org/Gallery:Team" info_url = "http://codex.galleryproject.org/Gallery3:Modules:gallery" -- cgit v1.2.3 From f212f6a794c4aff96446b99e4824a9e2c8cfb259 Mon Sep 17 00:00:00 2001 From: shadlaws Date: Thu, 14 Feb 2013 23:42:20 +0100 Subject: #2003 - Add admin/movies screen. Added admin/movies screen analogous to the admin/graphics screen so the user can: - see how FFmpeg is configured (path and version, similar to toolkits in admin/graphics) - get some instructions on how to install FFmpeg if not found - change the movie_allow_uploads setting - ask Gallery to rebuild their movie thumbs Specifics: - admin_movies, admin_movies.html (new) - new Movies admin screen - ffmpeg.png (new) - logo for admin screen - movie::get_ffmpeg_version (new) - return version number and date of FFmpeg - form_uploadify.html - change admin message if movie uploads are disabled - gallery_event::admin_menu - added Movies link to Settings - xss_data.txt - updated golden file for unit tests --- modules/gallery/controllers/admin_movies.php | 72 ++++++++++++++++++++++++++ modules/gallery/helpers/gallery_event.php | 4 ++ modules/gallery/helpers/movie.php | 28 ++++++++++ modules/gallery/images/ffmpeg.png | Bin 0 -> 2888 bytes modules/gallery/tests/xss_data.txt | 1 + modules/gallery/views/admin_movies.html.php | 44 ++++++++++++++++ modules/gallery/views/form_uploadify.html.php | 2 +- 7 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 modules/gallery/controllers/admin_movies.php create mode 100644 modules/gallery/images/ffmpeg.png create mode 100644 modules/gallery/views/admin_movies.html.php (limited to 'modules/gallery/helpers/movie.php') diff --git a/modules/gallery/controllers/admin_movies.php b/modules/gallery/controllers/admin_movies.php new file mode 100644 index 00000000..38fa44a5 --- /dev/null +++ b/modules/gallery/controllers/admin_movies.php @@ -0,0 +1,72 @@ +_get_admin_form(); + $this->_print_view($form); + } + + public function save() { + access::verify_csrf(); + $form = $this->_get_admin_form(); + if ($form->validate()) { + module::set_var("gallery", "movie_allow_uploads", $form->settings->allow_uploads->value); + if ($form->settings->rebuild_thumbs->value) { + graphics::mark_dirty(true, false, "movie"); + } + // All done - redirect with message. + message::success(t("Movies settings updated successfully")); + url::redirect("admin/movies"); + } + // Something went wrong - print view from existing form. + $this->_print_view($form); + } + + 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; + } + + private function _get_admin_form() { + $form = new Forge("admin/movies/save", "", "post", array("id" => "g-movies-admin-form")); + $group = $form->group("settings")->label(t("Settings")); + $group->dropdown("allow_uploads") + ->label(t("Allow movie uploads into Gallery (does not affect existing movies)")) + ->options(array("autodetect"=>t("only if FFmpeg is detected (default)"), + "always"=>t("always"), "never"=>t("never"))) + ->selected(module::get_var("gallery", "movie_allow_uploads", "autodetect")); + $group->checkbox("rebuild_thumbs") + ->label(t("Rebuild all movie thumbnails (once FFmpeg is installed, use this to update existing movie thumbnails)")) + ->checked(false); // always set as false + $form->submit("save")->value(t("Save")); + return $form; + } +} diff --git a/modules/gallery/helpers/gallery_event.php b/modules/gallery/helpers/gallery_event.php index aeb1c7eb..54c60296 100644 --- a/modules/gallery/helpers/gallery_event.php +++ b/modules/gallery/helpers/gallery_event.php @@ -398,6 +398,10 @@ class gallery_event_Core { ->id("graphics_toolkits") ->label(t("Graphics")) ->url(url::site("admin/graphics"))) + ->append(Menu::factory("link") + ->id("movies_settings") + ->label(t("Movies")) + ->url(url::site("admin/movies"))) ->append(Menu::factory("link") ->id("languages") ->label(t("Languages")) diff --git a/modules/gallery/helpers/movie.php b/modules/gallery/helpers/movie.php index 863e1cf9..aff2acc1 100644 --- a/modules/gallery/helpers/movie.php +++ b/modules/gallery/helpers/movie.php @@ -146,6 +146,34 @@ class movie_Core { return $ffmpeg_path; } + /** + * Return version number and build date of ffmpeg if found, empty string(s) if not. When using + * static builds that aren't official releases, the version numbers are strange, hence why the + * date can be useful. + */ + static function get_ffmpeg_version() { + $ffmpeg = movie::find_ffmpeg(); + if (empty($ffmpeg)) { + return array("", ""); + } + + // Find version using -h argument since -version wasn't available in early versions. + // To keep the preg_match searches quick, we'll trim the (otherwise long) result. + $cmd = escapeshellcmd($ffmpeg) . " -h 2>&1"; + $result = substr(`$cmd`, 0, 1000); + if (preg_match("/ffmpeg version (\S+)/i", $result, $matches_version)) { + // Version number found - see if we can get the build date or copyright year as well. + if (preg_match("/built on (\S+\s\S+\s\S+)/i", $result, $matches_build_date)) { + return array(trim($matches_version[1], ","), trim($matches_build_date[1], ",")); + } else if (preg_match("/copyright \S*\s?2000-(\d{4})/i", $result, $matches_copyright_date)) { + return array(trim($matches_version[1], ","), $matches_copyright_date[1]); + } else { + return array(trim($matches_version[1], ","), ""); + } + } + return array("", ""); + } + /** * 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), diff --git a/modules/gallery/images/ffmpeg.png b/modules/gallery/images/ffmpeg.png new file mode 100644 index 00000000..6be8b62a Binary files /dev/null and b/modules/gallery/images/ffmpeg.png differ diff --git a/modules/gallery/tests/xss_data.txt b/modules/gallery/tests/xss_data.txt index 51347f86..67a8b948 100644 --- a/modules/gallery/tests/xss_data.txt +++ b/modules/gallery/tests/xss_data.txt @@ -111,6 +111,7 @@ modules/gallery/views/admin_modules_confirm.html.php 11 DIRTY_ATTR $css modules/gallery/views/admin_modules_confirm.html.php 11 DIRTY $message modules/gallery/views/admin_modules_confirm.html.php 16 DIRTY access::csrf_form_field() modules/gallery/views/admin_modules_confirm.html.php 18 DIRTY form::hidden($module,1) +modules/gallery/views/admin_movies.html.php 43 DIRTY $form modules/gallery/views/admin_sidebar.html.php 50 DIRTY $available modules/gallery/views/admin_sidebar.html.php 58 DIRTY $active modules/gallery/views/admin_sidebar_blocks.html.php 4 DIRTY_ATTR $ref diff --git a/modules/gallery/views/admin_movies.html.php b/modules/gallery/views/admin_movies.html.php new file mode 100644 index 00000000..e7810711 --- /dev/null +++ b/modules/gallery/views/admin_movies.html.php @@ -0,0 +1,44 @@ + +
+

+

+ + +

+

+ + static build of FFmpeg from one of the links here.", array("url" => "http://ffmpeg.org/download.html")) ?> + +

+

+ +

+

+ We can help!", + array("url" => "http://codex.galleryproject.org/Gallery3:FAQ#Why_does_it_say_I.27m_missing_ffmpeg.3F")) ?> +

+ +
+

+
+ " alt="" /> +

+
+ FFmpeg website for more information.", array("url" => "http://ffmpeg.org")) ?> +

+
+ + +

$ffmpeg_version, "dir" => $ffmpeg_dir)) ?>

+ +

$ffmpeg_dir)) ?>

+ + +

+ +
+
+
+ + +
diff --git a/modules/gallery/views/form_uploadify.html.php b/modules/gallery/views/form_uploadify.html.php index 4426514a..c13e3418 100644 --- a/modules/gallery/views/form_uploadify.html.php +++ b/modules/gallery/views/form_uploadify.html.php @@ -131,7 +131,7 @@ admin && !$movies_allowed): ?>

- ffmpeg on your system. Movie uploading disabled. Help!", array("help_url" => "http://codex.galleryproject.org/Gallery3:FAQ#Why_does_it_say_I.27m_missing_ffmpeg.3F")) ?> + Help!", array("help_url" => url::site("admin/movies"))) ?>

-- cgit v1.2.3