/[drupal]/contributions/modules/cdn2/cdn2.module
ViewVC logotype

Contents of /contributions/modules/cdn2/cdn2.module

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


Revision 1.3 - (show annotations) (download) (as text)
Sat Dec 6 01:24:24 2008 UTC (11 months, 3 weeks ago) by akalsey
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-6--1
Changes since 1.2: +1 -1 lines
File MIME type: text/x-php
Tagging release 1.2
1 <?php
2 // $Id$
3
4 /*
5 * @file cdn2.module
6 */
7
8 // Find node nid matching video ID in cck field
9 // If status is error, throw a watchdog entry
10 // If status is complete,
11 // Push file to CDN
12 // Update CCK field to hold CDN URL
13 // Publish Entry
14 // Respond with "OK"
15 //
16
17 define('CDN2_DEFAULT_ENDPOINT', 'http://soap.cdn2.net:8080/services/transcodeService?wsdl');
18 define('CDN2_DEFAULT_FORM', 'http://upload1.cdn2.net:8080/fileUpload.html');
19
20 require_once('cdn2_field.inc');
21
22 /**
23 * parent function to render out the video node. Directs calls out to individual video assets.
24 */
25 function theme_cdn2_video($node, $field, $items, $teaser, $page) {
26 $output = '';
27 $presets = _cdn2_get_available_presets();
28 $output_items = array();
29 if (count($items)) {
30 foreach ($items as $item) {
31 if (isset($item['assets']) && count($item['assets'])) {
32 for ($asset_key = 0; $asset_key < count($item['assets']); $asset_key++) {
33 $asset = $item['assets'][$asset_key];
34 if (user_access('view cdn2 video transcoded with '. $asset['preset_name']) && $presets[$asset['preset_name']]->fileFormat != 'JPEG') {
35 $output_items[] = '<div id="node-'. $node->nid .'-'. $asset['preset_name'] .'">'. theme('cdn2_video_asset', $node, $asset, $presets[$asset['preset_name']]) .'</div>';
36 $preset_list[$asset['preset_name']] = '<a href="#node-'. $node->nid .'-'. $asset['preset_name'] .'"><span>'. $presets[$asset['preset_name']]->friendlyName .'</span></a>';
37 }
38 }
39 }
40 }
41 }
42 if (count($preset_list)) {
43 $output .= '<div class="cdn2_tabs">';
44 $output .= '<ul>';
45 foreach ($preset_list as $preset_name => $preset_list_item) {
46 if (strpos($preset_name, 'thumb') == FALSE) {
47 $output .= '<li>'. $preset_list_item .'</li>';
48 }
49 }
50 $output .= '</ul>';
51 $output .= implode("\n", $output_items);
52 $output .= '</div>';
53 }
54 return $output;
55 }
56
57 /**
58 * parent function to render wrapper around a video asset. Delegates to
59 * appropriate theming functions based on preset short name, followed by
60 * file format, then finally the generic type.
61 */
62 function theme_cdn2_video_asset(&$node, &$asset, $preset) {
63 $output = '';
64 $output .= '<div class="cdn2_video_asset">';
65 if ($asset['preset_name'] && user_access('view cdn2 video transcoded with '. $preset->shortName)) {
66 if (theme_get_function('cdn2_video_asset_'. drupal_strtolower($preset->shortName))) {
67 $output .= theme('cdn2_video_asset_'. drupal_strtolower($preset->shortName), $node, $asset, $preset);
68 }
69 else if (theme_get_function('cdn2_video_asset_'. drupal_strtolower($preset->fileFormat))) {
70 $output .= theme('cdn2_video_asset_'. drupal_strtolower($preset->fileFormat), $node, $asset, $preset);
71 }
72 else {
73 $output .= theme('cdn2_video_asset_generic', $node, $asset, $preset);
74 }
75 $output .= '</div>';
76 $output .= '<div class="cdn2_metadata">';
77 $output .= theme('cdn2_video_asset_metadata', $node, $asset, $preset);
78 $output .= '</div>';
79 $output .= '<div class="clear-block" style="clear: left"><!-- --></div>';
80
81 return $output;
82 }
83 }
84
85 /**
86 * themes the video length as a time formatted as (hh:mm:ss)
87 */
88 function theme_cdn2_asset_video_length($video_length) {
89 if (!is_numeric($video_length)) {
90 return $video_length;
91 }
92
93 $hms = '';
94 $hours = intval(intval($video_length) / 3600);
95 $hms .= str_pad($hours, 2, '0', STR_PAD_LEFT) .':';
96 $minutes = intval(($video_length / 60) % 60);
97 $hms .= str_pad($minutes, 2, '0', STR_PAD_LEFT) .':';
98 $seconds = intval($video_length % 60);
99 $hms .= str_pad($seconds, 2, '0', STR_PAD_LEFT);
100
101 return $hms;
102 }
103
104 /**
105 * themes file size in kb, mb, etc.
106 */
107 function theme_cdn2_asset_file_size($file_size) {
108 $output = '';
109 if (!is_numeric($file_size)) {
110 // try stripping off 'kb' from the end
111 //
112 $file_size = str_replace('kB', '', $file_size);
113 if (!is_numeric($file_size)) {
114 return $file_size;
115 }
116 }
117 if ($file_size < 1024) {
118 $output .= $file_size .' KBytes';
119 }
120 elseif ($file_size < 1048576) {
121 $file_size = $file_size / 1024;
122 $file_size = round($file_size, 2);
123 $output .= $file_size .' MBytes';
124 }
125 else {
126 $file_size = $file_size / 1048576;
127 $file_size = round($file_size, 2);
128 $output .= $file_size .' GBytes';
129 }
130 return $output;
131 }
132
133 /**
134 * theme metadata about a video asset
135 */
136 function theme_cdn2_video_asset_metadata(&$node, $asset, $preset) {
137 $items = array();
138 $title = t('Video Information:');
139 $item = t('Duration: ');
140 // TODO: theme the video length into DD:MM:SS
141 $item .= ($asset['video_length'] === NULL) ? 'unknown' : theme('cdn2_asset_video_length', $asset['video_length']);
142 $items[] = $item;
143 $item = t('File Size: ');
144 // TODO:
145 $item .= ($asset['file_size'] === NULL) ? 'unknown' : theme('cdn2_asset_file_size', $asset['file_size']);
146 $items[] = $item;
147 $item = t('File Format: ');
148 switch ($preset->fileFormat) {
149 case 'FLASH':
150 $item .= t('Flash Video (FLV)');
151 break;
152 case 'MOV':
153 $item .= t('Quicktime (MOV)');
154 break;
155 default:
156 $item .= $preset->fileFormat;
157 break;
158 }
159 $items[] = $item;
160 $items[] = l('Download raw video file', $asset['asset_fetch_url']);
161
162 return theme('item_list', $items, $title);
163 }
164
165 /**
166 * custom theming function for quicktime videos
167 */
168 function theme_cdn2_video_asset_mov(&$node, &$asset, $preset, $width = 320, $height = 240) {
169 $output = '
170 <object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab" width="%s" height="%s">
171 <param name="src" value="%s">
172 <param name="autoplay" value="false">
173 <param name="type" value="video/quicktime" width="%s" height="%s">
174 <param name="scale" value="tofit">
175 <embed src="%s" width="%s" height="%s" scale="tofit" autoplay="false" type="video/quicktime" pluginspage="http://www.apple.com/quicktime/download/">
176 </object>';
177 $output = sprintf($output, $width, $height, $asset['asset_fetch_url'], $width, $height, $asset['asset_fetch_url'], $width, $height);
178 return $output;
179 }
180
181 function theme_cdn2_video_asset_mov_hd_low_res(&$node, &$asset, $preset) {
182 return theme('cdn2_video_asset_mov', $node, $asset, $preset, 640, 360);
183 }
184
185 function theme_cdn2_video_asset_mov_hd_high_res(&$node, &$asset, $preset) {
186 return theme('cdn2_video_asset_mov', $node, $asset, $preset, 640, 360);
187 }
188
189 /**
190 * custom theming function for flv types
191 */
192 function theme_cdn2_video_asset_flash(&$node, &$asset, $preset) {
193 $player = variable_get('cdn2_flash_player', 'flowplayer');
194
195 $players = module_invoke_all('cdn2_player', 'flash');
196 $player = $players[$player];
197 $theme_function = $player['theme function'];
198
199 return theme($theme_function, $node, $asset, $preset, '320', '240');
200 }
201
202 /**
203 * custom theming function for flv hd types
204 */
205 function theme_cdn2_video_asset_flash_flv_hd_low(&$node, &$asset, $preset) {
206 $player = variable_get('cdn2_flash_player', 'flowplayer');
207
208 $players = module_invoke_all('cdn2_player', 'flash');
209 $player = $players[$player];
210 $theme_function = $player['theme function'];
211
212 return theme($theme_function, $node, $asset, $preset, '640', '360');
213 }
214
215 function theme_cdn2_video_asset_Flash_flv_hd_high(&$node, &$asset, $preset) {
216 return theme('cdn2_video_asset_flash_flv_hd_low', $node, $asset, $preset);
217 }
218
219
220 /**
221 * theming function for a thumbnail
222 */
223 function theme_cdn2_video_asset_320x240_thumb(&$node, &$asset, $preset) {
224 // return '<img src="'. check_url($asset['asset_fetch_url']) .'" alt="'. check_plain($node->title) .'"/>';
225 }
226
227 /**
228 * theming function for other (unknown) types that renders them as
229 * a link to the downloadable file.
230 */
231 function theme_cdn2_video_asset_generic(&$node, &$asset, $preset) {
232 return l($preset->friendlyName, $asset['asset_fetch_url']);
233 }
234
235
236 /**
237 * Implementation of hook_perm().
238 */
239 function cdn2_perm() {
240 $perms = array('administer cdn2', 'administer cdn2 formats', 'delete cdn2 video');
241 $enabled_presets = variable_get('cdn2_allowed_presets', array());
242 foreach ($enabled_presets as $preset) {
243 if ($preset) {
244 $perms[] = 'transcode cdn2 video to '. $preset;
245 $perms[] = 'view cdn2 video transcoded with '. $preset;
246 }
247 }
248 return $perms;
249 }
250
251
252 function _cdn2_get_assets_for_node($nid) {
253 $query = 'SELECT id, nid, video_token, preset_name, status, asset_fetch_url FROM {cdn2_videos} WHERE nid=%d';
254 $resultset = db_query($query, $nid);
255 $results = array();
256 while ($row = db_fetch_array($resultset)) {
257 $results[] = $row;
258 }
259 return $results;
260 }
261
262 /**
263 * Implementation of hook_widget_settings().
264 */
265 function cdn2_widget_settings($op, $widget) {
266 switch ($op) {
267 case 'callbacks':
268 break;
269 case 'form':
270 $form = array();
271 return $form;
272 case 'validate':
273 break;
274 case 'save':
275 return array('cdn2');
276 }
277 }
278
279 function cdn2_xmlrpc() {
280 //video_token, preset_name, status_as_string, asset_fetch_url
281
282 // format of this response:
283 /*
284 xmlrpc method name (e.g. module.function)
285 callback function (e.g. module_function)
286 method signature:
287 first argument is the return type.
288 remainder are arguments to the function.
289 */
290 return array(
291 array(
292 'cdn2.updateStatus',
293 'cdn2_update_status',
294 array('boolean', // return value
295 'string', // dateTime
296 'string', // calculatedHash
297 'string', // videoToken
298 'string', // preset shortName
299 'string', // status
300 'string', // fileName
301 'string', // fileSize
302 'string'), // videoLength
303 t('Update the status of a CDN2 video'),
304 )
305 );
306 }
307
308
309 function _cdn2_update_video_asset_status($video_token, $preset_name, $status, $asset_fetch_url, $file_size, $video_length) {
310 $content_types = _cdn2_get_content_types();
311
312 foreach ($content_types as $content_type) {
313 $nid = _cdn2_get_nid_by_video_token($content_type, $video_token);
314 // if the node has not yet been submitted, it's possible that we'll get a status message back before then. So
315 // we persist the videotoken with a nid of zero and the node save will handle the population. Hence why we ignore the nid here.
316 //
317
318 // fetch the existing video_nid if it exists
319 //
320 $query = "SELECT nid FROM {cdn2_video_node} where video_token='%s'";
321 $video_nid = db_result(db_query($query, $video_token));
322
323
324 $query = "SELECT id FROM {cdn2_videos} WHERE video_token = '%s' AND preset_name = '%s'";
325 $result = db_result(db_query($query, $video_token, $preset_name));
326
327 if (!$result) {
328 // creating a new record for the video asset. If the video's nid is set,
329 // we pass that, too
330 //
331 $id = db_next_id('cdn2_videos_id');
332 $query = "INSERT INTO {cdn2_videos} (id, nid, video_token, preset_name, status, asset_fetch_url, file_size, video_length)
333 VALUES(%d, %d, '%s', '%s', '%s', '%s', '%s', '%s')";
334 db_query($query, $id, $video_nid, $video_token, $preset_name, $status, $asset_fetch_url, $file_size, $video_length);
335 }
336 else {
337 // update the video asset independent of node context
338 $query = "UPDATE {cdn2_videos} SET status='%s', asset_fetch_url='%s', file_size='%s', video_length='%s' WHERE preset_name='%s' AND video_token='%s'";
339 db_query($query, $status, $asset_fetch_url, $preset_name, $video_token);
340 }
341 }
342
343 // check to see if the video was already submitted. If it was, we update the node with nid associated in cdn2_video_node. If not, we do nothing as
344 // it will get picked up by the node save itself.
345 //
346 if ($video_nid) {
347 // here we update the cdn2_videos table with the correct nid (in case the node was already submitted)
348 //
349 $query = "UPDATE {cdn2_videos} SET nid=%d WHERE video_token='%s'";
350 db_query($query, $video_nid, $video_token);
351
352 // forcing a re-save of the node to clear cache
353 //
354 $node = node_load($video_nid);
355
356 $content_type = $node->type;
357 $field_name = _cdn2_get_field_names_by_content_type($content_type);
358
359 if ($update = variable_get('cdn2_workflow_settings', 0)) {
360 // update the node's status based on workflow settings
361
362 if (!$node->status) {
363 $node->status = 1;
364 watchdog('cdn2', 'Marked '. $node->title .' as published');
365 }
366 }
367 node_save($node);
368 }
369 watchdog('cdn2', 'Completed transcoding '. $preset_name .' for video token '. $video_token);
370 return TRUE;
371 }
372
373
374 /**
375 * invoked when xmlrpc status callback is run
376 */
377 function cdn2_update_status($date_time, $calculated_hash, $video_token, $preset_name, $status, $asset_fetch_url, $file_size, $video_length) {
378 include_once('Crypt/HMAC.php');
379 if (!class_exists('Crypt_HMAC')) {
380 watchdog("cdn2", 'PEAR Package Crypt_HMAC is required to use the CDN2 module.', WATCHDOG_ERROR);
381 return FALSE;
382 }
383 require_once('lib/libcdn2.inc');
384
385 $cdn2_secret_key = variable_get("cdn2_secret_key", "");
386
387 $hmac = new CDN2_Crypt_HMAC($cdn2_secret_key);
388 $hmac->setKey($cdn2_secret_key);
389 $hmac->setFunction("sha1");
390
391 $message = variable_get("cdn2_client_id", "") . $date_time;
392 $verified_hash = $hmac->hash($message);
393 if ($verified_hash != $calculated_hash) {
394 // failed hash check.. Do nothing
395 watchdog("cdn2", "Invalid hash specified. Ignoring xmlrpc request.", WATCHDOG_ERROR);
396 return FALSE;
397 }
398 watchdog("cdn2", "Received valid authentication hash. Processing request.");
399 switch ($status) {
400 case 'error':
401 drupal_mail('admin_error_mail', variable_get('site_mail'), 'Error', 'There was an error in the transcoding process');
402 break;
403 case 'complete':
404 watchdog('cdn2', sprintf('Updating status of video: %s with preset %s', $video_token, $preset_name), 'info');
405 _cdn2_update_video_asset_status($video_token, $preset_name, $status, $asset_fetch_url, $file_size, $video_length);
406 break;
407 case 'deleted':
408 $content_types = _cdn2_get_content_types();
409
410 foreach ($content_types as $content_type) {
411 $nid = _cdn2_get_nid_by_video_token($content_type, $video_token);
412 $query = "SELECT id FROM {cdn2_videos} WHERE nid = %d";
413 $result = db_result(db_query($query, $nid));
414
415 if ($result) {
416 $query = "DELETE FROM {cdn2_videos} WHERE nid=%d ";
417 db_query($query, $nid);
418 }
419 else {
420 watchdog("cdn2", t('Error on deletion: nid %d, not found in cdn2_videos table', $nid), WATCHDOG_ERROR);
421 }
422 }
423 break;
424 }
425 // TODO: make sure this still works
426 module_invoke_all('cdn2_video_asset_status', $video_token, $preset_name, $status, $asset_fetch_url, $file_size, $video_length);
427 return TRUE;
428 }
429
430 function _cdn2_get_nid_by_video_token($content_type, $video_token) {
431 $field_name = _cdn2_get_field_names_by_content_type($content_type);
432 $query = "SELECT nid FROM {%s} WHERE %s = '%s'";
433 $result = db_query($query, 'content_type_'. $content_type, $field_name[0] .'_value', $video_token);
434 $nid = db_fetch_object($result);
435 return $nid->nid;
436 }
437 /*
438 * cdn2_menu
439 * hook_menu implementation
440 *
441 */
442 function cdn2_menu() {
443 $items = array();
444 $items[] = array(
445 'path' => 'admin/settings/cdn2',
446 'title' => t('CDN2 Settings'),
447 'description' => t('Configure CDN2'),
448 'callback' => 'drupal_get_form',
449 'callback arguments' => 'cdn2_settings',
450 'type' => MENU_NORMAL_ITEM,
451 'access' => user_access('administer site configuration'),
452 );
453 $items[] = array(
454 'path' => 'admin/settings/cdn2/config',
455 'title' => t('CDN2 Settings'),
456 'description' => t('Configure CDN2'),
457 'callback' => 'drupal_get_form',
458 'callback arguments' => 'cdn2_settings',
459 'type' => MENU_DEFAULT_LOCAL_TASK,
460 'access' => user_access('administer site configuration'),
461 );
462
463 $items[] = array(
464 'path' => 'admin/settings/cdn2/formats',
465 'title' => t('CDN2 Formats'),
466 'description' => t('Select which formats to allow users to transcode to.'),
467 'callback' => 'drupal_get_form',
468 'callback arguments' => 'cdn2_format_settings',
469 'type' => MENU_LOCAL_TASK,
470 'access' => user_access('administer cdn2 formats')
471 );
472 $items[] = array(
473 'path' => 'admin/settings/cdn2/workflow',
474 'title' => t('CDN2 Workflow Settings'),
475 'description' => t('General workflow settings for CDN2'),
476 'callback' => 'drupal_get_form',
477 'callback arguments' => 'cdn2_workflow_settings',
478 'type' => MENU_LOCAL_TASK,
479 'access' => user_access('administer site configuration'),
480 );
481 $items[] = array(
482 'path' => 'cdn2/uploadform',
483 'title' => t('Video upload form'),
484 'access' => user_access('access content'),
485 'type' => MENU_CALLBACK,
486 'callback' => 'cdn2_upload_form'
487 );
488 $items[] = array(
489 'path' => 'cdn2/xmlrpc',
490 'title' => t('XMLRPC callback'),
491 'access' => user_access('access content'),
492 'type' => MENU_CALLBACK,
493 'callback' => 'cdn2_xmlrpc',
494 );
495 $items[] = array(
496 'path' => 'cdn2/complete',
497 'title' => t('Upload Complete'),
498 'access' => user_access('access content'),
499 'type' => MENU_CALLBACK,
500 'callback' => 'cdn2_upload_complete'
501 );
502
503 $items[] = array(
504 'path' => 'cdn2/uploadform/status',
505 'title' => t('Upload Status'),
506 'access' => user_access('access content'),
507 'type' => MENU_CALLBACK,
508 'callback' => 'cdn2_get_upload_status',
509 'callback arguments' => array(arg(3)),
510 );
511 return $items;
512 }
513
514 function cdn2_workflow_settings() {
515 $form['cdn2_workflow_settings'] = array(
516 '#type' => 'radios',
517 '#title' => t('Workflow Settings'),
518 '#default_value' => variable_get('cdn2_workflow_settings', 0),
519 '#options' => array('1' => t('Publish node after transcoding is completed'), '0' => t('Do not automatically publish')),
520 );
521 return system_settings_form($form);
522 }
523
524 function cdn2_format_settings() {
525 $form = array();
526 drupal_add_css(drupal_get_path('module', 'cdn2') .'/cdn2.css');
527 drupal_add_js('/misc/jquery.js');
528 drupal_add_js(drupal_get_path('module', 'cdn2') .'/js/jquery.selectboxes.pack.js');
529 drupal_add_js(drupal_get_path('module', 'cdn2') .'/js/cdn2_admin.js');
530 $form['cdn2_markup'] = array(
531 '#type' => 'markup',
532 '#value' => t('Select the video formats that users should be able to transcode upload video to. Note that all formats checked below will be available users. You can configure permissions for which users have access to view and upload to certain formats by visiting the ') . l('user roles', 'admin/user/roles') . t(' page.')
533 );
534 $form['cdn2_presets'] = array(
535 '#type' => 'fieldset',
536 '#title' => t('Transcode Presets'),
537 '#attributes' => array('id' => 'cdn2_presets_fieldset')
538 );
539 $presets = _cdn2_get_available_presets();
540 $options = array();
541 $selection_options = array();
542 $selection_options['Select...'] = 'Select...';
543 $cdn2_allowed_presets = variable_get('cdn2_allowed_presets', array());
544 $js_list = array();
545 $js_list[] = 'var aPresetList = new Array();';
546 if (count($presets)) {
547 foreach ($presets as $preset) {
548 if ($preset->fileFormat != 'JPEG') {
549 $options[$preset->shortName] = sprintf(
550 '<div style="display:inline;">%s<br/><div class="description">Dimensions: %s<br/>Video Codec: %s (%sbps)<br/>Audio Codec: %s (%sbps)</div></div>',
551 $preset->friendlyName,
552 $preset->videoDimensions,
553 $preset->videoCodec,
554 $preset->videoBitRate,
555 $preset->audioCodec,
556 $preset->audioBitrate);
557 $selection_options[$preset->shortName] = $preset->friendlyName;
558 $js_list[] = sprintf('aPresetList[\'%s\'] = \'%s\';', $preset->shortName, $preset->friendlyName);
559 }
560 }
561 }
562 $js_output .= implode("\n", $js_list) ."\n";
563 drupal_add_js($js_output, 'inline');
564 $form['cdn2_presets']['cdn2_allowed_presets'] = array(
565 '#type' => 'checkboxes',
566 '#title' => 'Allowed Presets',
567 '#default_value' => $cdn2_allowed_presets,
568 '#description' => t('Set the types of presets that are transcoded by default. Items of this list may be exposed by allowing them permissions on the drupal permissions page.'),
569 '#options' => $options,
570 '#suffix' => '<div class="clear-block"></div>'
571 );
572
573 $top_keys = array_keys($selection_options);
574 $top_key = $top_keys[1];
575 $cdn2_default_preset = variable_get('cdn2_default_preset', $top_key);
576 $form['cdn2_presets']['cdn2_default_preset'] = array(
577 '#type' => 'select',
578 '#title' => t('Show format by default'),
579 '#default_value' => $cdn2_default_preset,
580 '#options' => $selection_options
581 );
582
583
584 $cdn2_flash_players = module_invoke_all('cdn2_player', 'flash');
585 $cdn2_flash_player_options = array();
586 if (count($cdn2_flash_players)) {
587 $form['cdn2_playback'] = array(
588 '#type' => 'fieldset',
589 '#title' => t('Playback Settings')
590 );
591
592 foreach ($cdn2_flash_players as $name => $player) {
593 $cdn2_flash_player_options[$name] = $player['title'] .' ('. l($player['source url'], $player['source url'], array('target' => '_new')) .')';
594 }
595
596 $form['cdn2_playback']['cdn2_flash_player'] = array(
597 '#type' => 'radios',
598 '#title' => t('Preferred Flash Player'),
599 '#options' => $cdn2_flash_player_options,
600 '#default_value' => variable_get('cdn2_flash_player', 'flowplayer')
601 );
602 }
603
604 $output = system_settings_form($form);
605
606 return $output;
607 }
608
609 /*
610 * cdn2_settings
611 * Admin settings hook
612 *
613 * Form for the cdn2 module's settings.
614 */
615 function cdn2_settings() {
616 $form['cdn2_uploader_endpoint'] = array(
617 '#type' => 'textfield',
618 '#title' => t('SOAP Endpoint'),
619 '#default_value' => variable_get('cdn2_uploader_endpoint', CDN2_DEFAULT_ENDPOINT),
620 '#required' => TRUE,
621 '#description' => t('The URL of the uploader\'s SOAP service'),
622 );
623 $form['cdn2_uploader_form'] = array(
624 '#type' => 'textfield',
625 '#title' => t('Upload form URL'),
626 '#default_value' => variable_get('cdn2_uploader_form', CDN2_DEFAULT_FORM),
627 '#required' => TRUE,
628 '#description' => t('The URL of the uploader\'s HTML form'),
629 );
630 $form['cdn2_client_id'] = array(
631 '#type' => 'textfield',
632 '#title' => t('Client ID'),
633 '#default_value' => variable_get('cdn2_client_id', ''),
634 '#required' => TRUE,
635 '#description' => t('Your client ID for the cdn2 service.'),
636 );
637
638 $form['cdn2_secret_key'] = array(
639 '#type' => 'textfield',
640 '#title' => t('Secret Key'),
641 '#default_value' => variable_get('cdn2_secret_key', ''),
642 '#required' => TRUE,
643 '#description' => t('The Secret Key provided to you for the cdn2 service.'),
644 );
645 cache_clear_all();
646
647 $output = system_settings_form($form);
648
649 return $output;
650 }
651
652 function _cdn2_filter_presets_by_user($account, $assoc_presets, $show_all) {
653 $user_presets = array();
654 $cdn2_allowed_presets = variable_get('cdn2_allowed_presets', array());
655 foreach ($assoc_presets as $short_name => $preset) {
656 if (user_access('transcode cdn2 video to '. $short_name, $account) && $cdn2_allowed_presets[$short_name] !== 0) {
657 $user_presets[$short_name] = $preset;
658 }
659 }
660 return $user_presets;
661 }
662
663 function _cdn2_get_available_presets($account = NULL, $show_all = TRUE) {
664 static $assoc_presets;
665 if (count($assoc_presets)) {
666 if ($account) {
667 return _cdn2_filter_presets_by_user($account, $assoc_presets);
668 }
669 return $assoc_presets;
670 }
671 $presets = unserialize(cache_get('cdn2_presets')->data);
672 if (!$presets) {
673 $cdn2 = _cdn2_get_soap_client();
674 if (!$cdn2) {
675 return NULL;
676 }
677 $presets = $cdn2->getFormatPresets();
678 if ($presets['error']) {
679 drupal_set_message('Error occurred: '. $presets['error'], 'error');
680 return NULL;
681 }
682 }
683 $assoc_presets = array();
684 foreach ($presets as $preset) {
685 $assoc_presets[$preset->shortName] = $preset;
686 }
687 cache_set('cdn2_presets', 'cache', serialize($assoc_presets), time() + 86400);
688 if ($account) {
689 return _cdn2_filter_presets_by_user($account, $assoc_presets, $show_all);
690 }
691 return $assoc_presets;
692 }
693
694 function _cdn2_content_types() {
695 $type_list = array(0 => 'None');
696 $result = db_query("SELECT distinct(type_name) as name FROM {node_field_instance} ORDER BY type_name");
697 while ($row = db_fetch_object($result)) {
698 $type_list[$row->name] = $row->name;
699 }
700 return $type_list;
701 }
702
703 function _cdn2_cck_fields() {
704 $field_list = array(0 => 'None');
705 $result = db_query("SELECT distinct(field_name) as name, label FROM {node_field_instance} where type_name = '%s' ORDER BY label", variable_get('cdn2_content_type', ''));
706 while ($row = db_fetch_object($result)) {
707 $field_list[$row->name] = $row->label;
708 }
709 return $field_list;
710 }
711
712 function cdn2_upload_form($token=0, $messages = '') {
713 global $user;
714 $redirect_url = url('cdn2/complete', NULL, NULL, TRUE);
715 $action = variable_get('cdn2_uploader_form', CDN2_DEFAULT_FORM);
716 $jquery = '/misc/jquery.js';
717 $jquery_progressbar = '/'. drupal_get_path('module', 'cdn2') .'/js/jquery.progressbar.min.js';
718 $our_jquery = '/'. drupal_get_path('module', 'cdn2') .'/js/upload.js';
719 $style_css = "/". path_to_theme() ."/style.css";
720 $cdn2_progress_image = '/'. drupal_get_path('module', 'cdn2') .'/images/progressbg_blue.gif';
721 $cdn2_progress_boximage = '/'. drupal_get_path('module', 'cdn2') .'/images/progressbar.gif';
722
723 $presets = _cdn2_get_available_presets($user);
724 $preset_inputs = '';
725 $i = 0;
726 foreach ($presets as $short_name => $preset) {
727 # Note: each input name here must be prefixed by 'selectedPresets' to be properly processed by the backend service
728 # If the backend service does not properly parse these args, it will not approve the selected formats for
729 # processing, and no transcoding will occur.
730 $inputName = "selectedPresets".$i;
731 $preset_inputs .= sprintf('<input type="checkbox" name="%s" value="%s" checked/>%s<br/>', $inputName, $short_name, $preset->friendlyName);
732 $i++;
733 }
734 if ($messages) {
735 $messages = '<div class="error">'. $messages .'</div>'."\n";
736 }
737 $output = <<<HTML
738 <html class="js" lang="en" xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
739 <head>
740 <title></title>
741 <style type="text/css" media="all">@import "/modules/node/node.css";</style>
742 <style type="text/css" media="all">@import "/modules/system/defaults.css";</style>
743 <style type="text/css" media="all">@import "/modules/system/system.css";</style>
744 <style type="text/css" media="all">@import "$style_css";</style>
745 <style>
746 #progress-bar {
747 display: none;
748 }
749 #progress-info {
750 display: none;
751 }
752 body {
753 background: transparent;
754 }
755 </style>
756 <script language="javascript" type="text/javascript">
757 var cdn2_progress_image = '$cdn2_progress_image';
758 var cdn2_progress_boximage = '$cdn2_progress_boximage';
759 </script>
760 <script type="text/javascript" src="$jquery"></script>
761 <script type="text/javascript" src="$jquery_progressbar"></script>
762 <script type="text/javascript" src="$our_jquery"></script>
763 </head>
764 <body>
765 $messages
766 <form id="upload" action="$action" method="post" enctype="multipart/form-data">
767 <div class="form-item">
768 <p><label>Upload a video: </label>
769 <input type="hidden" name="videoToken" id="videoToken" value="$token"/>
770 <input type="hidden" name="redirectUrl" value="$redirect_url"/>
771 <input type="file" name="file"/></p>
772 <p>
773 <label>Show this file in the following formats:</label>
774 $preset_inputs
775 </p>
776 <input type="submit" name="Send" value="Upload"/>
777 </div>
778 </form>
779 <div id="progress-info"><p>Your video is uploading. Please do not submit your form or navigate away from this page until it is complete.</p>
780 <b>Upload Progress:</b>
781 </div>
782 <div id="progress-bar"></div>
783 </body>
784 </html>
785 HTML;
786
787 print $output;
788 }
789
790 /**
791 * shows the upload form in an iframe
792 */
793 function cdn2_upload_complete($video_token = '') {
794 $error = $_REQUEST['e'];
795 $video_token = check_plain($video_token);
796 if ($error) {
797 // show the upload form again, with the error inline.
798 //
799 print cdn2_upload_form($video_token, $error);
800 return;
801 }
802
803 // save the video token in the database. Note that it will not yet be associated with a node. That's okay.
804 //
805 $vid = db_next_id("cdn2_video_vid");
806
807 $query = "INSERT INTO {cdn2_video_node} (vid, nid, video_token, is_submitted) values(%d, 0, '%s', %d)";
808 db_query($query, $vid, $video_token, 1);
809
810 $jquery = '/misc/jquery.js';
811 $style_css = "/". path_to_theme() ."/style.css";
812 $output = <<<HTML
813 <html class="js" lang="en" xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
814 <head>
815 <title></title>
816 <style type="text/css" media="all">@import "/modules/node/node.css";</style>
817 <style type="text/css" media="all">@import "/modules/system/defaults.css";</style>
818 <style type="text/css" media="all">@import "/modules/system/system.css";</style>
819 <style type="text/css" media="all">@import "$style_css";</style>
820 <script type="text/javascript" src="$jquery"></script>
821 <p>Your video has been uploaded. It can take some time to process, so be patient.</p>
822
823 <p>Please make sure you <b>submit</b> this page before continuing, otherwise your video will be lost.</p>
824 <script language="javascript">
825 $(document).ready(function(){
826 $(window.parent.document).find('input#edit-cdn2-is-submitted').val('true');
827 $(window.parent.document).find('input#edit-submit').removeAttr('disabled');
828 return;
829 });
830 </script>
831 </body>
832 </html>
833 HTML;
834
835 print $output;
836 }
837
838 function cdn2_get_upload_status($vidid) {
839 $cdn2 = _cdn2_get_soap_client();
840 // this PRINT_R is NOT FOR DEBUGGING. Don't remove it, mmkay?
841 print_r($cdn2->getVideoUploadStatus($vidid));
842 }
843
844 function _cdn2_get_soap_client() {
845 include_once('Crypt/HMAC.php');
846 if (!class_exists('Crypt_HMAC')) {
847 drupal_set_message('PEAR Package Crypt_HMAC is required to use the CDN2 module.', 'error');
848 return;
849 }
850 require_once('lib/libcdn2.inc');
851
852 $site_token = variable_get('cdn2_client_id', 'workhabit');
853 $secret_key = variable_get('cdn2_secret_key', '');
854 $endpoint_url = variable_get('cdn2_uploader_endpoint', CDN2_DEFAULT_ENDPOINT);
855 try {
856 return new ErrorHandlingSoapClient(CDN2SoapClientImpl::getInstance($endpoint_url, $site_token, $secret_key));
857 } catch (Exception $e) {
858 drupal_set_message($e->getMessage(), 'error');
859 watchdog('error', $e->getMessage());
860 }
861 return NULL;
862 }
863
864
865 function _cdn2_get_content_types() {
866 $widget_info = cdn2_widget_info();
867 $content_types = array();
868 foreach ($widget_info as $key => $value) {
869 $query = "SELECT type_name FROM {node_field_instance} WHERE widget_type='%s'";
870 $result = db_query($query, $key);
871 while ($row = db_fetch_object($result)) {
872 $content_types[] = $row->type_name;
873 }
874 }
875 return $content_types;
876 }
877
878 function _cdn2_get_field_names_by_content_type($content_type) {
879 $query = "SELECT field_name FROM {node_field_instance} WHERE type_name='%s'";
880 $result = db_query($query, $content_type);
881 while ($row = db_fetch_object($result)) {
882 $field_names[] = $row->field_name;
883 }
884 return $field_names;
885 }

  ViewVC Help
Powered by ViewVC 1.1.2