Aleksander Machniak
2013-06-15 1dcd9406bdbfe356bbf744be1714646bb941cd89
Merge branch 'master' of github.com:roundcube/roundcubemail
1 files added
7 files modified
182 ■■■■■ changed files
program/js/app.js 19 ●●●●● patch | view | raw | blame | history
program/lib/Roundcube/html.php 4 ●●●● patch | view | raw | blame | history
program/localization/en_US/labels.inc 1 ●●●● patch | view | raw | blame | history
program/localization/en_US/messages.inc 2 ●●●●● patch | view | raw | blame | history
program/steps/mail/func.inc 39 ●●●●● patch | view | raw | blame | history
program/steps/mail/import.inc 105 ●●●●● patch | view | raw | blame | history
skins/larry/templates/mail.html 11 ●●●●● patch | view | raw | blame | history
skins/larry/ui.js 1 ●●●● patch | view | raw | blame | history
program/js/app.js
@@ -191,7 +191,7 @@
      case 'mail':
        // enable mail commands
        this.enable_command('list', 'checkmail', 'add-contact', 'search', 'reset-search', 'collapse-folder', true);
        this.enable_command('list', 'checkmail', 'add-contact', 'search', 'reset-search', 'collapse-folder', 'import-messages', true);
        if (this.gui_objects.messagelist) {
          this.message_list = new rcube_list_widget(this.gui_objects.messagelist, {
@@ -277,11 +277,12 @@
          this.init_messageform();
        }
        // show printing dialog
        else if (this.env.action == 'print' && this.env.uid)
        else if (this.env.action == 'print' && this.env.uid) {
          if (bw.safari)
            setTimeout('window.print()', 10);
          else
            window.print();
        }
        // get unread count for each mailbox
        if (this.gui_objects.mailboxlist) {
@@ -1000,7 +1001,7 @@
        // Reset the auto-save timer
        clearTimeout(this.save_timer);
        this.upload_file(props || this.gui_objects.uploadform);
        this.upload_file(props || this.gui_objects.uploadform, 'upload');
        break;
      case 'insert-sig':
@@ -1099,6 +1100,12 @@
      case 'listgroup':
        this.reset_qsearch();
        this.list_contacts(props.source, props.id);
        break;
      case 'import-messages':
        var form = props || this.gui_objects.importform;
        $('input[name="_unlock"]', form).val(this.set_busy(true, 'importwait'));
        this.upload_file(form, 'import');
        break;
      case 'import':
@@ -3492,8 +3499,8 @@
    return true;
  };
  // upload attachment file
  this.upload_file = function(form)
  // upload (attachment) file
  this.upload_file = function(form, action)
  {
    if (!form)
      return false;
@@ -3520,7 +3527,7 @@
        return;
      }
      var frame_name = this.async_upload_form(form, 'upload', function(e) {
      var frame_name = this.async_upload_form(form, action || 'upload', function(e) {
        var d, content = '';
        try {
          if (this.contentDocument) {
program/lib/Roundcube/html.php
@@ -360,8 +360,8 @@
    protected $allowed = array(
        'type','name','value','size','tabindex','autocapitalize',
        'autocomplete','checked','onchange','onclick','disabled','readonly',
        'spellcheck','results','maxlength','src','multiple','placeholder',
        'autofocus',
        'spellcheck','results','maxlength','src','multiple','accept',
        'placeholder','autofocus',
    );
    /**
program/localization/en_US/labels.inc
@@ -194,6 +194,7 @@
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Compact';
$labels['empty'] = 'Empty';
$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Disk usage';
$labels['unknown']  = 'unknown';
program/localization/en_US/messages.inc
@@ -126,6 +126,8 @@
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>Successfully imported $inserted contacts</b>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Operation not permitted!';
$messages['nofromaddress'] = 'Missing e-mail address in selected identity.';
$messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?';
program/steps/mail/func.inc
@@ -120,7 +120,7 @@
  if (!$OUTPUT->ajax_call)
    $OUTPUT->add_label('checkingmail', 'deletemessage', 'movemessagetotrash',
      'movingmessage', 'copyingmessage', 'deletingmessage', 'markingmessage',
      'copy', 'move', 'quota', 'replyall', 'replylist');
      'copy', 'move', 'quota', 'replyall', 'replylist', 'importwait');
  $pagetitle = $RCMAIL->localize_foldername($RCMAIL->storage->mod_folder($mbox_name), true);
  $pagetitle = str_replace($delimiter, " \xC2\xBB ", $pagetitle);
@@ -1922,6 +1922,42 @@
  $RCMAIL->output->send('messageerror');
}
function rcmail_message_import_form($attrib = array())
{
  global $OUTPUT;
  // set defaults
  $attrib += array('id' => 'rcmImportform', 'buttons' => 'yes');
  // Get filesize, enable upload progress bar
  $max_filesize = rcube_upload_init();
  $button = new html_inputfield(array('type' => 'button'));
  $fileinput = new html_inputfield(array(
      'type' => 'file',
      'name' => '_file[]',
      'size' => $attrib['attachmentfieldsize'],
      'multiple' => 'multiple',
      'accept' => ".eml, .mbox, message/rfc822, text/*",
  ));
  $out = html::div($attrib,
    $OUTPUT->form_tag(array('id' => $attrib['id'].'Frm', 'method' => 'post', 'enctype' => 'multipart/form-data'),
      html::tag('input', array('type' => 'hidden', 'name' => '_unlock', 'value' => '')) .
      html::div(null, $fileinput->show()) .
      html::div('hint', rcube_label(array('name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize)))) .
      (get_boolean($attrib['buttons']) ? html::div('buttons',
        $button->show(rcube_label('close'), array('class' => 'button', 'onclick' => "$('#$attrib[id]').hide()")) . ' ' .
        $button->show(rcube_label('upload'), array('class' => 'button mainaction', 'onclick' => JS_OBJECT_NAME . ".command('import-messages', this.form)"))
      ) : '')
    )
  );
  $OUTPUT->add_gui_object('importform', $attrib['id'].'Frm');
  return $out;
}
// register UI objects
$OUTPUT->add_handlers(array(
  'mailboxlist' => 'rcmail_mailbox_list',
@@ -1935,6 +1971,7 @@
  'messagecontentframe' => 'rcmail_messagecontent_frame',
  'messagepartframe' => 'rcmail_message_part_frame',
  'messagepartcontrols' => 'rcmail_message_part_controls',
  'messageimportform' => 'rcmail_message_import_form',
  'searchfilter' => 'rcmail_search_filter',
  'searchform' => array($OUTPUT, 'search_form'),
));
program/steps/mail/import.inc
New file
@@ -0,0 +1,105 @@
<?php
/*
 +-----------------------------------------------------------------------+
 | program/steps/mail/import.inc                                         |
 |                                                                       |
 | This file is part of the Roundcube Webmail client                     |
 | Copyright (C) 2005-2013, The Roundcube Dev Team                       |
 |                                                                       |
 | Licensed under the GNU General Public License version 3 or            |
 | any later version with exceptions for skins & plugins.                |
 | See the README file for a full license statement.                     |
 |                                                                       |
 | PURPOSE:                                                              |
 |   Save the uploaded file(s) as messages to the current IMAP folder    |
 |                                                                       |
 +-----------------------------------------------------------------------+
 | Author: Thomas Bruederli <roundcube@gmail.com>                        |
 +-----------------------------------------------------------------------+
*/
// clear all stored output properties (like scripts and env vars)
$OUTPUT->reset();
if (is_array($_FILES['_file'])) {
    $imported = 0;
    foreach ((array)$_FILES['_file']['tmp_name'] as $i => $filepath) {
        // Process uploaded file if there is no error
        $err = $_FILES['_file']['error'][$i];
        if (!$err) {
            // check file content type first
            list($mtype_primary,) = explode('/', rc_mime_content_type($filepath, $_FILES['_file']['name'][$i], $_FILES['_file']['type'][$i]));
            if (!in_array($mtype_primary, array('text','message'))) {
                $OUTPUT->show_message('importmessageerror', 'error');
                continue;
            }
            // read the first few lines to detect header-like structure
            $fp = fopen($filepath, 'r');
            do { $line = fgets($fp); }
            while ($line !== false && trim($line) == '');
            if (!preg_match('/^From\s+-/', $line) && !preg_match('/^[a-z-_]+:\s+.+/i', $line)) {
                $OUTPUT->show_message('importmessageerror', 'error');
                continue;
            }
            $message = $lastline = '';
            fseek($fp, 0);
            while (($line = fgets($fp)) !== false) {
                // importing mbox file, split by From - lines
                if (preg_match('/^From\s+-/', $line) && $lastline == '') {
                    if (!empty($message)) {
                        if ($RCMAIL->storage->save_message(null, rtrim($message))) {
                            $imported++;
                        }
                        else {
                            rcube::raise_error("Failed to import message to " . $RCMAIL->storage->get_folder(), false, true);
                        }
                        $message = '';
                    }
                    continue;
                }
                $message .= $line;
                $lastline = rtrim($line);
            }
            if (!empty($message) && $RCMAIL->storage->save_message(null, rtrim($message))) {
                $imported++;
            }
        }
        if ($err == UPLOAD_ERR_INI_SIZE || $err == UPLOAD_ERR_FORM_SIZE) {
            $msg = rcube_label(array('name' => 'filesizeerror', 'vars' => array('size' => show_bytes(parse_bytes(ini_get('upload_max_filesize'))))));
        }
        else if ($err) {
            $OUTPUT->show_message('fileuploaderror', 'error');
        }
    }  // end foreach
    if ($imported) {
        $OUTPUT->show_message(rcube_label(array('name' => 'importmessagesuccess', 'nr' => $imported, 'vars' => array('nr' => $imported))), 'confirmation');
        $OUTPUT->command('command', 'list');
    }
    else {
        $OUTPUT->show_message('importmessageerror', 'error');
    }
}
else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    // if filesize exceeds post_max_size then $_FILES array is empty,
    // show filesizeerror instead of fileuploaderror
    if ($maxsize = ini_get('post_max_size'))
        $msg = rcube_label(array('name' => 'filesizeerror', 'vars' => array('size' => show_bytes(parse_bytes($maxsize)))));
    else
        $msg = rcube_label('fileuploaderror');
    $OUTPUT->command('display_message', $msg, 'error');
}
// send html page with JS calls as response
$OUTPUT->send('iframe');
skins/larry/templates/mail.html
@@ -148,7 +148,8 @@
<div id="mailboxmenu" class="popupmenu">
    <ul class="toolbarmenu" id="mailboxoptionsmenu">
        <li><roundcube:button command="expunge" type="link" label="compact" classAct="active" /></li>
        <li class="separator_below"><roundcube:button command="purge" type="link" label="empty" classAct="active" /></li>
        <li><roundcube:button command="purge" type="link" label="empty" classAct="active" /></li>
        <li><roundcube:button name="messageimport" type="link" class="active" label="importmessages" onclick="UI.show_uploadform()" /></li>
        <li><roundcube:button command="folders" task="settings" type="link" label="managefolders" classAct="active" /></li>
        <roundcube:container name="mailboxoptions" id="mailboxoptionsmenu" />
    </ul>
@@ -226,6 +227,14 @@
    </div>
</div>
<div id="upload-dialog" class="propform popupdialog" title="<roundcube:label name='importmessages' />">
    <roundcube:object name="messageimportform" id="uploadform" attachmentFieldSize="40" buttons="no" />
    <div class="formbuttons">
        <roundcube:button command="import-messages" type="input" class="button mainaction" label="upload" />
        <roundcube:button name="close" type="input" class="button" label="cancel" onclick="UI.show_uploadform()" />
    </div>
</div>
<roundcube:include file="/includes/footer.html" />
</body>
skins/larry/ui.js
@@ -152,6 +152,7 @@
        rcmail.addEventListener('setquota', update_quota);
        rcmail.addEventListener('enable-command', enable_command);
        rcmail.addEventListener('afterimport-messages', show_uploadform);
      }
      if ($('#mailview-left').length) {