Index: file_import.batch.inc =================================================================== RCS file: file_import.batch.inc diff -N file_import.batch.inc 0a1,464 > > // TODO - permissions on admin screen > > // TODO - final screen shows results! and errors! > > // TODO - make it clear that the administrator of this module is > // capable of running any external command via the webserver user - > // THIS PERMISSION IS NOT TO BE GRANTED LOOSELY > > // TODO - provide option for files to be moved or copied to the > // Drupal folders tree? > > // TODO - provide ability to not move files around if they are > // already in Drupal files dir? default should be just to pull copy > // from files dir > > // TODO - provide regex method for selecting which files are > // handled, eg only import PDF on this run > > // TODO - trigger actions so that post-import things can be done, eg > // imagecache or op_video parse on imported file (would require > // being able to define what form the attachment took; media modules > // don't necess make file an attachment as per upload.module > > // no wait!! implement upload.module attachment as an action, then > // allow selection of this or other attachment forms > > // TODO - provide taxonomy selector to tag all imported files with > // (should validate that node type is able to be tagged with > // specified vocab, or maybe make multistep?) > > // TODO - validation - node type must support file attachment (or > // whatever other method is used) > > // TODO - settings for cmds to match import files (eg ps2ascii *pdf) > > // TODO - attachment is a hookable operation, and we select the > // hookable operation when in first form > > // TODO - customise node name (currently extracted from filename > // plain) > > define('FILE_IMPORT_CANNOT_WRITE_FILE',-1); > define('FILE_IMPORT_CANNOT_WRITE_DIR',-2); > define('FILE_IMPORT_FILE_OUTSIDE_SOURCE_DIR',-4); > > function file_import_batch_import_form() { > // specify the directory to scan from > $outpath = variable_get('file_import_output_path', file_directory_path()); > $inpath = variable_get('file_import_path', file_directory_path()); > > // select which node type to import as > foreach( node_get_types() as $name => $type ) { > $node_types['DOES_NOT_EXIST'] = '' ; > $node_types[$name] = $type->name ; > } > $form['type'] = array( > '#type' => 'select', > '#options' => $node_types, > /* '#default_value' => '' */ > '#description' => t('Select the type of node you would like each file to generate'), > '#title' => 'Node Type', > ) ; > > // if this file is *outside* file_directory_path() then we should > // see whether people want to cp or mv to that location. some use > // cases (eg ubercart feature download) suggest that the video is > // stored outside that path anyway > $form['inpath'] = array( > '#type' => 'textfield', > '#default_value' => $inpath, > '#title' => 'Import files from', > '#description' => 'The directory to import files from. This folder can be outside your Drupal tree.', > ) ; > > // optional, can be useful to clean up along the way tho, and avoid > // dupe imports > $form['outpath'] = array( > '#type' => 'textfield', > '#default_value' => $outpath, > '#title' => t('Move files to'), > '#description' => t('Files will be moved (or copied) to this folder once imported. This folder should be within the Drupal files path so the files are available for download'), > ) ; > > // optional, can be useful to clean up along the way tho, and avoid > // dupe imports > $args = array( > '!func_url' => l('file_scan_directory()', 'http://api.drupal.org/api/function/file_scan_directory/6'), > '!ereg_url' => l('ereg()', 'http://www.php.net/ereg'), > ); > > $form['mask'] = array( > '#type' => 'textfield', > '#size' => 20, > '#default_value' => '.*\..*', > '#title' => t('File mask'), > '#description' => t('Glob pattern to select files to import. Will be passed to !func_url, regex as handled by !ereg_url',$args), > ) ; > > // ignored currently > $recurse_opts = array( 'recurse' => t('Scan child directories also') ) ; > $form['recurse'] = array( > '#type' => 'checkboxes', > '#options' => $recurse_opts, > /* '#label' => 'Include child directories', */ > ) ; > > $form['submit'] = array( > '#type' => 'submit', > '#value' => 'Confirm Import', > ) ; > > return $form ; > } > > function file_import_batch_import_form_submit( $form_id, &$form_state ) { > $node_type = $form_state['values']['type'] ; > $source_dir = $form_state['values']['inpath'] ; > $dest_dir = $form_state['values']['outpath'] ; > $recurse = $form_state['values']['type'] ; > $mask = $form_state['values']['mask'] ; > > $options = array( > 'node_type' => $node_type, > 'source_dir' => $source_dir, > 'dest_dir' => $dest_dir, > 'recurse' => $recurse, > 'mask' => $mask, > ) ; > > // if we are unable to handle a file, we need to move on to the next > // one. therefore we build a list first, then iterate thru the list > $file_list = file_scan_directory( $source_dir, $mask ) ; > $options['files'] = $file_list ; > if ( !empty( $file_list ) ) { > foreach( $file_list as $file ) { > $operations[] = array('file_import_batch_import_batch_process', array($file,$options)) ; > } > > $batch = array( > 'operations' => $operations, > 'finished' => 'file_import_batch_import_finished', > 'title' => t('Importing Files'), > 'progress_message' => t('Imported @current of @total.'), > 'error_message' => t('The import process encountered an error.'), > 'init_message' => t('Preparing'), > 'file' => drupal_get_path( 'module','file_import' ).'/file_import.batch.inc', > ) ; > > batch_set( $batch ) ; > } > else { > // will have been caught by validate function anyway > drupal_set_message(t('No files found in %dir to import', array('%dir'=>$source_dir))); > } > } > > function file_import_batch_import_form_validate($form_id, &$form_state) { > $source_dir = $form_state['values']['inpath'] ; > $mask = $form_state['values']['mask'] ; > $args = array( > '%dir' => $source_dir, > '%mask' => $mask, > ) ; > // could also check that the mask is valid? > if ( !is_dir( $source_dir ) ) { > form_set_error('source_dir', t('The directory specified, %dir, does not exist.', $args)); > } > else { > $file_list = file_scan_directory( $source_dir, $mask ) ; > if ( empty($file_list) ) { > form_set_error('', t('No files were found in directory %dir matching the mask %mask', $args)) ; > } > } > } > > function file_import_batch_import_batch_process( $file, $options, &$context ) { > $args = array( > '!file' => $file->basename, > '!dir' => dirname($file->filename), > ) ; > global $user ; > $node = new stdClass ; > $node->title = $file->name ; > $node->type = $options['node_type'] ; > $node->uid = $user->uid ; > foreach ( variable_get('file_import_batch_patterns', file_import_batch_default_exts()) as $mask => $cmd ) { > if ( ereg($mask, $file->basename) ) { > // is this compatible with windows, using $retvar? > $args['!details'] = t('Using cmd !cmd to extract content', array('!cmd'=>$cmd)); > $extract_cmd = escapeshellcmd($cmd . ' "'.$file->filename.'"') ; > exec($extract_cmd, $output, $retvar) ; > $body = implode("\n", $output); > error_log( print_r(array( $retvar, $body ),1) ) ; > if ( $body != '' ) { > $node->body = $body ; > } > } else { > $args['!details'] = t('No command match for this filename, so unable to extract body.') ; > } > } > node_save($node) ; > // attach file > $fi_args = array( > 'source_file' => $args['!file'], > 'source_dir' => $args['!dir'], // from source file, not $options, > // b/c we may have recursed into > // child dir > 'dest_dir' => $options['dest_dir'], > 'dest_file' => $args['!file'], // from source file > ) ; > file_import_attach_file_to_node($fi_args, $node); > $context['message'] = t('Now importing from !dir, file !file. !details', $args) ; > $context['finished'] = 1 ; > $context['results'][] = $filename ; > } > > > > /** > * run the file_import hook, returns specified things > * > * @param $hook_name is the name of the hook to call, eg "file_import_import_file" > * @param $op is the action that a module should run > * @param $data is signit data > * @param $config is configuration data > * @return an array of data > * > */ > // function file_import_extend($hook_name, $op = null, $data = null, $config = null) { > // $items = array(); > // foreach (module_implements($hook_name) as $module) { > // if ($new = module_invoke($module, $hook_name, $op, $data, $config)) { > // $items = array_merge($items, $new); > // } > // } > // // make sure we return an array > // if (! is_array($items)) { return array(); } > // return $items; > // } > > // function upload_file_import($op, $data, $config = NULL) { > // // attach a file to a nodex > // } > > function file_import_batch_admin_settings() { > drupal_add_css(drupal_get_path( 'module','file_import' ).'/file_import_batch.css'); > $patterns = variable_get('file_import_batch_patterns', file_import_batch_default_exts()) ; > $n = sizeof($patterns); > $i = 0 ; > $args = array( > '!ereg_url' => l('ereg()', 'http://www.php.net/ereg'), > ); > > $form['patterns'] = array( > '#type' => 'fieldset', > '#title' => t('File import commands'), > '#description' => t('Enter an !ereg_url pattern to match filenames, and a suitable system command which can be used to extract the node body from imported files.', $args), > ) ; > > $examples = " > .*\.pdf /usr/bin/ps2ascii > .*\.doc /usr/bin/docvert (or /usr/bin/antiword) > .*\.txt /usr/bin/cat > " ; > $form['patterns']['help1'] = array( > '#value' => t('Examples:
!examples', array('!examples'=>$examples)), > ) ; > $form['patterns']['help2'] = array( > '#value' => t('A new blank field will be available to add more patterns on submission.'), > ) ; > > > /* seems we don't need to provide this form field; > * system_settings_form() will store anything in > * $form_state['values'] later. */ > // $form['patterns']['file_import_batch_patterns'] = array( > // '#type' => 'hidden', > // ) ; > > foreach( $patterns as $mask => $cmd ) { > $form['patterns']['mask_'.$i] = array( > '#type' => 'textfield', > '#size' => '12', > '#title' => t('Mask'), > '#default_value' => $mask, > '#prefix' => '