PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/3.1/modules/videos/controllers/videos.php

https://github.com/jersub/gallery3-contrib
PHP | 302 lines | 83 code | 16 blank | 203 comment | 11 complexity | b1c6abb61b7786e3ec665c18287efff0 MD5 | raw file
  1. <?php defined("SYSPATH") or die("No direct script access.");
  2. /**
  3. * Gallery - a web based photo album viewer and editor
  4. * Copyright (C) 2000-2010 Bharat Mediratta
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or (at
  9. * your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. class Videos_Controller extends Admin_Controller {
  21. public function browse($id) {
  22. $paths = unserialize(module::get_var("videos", "authorized_paths"));
  23. foreach (array_keys($paths) as $path) {
  24. $files[] = $path;
  25. }
  26. $item = ORM::factory("item", $id);
  27. $view = new View("videos_tree_dialog.html");
  28. $view->item = $item;
  29. $view->tree = new View("videos_tree.html");
  30. $view->tree->files = $files;
  31. $view->tree->parents = array();
  32. print $view;
  33. }
  34. public function children() {
  35. $path = Input::instance()->get("path");
  36. $tree = new View("videos_tree.html");
  37. $tree->files = array();
  38. $tree->parents = array();
  39. // Make a tree with the parents back up to the authorized path, and all the children under the
  40. // current path.
  41. if (videos::is_valid_path($path)) {
  42. $tree->parents[] = $path;
  43. while (videos::is_valid_path(dirname($tree->parents[0]))) {
  44. array_unshift($tree->parents, dirname($tree->parents[0]));
  45. }
  46. $glob_path = str_replace(array("{", "}", "[", "]"), array("\{", "\}", "\[", "\]"), $path);
  47. foreach (glob("$glob_path/*") as $file) {
  48. if (!is_readable($file)) {
  49. continue;
  50. }
  51. if (!is_dir($file)) {
  52. $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
  53. //if (!in_array($ext, array("gif", "jpeg", "jpg", "png", "flv", "mp4", "m4v"))) {
  54. if (!in_array($ext, unserialize(module::get_var("videos", "allowed_extensions")))) {
  55. continue;
  56. }
  57. }
  58. $tree->files[] = $file;
  59. }
  60. } else {
  61. // Missing or invalid path; print out the list of authorized path
  62. $paths = unserialize(module::get_var("videos", "authorized_paths"));
  63. foreach (array_keys($paths) as $path) {
  64. $tree->files[] = $path;
  65. }
  66. }
  67. print $tree;
  68. }
  69. /**
  70. * Begin the task of adding files.
  71. */
  72. public function start() {
  73. access::verify_csrf();
  74. $item = ORM::factory("item", Input::instance()->get("item_id"));
  75. foreach (Input::instance()->post("paths") as $path) {
  76. if (videos::is_valid_path($path)) {
  77. $paths[] = array($path, null);
  78. }
  79. }
  80. $task_def = Task_Definition::factory()
  81. ->callback("Videos_Controller::add")
  82. ->description(t("Add videos from the local server"))
  83. ->name(t("Add from server"));
  84. $task = task::create($task_def, array("item_id" => $item->id, "queue" => $paths));
  85. json::reply(
  86. array("result" => "started",
  87. "status" => (string)$task->status,
  88. "url" => url::site("videos/run/$task->id?csrf=" . access::csrf_token())));
  89. }
  90. /**
  91. * Run the task of adding files
  92. */
  93. function run($task_id) {
  94. access::verify_csrf();
  95. $task = ORM::factory("task", $task_id);
  96. if (!$task->loaded() || $task->owner_id != identity::active_user()->id) {
  97. access::forbidden();
  98. }
  99. $task = task::run($task_id);
  100. // Prevent the JavaScript code from breaking by forcing a period as
  101. // decimal separator for all locales with sprintf("%F", $value).
  102. json::reply(array("done" => (bool)$task->done,
  103. "status" => (string)$task->status,
  104. "percent_complete" => sprintf("%F", $task->percent_complete)));
  105. }
  106. /**
  107. * This is the task code that adds photos and albums. It first examines all the target files
  108. * and creates a set of Server_Add_File_Models, then runs through the list of models and adds
  109. * them one at a time.
  110. */
  111. static function add($task) {
  112. $mode = $task->get("mode", "init");
  113. $start = microtime(true);
  114. switch ($mode) {
  115. case "init":
  116. $task->set("mode", "build-file-list");
  117. $task->percent_complete = 0;
  118. $task->status = t("Starting up");
  119. batch::start();
  120. break;
  121. case "build-file-list": // 0% to 10%
  122. // We can't fit an arbitrary number of paths in a task, so store them in a separate table.
  123. // Don't use an iterator here because we can't get enough control over it when we're dealing
  124. // with a deep hierarchy and we don't want to go over our time quota. The queue is in the
  125. // form [path, parent_id] where the parent_id refers to another Server_Add_File_Model. We
  126. // have this extra level of abstraction because we don't know its Item_Model id yet.
  127. $queue = $task->get("queue");
  128. $paths = unserialize(module::get_var("videos", "authorized_paths"));
  129. while ($queue && microtime(true) - $start < 0.5) {
  130. list($file, $parent_entry_id) = array_shift($queue);
  131. // Ignore the staging directories as directories to be imported.
  132. if (empty($paths[$file])) {
  133. $entry = ORM::factory("videos_file");
  134. $entry->task_id = $task->id;
  135. $entry->file = $file;
  136. $entry->parent_id = $parent_entry_id;
  137. $entry->save();
  138. $entry_id = $entry->id;
  139. } else {
  140. $entry_id = null;
  141. }
  142. $file = preg_quote($file);
  143. foreach (glob("$file/*") as $child) {
  144. if (is_dir($child)) {
  145. $queue[] = array($child, $entry_id);
  146. } else {
  147. $ext = strtolower(pathinfo($child, PATHINFO_EXTENSION));
  148. //if (in_array($ext, array("gif", "jpeg", "jpg", "png", "flv", "mp4", "m4v")) &&
  149. if (in_array($ext, unserialize(module::get_var("videos", "allowed_extensions"))) &&
  150. filesize($child) > 0) {
  151. $child_entry = ORM::factory("videos_file");
  152. $child_entry->task_id = $task->id;
  153. $child_entry->file = $child;
  154. $child_entry->parent_id = $entry_id;
  155. $child_entry->save();
  156. }
  157. }
  158. }
  159. }
  160. // We have no idea how long this can take because we have no idea how deep the tree
  161. // hierarchy rabbit hole goes. Leave ourselves room here for 100 iterations and don't go
  162. // over 10% in percent_complete.
  163. $task->set("queue", $queue);
  164. $task->percent_complete = min($task->percent_complete + 0.1, 10);
  165. $task->status = t2(
  166. "Found one file", "Found %count files",
  167. ORM::factory("videos_file")->where("task_id", "=", $task->id)->count_all());
  168. if (!$queue) {
  169. $task->set("mode", "add-files");
  170. $task->set(
  171. "total_files",
  172. ORM::factory("videos_file")->where("task_id", "=", $task->id)->count_all());
  173. $task->percent_complete = 10;
  174. }
  175. break;
  176. case "add-files": // 10% to 100%
  177. $completed_files = $task->get("completed_files", 0);
  178. $total_files = $task->get("total_files");
  179. // Ordering by id ensures that we add them in the order that we created the entries, which
  180. // will create albums first. Ignore entries which already have an Item_Model attached,
  181. // they're done.
  182. $entries = ORM::factory("videos_file")
  183. ->where("task_id", "=", $task->id)
  184. ->where("item_id", "IS", null)
  185. ->order_by("id", "ASC")
  186. ->limit(10)
  187. ->find_all();
  188. if ($entries->count() == 0) {
  189. // Out of entries, we're done.
  190. $task->set("mode", "done");
  191. }
  192. $owner_id = identity::active_user()->id;
  193. foreach ($entries as $entry) {
  194. if (microtime(true) - $start > 0.5) {
  195. break;
  196. }
  197. // Look up the parent item for this entry. By now it should exist, but if none was
  198. // specified, then this belongs as a child of the current item.
  199. $parent_entry = ORM::factory("videos_file", $entry->parent_id);
  200. if (!$parent_entry->loaded()) {
  201. $parent = ORM::factory("item", $task->get("item_id"));
  202. } else {
  203. $parent = ORM::factory("item", $parent_entry->item_id);
  204. }
  205. $name = basename($entry->file);
  206. $title = item::convert_filename_to_title($name);
  207. if (is_dir($entry->file)) {
  208. $album = ORM::factory("item");
  209. $album->type = "album";
  210. $album->parent_id = $parent->id;
  211. $album->name = $name;
  212. $album->title = $title;
  213. $album->owner_id = $owner_id;
  214. $album->save();
  215. $entry->item_id = $album->id;
  216. } else {
  217. try {
  218. $extension = strtolower(pathinfo($name, PATHINFO_EXTENSION));
  219. if (in_array($extension, unserialize(module::get_var("videos", "allowed_extensions")))) {
  220. $movie = ORM::factory("item");
  221. $movie->type = "movie";
  222. $movie->parent_id = $parent->id;
  223. $movie->set_data_file($entry->file);
  224. $movie->name = $name;
  225. $movie->title = $title;
  226. $movie->owner_id = $owner_id;
  227. $movie->save();
  228. $entry->item_id = $movie->id;
  229. $items_video = ORM::factory("items_video");
  230. $items_video->item_id = $movie->id;
  231. $items_video->save();
  232. if (file_exists($entry->file . ".flv")) {
  233. copy($entry->file . ".flv", $movie->resize_path() . ".flv");
  234. list ($vid_width, $vid_height, $mime_type) = movie::get_file_metadata($entry->file . ".flv");
  235. $movie->height = $vid_height;
  236. $movie->width = $vid_width;
  237. $movie->save();
  238. }
  239. } else {
  240. // This should never happen, because we don't add stuff to the list that we can't
  241. // process. But just in, case.. set this to a non-null value so that we skip this
  242. // entry.
  243. $entry->item_id = 0;
  244. $task->log("Skipping unknown file type: $entry->file");
  245. }
  246. } catch (Exception $e) {
  247. // This can happen if a photo file is invalid, like a BMP masquerading as a .jpg
  248. $entry->item_id = 0;
  249. $task->log("Skipping invalid file: $entry->file");
  250. }
  251. }
  252. $completed_files++;
  253. $entry->save();
  254. }
  255. $task->set("completed_files", $completed_files);
  256. $task->status = t("Adding photos / albums (%completed of %total)",
  257. array("completed" => $completed_files,
  258. "total" => $total_files));
  259. $task->percent_complete = $total_files ? 10 + 100 * ($completed_files / $total_files) : 100;
  260. break;
  261. case "done":
  262. batch::stop();
  263. $task->done = true;
  264. $task->state = "success";
  265. $task->percent_complete = 100;
  266. db::build()
  267. ->delete("videos_files")
  268. ->where("task_id", "=", $task->id)
  269. ->execute();
  270. message::info(t2("Successfully added one file",
  271. "Successfully added %count files",
  272. $task->get("completed_files")));
  273. }
  274. }
  275. }