/[drupal]/contributions/modules/movino/movino_videos.inc
ViewVC logotype

Contents of /contributions/modules/movino/movino_videos.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.15 - (show annotations) (download) (as text)
Sun May 4 15:58:36 2008 UTC (18 months, 3 weeks ago) by tomsun
Branch: MAIN
CVS Tags: DRUPAL-5--1-1, HEAD
Changes since 1.14: +52 -7 lines
File MIME type: text/x-php
Video select handlers now respect published and removed states.
1 <?php // $Id: movino_videos.inc,v 1.14 2008/05/04 15:52:40 tomsun Exp $
2 /*
3 Movino Web Frontend - Server handling, feed parsing and feed caching
4 Copyright 2006, 2007 Tom Sundström
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 version 2 as
8 published by the Free Software Foundation.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public
16 License along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20
21 /**
22 * Parses all feeds from all servers.
23 * Ignores recently updated feeds.
24 */
25 function movino_update_video_cache($type = NULL) {
26
27 // If the feed is updated after this point in time, skip it.
28 $feed_live_expires = time() - variable_get('movino_feed_age_live', 10);
29 $feed_archive_expires = time() - variable_get('movino_feed_age_archive', 300);
30
31 $servers = movino_get_servers();
32
33 if (empty($servers)) {
34 return;
35 }
36
37 foreach ($servers as $server) {
38 $processed = array();
39 $skipped = array();
40 if (empty($server['feed_live'])) {
41 $skipped[] = 'live';
42 } else {
43 if ($server['feed_live_updated'] > $feed_live_expires || $type == 'archived') {
44 $skipped[] = 'live';
45 } else {
46 movino_server_update_feed_age($server['id'], 'live');
47 $feed = _movino_feed_parse(movino_feed_url($server, 'live'));
48 if (empty($feed)) {
49 // $skipped[] = 'live';
50 } else {
51 foreach ($feed as $video) {
52 $video['type'] = 'live';
53 $video['server'] = $server['id'];
54 if ($cached_video = movino_get_video($video['server'], $video['id'], FALSE, TRUE, $video['username'], $video['created'])) {
55 // Update if necessary.
56 $processed[] = $cached_video['vid'];
57 if ($cached_video['available'] == 0 || $cached_video['type'] != $video['type'] || $cached_video['position'] != $video['position'] || $cached_video['trail'] != $video['trail'] || $cached_video['title'] != $video['title'] || $cached_video['author'] != $video['author'] || (empty($cached_video['preview']) && !empty($video['preview']))) {
58 movino_update_video($video);
59 }
60 } else {
61 $processed[] = movino_insert_video($video);
62 }
63 }
64 }
65 }
66 }
67 if (empty($server['feed_archive'])) {
68 $skipped[] = 'archived';
69 } else {
70 if ($server['feed_archive_updated'] > $feed_archive_expires || $type == 'live') {
71 $skipped[] = 'archived';
72 } else {
73 movino_server_update_feed_age($server['id'], 'archive');
74 $feed = _movino_feed_parse(movino_feed_url($server, 'archive'));
75 if (empty($feed)) {
76 $skipped[] = 'archived';
77 } else {
78 foreach ($feed as $video) {
79 $video['type'] = 'archived';
80 $video['server'] = $server['id'];
81 if ($cached_video = movino_get_video($video['server'], $video['id'], FALSE, TRUE, $video['username'], $video['created'])) {
82 $processed[] = $cached_video['vid'];
83 if ($cached_video['available'] == 0 || $cached_video['type'] != $video['type'] || $cached_video['position'] != $video['position'] || $cached_video['trail'] != $video['trail'] || $cached_video['title'] != $video['title'] || $cached_video['author'] != $video['author']) {
84 movino_update_video($video);
85 }
86 } else {
87 $processed[] = movino_insert_video($video);
88 }
89 }
90 }
91 }
92 }
93 /*
94 global $user;
95 if ($user->uid == 1) {
96 drupal_set_message('test ' . $server['id']);
97 }
98 */
99
100 if ((empty($skipped) || !in_array('live', $skipped)) && (variable_get('movino_unpublish', 1) != 0)) {
101 /*
102 if ($user->uid == 1) {
103 drupal_set_message('unpublish ' . $server['id']);
104 }
105 */
106 // Unpublish all live streams no longer available.
107 $sql = "SELECT vid, id, server FROM {movino_videos} WHERE available = 1 AND server = '%s' AND type = 'live' ";
108 $additional_conditions = '';
109 if (!empty($processed)) {
110 $additional_conditions .= 'AND vid != ' . implode(' AND vid != ', $processed) . ' ';
111 }
112 $results = db_query($sql . $additional_conditions, $server['id']);
113
114 while($video = db_fetch_array($results)) {
115 /*
116 if ($user->uid == 1) {
117 drupal_set_message('deactivate: ' . print_r($video, TRUE));
118 }
119 */
120 // Allow other modules to perform actions on inactive videos.
121 module_invoke_all('movino_video_deactivate', $video);
122 }
123
124 // Mark all inactive videos.
125 $sql = "UPDATE {movino_videos} SET available = 0 WHERE type = 'live' AND available = 1 AND server = '%s' ";
126 db_query($sql . $additional_conditions, $server['id']);
127
128 }
129
130
131 /* No need to unpublish archived videos for now...
132 if ((empty($skipped) || count($skipped) == 1) && (variable_get('movino_unpublish', 1) != 0)) {
133 // Find all videos in cache originating from this server, which were
134 // no longer found in the server feeds.
135 $sql = "SELECT vid, id, server FROM {movino_videos} WHERE available = 1 AND server = '%s' ";
136 $additional_conditions = '';
137 if (!empty($processed)) {
138 $additional_conditions .= 'AND vid != ' . implode(' AND vid != ', $processed) . ' ';
139 }
140 if (!empty($skipped)) {
141 $additional_conditions .= "AND type != '" . implode("' AND type != '", $skipped) . "' ";
142 }
143 $results = db_query($sql . $additional_conditions, $server['id']);
144
145 while($video = db_fetch_array($results)) {
146 // Allow other modules to perform actions on inactive videos.
147 module_invoke_all('movino_video_deactivate', $video);
148 }
149
150 // Mark all inactive videos.
151 $sql = "UPDATE {movino_videos} SET available = 0 WHERE available = 1 AND server = '%s' ";
152 db_query($sql . $additional_conditions, $server['id']);
153
154 }
155 */
156 }
157 }
158
159
160 /**
161 * Inserts a new video into DB
162 */
163 function movino_insert_video($video) {
164 if (empty($video)) {
165 return FALSE;
166 }
167
168 $query = <<<END
169 INSERT INTO {movino_videos} SET
170 vid = %d,
171 id = '%s',
172 server = '%s',
173 type = '%s',
174 title = '%s',
175 author = '%s',
176 username = '%s',
177 url = '%s',
178 size = '%s',
179 created = %d,
180 length = %d,
181 encoding = '%s',
182 preview = '%s',
183 position = '%s',
184 trail = '%s',
185 available = 1,
186 published = 1,
187 removed = 0
188 END;
189
190 $video['vid'] = db_next_id('{movino_videos}_vid');
191 if ($result = db_query($query,
192 $video['vid'],
193 $video['id'],
194 $video['server'],
195 $video['type'],
196 $video['title'],
197 $video['author'],
198 empty($video['username']) ? '' : $video['username'],
199 $video['url'],
200 $video['size'],
201 $video['created'],
202 $video['length'],
203 $video['encoding'],
204 $video['preview'],
205 $video['position'],
206 $video['trail'])) {
207
208 // Allow modules to interact when a video has been inserted.
209 movino_invoke_all('movino_video_insert', $video);
210
211 if (MOVINO_DEBUG) {
212 drupal_set_message('Movino video ' . $video['title'] . ' (' . $video['id'] . ') is added.');
213 }
214 return $video['vid'];
215 } else {
216 if (MOVINO_DEBUG) {
217 drupal_set_message('Unknown error - Movino video ' . $video['title'] . ' (' . $video['id'] . ') not added.', 'error');
218 }
219 return 0;
220 }
221 }
222
223
224 /**
225 * Updates a video in DB
226 */
227 function movino_update_video($video) {
228 if (empty($video)) {
229 return FALSE;
230 }
231
232 $query = <<<END
233 UPDATE {movino_videos} SET
234 type = '%s',
235 title = '%s',
236 author = '%s',
237 username = '%s',
238 url = '%s',
239 size = '%s',
240 created = %d,
241 length = %d,
242 encoding = '%s',
243 preview = '%s',
244 position = '%s',
245 trail = '%s',
246 available = 1,
247 published = 1,
248 removed = 0
249 WHERE id = '%s'
250 AND server = '%s'
251 END;
252
253 if ($result = db_query($query,
254 $video['type'],
255 $video['title'],
256 $video['author'],
257 empty($video['username']) ? '' : $video['username'],
258 $video['url'],
259 $video['size'],
260 $video['created'],
261 $video['length'],
262 $video['encoding'],
263 $video['preview'],
264 $video['position'],
265 $video['trail'],
266 $video['id'],
267 $video['server'])) {
268
269 // Allow modules to interact when a video has been updated.
270 $video = movino_get_video($video['server'], $video['id']);
271 module_invoke_all('movino_video_update', $video);
272
273 if (MOVINO_DEBUG) {
274 drupal_set_message('Movino video ' . $video['title'] . ' (' . $video['id'] . ') is updated.');
275 }
276 return 1;
277 } else {
278 if (MOVINO_DEBUG) {
279 drupal_set_message('Unknown error - Movino video ' . $video['title'] . ' (' . $video['id'] . ') not updated.', 'error');
280 }
281 return 0;
282 }
283 }
284
285
286 /**
287 * Marks video as unpublished (compare to node status = 0).
288 */
289 function movino_unpublish_video($vid) {
290 db_query('UPDATE {movino_videos} SET published = 0 WHERE vid = %d', $vid);
291 }
292
293
294 /**
295 * Marks video as published (compare to node status = 1).
296 */
297 function movino_republish_video($vid) {
298 db_query('UPDATE {movino_videos} SET published = 1 WHERE vid = %d', $vid);
299 }
300
301
302 /**
303 * Mark video as removed (i.e. not supposed to be returned in searches regardless of publishing status and server availability).
304 */
305 function movino_remove_video($vid) {
306 db_query('UPDATE {movino_videos} SET removed = 1 WHERE vid = %d', $vid);
307 }
308
309
310 /**
311 * Returns a single video.
312 */
313 function movino_get_video_by_vid($vid, $prepare = TRUE, $include_deactivated = TRUE) {
314 $sql = 'SELECT * FROM {movino_videos} WHERE vid = %d ' . ($include_deactivated ? '' : 'AND available = 1 AND removed = 0 AND published = 1 ');
315 $result = db_query($sql, $vid);
316
317 if ($video = db_fetch_array($result)) {
318 if (MOVINO_DEBUG && $prepare) {
319 drupal_set_message('Loaded single video by vid: '. $video['title'] . ' (' . $video['id'] . ')');
320 }
321 $video = ($prepare ? _movino_videos_prepare(array($video)) : array($video));
322 return array_shift($video);
323 }
324 return FALSE;
325 }
326
327
328 /**
329 * Returns a single video.
330 */
331 function movino_get_video($server_id, $video_id, $prepare = TRUE, $deactivated = FALSE, $username = NULL, $created = NULL) {
332 return movino_get_videos('single', $server_id, $video_id, 0, 0, $prepare, $deactivated, $username, $created);
333 }
334
335
336 /**
337 * Returns a list of videos. Uses cached values when possible.
338
339 * @param string $op
340 * 'archived' - return only archived videos
341 * 'live' - return only live videos
342 * 'single' - return a single video
343 * 'all' - return all videos
344 *
345 * @param mixed $servers
346 * Restrict search to a single server (string) or multiple servers (array).
347 *
348 * @param string $vid
349 * When returning a single video, the video id is required (as well as the server id).
350 *
351 * @param integer $limit
352 * Maximum number of videos to return (newest first).
353 *
354 * @param integer $offset
355 * Number of newest videos to skip (useful for pagination).
356 *
357 * @param integer $prepare
358 * Whether or not to execute video preparation hooks.
359 */
360 function movino_get_videos($op = 'all', $servers = NULL, $video_id = NULL, $limit = 0, $offset = 0, $prepare = TRUE, $deactivated = FALSE, $username = NULL, $created = NULL, $max_age = 0) {
361
362 if (defined('MOVINO_STANDALONE')) {
363 // No DB - no caching - reload feeds once per page load and keep feed contents in memory.
364 return movino_get_videos_direct($op, $servers, $video_id, $limit, $offset, $prepare);
365 }
366
367 if ($op == 'single') {
368 $sql = "SELECT * FROM {movino_videos} WHERE server = '%s' AND id = '%s' " . ($deactivated ? '' : 'AND available = 1 AND published = 1 AND removed = 0 ');
369 $params = array($servers, $video_id);
370
371 if ($username != NULL) {
372 if (!is_array($username)) {
373 $username = array($username);
374 }
375 $sql .= "AND ( ";
376 $first = TRUE;
377 foreach($username as $name) {
378 if (!$first) {
379 $sql .= "OR ";
380 }
381 $first = FALSE;
382 $sql .= "username = '%s' ";
383 $params[] = $name;
384 }
385 $sql .= " ) ";
386 }
387
388 if ($created != NULL) {
389 $sql .= "AND created = %d ";
390 $params[] = $created;
391 }
392
393 if ($max_age > 0) {
394 $sql .= "AND created >= %d ";
395 $params[] = $max_age;
396 }
397
398 $result = db_query($sql ,$params);
399 if ($video = db_fetch_array($result)) {
400 if (MOVINO_DEBUG && $prepare) {
401 drupal_set_message('Loaded single video: '. $video['title'] . ' (' . $video['id'] . ')');
402 }
403 $video = ($prepare ? _movino_videos_prepare(array($video)) : array($video));
404 return array_shift($video);
405 }
406 return FALSE;
407 }
408
409 $sql = 'SELECT * FROM {movino_videos} ' . ($deactivated ? '' : ' WHERE available = 1 AND published = 1 AND removed = 0 ');
410 $params = array();
411
412 if ($op == 'live' || $op == 'archived') {
413 $sql .= "AND type = '%s' ";
414 $params[] = $op;
415 }
416 /*
417 if ($username != NULL) {
418 $sql .= "AND username = '%s' ";
419 $params[] = $username;
420 }
421 */
422 if ($username != NULL) {
423 if (!is_array($username)) {
424 $username = array($username);
425 }
426 $sql .= "AND ( ";
427 $first = TRUE;
428 foreach($username as $name) {
429 if (!$first) {
430 $sql .= "OR ";
431 }
432 $first = FALSE;
433 $sql .= "username = '%s' ";
434 $params[] = $name;
435 }
436 $sql .= " ) ";
437 }
438
439 if ($created != NULL) {
440 $sql .= "AND created = %d ";
441 $params[] = $created;
442 }
443
444 if ($max_age > 0) {
445 $sql .= "AND created >= %d ";
446 $params[] = $max_age;
447 }
448
449 if ($servers != NULL && !is_array($servers)) {
450 $servers = array($servers);
451 }
452 if (!empty($servers)) {
453 $sql .= 'AND (';
454 $scnt = count($servers);
455 foreach($servers as $server) {
456 $sql .= "server = '%s' ";
457 $params[] = $server;
458 $scnt--;
459 if ($scnt > 0) {
460 $sql .= 'OR ';
461 }
462 }
463 $sql .= ') ';
464 }
465
466 $sql .= 'ORDER BY created DESC ';
467
468 if ($limit > 0) {
469 $sql .= 'LIMIT ' . $limit . ' ';
470 $params[] = $limit;
471 }
472 if ($offset > 0) {
473 $sql .= 'OFFSET ' . $offset . ' ';
474 $params[] = $offset;
475 }
476
477 $videos = array();
478 $results = db_query($sql, $params);
479 while($video = db_fetch_array($results)) {
480 $videos[] = $video;
481 }
482 if (MOVINO_DEBUG) {
483 drupal_set_message('Loaded multiple videos: '. count($videos) . ' - ' . $limit);
484 }
485 return $video = ($prepare ? _movino_videos_prepare($videos) : $videos);
486 }
487
488
489 /**
490 * Alternative way of reading video data.
491 * Loads all feeds into memory once per page load.
492 * For situations when we don't use a database (standalone version).
493 */
494 function movino_get_videos_direct($op = 'all', $servers = NULL, $video_id = NULL, $limit = 0, $offset = 0, $prepare = TRUE) {
495 static $videos = array();
496 static $lookup = array();
497
498 // Parse all feeds.
499 if (empty($feeds)) {
500
501 $server_info = movino_get_servers();
502 if (empty($server_info)) {
503 return;
504 }
505 foreach($server_info as $server) {
506 if (!empty($server['feed_live'])) {
507 $feed = _movino_feed_parse(movino_feed_url($server, 'live'));
508 if (!empty($feed) && is_array($feed)) {
509 foreach ($feed as $video) {
510 $video['type'] = 'live';
511 $key = $video['created'] . '-' . $server['id'] . '-' . $video['id'];
512 $lookup[$server['id']][$video['id']] = $key;
513 $videos[$key] = $video;
514 // Instead of implementing hook_movino_video_prepare() for standalone version.
515 $videos[$key]['page'] = 'movino/video/' . $video['server'] . '/' . $video['id'];
516 }
517 }
518 }
519 if (!empty($server['feed_archive'])) {
520 $feed = _movino_feed_parse(movino_feed_url($server, 'archive'));
521 if (!empty($feed) && is_array($feed)) {
522 foreach ($feed as $video) {
523 $video['type'] = 'archived';
524 $key = $video['created'] . '-' . $server['id'] . '-' . $video['id'];
525 $lookup[$server['id']][$video['id']] = $key;
526 $videos[$key] = $video;
527 // Instead of implementing hook_movino_video_prepare() for standalone version.
528 $videos[$key]['page'] = 'movino/video/' . $server['id'] . '/' . $video['id'];
529 }
530 }
531 }
532 }
533 // Sort results.
534 krsort($videos);
535 }
536
537 if ($op == 'single') {
538 $videos = $video = ($prepare ? _movino_videos_prepare(array($videos[$lookup[$servers][$video_id]])) : $array($videos[$lookup[$servers][$video_id]]));
539 return array_shift($videos);
540 }
541
542 if ($server != NULL && !is_array($servers)) {
543 $servers = array($servers);
544 }
545
546 $results = array();
547 $result_count = 0;
548
549 foreach($videos as $video) {
550 if ($offset > 0) {
551 $offset -= 1;
552 } else {
553 if ($servers == NULL || in_array($video['serverId'], $servers)) {
554 if ($op == 'all' || $video['type'] == $op) {
555 $results[] = $video;
556 if ($limit > 0 && $result_count == $limit) {
557 return ($prepare ? _movino_videos_prepare($results) : $results);
558 }
559 }
560 }
561 }
562 }
563
564 return ($prepare ? _movino_videos_prepare($results) : $results);
565 }
566
567
568 /**
569 * Count the number of videos in the cache.
570 */
571 function movino_get_video_count($inactive = FALSE) {
572 $result = db_query('SELECT count(*) FROM {movino_videos} ' . (!$inactive ? 'WHERE available = 1 ' : 'WHERE available != 1 '));
573 if($count = db_fetch_array($result)) {
574 return $count['count(*)'];
575 }
576 return 0;
577 }
578
579
580 /**
581 * Do some preparations on the videos after loading them from the XML feed.
582 */
583 function _movino_videos_prepare($videos) {
584 if (empty($videos)) {
585 return $videos;
586 }
587
588 foreach ($videos as $key => $video) {
589 $id = $video['id'];
590
591 if (!empty($videos[$key]['size'])) {
592 $size = explode('x', $videos[$key]['size']);
593 if (intval($size[0]) > 0 && intval($size[1] > 0)) {
594 // Split size into width and height
595 $videos[$key]['width'] = $size[0];
596 $videos[$key]['height'] = $size[1];
597 } else {
598 $videos[$key]['width'] = 320;
599 $videos[$key]['height'] = 240;
600 }
601 } else {
602 $videos[$key]['width'] = 320;
603 $videos[$key]['height'] = 240;
604 }
605
606 // Allow moduels to customize values.
607 movino_invoke_all('movino_video_prepare', $videos[$key]);
608
609 // Allow modules to disable video.
610 if (!empty($videos[$key]['disabled'])) {
611 unset($videos[$key]);
612 }
613 }
614 return $videos;
615 }

  ViewVC Help
Powered by ViewVC 1.1.2