diff options
| author | Thomas Bruederli <thomas@roundcube.net> | 2013-06-14 01:13:13 +0200 | 
|---|---|---|
| committer | Thomas Bruederli <thomas@roundcube.net> | 2013-06-14 01:13:13 +0200 | 
| commit | 4f53ab347e6ad026f69105b69ce66e21a7654c78 (patch) | |
| tree | fb4bf5b2d3de9c0799d0b1a5139996a99cf5e5bc | |
| parent | bf305c181095cc05522b1c0fcee7093dea3043c1 (diff) | |
Add feature to import messages to the currently selected folder
| -rw-r--r-- | program/js/app.js | 19 | ||||
| -rw-r--r-- | program/lib/Roundcube/html.php | 4 | ||||
| -rw-r--r-- | program/localization/en_US/labels.inc | 1 | ||||
| -rw-r--r-- | program/localization/en_US/messages.inc | 2 | ||||
| -rw-r--r-- | program/steps/mail/func.inc | 39 | ||||
| -rw-r--r-- | program/steps/mail/import.inc | 105 | ||||
| -rw-r--r-- | skins/larry/templates/mail.html | 11 | ||||
| -rw-r--r-- | skins/larry/ui.js | 1 | 
8 files changed, 172 insertions, 10 deletions
| diff --git a/program/js/app.js b/program/js/app.js index 0dea59216..37aee8d88 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -191,7 +191,7 @@ function rcube_webmail()        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 @@ function rcube_webmail()            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 @@ function rcube_webmail()          // 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': @@ -1101,6 +1102,12 @@ function rcube_webmail()          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':          if (this.env.action == 'import' && this.gui_objects.importform) {            var file = document.getElementById('rcmimportfile'); @@ -3492,8 +3499,8 @@ function rcube_webmail()      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 @@ function rcube_webmail()          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) { diff --git a/program/lib/Roundcube/html.php b/program/lib/Roundcube/html.php index eb23c8b2e..3e6e47a56 100644 --- a/program/lib/Roundcube/html.php +++ b/program/lib/Roundcube/html.php @@ -360,8 +360,8 @@ class html_inputfield extends html      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',      );      /** diff --git a/program/localization/en_US/labels.inc b/program/localization/en_US/labels.inc index d8e517387..c5e6cae4c 100644 --- a/program/localization/en_US/labels.inc +++ b/program/localization/en_US/labels.inc @@ -194,6 +194,7 @@ $labels['listmode'] = 'List view mode';  $labels['folderactions'] = 'Folder actions...';  $labels['compact'] = 'Compact';  $labels['empty'] = 'Empty'; +$labels['importmessages'] = 'Import messages';  $labels['quota'] = 'Disk usage';  $labels['unknown']  = 'unknown'; diff --git a/program/localization/en_US/messages.inc b/program/localization/en_US/messages.inc index f9b5e00a6..16f4c67bf 100644 --- a/program/localization/en_US/messages.inc +++ b/program/localization/en_US/messages.inc @@ -126,6 +126,8 @@ $messages['importwait'] = 'Importing, please wait...';  $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?'; diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc index 1a687f508..7b6a4829d 100644 --- a/program/steps/mail/func.inc +++ b/program/steps/mail/func.inc @@ -120,7 +120,7 @@ if (empty($RCMAIL->action) || $RCMAIL->action == 'list') {    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 @@ function rcmail_message_error($uid=null)    $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 @@ $OUTPUT->add_handlers(array(    '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'),  )); diff --git a/program/steps/mail/import.inc b/program/steps/mail/import.inc new file mode 100644 index 000000000..f7e7a3eb8 --- /dev/null +++ b/program/steps/mail/import.inc @@ -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'); + diff --git a/skins/larry/templates/mail.html b/skins/larry/templates/mail.html index 85cd5203b..575cb792a 100644 --- a/skins/larry/templates/mail.html +++ b/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> diff --git a/skins/larry/ui.js b/skins/larry/ui.js index f7428f4da..ec4d03d00 100644 --- a/skins/larry/ui.js +++ b/skins/larry/ui.js @@ -152,6 +152,7 @@ function rcube_mail_ui()          rcmail.addEventListener('setquota', update_quota);          rcmail.addEventListener('enable-command', enable_command); +        rcmail.addEventListener('afterimport-messages', show_uploadform);        }        if ($('#mailview-left').length) { | 
