Created a file named descript.ion. Added a line with filename and description (seperated with a space with cr-lf atthe end) but nothing is showing up on the page display. Can you explain how it works and also what happen with subdirs?

CommentFileSizeAuthor
#14 filebrowser.module.txt18.96 KBclauded
#12 capture.jpeg23.06 KBclauded
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

clauded’s picture

Ok, after reading and understanding the code, I found that ":" is used to seperate filename from description so a description file might look like this :

filename1.ext: Description of filename1
filename2.ext: Description of filename2
dir1: Description of directory1

I also found a couple of bugs in the code so here's a revised version of filebowser.module with those bugs corrected and where the description is part of the table display so we have "filename-file size-file description", a more natural way of displaying content. May I suggest to make this part of the module :

<?php
// $Id: filebrowser.module,v 1.9.2.8.2.19 2008/07/04 06:39:12 susurrus Exp $

function filebrowser_form(&$node, &$param) {
  $type = node_get_types('type', $node);
  
  $form['title'] = array(
    '#type' => 'textfield',
    '#title' => t('Title'),
    '#default_value' => !empty($node->title) ? $node->title : '',
    '#required' => TRUE,
    '#weight' => -6
  );
  
  $form['file_path'] = array(
    '#type' => 'textfield',
    '#title' => t('The system file path to the directory'),
    '#description' => t('This can be an absolute path or should be relative to the Drupal root directory.'),
    '#default_value' => isset($node->file_path) ? check_plain($node->file_path) : '',
    '#required' => TRUE,
    '#weight' => -5
  );
  $form['explore_subdirs'] = array(
    '#type' => 'checkbox',
    '#title' => t('Allow subdirectory listings.'),
    '#default_value' => isset($node->explore_subdirs) ? $node->explore_subdirs : '',
    '#weight' => -4
  );
  $form['file_blacklist'] = array(
    '#type' => 'textfield',
    '#title' => t('A blacklist of all files that shouldn\'t be accessible by users'),
    '#description' => t('List files separated by commas. Use <em>.*</em> to signify all files starting with a period.'),
    '#default_value' => isset($node->file_blacklist) ? $node->file_blacklist : '.*, descript.ion, file.bbs, CVS',
    '#weight' => -3
  );
  $form['private_downloads'] = array(
    '#type' => 'checkbox',
    '#title' => t("Enable private downloads"),
    '#description' => t("Some files won't download unless this private downloads are enabled (PHP files for instance)."),
    '#default_value' => isset($node->private_downloads) ? $node->private_downloads : '',
    '#weight' => -3
  );
  
  return $form;
}

function filebrowser_node_info() {
  return array(
    'dir_listing' => array(
      'name' => t('Directory listing'),
      'module' => 'filebrowser',
      'description' => t("A listing of files similar to how Apache lists files in a directory."),
      'title_label' => 'hey',
      'has_body' => FALSE
    )
  );
}

function filebrowser_load($node) {
  $additions = db_fetch_object(db_query('SELECT file_path, explore_subdirs, file_blacklist, private_downloads FROM {filebrowser} WHERE nid = %d', $node->nid));
  return $additions;
}

function filebrowser_insert($node) {
  db_query("INSERT INTO {filebrowser} (nid, file_path, explore_subdirs, file_blacklist, private_downloads) VALUES (%d, '%s', %d, '%s', %d)", $node->nid, $node->file_path, $node->explore_subdirs, $node->file_blacklist, $node->private_downloads);
}

function filebrowser_update($node) {
  db_query("UPDATE {filebrowser} SET file_path = '%s', explore_subdirs = %d, file_blacklist = '%s', private_downloads = %d WHERE nid = %d", $node->file_path, $node->explore_subdirs, $node->file_blacklist, $node->private_downloads, $node->nid);
}

function filebrowser_delete($node) {
  // Notice that we're matching all revisions, by using the node's nid.
  db_query('DELETE FROM {filebrowser} WHERE nid = %d', $node->nid);
}

/**
 * Validate the node form submission. Just check if the file path specified is 
 * accessible and readable.
 *
 * @param Drupal node object $node
 */
