This repository has been archived by the owner on Feb 12, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathscripto.module
490 lines (440 loc) · 16.7 KB
/
scripto.module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
<?php
/**
* @file
* Adds the ability to transcribe files using the Scripto library.
*/
/**
* Implements hook_help.
*/
function scripto_help($path, $arg) {
switch ($path) {
case 'admin/help#scripto':
return '<p>'. t('Adds the ability to transcribe files using the Scripto library.') .'</p>';
break;
}
}
/**
* Implements hook_permission().
*/
function scripto_permission() {
return array(
'configure scripto' => array(
'title' => t('Configure Scripto'),
'description' => 'Perform administration tasks for the Scripto module.',
),
);
}
/**
* Implements hook_menu().
*/
function scripto_menu() {
$items['admin/config/scripto'] = array(
'title' => 'Configure Scripto',
'page callback' => 'drupal_get_form',
'page arguments' => array('scripto_config_form'),
'access arguments' => array('configure scripto'),
);
$items['scripto/transcribe'] = array(
'title' => 'Transcribe',
'page callback' => 'drupal_get_form',
'page arguments' => array('scripto_transcribe_form'),
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
$items['scripto/login'] = array(
'title' => 'Scripto Login',
'page callback' => 'drupal_get_form',
'page arguments' => array('scripto_login_form'),
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Menu callback: displays the scripto module configuration form.
*
* @see scripto_menu()
*/
function scripto_config_form() {
$form['scripto_zend_framework_path'] = array(
'#type' => 'textfield',
'#title' => t('Path to Zend Framework'),
'#description' => t('The full path, from root, to the directory containing the Zend Framework library.'),
'#default_value' => variable_get('scripto_zend_framework_path'),
);
$form['scripto_mediawiki_api_url'] = array(
'#type' => 'textfield',
'#title' => t('MediaWiki API URL'),
'#description' => t('URL to your <a href="http://www.mediawiki.org/wiki/API:Quick_start_guide#What_you_need_to_access_the_API">MediaWiki installation API</a>'),
'#default_value' => variable_get('scripto_mediawiki_api_url'),
);
// Get all existing node types.
$type_names = array();
foreach (node_type_get_types() as $type_name => $type_info) {
$type_names[$type_name] = $type_info->name;
}
$form['scripto_node_types'] = array(
'#type' => 'checkboxes',
'#title' => t('Node types'),
'#description' => t('Check to enable transcriptions on the specified node types. All files will be transcribable. Use caution when unchecking a node type; all transcriptions that have been imported will be deleted, but they can be re-imported.'),
'#options' => $type_names,
'#default_value' => variable_get('scripto_node_types') ? variable_get('scripto_node_types') : array(),
);
$form['#validate'][] = 'scripto_config_form_validate';
$form['#submit'][] = 'scripto_config_form_submit';
return system_settings_form($form);
}
/**
* Form validation handler for scripto_config_form().
*/
function scripto_config_form_validate($form, &$form_state) {
$zend_framework_path = $form_state['values']['scripto_zend_framework_path'];
$mediawiki_api_url = $form_state['values']['scripto_mediawiki_api_url'];
// Don't continue to validate if the path is invalid.
if (!is_dir($zend_framework_path)) {
form_set_error('scripto_zend_framework_path', t('Invalid path to the Zend Framework library.'));
return;
}
// Load the Scripto environment to validate the MediaWiki API URL.
set_include_path(get_include_path()
. PATH_SEPARATOR . $zend_framework_path
. PATH_SEPARATOR . _scripto_get_scripto_path());
require_once 'Scripto.php';
if (!Scripto::isValidApiUrl($mediawiki_api_url)) {
form_set_error('scripto_mediawiki_api_url', t('Invalid MediaWiki API URL.'));
}
}
/**
* Form submission handler for scripto_config_form().
*/
function scripto_config_form_submit($form, &$form_state) {
variable_set('scripto_zend_framework_path', $form_state['values']['scripto_zend_framework_path']);
variable_set('scripto_mediawiki_api_url', $form_state['values']['scripto_mediawiki_api_url']);
variable_set('scripto_node_types', $form_state['values']['scripto_node_types']);
// Build an array of all node types that have an instance of the
// scripto_transcription field.
$types_with_instance = array();
$field_instances = field_info_instances();
foreach ($field_instances['node'] as $type_name => $type) {
foreach ($type as $field_name => $field) {
if ('scripto_transcription' == $field_name) {
$types_with_instance[] = $type_name;
}
}
}
// Iterate the node type checklist.
foreach ($form_state['values']['scripto_node_types'] as $type_name => $result) {
// Build the instance structure.
$instance = array(
'field_name' => 'scripto_transcription',
'label' => 'Transcription',
'entity_type' => 'node',
'bundle' => $type_name,
'required' => false,
);
// Delete/ignore the instance if it was not selected.
if (0 === $result) {
field_delete_instance($instance, false);
continue;
}
// Do not re-create the instance.
if (in_array($type_name, $types_with_instance)) {
continue;
}
// Create the instance.
field_create_instance($instance);
}
}
/**
* Menu callback: displays the scripto module transcription form.
*
* @see scripto_menu().
*/
function scripto_transcribe_form($form, &$form_state, $node_id, $file_id) {
// Set the Scripto document and page.
$scripto = _scripto_get_scripto();
$doc = $scripto->getDocument($node_id);
$doc->setPage($file_id);
// Log out of Scripto.
if (isset($_GET['logout'])) {
$scripto->logout();
drupal_set_message('You are logged out of Scripto.');
}
// Get the node and file objects.
$node = node_load($node_id);
$file = file_load($file_id);
$form['node_title'] = array('#markup' => '<h2>' . l($node->title, 'node/' .$node_id) . ': ' . $file->filename . '</h2>');
// Build the transcription form.
if ($doc->canEditTranscriptionPage()) {
// Zoom.it image viewer.
if (in_array($file->filemime, _scripto_get_filemime_zoomit())) {
$url = url('http://api.zoom.it/v1/content/', array('query' => array('url' => file_create_url($file->uri))));
$response = drupal_http_request($url);
$html = json_decode($response->data)->embedHtml;
// Google Docs document viewer.
} else if (in_array($file->filemime, _scripto_get_filemime_googledocs())) {
$url = url('http://docs.google.com/viewer', array('query' => array('url' => file_create_url($file->uri), 'embedded' => 'true')));
$html = '<iframe src="' . $url . '" width="600" height="600" style="border: none;"></iframe>';
// No media viewer.
} else {
$html = '<p>No media viewer is available for ' . $file->filemime . ' files. ' . l('Click here', file_create_url($file->uri), array('attributes' => array('_target' => 'blank'))) . ' to open the file manually.</p>';
}
$form['media_viewer'] = array('#markup' => $html);
$form['transcription'] = array(
'#type' => 'textarea',
'#title' => t('Transcription'),
'#default_value' => $doc->getTranscriptionPageWikitext(),
'#cols' => 60,
'#rows' => 16,
);
$form['submit'] = array('#type' => 'submit', '#value' => t('Save Transcription'));
if ($scripto->canExport()) {
$form['scripto_wiki'] = array('#markup' => l('View wiki page', $doc->getTranscriptionPageMediawikiUrl()) . '. ');
}
if ($scripto->isLoggedIn()) {
$form['scripto_logout'] = array('#markup' => l('Log out, ' . $scripto->getUserName(), "scripto/transcribe/$node_id/$file_id", array('query' => array('logout' => null))));
} else {
$form['scripto_login'] = array('#markup' => l('Log in to Scripto', "scripto/login/$node_id/$file_id"));
}
$form['#submit'][] = 'scripto_transcribe_form_submit';
// Access to MediaWiki is restricted. Show login link or access denied message.
} else {
if ($scripto->isLoggedIn()) {
$form['access_restricted'] = array('#markup' => 'Access to edit this transcription is restricted');
} else {
$form['access_restricted'] = array('#markup' => 'Access to edit this transcription is restricted. Please ' . l('log in', "scripto/login/$node_id/$file_id") . ' to the Scripto transcription service.');
}
}
$form['current_transcription'] = array('#markup' => '<h2>Current Transcription</h2>' . $doc->getTranscriptionPageHtml());
$form['node_id'] = array('#type' => 'value', '#value' => $node_id);
$form['file_id'] = array('#type' => 'value', '#value' => $file_id);
return $form;
}
/**
* Form submission handler for scripto_transcribe_form().
*/
function scripto_transcribe_form_submit($form, &$form_state) {
$scripto = _scripto_get_scripto();
$doc = $scripto->getDocument($form_state['values']['node_id']);
$doc->setPage($form_state['values']['file_id']);
$doc->editTranscriptionPage($form_state['values']['transcription']);
drupal_set_message('The transcription has been saved.');
}
function scripto_login_form($form, &$form_state, $node_id, $file_id) {
$form['scripto_username'] = array(
'#type' => 'textfield',
'#title' => t('Username'),
'#size' => 20,
);
$form['scripto_password'] = array(
'#type' => 'password',
'#title' => t('Password'),
'#size' => 20,
);
$form['scripto_submit'] = array('#type' => 'submit', '#value' => t('Login'));
$form['node_id'] = array('#type' => 'value', '#value' => $node_id);
$form['file_id'] = array('#type' => 'value', '#value' => $file_id);
$form['#validate'][] = 'scripto_login_form_validate';
$form['#submit'][] = 'scripto_login_form_submit';
return $form;
}
/**
* Form validation handler for scripto_transcribe_form() login.
*/
function scripto_login_form_validate($form, &$form_state) {
try {
// Attempt the login.
$scripto = _scripto_get_scripto();
$scripto->login($form_state['values']['scripto_username'], $form_state['values']['scripto_password']);
} catch (Scripto_Service_Exception $e) {
form_set_error('', $e->getMessage());
}
}
/**
* Form submission handler for scripto_transcribe_form() login.
*/
function scripto_login_form_submit($form, &$form_state) {
// The validation handler took care of everything.
drupal_set_message('You are logged into Scripto.');
drupal_goto("scripto/transcribe/{$form_state['values']['node_id']}/{$form_state['values']['file_id']}");
}
/**
* Implementation of hook_node_view_alter().
*/
function scripto_node_view_alter(&$build) {
// Only nodes with the scripto_transcription field can be transcribed.
if ('full' != $build['#view_mode'] || !isset($build['#node']->scripto_transcription)) {
return;
}
// Get this node's pages and return if there are none.
$pages = _scripto_get_pages($build['#node']);
if (!$pages) {
return;
}
// Add a list of links to transcription pages for all files and images
// assigned to this node. Assume current order is the correct page order.
$html = '<h3>Transcribe</h3>';
$html .= '<ol>';
foreach ($pages as $page) {
$html .= '<li>' . l($page['filename'], 'scripto/transcribe/' . $build['#node']->nid . '/' . $page['fid']) . '</li>';
}
$html .= '</ol>';
$build['transcription_page_list'] = array(
'#markup' => $html,
'#weight' => 20,
);
// Show the import button if the current user has permission to export.
$scripto = _scripto_get_scripto();
if ($scripto->canExport()) {
$build['import_transcription'] = drupal_get_form('scripto_import_transcription', $build['#node']->nid);
}
}
/**
* Node build callback: displays the scripto module import transcription form.
*/
function scripto_import_transcription($form, &$form_state, $node_id) {
$form['node_id'] = array('#type' => 'value', '#value' => $node_id);
$form['submit'] = array('#type' => 'submit', '#value' => t('Import Transcriptions'));
$form['#submit'][] = 'scripto_import_transcription_submit';
$form['#weight'] = '20';
return $form;
}
/**
* Form submission handler for scripto_import_transcription().
*/
function scripto_import_transcription_submit($form, &$form_state) {
$scripto = _scripto_get_scripto();
if (!$scripto->canExport()) {
return;
}
$doc = $scripto->getDocument($form_state['values']['node_id']);
// Export in HTML to preserve formatting.
$doc->export('html');
drupal_set_message('The transcriptions have been imported.');
}
/**
* Dumps a var directly to the browser. Used for debugging purposes only.
*/
function _scripto_debug($var, $exit = false) {
echo '<pre>' . print_r($var,true) . '</pre>';
if ($exit) exit;
}
/**
* Load the Scripto environment and return a Scripto object.
*/
function _scripto_get_scripto() {
set_include_path(get_include_path()
. PATH_SEPARATOR . variable_get('scripto_zend_framework_path')
. PATH_SEPARATOR . _scripto_get_scripto_path());
require_once 'Scripto.php';
require_once 'ScriptoAdapterDrupal.php';
$scripto = new Scripto(new ScriptoAdapterDrupal,
array('api_url' => variable_get('scripto_mediawiki_api_url')));
return $scripto;
}
/**
* Return the path to the directory containing the Scripto library.
*/
function _scripto_get_scripto_path() {
return realpath(drupal_get_path('module', 'scripto')) . '/lib';
}
/**
* Returns all the pages (files and images) of a node, in current order.
*/
function _scripto_get_pages($node) {
$pages = array();
$fields = field_read_fields(array('type' => array('file', 'image')));
foreach ($node as $key => $value) {
// Only process file and image fields.
if (!array_key_exists($key, $fields)) {
continue;
}
$items = field_get_items('node', $node, $key);
// Only process image and file fields that have items.
if (!$items) {
continue;
}
$pages = array_merge($pages, $items);
}
return $pages;
}
/**
* Returns an array of MIME types compatible with the Zoom.it image viewer.
*/
function _scripto_get_filemime_zoomit() {
return array(
// gif
'image/gif', 'image/x-xbitmap', 'image/gi_',
// jpg
'image/jpeg', 'image/jpg', 'image/jpe_', 'image/pjpeg',
'image/vnd.swiftview-jpeg',
// png
'image/png', 'application/png', 'application/x-png',
// bmp
'image/bmp', 'image/x-bmp', 'image/x-bitmap',
'image/x-xbitmap', 'image/x-win-bitmap',
'image/x-windows-bmp', 'image/ms-bmp', 'image/x-ms-bmp',
'application/bmp', 'application/x-bmp',
'application/x-win-bitmap',
// ico
'image/ico', 'image/x-icon', 'application/ico', 'application/x-ico',
'application/x-win-bitmap', 'image/x-win-bitmap',
// tiff
'image/tiff',
);
}
/**
* Returns an array of MIME types compatible with the Google Docs document
* viewer.
*/
function _scripto_get_filemime_googledocs() {
return array(
// pdf
'application/pdf', 'application/x-pdf',
'application/acrobat', 'applications/vnd.pdf', 'text/pdf',
'text/x-pdf',
// docx
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
// doc
'application/msword', 'application/doc', 'appl/text',
'application/vnd.msword', 'application/vnd.ms-word',
'application/winword', 'application/word', 'application/vnd.ms-office',
'application/x-msw6', 'application/x-msword',
// ppt
'application/vnd.ms-powerpoint', 'application/mspowerpoint',
'application/ms-powerpoint', 'application/mspowerpnt',
'application/vnd-mspowerpoint', 'application/powerpoint',
'application/x-powerpoint', 'application/x-m',
// pptx
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
// xls
'application/vnd.ms-excel', 'application/msexcel',
'application/x-msexcel', 'application/x-ms-excel',
'application/vnd.ms-excel', 'application/x-excel',
'application/x-dos_ms_excel', 'application/xls',
// xlsx
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
// tiff
'image/tiff',
// ps, ai
'application/postscript', 'application/ps',
'application/x-postscript', 'application/x-ps',
'text/postscript', 'application/x-postscript-not-eps',
// eps
'application/eps', 'application/x-eps', 'image/eps',
'image/x-eps',
// psd
'image/vnd.adobe.photoshop', 'image/photoshop',
'image/x-photoshop', 'image/psd', 'application/photoshop',
'application/psd', 'zz-application/zz-winassoc-psd',
// dxf
'application/dxf', 'application/x-autocad',
'application/x-dxf', 'drawing/x-dxf', 'image/vnd.dxf',
'image/x-autocad', 'image/x-dxf',
'zz-application/zz-winassoc-dxf',
// xvg
'image/svg+xml',
// xps
'application/vnd.ms-xpsdocument',
);
}