summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorNathan Kinkade <nath@nkinka.de>2013-01-16 17:32:36 +0000
committerNathan Kinkade <nath@nkinka.de>2013-01-16 17:32:36 +0000
commit0047af90bf4db08b22838e6ded22a7fa70cee98a (patch)
tree1c6cb658ffac9ae5d00e32668bed1b1bfbf70b5a /modules
parent77e2e58aeff49477242f789b367def4b08836a47 (diff)
parent9d684b7b83f0aa026e9d6f06228294f179a3bcaa (diff)
Manually resolved conflict after recent pull.
Diffstat (limited to 'modules')
-rw-r--r--modules/g2_import/controllers/g2.php7
-rw-r--r--modules/gallery/css/gallery.css6
-rw-r--r--modules/gallery/helpers/gallery_installer.php10
-rw-r--r--modules/gallery/helpers/graphics.php54
-rw-r--r--modules/gallery/helpers/item_rest.php2
-rw-r--r--modules/gallery/helpers/movie.php34
-rw-r--r--modules/gallery/models/item.php69
-rw-r--r--modules/gallery/module.info2
-rw-r--r--modules/gallery/views/movieplayer.html.php61
-rw-r--r--modules/tag/controllers/tag_name.php33
-rw-r--r--modules/tag/models/tag.php16
-rw-r--r--modules/user/controllers/users.php2
12 files changed, 228 insertions, 68 deletions
diff --git a/modules/g2_import/controllers/g2.php b/modules/g2_import/controllers/g2.php
index 6c960893..98eb57f1 100644
--- a/modules/g2_import/controllers/g2.php
+++ b/modules/g2_import/controllers/g2.php
@@ -34,6 +34,11 @@ class G2_Controller extends Controller {
$path = $input->get("path");
$id = $input->get("g2_itemId");
+ /* Tags are handled specially, since there's no mapping for them */
+ if (($path && 0 === strpos($path, "tag/"))) {
+ url::redirect("tag_name/" . substr($path, 4));
+ }
+
if (($path && $path != 'index.php' && $path != 'main.php') || $id) {
if ($id) {
// Requests by id are either core.DownloadItem or core.ShowItem requests. Later versions of
@@ -94,4 +99,4 @@ class G2_Controller extends Controller {
throw new Kohana_404_Exception();
}
}
-} \ No newline at end of file
+}
diff --git a/modules/gallery/css/gallery.css b/modules/gallery/css/gallery.css
index 9d773699..7e711156 100644
--- a/modules/gallery/css/gallery.css
+++ b/modules/gallery/css/gallery.css
@@ -143,6 +143,12 @@
width: 1%;
}
+/* Unsupported movie download link ~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+.g-movie-download-link {
+ text-align: center;
+}
+
/** *******************************************************************
* 2) Admin
**********************************************************************/
diff --git a/modules/gallery/helpers/gallery_installer.php b/modules/gallery/helpers/gallery_installer.php
index 1f190800..597771f3 100644
--- a/modules/gallery/helpers/gallery_installer.php
+++ b/modules/gallery/helpers/gallery_installer.php
@@ -313,8 +313,9 @@ class gallery_installer {
module::set_var("gallery", "extra_binary_paths", "/usr/local/bin:/opt/local/bin:/opt/bin");
module::set_var("gallery", "timezone", null);
module::set_var("gallery", "lock_timeout", 1);
+ module::set_var("gallery", "movie_extract_frame_time", 3);
- module::set_version("gallery", 52);
+ module::set_version("gallery", 53);
}
static function upgrade($version) {
@@ -735,6 +736,13 @@ class gallery_installer {
->execute();
module::set_version("gallery", $version = 52);
}
+
+ if ($version == 52) {
+ // In v53, we added the ability to change the default time used when extracting frames from
+ // movies. Previously we hard-coded this at 3 seconds, so we use that as the default.
+ module::set_var("gallery", "movie_extract_frame_time", 3);
+ module::set_version("gallery", $version = 53);
+ }
}
static function uninstall() {
diff --git a/modules/gallery/helpers/graphics.php b/modules/gallery/helpers/graphics.php
index c19fbe6d..e7c5da68 100644
--- a/modules/gallery/helpers/graphics.php
+++ b/modules/gallery/helpers/graphics.php
@@ -155,13 +155,27 @@ class graphics_Core {
try {
foreach ($ops as $target => $output_file) {
if ($input_item->is_movie()) {
- // Convert the movie to a JPG first
+ // Convert the movie filename to a JPG first, delete anything that might already be there
$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);
+ 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 {
@@ -201,7 +215,7 @@ class graphics_Core {
// 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());
+ $e->getMessage() . "\n" . $e->getTraceAsString());
throw $e;
}
}
@@ -260,13 +274,13 @@ class graphics_Core {
$count = graphics::find_dirty_images_query()->count_records();
if ($count) {
site_status::warning(
- t2("One of your photos is out of date. <a %attrs>Click here to fix it</a>",
- "%count of your photos are out of date. <a %attrs>Click here to fix them</a>",
- $count,
- array("attrs" => html::mark_clean(sprintf(
- 'href="%s" class="g-dialog-link"',
- url::site("admin/maintenance/start/gallery_task::rebuild_dirty_images?csrf=__CSRF__"))))),
- "graphics_dirty");
+ t2("One of your photos is out of date. <a %attrs>Click here to fix it</a>",
+ "%count of your photos are out of date. <a %attrs>Click here to fix them</a>",
+ $count,
+ array("attrs" => html::mark_clean(sprintf(
+ 'href="%s" class="g-dialog-link"',
+ url::site("admin/maintenance/start/gallery_task::rebuild_dirty_images?csrf=__CSRF__"))))),
+ "graphics_dirty");
}
}
@@ -320,12 +334,12 @@ class graphics_Core {
} else {
// ImageMagick & GraphicsMagick
$magick_kits = array(
- "imagemagick" => array(
- "name" => "ImageMagick", "binary" => "convert", "version_arg" => "-v",
- "version_regex" => "/Version: \S+ (\S+)/"),
- "graphicsmagick" => array(
- "name" => "GraphicsMagick", "binary" => "gm", "version_arg" => "version",
- "version_regex" => "/\S+ (\S+)/"));
+ "imagemagick" => array(
+ "name" => "ImageMagick", "binary" => "convert", "version_arg" => "-version",
+ "version_regex" => "/Version: \S+ (\S+)/"),
+ "graphicsmagick" => array(
+ "name" => "GraphicsMagick", "binary" => "gm", "version_arg" => "version",
+ "version_regex" => "/\S+ (\S+)/"));
// Loop through the kits
foreach ($magick_kits as $index => $settings) {
$path = system::find_binary(
diff --git a/modules/gallery/helpers/item_rest.php b/modules/gallery/helpers/item_rest.php
index 14580cd9..43fec3ab 100644
--- a/modules/gallery/helpers/item_rest.php
+++ b/modules/gallery/helpers/item_rest.php
@@ -150,7 +150,7 @@ class item_rest_Core {
static function post($request) {
$parent = rest::resolve($request->url);
- access::required("edit", $parent);
+ access::required("add", $parent);
$entity = $request->params->entity;
$item = ORM::factory("item");
diff --git a/modules/gallery/helpers/movie.php b/modules/gallery/helpers/movie.php
index ddc513ea..6d70ab2d 100644
--- a/modules/gallery/helpers/movie.php
+++ b/modules/gallery/helpers/movie.php
@@ -57,7 +57,16 @@ class movie_Core {
return $form;
}
- static function extract_frame($input_file, $output_file) {
+ /**
+ * Extract a frame from a movie file. Valid movie_options are start_time (in seconds),
+ * input_args (extra ffmpeg input args) and output_args (extra ffmpeg output args). Extra args
+ * are added at the end of the list, so they can override any prior args.
+ *
+ * @param string $input_file
+ * @param string $output_file
+ * @param array $movie_options (optional)
+ */
+ static function extract_frame($input_file, $output_file, $movie_options=NULL) {
$ffmpeg = movie::find_ffmpeg();
if (empty($ffmpeg)) {
throw new Exception("@todo MISSING_FFMPEG");
@@ -65,23 +74,32 @@ class movie_Core {
list($width, $height, $mime_type, $extension, $duration) = movie::get_file_metadata($input_file);
- // extract frame at 0:03, unless movie is shorter than 4 sec.
- $start_time_arg = ($duration > 4) ? " -ss 00:00:03" : "";
-
- $cmd = escapeshellcmd($ffmpeg) . " -i " . escapeshellarg($input_file) .
+ if (is_numeric($movie_options["start_time"])) {
+ $start_time = max(0, $movie_options["start_time"]); // ensure it's non-negative
+ } else {
+ $start_time = module::get_var("gallery", "movie_extract_frame_time", 3); // use default
+ }
+ // extract frame at start_time, unless movie is too short
+ $start_time_arg = ($duration >= $start_time + 0.1) ?
+ "-ss " . date("H:i:s", mktime(0,0,$start_time,0,0,0,0)) : "";
+
+ $input_args = $movie_options["input_args"] ? $movie_options["input_args"] : "";
+ $output_args = $movie_options["output_args"] ? $movie_options["output_args"] : "";
+
+ $cmd = escapeshellcmd($ffmpeg) . " $input_args -i " . escapeshellarg($input_file) .
" -an $start_time_arg -an -r 1 -vframes 1" .
" -s {$width}x{$height}" .
- " -y -f mjpeg " . escapeshellarg($output_file) . " 2>&1";
+ " -y -f mjpeg $output_args " . escapeshellarg($output_file) . " 2>&1";
exec($cmd, $exec_output, $exec_return);
clearstatcache(); // use $filename parameter when PHP_version is 5.3+
if (filesize($output_file) == 0 || $exec_return) {
// Maybe the movie needs the "-threads 1" argument added
// (see http://sourceforge.net/apps/trac/gallery/ticket/1924)
- $cmd = escapeshellcmd($ffmpeg) . " -threads 1 -i " . escapeshellarg($input_file) .
+ $cmd = escapeshellcmd($ffmpeg) . " -threads 1 $input_args -i " . escapeshellarg($input_file) .
" -an $start_time_arg -an -r 1 -vframes 1" .
" -s {$width}x{$height}" .
- " -y -f mjpeg " . escapeshellarg($output_file) . " 2>&1";
+ " -y -f mjpeg $output_args " . escapeshellarg($output_file) . " 2>&1";
exec($cmd, $exec_output, $exec_return);
clearstatcache();
diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php
index 931da382..8f127532 100644
--- a/modules/gallery/models/item.php
+++ b/modules/gallery/models/item.php
@@ -663,31 +663,70 @@ class Item_Model_Core extends ORM_MPTT {
}
/**
- * Return a flowplayer <script> tag for movies
+ * Return a view for movies. By default this is a Flowplayer v3 <script> tag, but
+ * movie_img events can override this and provide their own player/view. If no player/view
+ * is found and the movie is unsupported by Flowplayer v3, this returns a simple download link.
* @param array $extra_attrs
* @return string
*/
public function movie_img($extra_attrs) {
- $v = new View("movieplayer.html");
$max_size = module::get_var("gallery", "resize_size", 640);
$width = $this->width;
$height = $this->height;
- if ($width > $max_size || $height > $max_size) {
- if ($width > $height) {
- $height = (int)($height * $max_size / $width);
- $width = $max_size;
+ if ($width == 0 || $height == 0) {
+ // Not set correctly, likely because ffmpeg isn't available. Making the window 0x0 causes the
+ // video to be effectively unviewable. So, let's guess: set width to max_size and guess a
+ // height (using 4:3 aspect ratio). Once the video metadata is loaded, js in
+ // movieplayer.html.php will correct these values.
+ $width = $max_size;
+ $height = ceil($width * 3/4);
+ }
+ $attrs = array_merge(array("id" => "g-item-id-{$this->id}"), $extra_attrs,
+ array("class" => "g-movie"));
+
+ // Run movie_img events, which can either:
+ // - generate a view, which is used in place of the standard Flowplayer v3 player
+ // (use view variable)
+ // - alter the arguments sent to the standard player
+ // (use fp_params and fp_config variables)
+ $movie_img = new stdClass();
+ $movie_img->max_size = $max_size;
+ $movie_img->width = $width;
+ $movie_img->height = $height;
+ $movie_img->attrs = $attrs;
+ $movie_img->url = $this->file_url(true);
+ $movie_img->fp_params = array(); // additional Flowplayer params values (will be json encoded)
+ $movie_img->fp_config = array(); // additional Flowplayer config values (will be json encoded)
+ $movie_img->view = array();
+ module::event("movie_img", $movie_img, $this);
+
+ if (count($movie_img->view) > 0) {
+ // View generated - use it
+ $view = implode("\n", $movie_img->view);
+ } else {
+ // View NOT generated - see if filetype supported by Flowplayer v3
+ // Note that the extension list below is hard-coded and doesn't use the legal_file helper
+ // since anything else will not work in Flowplayer v3.
+ if (in_array(strtolower(pathinfo($this->name, PATHINFO_EXTENSION)),
+ array("flv", "mp4", "m4v", "mov", "f4v"))) {
+ // Filetype supported by Flowplayer v3 - use it (default)
+ $view = new View("movieplayer.html");
+ $view->max_size = $movie_img->max_size;
+ $view->width = $movie_img->width;
+ $view->height = $movie_img->height;
+ $view->attrs = $movie_img->attrs;
+ $view->url = $movie_img->url;
+ $view->fp_params = $movie_img->fp_params;
+ $view->fp_config = $movie_img->fp_config;
} else {
- $width = (int)($width * $max_size / $height);
- $height = $max_size;
+ // Filetype NOT supported by Flowplayer v3 - display download link
+ $attrs = array_merge($attrs, array("style" => "width: {$max_size}px;",
+ "download" => $this->name, // forces download (HTML5 only)
+ "class" => "g-movie g-movie-download-link"));
+ $view = html::anchor($this->file_url(true), t("Click here to download item."), $attrs);
}
}
-
- $v->attrs = array_merge($extra_attrs, array("style" => "width:{$width}px;height:{$height}px",
- "class" => "g-movie"));
- if (empty($v->attrs["id"])) {
- $v->attrs["id"] = "g-item-id-{$this->id}";
- }
- return $v;
+ return $view;
}
/**
diff --git a/modules/gallery/module.info b/modules/gallery/module.info
index faefd663..64cad0a7 100644
--- a/modules/gallery/module.info
+++ b/modules/gallery/module.info
@@ -1,6 +1,6 @@
name = "Gallery 3"
description = "Gallery core application"
-version = 52
+version = 53
author_name = "Gallery Team"
author_url = "http://codex.gallery2.org/Gallery:Team"
info_url = "http://codex.gallery2.org/Gallery3:Modules:gallery"
diff --git a/modules/gallery/views/movieplayer.html.php b/modules/gallery/views/movieplayer.html.php
index 343eafe8..25cb9f58 100644
--- a/modules/gallery/views/movieplayer.html.php
+++ b/modules/gallery/views/movieplayer.html.php
@@ -1,26 +1,49 @@
<?php defined("SYSPATH") or die("No direct script access.") ?>
-<?= html::anchor($item->file_url(true), "", $attrs) ?>
+<?= html::anchor($url, "", $attrs) ?>
<script type="text/javascript">
- flowplayer(
- "<?= $attrs["id"] ?>",
- {
- src: "<?= url::abs_file("lib/flowplayer.swf") ?>",
- wmode: "transparent",
- provider: "pseudostreaming"
- },
- {
- clip: {
- scaling: 'fit'
- },
- plugins: {
- pseudostreaming: {
- url: "<?= url::abs_file("lib/flowplayer.pseudostreaming-byterange.swf") ?>"
+ var id = "<?= $attrs["id"] ?>";
+ var max_size = <?= $max_size ?>;
+ // set the size of the movie html anchor, taking into account max_size and height of control bar
+ function set_movie_size(width, height) {
+ if((width > max_size) || (height > max_size)) {
+ if (width > height) {
+ height = Math.ceil(height * max_size / width);
+ width = max_size;
+ } else {
+ width = Math.ceil(width * max_size / height);
+ height = max_size;
+ }
+ }
+ height += flowplayer(id).getConfig().plugins.controls.height;
+ $("#" + id).css({width: width, height: height});
+ };
+ // setup flowplayer
+ flowplayer(id,
+ $.extend(true, {
+ "src": "<?= url::abs_file("lib/flowplayer.swf") ?>",
+ "wmode": "transparent",
+ "provider": "pseudostreaming"
+ }, <?= json_encode($fp_params) ?>),
+ $.extend(true, {
+ "plugins": {
+ "pseudostreaming": {
+ "url": "<?= url::abs_file("lib/flowplayer.pseudostreaming-byterange.swf") ?>"
},
- controls: {
- autoHide: 'always',
- hideDelay: 2000
+ "controls": {
+ "autoHide": "always",
+ "hideDelay": 2000,
+ "height": 24
+ }
+ },
+ "clip": {
+ "scaling": "fit",
+ "onMetaData": function(clip) {
+ // set movie size a second time using actual size from metadata
+ set_movie_size(parseInt(clip.metaData.width), parseInt(clip.metaData.height));
}
}
- }
+ }, <?= json_encode($fp_config) ?>)
).ipad();
+ // set movie size using width and height passed from movie_img function
+ $("document").ready(set_movie_size(<?= $width ?>, <?= $height ?>));
</script>
diff --git a/modules/tag/controllers/tag_name.php b/modules/tag/controllers/tag_name.php
new file mode 100644
index 00000000..1a1179fe
--- /dev/null
+++ b/modules/tag/controllers/tag_name.php
@@ -0,0 +1,33 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2012 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+class Tag_Name_Controller extends Controller {
+ public function __call($function, $args) {
+ $tag_name = $function;
+ $tag = ORM::factory("tag")->where("name", "=", $tag_name)->find();
+ if (!$tag->loaded()) {
+ // No matching tag was found. If this was an imported tag, this is probably a bug.
+ // If the user typed the URL manually, it might just be wrong
+ throw new Kohana_404_Exception();
+ }
+
+ url::redirect($tag->abs_url());
+ }
+
+}
diff --git a/modules/tag/models/tag.php b/modules/tag/models/tag.php
index 37d1aa68..213ea0df 100644
--- a/modules/tag/models/tag.php
+++ b/modules/tag/models/tag.php
@@ -141,7 +141,7 @@ class Tag_Model_Core extends ORM {
/**
* Return the server-relative url to this item, eg:
- * /gallery3/index.php/tags/35
+ * /gallery3/index.php/tags/35/Bob
*
* @param string $query the query string (eg "page=3")
*/
@@ -152,4 +152,18 @@ class Tag_Model_Core extends ORM {
}
return $url;
}
+
+ /**
+ * Return the full url to this item, eg:
+ * http://example.com/gallery3/index.php/tags/35/Bob
+ *
+ * @param string $query the query string (eg "page=3")
+ */
+ public function abs_url($query=null) {
+ $url = url::abs_site("tag/{$this->id}/" . urlencode($this->name));
+ if ($query) {
+ $url .= "?$query";
+ }
+ return $url;
+ }
}
diff --git a/modules/user/controllers/users.php b/modules/user/controllers/users.php
index 0f880fa9..bfa9d720 100644
--- a/modules/user/controllers/users.php
+++ b/modules/user/controllers/users.php
@@ -198,7 +198,7 @@ class Users_Controller extends Controller {
->error_messages("length", t("Your email address is too long"))
->error_messages("required", t("You must enter a valid email address"));
- module::event("user_change_password_form", $user, $form);
+ module::event("user_change_email_form", $user, $form);
$group->submit("")->value(t("Save"));
return $form;
}