function filebrowser_validate(&$node) {
  // Verify the file system location
  // Check that it's a directory
  if (!is_dir($node->file_path)) {
    form_set_error('file_path', t('You must specify a valid directory.'));
  }
  // Check that it's readable
  if (!is_readable($node->file_path)) {
    form_set_error('file_path', t('The directory %dir is not readable.', array('%dir' => $node->file_path)));
  }
}

function filebrowser_access($op, $node, $account) {
  if ($op == 'view') {
    return user_access('view directory listings', $account);
  }
  else if ($op == 'create') {
    return user_access('create directory listings', $account);
  }
  else if ($op == 'update') {
    if (user_access('edit any directory listings', $account) || (user_access('edit own directory listings', $account) && ($account->uid == $node->uid))) {
      return TRUE;
    }
  }
  else if ($op == 'delete') {
    if (user_access('delete any directory listings', $account) || (user_access('delete own directory listings', $account) && ($account->uid == $node->uid))) {
      return TRUE;
    }
  }
  
  return FALSE;
}

function filebrowser_perm() {
  return array(
    'create directory listings',
    'delete own directory listings',
    'delete any directory listings',
    'edit own directory listings',
    'edit any directory listings',
    'view directory listings'
  );
}

/**
 * Implementation of hook_db_rewrite_sql().
 * 
 * Prevents node listings from listing directory nodes if the user doesn't have
 * permission.
 */
function filebrowser_db_rewrite_sql($query, $primary_table, $primary_field, $args) {
  global $user;
  if ($primary_table == 'n' && $primary_field == 'nid' && !user_access('view directory listings', $user)) {
      $return = array(
        'where' => 'n.type != "dir_listing"'
      );
      return $return;
  }
}

function _filebrowser_dir_stats($dir) {
  $file_count = 0;
  $total_size = 0;
  if (is_dir($dir) && $dh = opendir($dir)) {
    while (($file = readdir($dh)) !== false && is_readable($dir . '/' . $file)) {
      // Exclude fake directories
      if ($file == '.' || $file == '..') {
        continue;
      }
      $full_path = $dir . '/' . $file;
      $f_size = filesize($full_path);
      $total_size += $f_size;
      ++$file_count;
    }
    closedir($dh);
  }
  
  return array('file_count' => $file_count, 'total_size' => $total_size);
}

/**
 * Implementation of hook_theme.
 *
 * @return An array of theming functions.
 */
function filebrowser_theme() {
  return array(
    'filebrowser_dir_listing' => array(
      'arguments' => array('files' => array(), 'folders' => array(), 'curr_dir' => '', 'total_size' => 0)
    ),
    'filebrowser_page_title' => array(
      'arguments' => array('node' => NULL)
    )
  );
}

/**
 * Implementation of hook_init.
 * 
 * Needed to override standard node output. Checks if path refers to a file
 * in a dir_listing and outputs it if it is.
 *
 */
function filebrowser_init() {
  $path_parts = explode('/', $_GET['q']);
  // count() checks that $path_parts[1] will succeed.
  if (count($path_parts) >= 2 && $path_parts[0] == 'node') {
    $node = node_load($path_parts[1]);
    if ($node->type == 'dir_listing' && $node->private_downloads) {
      // We just check the rest of the path to verify that it points to a file.
      array_shift($path_parts);
      array_shift($path_parts);
      $file = $node->file_path . '/' . implode('/', $path_parts);
      if (is_file($file) && is_readable($file)) {
        // Transfer file in 1024 byte chunks to save memory usage.
        if ($fd = @fopen($file, 'rb')) {
          while (!feof($fd)) {
            echo fread($fd, 1024);
          }
          fclose($fd);
          exit;
        }
        else {
        	drupal_set_message('File could not be opened.', 'error');
        }
      }
    }
  }
}

function filebrowser_view($node, $teaser = FALSE, $page = FALSE) {
  global $user, $base_url;

  $node = node_prepare($node, $teaser);

  // Grab various Drupal paths
  $path_alias = drupal_get_path_alias('node/' . $node->nid);
  // Handle both aliased and non-aliased cases
  $subdir = str_replace($path_alias, '', $_GET['q']);
  $subdir = str_replace('node/' . $node->nid, '', $_GET['q']); 
  $curr_dir = $node->file_path . $subdir;
  
  // Keep track of the current location and update breadcrumbs to reflect that
  if ($page) {
    $breadcrumbs = array(
      l(t('Home'), NULL), 
      l($node->file_path, $path_alias)
    );
    foreach (explode('/', $subdir) as $child_dir) {
      if (!empty($child_dir)) {
        $path_alias .= '/' . $child_dir;
        $breadcrumbs[] = l($child_dir, $path_alias);
      }
    }
    drupal_set_breadcrumb($breadcrumbs);
    
    drupal_set_title(theme('filebrowser_page_title', $node));
  }
  
  // Are we in a subdirectory?
  $is_subdir = !empty($subdir);

  // If we shouldn't be in a subdirectory, redirect to root_dir
  $has_access = TRUE;
  if ($is_subdir && !$node->explore_subdirs){
    $has_access = FALSE;
  }
  
  // More advanced check to make sure no parent directories match our files
  // blacklist
  if (!empty($subdir) && $has_access) {
    $dirs = explode('/', $subdir);
    foreach ($dirs as $dir) {
      if (!empty($dir)) {
        if (strpos($node->file_blacklist, $dir) !== FALSE ||
            ($dir[0] == '.' && strpos($node->file_blacklist, '.*') !== FALSE)) {
          $has_access = FALSE;
          break;
        }
      }
    }
  }
  
  if (!$has_access) {
    drupal_set_message(t('You\'re not allowed to view %dir.', array('%dir' => $curr_dir)), 'error');
    drupal_goto(drupal_get_path_alias('node/' . $node->nid));
  }
  
  // Store the descript.ion or file.bbs file for grabbing meta data from 
  $file_metadata = array();
  $files = array();
  $folders = array();
  $total_size = 0;
  if (is_dir($curr_dir) && $dh = opendir($curr_dir)) {
    while (($file = readdir($dh)) !== false && is_readable($curr_dir . '/' . $file)) {
      $full_path = $curr_dir . '/' . $file;

      // Check for meta files if we need info
      if (empty($file_metadata) && in_array($file, array('descript.ion', 'file.bbs'))) {
        $file_metadata = filebrowser_get_fileinfo($full_path, $curr_dir);
      }
         
      if (is_file($full_path)) {      
        // Handle files that should not be shown
        if (strpos($node->file_blacklist, $file) !== FALSE ||
            ($file[0] == '.' && strpos($node->file_blacklist, '.*') !== FALSE)) {
          continue;
        }

        $files[$file] = array(
          'name' => $file,
          'path' => $full_path,
          'url' => $node->private_downloads == '1'?url($_GET['q'] . '/' . $file):$base_url . '/' . $full_path,
          'status' => MARK_READ,
          'size' => 0
        );
        
        if (($f_stats = stat($full_path)) !== false) {
          $total_size += $f_stats['size'];
          
          // Update file size if we found it.
          $files[$file]['size'] = $f_stats['size'];
          
          // Mark this file new or updated
          if ($user->uid) {
            if ($user->access < $f_stats['ctime']) {
              $files[$file]['status'] = MARK_NEW;
            }
            else if ($user->access < $f_stats['mtime']) {
              $files[$file]['status'] = MARK_UPDATED;
            }
          }
        }
      }
      // Keep a separate list of directories to append to beginning of array
      else if ($node->explore_subdirs && is_dir($full_path)) {
        // Always remove '.' and only allow '..' in subdirectories.
        if ($file == '.' || (!$is_subdir && $file == '..')) {
          continue;
        }
        // Handle files that should not be shown. Make sure that '..' can be 
        // shown even if '.*' is on the blacklist.
        else if (strpos($node->file_blacklist, $file) !== FALSE ||
                 ($file[0] == '.' && $file[1] != '.' && strpos($node->file_blacklist, '.*') !== FALSE)) {
          continue;
        }
        
        $folders[$file] = array(
          'name' => $file,
          'path' => $full_path,
          'url' => $_GET['q'] . '/' . $file,
          'status' => MARK_READ,
          'size' => 0
        );
      
        // Try to mark a folder as new/updated
        if ($user->uid && ($f_stats = stat($full_path)) !== false) {
          if ($user->access < $f_stats['ctime']) {
            $folders[$file]['status'] = MARK_NEW;
          }
          else if ($user->access < $f_stats['mtime']) {
            $folders[$file]['status'] = MARK_UPDATED;
          }
        }
      }
    }
    closedir($dh);
  }
  
  // Add in metadata from description files
  if (!empty($file_metadata)) {
    // For files
    foreach ($files as $filename => $row) {
      if (isset($file_metadata[$filename])) {
        $files[$filename]['description'] = $file_metadata[$filename][0];
      }
    }
    // For directories
    if ($node->explore_subdirs) {
      foreach ($folders as $dir_name => $data) {
        if (isset($file_metadata[$dir_name])) {
          $folders[$dir_name]['description'] = $file_metadata[$dir_name][0];
        }
      }
    }
  }

  // Display metadata for the current directory at the top of the page
  //if (isset($file_metadata['.'])) {
  //  $node->content['filebrowser-help'] = array(
  //    '#value' => '<p>' . $file_metadata['.'][0] . '</p>',
  //    '#weight' => 0
  //  );
  //}

  $node->content['filebrowser'] = array(
    '#value' => theme('filebrowser_dir_listing', $files, $folders, $curr_dir, $total_size),
    '#weight' => 1,
  );
  
  return $node;
}

/**
 * Loads file metainformation from the specified file. Also
 * allows the file to specify a *callback* with which the
 * descriptions are parsed, so more metainformation can be
 * presented on the output.
 */
function filebrowser_get_fileinfo($info_file_path = NULL, $subfolder = '') {
  static $metacols = array();

  // Return (previously generated) meta column list
  if (!isset($info_file_path)) {
    return $metacols;
  }
  
  // Build meta information list
  $metainfo = array();
  if (is_readable($info_file_path) && ($file = file($info_file_path))) {
    foreach ($file as $line) {
      // Skip empty and commented lines 
      if (trim($line) == '' || strpos(trim($line), '#') === 0) {
        continue;
      }
      
      // Use PCRE regular expressions to parse file
      $matches = array();
      preg_match('/(\S+)\s*:\s*(.*)/', $line, $matches);
      list(, $name, $description) = $matches;

      unset($matches);

      if (isset($metainfo[$name])) {
        $metainfo[$name] .= ' ' . trim($description);
      }
      else {
        $metainfo[$name] = trim($description);
      }
    }
    
    $callback = FALSE;
    if (isset($metainfo['*callback*']) && function_exists(trim($metainfo['*callback*']))) {
      $callback = trim($metainfo['*callback*']);
      unset($metainfo['*callback*']);
    }
    
    foreach ($metainfo as $name => $description) {
      $metainfo[$name] = ($callback ? $callback($description, $subfolder, $name) : array($description));
    }
    $metacols = ($callback ? $callback() : array(t('Description')));
  }
  return $metainfo;
}

/**
 * Returns the appropriate HTML code for an icon representing
 * a file, based on the extension of the file. A specific icon
 * can also be requested with the second parameter.
 */
function filebrowser_get_fileicon($fullpath = NULL, $iconname = NULL) {
  // Determine the type of file found
  if (isset($fullpath)) {
    $iconname = (is_dir($fullpath) ? 'folder' : preg_replace("!^.+\\.([^\\.]+)$!", "\\1", $fullpath));
  }
  else if (!isset($iconname)) {
    $iconname = 'default';
  }
  
  // Check to make sure the icon we want exists
  $icon_path = drupal_get_path('module', 'filebrowser') . "/icons/file-$iconname.png";
  if (!file_exists($icon_path)) {
    $iconname = 'default';
  }
  return theme('image', $icon_path);
}

/**
 * Theme a directory listing of files in a system directory.
 *
 * @param array $files An array of data of files in this directory.
 * @param array $folders An array of data of folders in this directory.
 * @param string $curr_dir The current directory path we're in.
 * @param integer $total_size The total size in bytes of data in this folder.
 * @return A string containing real page HTML.
 */
function theme_filebrowser_dir_listing(&$files, &$folders, $curr_dir, $total_size = 0) {
  $output = '';
  if (!empty($files) || !empty($folders)) {
    // CSS can hook on this ID to style table elements differently
    $header = array('', array('data' => t('Name'), 'field' => 'name', 'sort' => 'asc'), array('data' => t('Size'), 'field' => 'size'), array('data' => t('Description'), 'field' => 'description'));

    // Deal with files
    $table_rows_unsorted = array();
    foreach ($files as $filename => $data) {
      $table_rows_unsorted[$filename] = array(
        array('data' => filebrowser_get_fileicon($data['path']), 'style' => 'width:1%;'),
        '<a href="' . $data['url'] . '">' . $filename . '</a>' . theme('mark', $data['status']),
        format_size($data['size']), $data['description']
      );
    }
    
    // Deal with folders
    foreach ($folders as $foldername => $data) {
      $table_rows_unsorted[$foldername] = array(
        array('data' => filebrowser_get_fileicon($data['path']), 'style' => 'width:1%;'),
        l($foldername, $data['url']) . theme('mark', $data['status']),
        ' ', $data['description']
      );
    }
    
    // Handle any and all sorting
    $ts = tablesort_init($header);
    // Sort things by name or size in ascending order
    // Grab some keys to sort
    $files_order = array_values($files);
    $folders_order = array_values($folders);
    
    // Sort files according to correct column
    usort($folders_order, "filebrowser_{$ts['sql']}_sort");
    usort($files_order, "filebrowser_{$ts['sql']}_sort");
    $final_order = array_merge($folders_order, $files_order);
    
    // Combine folders and files array and setup correct order
    $rows = array();
    foreach ($final_order as $index => $file_info) {
      $rows[] = $table_rows_unsorted[$file_info['name']];
    }
    
    if ($ts['sort'] == 'desc') {
      $rows = array_reverse($rows, TRUE);
    }
    
    // Concatenate them all together
    $output .= '<p>' . t('Displaying %dir.', array('%dir' => $curr_dir)) . '</p>';
    $output .= theme('table', $header, $rows, array('id' => 'filebrowser-file-listing'));
    $output .= '<p>' . t('Contains @fc totaling @ds in size.', array('@fc' => format_plural(count($files), '1 file', '@count files'), '@ds' => format_size($total_size))) . '</p>';
    
  }
  else {
    $output .= '<p>' . t('This directory is empty.') . '</p>';
  }

  return $output;
}

function theme_filebrowser_page_title($node) {
  return !empty($node->title)?$node->title:'';
}

function filebrowser_size_sort($a, $b) {
  if ($a['size'] == $b['size']) {
    return 0;
  }
  return ($a['size'] > $b['size']) ? -1 : 1;
}

function filebrowser_name_sort($a, $b) {
  return strcmp($a['name'], $b['name']);
}

3 other suggestions :

1. descript.ion syntax should be documented
2. the location of the file icons (and the syntax for file names) should be documented (create a subdir named icons in the module directory)
3. a set of standard icons could be included with the module (look at http://drupal.org/files/issues/mimetypes-01.zip.txt)

Anonymous’s picture

Good work, thanks Claude! It's a significant improvement of the module since a long time.

Now we still have the problem with the MIME type recognition (#268181: Cron vs. Subdirectory displaying) and your suggestion (#289127: Few suggestions - 'hey'). And there is a problem with the encoding of the file description.

It would be very good to have the metadata for the current directory at the top of the page. ;-)

clauded’s picture

Not sure I can help with the mime bug.

The hey field display is corrected in the code submitted so I don't think it's an issue anymore.

Can you be more specific about the encoding issue?

Now for the metadata at the top of the page, I never been able to have it working here (maybe another bug). Perhaps we could turn this into an option : display metainfo at the top or inline so everybody would be happy.

Anonymous’s picture

Not sure I can help with the mime bug.

With this bug the module isn't usable, imho.

The hey field display is corrected in the code submitted so I don't think it's an issue anymore.

Okay, but I've found another 'hey' in the code. :-)

Can you be more specific about the encoding issue?

I use German umlauts ä, ö, and ü in the file description. I have to use &#xxx; to display the umlauts. The rest of the site is encoded properly (UTF-8).

Now for the metadata at the top of the page, I never been able to have it working here (maybe another bug). Perhaps we could turn this into an option : display metainfo at the top or inline so everybody would be happy.

The metadata as an additional input field in the node (in a seperate database field)? That's one solution and good for users without FTP access (who cannot upload the descript.ion file).

clauded’s picture

For the mime bug, if it can't be solved then the module could still be usefull for public downloads (with a mention in the documentation). At least for the first release of the final version...

The "hey" in filebrowser_node_info()? If so it can be replaced with 'title_label' => t('Title'),.

On my machine (OpenSuse), I can put foreign caracters in the desciption file and they are displayed ok (even German umlauts). Do you edit the file on linux or Windows?

For the metadata, I meant another option in the configuration :

  $form['display_description_inline'] = array(
    '#type' => 'checkbox',
    '#title' => t('Display descript.ion file inline with directory listing (default : display above).'),
    '#default_value' => isset($node->display_description_inline) ? $node->display_description_inline : '',
    '#weight' => -2
  );

And a couple of if statements to produce the right display :

  // Display metadata for the current directory at the top of the page if display descript.ion inline is not selected
  if (isset($file_metadata['.']) && !($node->display_description_inline)) {
    $node->content['filebrowser'] = array(
      '#value' => '<p>' . $file_metadata['.'][0] . '</p>',
      '#weight' => 0
    );
  }
...
Plus some if statements in theme_filebrowser_dir_listing...

Now your idea of using a db field to store the description is good but I prefer to have description with files. Anyway, if some one stores a new file, it has an ftp access on some kind so he can also update the descript.ion file. On the other hand, this could maybe solve the encoding problem...

Anonymous’s picture

Do you edit the file on linux or Windows?

Sorry, my fault! I forgot to convert the file to UTF-8. :-/

but I prefer to have description with files

Me too. It's like htaccess. In my pre-Drupal time I have had a download directory with the file descriptions in the htaccess file.

MIME bug:
Because I use only the private download the MIME bug is a big problem for me. It's unprofessional if users have to rename the file during or after the download.

clauded’s picture

Thomas,

If I understand well, the MIME bug occurs when cron is run and probably when it scan a directory listing page with private files. Not knowing the MIME type of the files, it just hangs there, correct? If this is the case, is it because the file was pushed with something like a ftp program instead of using the upload mechanism in Drupal and Drupal doesn't know about the file?

Anonymous’s picture

If I understand well, the MIME bug occurs when cron is run

No, the cron issue is fixed. I should change the subject of the issue to "Private download vs. MIME type recognition".

With private download the MIME bug is always existing.

Drupal doesn't know about the file?

This can be the reason for it that private download do not work with the filebrowser module. It is a bad solution to attach all files to the dir_listing node.

clauded’s picture

May I suggest to start a new thread on this one and explain what is not working (are files displayed or not, can they be downloaded, ...).

Susurrus’s picture

Status: Active » Needs review

It would be much nicer if discussion of unrelated topics were discussed in separate issues so we can keep things orderly.

Regarding this issue, what bugs did you find in the code?

Susurrus’s picture

Status: Needs review » Needs work

So there're about 30 different comments and suggestions in this issue, but very few have to do with the topic. Documentation does have to be improved and I've created a task for it, but this isn't the issue to comment on everything that's with this module. The way to deal with this is to create a new issue for each problem or suggestion. It takes all of 3 minutes to do and it makes things a lot easier.

Since there's no patch and I've changed the code so much from the base you were working with, I can't test your code easily clauded. Posting a screenshot would help. Depending on how this looks, I may "won't fix" this.

clauded’s picture

FileSize
23.06 KB

What I propose is to display the description as part of the table display (instead of displaying at the top of the table) so we have "filename-file size-file description", a more natural way of displaying content. If you agree to make this part of the module, I can use RC5 as a base and post it here.

See the screenshot attached.

Susurrus’s picture

I think this would be reasonable. I'd only be worried about how the text will wrap when the description is too long. If you roll a patch, I'll commit it.

clauded’s picture

FileSize
18.96 KB

Here's the revised version of the module based on RC5. Please note the following changes :

- description is displayed as part of the table (description column will appear even if no descript.ion file present)
- corrected a bug that prevented directories description to be listed
- nb of files and total file size has been moved after directory listing so it looks more consistent with usual file browsers

Long description will wrap into the column max. width within page display.

Susurrus’s picture

Title: Help with descript.ion » Display descript.ion text in file listing table
Version: 6.x-2.0-rc4 » 6.x-2.x-dev
Category: support » feature
Status: Needs work » Needs review

I'm still against the details of a directory being displayed at the end. Excluding that change, I'll review this and commit it if it works.

dman’s picture

Just a note, AFAIK, descript.ion file should not be delimited by ":"
The format, as I've encountered in several applications over the years (ACDSee, Newsgrabber, maybe others) is whitespace-delimited, with the filename quoted if needed. If you know of other conflicting examples, I'd be interested.
The regex where can be adjusted to allow : OR spaces, to maintain a semblance of compatability, but if it's to be used, it should at least be portable with other loosely-defined examples already in the wild.
I've been using a similar approach as an enhancement to image_import

Susurrus’s picture

I'm a new maintainer to this project and created the 6.x branch from scratch adding features back in from 5.x that were needed. I didn't know about the descript.ion format, but found a reference to it here: http://www.leeholmes.com/blog/AddFileDescriptionsToYourDirectoryListings....

Looks like the following will work for space-separated descript.ion files. I see no point in supporting colon-delimited files as it's a trivial fix to do at a command line and backwards compatibility must end at a point. The 6.x-2.x isn't afraid to do that.

$descriptionRegex = "`"(?<file>[^`"]*)`" (?<text>.*)|(?<file>[^ ]*) (?<text>.*)"

Also, everyone likes to clutter up issues with other issues. It's damn annoying....stop. Make a new issue for things like this instead of turning an old one down a sidepath. I appreciate you wanting to contribute, I really do. But contributing in this way doesn't really make things easier, just more difficult.

Anonymous’s picture

Just a note, AFAIK, descript.ion file should not be delimited by ":"

In some non-UNIX systems : isn't allowed in file names. In the descript.ion file : should be used neither in file names nor in descriptions. I prefer : instead of space.

dman’s picture

Sorry if you thought that was off-topic, I was responding to the Original Post, Post #1, and the issue which started this thread.
I see the topic has drifted a little bit since then, but I only noticed it in the tracker now, so thought it was trivial to point out.

descript.ion is a pre-existing format that I've encountered in several contexts, not something to be made up from scratch. I'd rather it stuck to the simple format it is rather than be turned into something else. That reference linked above seems to match my expectation of the syntax...
It seems simple enough to support at the stage this module is now, so lets just see if we can be liberal in what we accept ;-)

Sorry my if addressing the original topic was annoying...

Susurrus’s picture

Since a space is the common delimiter and there are enough deviations from "standards" to make any web developer scream, I think that's what the new delimiter will be.

So #14 is still the code to test.

Anonymous’s picture

What I propose is to display the description as part of the table display (instead of displaying at the top of the table)

That's okay and it works with the latest version of filebrowser.module but we should have a description for the current folder above the table. This text should be in the descript.ion file.

Susurrus’s picture

Status: Needs review » Needs work

Definitely the description should be above the table. CNW for the changes suggest in #15, #20, and #21.

Anonymous’s picture

Title

A space as delimiter is okay. :-)

With the directory description I mean a short text about the content of the current directory (general description) as an addition to the file descriptions in the table.

Because of the files summary I'm with Claude. I've moved the number of files and the size at the bottom of the page. ;-)

Directory description (multi-line)

Table
Icon - Name - Size - Description
...

# of files | Size
Susurrus’s picture

Since everyone seems to be commenting in this issue, has anyone had problems with rc5 so far with respect to Cron or subdirectories displaying, private downloads, clean URLs? I've tested it, but between rc3 and rc4 a lot of issues popped up and I thought I addressed them all. I didn't mean for the number of RCs for this release to get so out of control...

Also, Fine! I'll move the files/size description to the bottom since everyone seems intent on complaining :-).

Don't forget to check out #298385: Add PDF file icon as I plan to incorporate that into the next RC too.

Susurrus’s picture

Status: Needs work » Fixed

Done.

clauded’s picture

In the latest dev build (v 1.9.2.8.2.33 2008/08/24 17:15:04), no description is displayed. Is this on purpose ?

clauded’s picture

Sorry for the previous post : I edited my descript.ion files to remove the ":" so now it works :-)

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.