Skip to content

/ Zope / gocept svn checkins / Archive / 2010 / 2010-03 / SVN: r30644 - webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources

[ << ] [ >> ]

[ SVN: r30636 - in gocept.autocomplete/trunk: . ... ] [ SVN: r30663 - zopeversions / Christian Zagrodnick ... ]

SVN: r30644 - webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources
Thomas Lotze <tl(at)gocept.com>
2010-03-01 17:46:08 [ FULL ]
Author: thomas
Date: Mon Mar  1 17:46:07 2010
New Revision: 30644

Log:
when sending a message, remove its message list entry if the draft folder is
selected


Modified:
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/message.js

Modified:
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js	(original)
+++
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js	Mon
Mar  1 17:46:07 2010
(at)(at) -326,6 +326,9 (at)(at)
         },
 
         close_draft: function(ev) {
+            var self = this;
+            var parent_app = window.opener.document.App;
+            parent_app.gocept.webmailer.onMessageDeleted.fire(self.draft_url);
             window.close();
         },
 

Modified:
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/message.js
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/message.js	(original)
+++
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/message.js	Mon
Mar  1 17:46:07 2010
(at)(at) -2,6 +2,7 (at)(at)
 
     YAHOO.gocept.webmailer.onMessageListResized = new
YAHOO.util.CustomEvent("onMessageListResized");
     YAHOO.gocept.webmailer.onDraftModified = new
YAHOO.util.CustomEvent("onDraftModified");
+    YAHOO.gocept.webmailer.onMessageDeleted = new
YAHOO.util.CustomEvent("onMessageDeleted");
     YAHOO.gocept.webmailer.onFolderContentsChanged = new
YAHOO.util.CustomEvent("onFolderContentsChanged");
     YAHOO.gocept.webmailer.onFolderInfoUpdated = new
YAHOO.util.CustomEvent("onFolderInfoUpdated");
     YAHOO.gocept.webmailer.onOpenComposer = new
YAHOO.util.CustomEvent("onOpenComposer");
(at)(at) -384,6 +385,11 (at)(at)
     $('#message-table').jqGrid('setRowData', draft_url, data);
 });
 
+YAHOO.gocept.webmailer.onMessageDeleted.subscribe(function(event, params){
+    var draft_url = params[0];
+    $('#message-table').jqGrid('delRowData', draft_url);
+});
+
 YAHOO.gocept.webmailer.onOpenComposer.subscribe(function(type, arg) {
     var draft_url = arg[0];
     document.App.lastwindow = window.open(

SVN: r30645 - in webmailer/gocept.restmail/trunk/gocept/restmail: . browser
Thomas Lotze <tl(at)gocept.com>
2010-03-02 08:30:49 [ FULL ]
Author: thomas
Date: Tue Mar  2 08:30:43 2010
New Revision: 30645

Log:
re #6925: added a modification date to drafts and a purge_drafts method to
profiles


Modified:
   webmailer/gocept.restmail/trunk/gocept/restmail/browser/draft.py
   webmailer/gocept.restmail/trunk/gocept/restmail/draft.py
   webmailer/gocept.restmail/trunk/gocept/restmail/draft.txt
   webmailer/gocept.restmail/trunk/gocept/restmail/interfaces.py
   webmailer/gocept.restmail/trunk/gocept/restmail/profile.py

Modified: webmailer/gocept.restmail/trunk/gocept/restmail/browser/draft.py
==============================================================================
--- webmailer/gocept.restmail/trunk/gocept/restmail/browser/draft.py	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/browser/draft.py	Tue Mar  2
08:30:43 2010
(at)(at) -1,8 +1,9 (at)(at)
 # vim:fileencoding=utf-8
-# Copyright (c) 2008-2009 gocept gmbh & co. kg
+# Copyright (c) 2008-2010 gocept gmbh & co. kg
 # See also LICENSE.txt
 """Draft methods."""
 
+import datetime
 import gocept.restmail.browser.json
 
 
(at)(at) -82,6 +83,7 (at)(at)
         self.context.bcc = bcc
         self.context.subject = subject
         self.context.body = body
+        self.context.last_modified = datetime.datetime.now()
 
     (at)gocept.restmail.browser.json.view
     def raw(self):

Modified: webmailer/gocept.restmail/trunk/gocept/restmail/draft.py
==============================================================================
--- webmailer/gocept.restmail/trunk/gocept/restmail/draft.py	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/draft.py	Tue Mar  2
08:30:43 2010
(at)(at) -128,10 +128,11 (at)(at)
     references = None
     body = u''
     orig_message_path = None
+    last_modified = None
 
     def __init__(self, id):
         self.id = id
-        self.date = datetime.datetime.now()
+        self.date = self.last_modified = datetime.datetime.now()
 
     def _update_subject(self, flag, message):
         subject = message.headers.get('Subject', '')
(at)(at) -328,6 +329,17 (at)(at)
         draft.absolute_url() + '/manage_workspace')
 
 
+def purge_drafts(container, maxdays):
+    limit = datetime.datetime.now() - datetime.timedelta(days=maxdays)
+    count = 0
+    for id, draft in container.objectItems():
+        if (draft.last_modified is None and draft.date <= limit # BBB
+            or draft.last_modified <= limit):
+            container._delObject(id)
+            count += 1
+    return count
+
+
 class Attachment(SimpleItem):
 
     zope.interface.implements(gocept.restmail.interfaces.IDraftAttachment)

Modified: webmailer/gocept.restmail/trunk/gocept/restmail/draft.txt
==============================================================================
--- webmailer/gocept.restmail/trunk/gocept/restmail/draft.txt	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/draft.txt	Tue Mar  2
08:30:43 2010
(at)(at) -254,6 +254,33 (at)(at)
 </html>
 
 
+Purging old drafts
+==================
+
+There is a function that purges all drafts that have last been touched longer
+than a given numbers of days ago. This function can, for example, be run
+regularly by a manager or cron job in order to keep the database size
+reasonable. It takes two arguments, the drafts container to purge and the
+maximum number of days a draft is allowed to stick around untouched. It
+returns the number of drafts deleted:
+
+>>> len(profile['drafts'].objectValues())
+6
+
+>>> import datetime
+>>> now = datetime.datetime.now()
+>>> drafts = profile['drafts'].objectValues()
+>>> drafts[0].last_modified = now - datetime.timedelta(days=1)
+>>> drafts[1].last_modified = now - datetime.timedelta(days=2)
+>>> drafts[2].last_modified = now - datetime.timedelta(days=3)
+>>> from gocept.restmail.draft import purge_drafts
+>>> purge_drafts(profile['drafts'], 2)
+2
+
+>>> len(profile['drafts'].objectValues())
+4
+
+
 .. [#getmessages]
     >>> from gocept.restmail.imapaccount import IMAPAccount
     >>> account = IMAPAccount('account', 'localhost', 10143, 'test',
'bsdf')

Modified: webmailer/gocept.restmail/trunk/gocept/restmail/interfaces.py
==============================================================================
--- webmailer/gocept.restmail/trunk/gocept/restmail/interfaces.py	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/interfaces.py	Tue Mar  2
08:30:43 2010
(at)(at) -18,6 +18,11 (at)(at)
 
         """
 
+    def purge_drafts(maxdays):
+        """Delete all draft messages last touched more than maxdays days ago.
+
+        """
+
     def get_identity(id):
         """Return the identity with the given id."""
 
(at)(at) -185,6 +190,7 (at)(at)
     in_reply_to = zope.schema.ASCIILine(title=u'In reply to', required=False)
     references = zope.schema.ASCIILine(title=u'References', required=False)
     body = zope.schema.Text(title=u'Message')
+    last_modified = zope.schema.Datetime(title=u'Modification date')
 
     def send():
         """Send the message.

Modified: webmailer/gocept.restmail/trunk/gocept/restmail/profile.py
==============================================================================
--- webmailer/gocept.restmail/trunk/gocept/restmail/profile.py	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/profile.py	Tue Mar  2
08:30:43 2010
(at)(at) -1,4 +1,4 (at)(at)
-# Copyright (c) 2007-2009 gocept gmbh & co. kg
+# Copyright (c) 2007-2010 gocept gmbh & co. kg
 # See also LICENSE.txt
 
 from AccessControl.Role import RoleManager
(at)(at) -43,6 +43,9 (at)(at)
     def new_draft(self, message=None, forward=False):
         return gocept.restmail.draft.new_draft(self.drafts, message, forward)
 
+    def purge_drafts(self, maxdays):
+        return gocept.restmail.draft.purge_drafts(self.drafts, maxdays)
+
     def get_identities(self):
         identities = []
         sources = zope.component.getAdapters(

SVN: r30646 - webmailer/gocept.webmail/trunk/gocept/webmail
Thomas Lotze <tl(at)gocept.com>
2010-03-02 08:31:29 [ FULL ]
Author: thomas
Date: Tue Mar  2 08:31:26 2010
New Revision: 30646

Log:
re #6925: added a purge_drafts method to the webmailer


Modified:
   webmailer/gocept.webmail/trunk/gocept/webmail/webmailer.py

Modified: webmailer/gocept.webmail/trunk/gocept/webmail/webmailer.py
==============================================================================
--- webmailer/gocept.webmail/trunk/gocept/webmail/webmailer.py	(original)
+++ webmailer/gocept.webmail/trunk/gocept/webmail/webmailer.py	Tue Mar  2
08:31:26 2010
(at)(at) -1,4 +1,4 (at)(at)
-# Copyright (c) 2008-2009 gocept gmbh & co. kg
+# Copyright (c) 2008-2010 gocept gmbh & co. kg
 # See also LICENSE.txt
 
 import zope.interface
(at)(at) -25,6 +25,11 (at)(at)
         """foo"""
         return self, ["index_html"]
 
+    def purge_drafts(self, maxage):
+        for profile in self.objectValues():
+            if gocept.restmail.interfaces.IProfile.implementedBy(profile):
+                profile.purge_drafts(maxage)
+
 
 manage_addWebmailerForm = PageTemplateFile('www/add_webmailer.pt', globals())

SVN: r30647 - webmailer/gocept.webmail/trunk/gocept/webmail
Thomas Lotze <tl(at)gocept.com>
2010-03-02 08:32:27 [ FULL ]
Author: thomas
Date: Tue Mar  2 08:32:24 2010
New Revision: 30647

Log:
re #6925: added the purge_drafts method to IWebmailer


Modified:
   webmailer/gocept.webmail/trunk/gocept/webmail/interfaces.py

Modified: webmailer/gocept.webmail/trunk/gocept/webmail/interfaces.py
==============================================================================
--- webmailer/gocept.webmail/trunk/gocept/webmail/interfaces.py	(original)
+++ webmailer/gocept.webmail/trunk/gocept/webmail/interfaces.py	Tue Mar  2
08:32:24 2010
(at)(at) -9,3 +9,8 (at)(at)
     """
 
     banner_url = zope.interface.Attribute("URL of the CI banner.")
+
+    def purge_drafts(maxdays):
+        """Delete all draft messages last touched more than maxdays days ago.
+
+        """

SVN: r30648 - webmailer/mytum.webmail/trunk/scripts
Thomas Lotze <tl(at)gocept.com>
2010-03-02 08:36:00 [ FULL ]
Author: thomas
Date: Tue Mar  2 08:35:56 2010
New Revision: 30648

Log:
re #6925: added a command-line script to purge old drafts


Added:
   webmailer/mytum.webmail/trunk/scripts/purge-drafts.py   (contents, props
changed)

Added: webmailer/mytum.webmail/trunk/scripts/purge-drafts.py
==============================================================================
--- (empty file)
+++ webmailer/mytum.webmail/trunk/scripts/purge-drafts.py	Tue Mar  2 08:35:56
2010
(at)(at) -0,0 +1,30 (at)(at)
+# Copyright (c) 2010 gocept gmbh & co. kg
+# See also LICENSE.txt
+
+# Dieses Script löscht alle Nachrichten-Entwürfe aller Nutzer von
+# TUM_Portal/webmail_beta, die älter als eine bestimmte Anzahl Tage sind.
+#
+# Aufruf:
+# $ bin/zopectl run scripts/purge-drafts.py
+#
+# Per Vorgabe werden Entwürfe älter als 90 Tage gelöscht, die Zeit kann
aber
+# auch als Parameter übergeben werden:
+#
+# $ bin/zopectl run scripts/purge-drafts.py 30
+
+
+import sys
+
+
+def purge_drafts(root):
+    try:
+        maxdays = int(sys.argv[1])
+    except (IndexError, ValueError):
+        maxdays = 90
+    webmailer = root['TUM_Portal']['webmail_beta']
+    webmailer.purge_drafts(maxage)
+
+
+if __name__ == '__main__':
+    purge_drafts(app)
+    transaction.commit()

SVN: r30649 - webmailer/mytum.webmail/trunk/scripts
Thomas Lotze <tl(at)gocept.com>
2010-03-02 08:39:48 [ FULL ]
Author: thomas
Date: Tue Mar  2 08:39:45 2010
New Revision: 30649

Log:
re #6925: added a missing import


Modified:
   webmailer/mytum.webmail/trunk/scripts/purge-drafts.py

Modified: webmailer/mytum.webmail/trunk/scripts/purge-drafts.py
==============================================================================
--- webmailer/mytum.webmail/trunk/scripts/purge-drafts.py	(original)
+++ webmailer/mytum.webmail/trunk/scripts/purge-drafts.py	Tue Mar  2 08:39:45
2010
(at)(at) -14,6 +14,7 (at)(at)
 
 
 import sys
+import transaction
 
 
 def purge_drafts(root):

SVN: r30650 - webmailer/mytum.webmail/trunk/scripts
Thomas Lotze <tl(at)gocept.com>
2010-03-03 11:51:53 [ FULL ]
Author: thomas
Date: Wed Mar  3 11:51:52 2010
New Revision: 30650

Log:
fixed a variable name


Modified:
   webmailer/mytum.webmail/trunk/scripts/purge-drafts.py

Modified: webmailer/mytum.webmail/trunk/scripts/purge-drafts.py
==============================================================================
--- webmailer/mytum.webmail/trunk/scripts/purge-drafts.py	(original)
+++ webmailer/mytum.webmail/trunk/scripts/purge-drafts.py	Wed Mar  3 11:51:52
2010
(at)(at) -23,7 +23,7 (at)(at)
     except (IndexError, ValueError):
         maxdays = 90
     webmailer = root['TUM_Portal']['webmail_beta']
-    webmailer.purge_drafts(maxage)
+    webmailer.purge_drafts(maxdays)
 
 
 if __name__ == '__main__':

SVN: r30651 - webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources
Thomas Lotze <tl(at)gocept.com>
2010-03-03 17:51:36 [ FULL ]
Author: thomas
Date: Wed Mar  3 17:51:34 2010
New Revision: 30651

Log:
removed autosave functionality


Modified:
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js

Modified:
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js	(original)
+++
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js	Wed
Mar  3 17:51:34 2010
(at)(at) -22,9 +22,6 (at)(at)
     YAHOO.gocept.webmailer.Composer = Class({
         construct: function(draft_url, profile_url) {
             var self = this;
-            YAHOO.util.Event.addListener(window, "unload", function () {
-                document.App.composer.save_draft();
-            }); 
             self.draft_url = draft_url;
             self.profile_url = profile_url;
 
(at)(at) -43,7 +40,6 (at)(at)
             self.editor = new YAHOO.widget.SimpleEditor(
                 self.getControl('Body').id);
             self.editor._defaultToolbar.titlebar = false;
-            self.editor.autosave_counter = 0;
             self.editor.on('editorKeyPress', self.handleEditorKey, self,
true);
             self.editor.on('editorContentLoaded', function() {
                 // Load content from server.
(at)(at) -96,15 +92,6 (at)(at)
                     YAHOO.util.Event.stopEvent(event.ev);
                 };
             };
-            this.handleAutoSave();
-        },
-
-        handleAutoSave: function() {
-            this.editor.autosave_counter += 1;
-            if (this.editor.autosave_counter > 10) {
-                this.save_draft(true);
-                this.editor.autosave_counter = 0;
-            }
         },
 
         splitBlockQuote: function() {
(at)(at) -217,12 +204,12 (at)(at)
             }, 60);
         },
 
-        save_draft: function(autosave) {
+        save_draft: function() {
             var self = this;
             document.Connection.post(
                 self.draft_url+'/(at)(at)save', self._prepare_data(),
                 function () {
-                   if (!autosave) { self.reload_draft_folder(); }
+                    self.reload_draft_folder();
                 }
             );
         },

SVN: r30652 - webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources
Thomas Lotze <tl(at)gocept.com>
2010-03-03 18:34:21 [ FULL ]
Author: thomas
Date: Wed Mar  3 18:34:19 2010
New Revision: 30652

Log:
now that autosave is gone, at least have the user confirm when leaving the
composer without saving unsaved edits


Modified:
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js

Modified:
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js	(original)
+++
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js	Wed
Mar  3 18:34:19 2010
(at)(at) -24,6 +24,13 (at)(at)
             var self = this;
             self.draft_url = draft_url;
             self.profile_url = profile_url;
+            self.set_dirty(false);
+            window.onbeforeunload = function() {
+                if (self.dirty) {
+                    return ('Das Fenster enthält Änderungen, ' +
+                            'die noch nicht gespeichert wurden.');
+                }
+            };
 
             // Query the identities to compose with
             document.Connection.get(profile_url+'/(at)(at)identities',
function(result) {
(at)(at) -36,6 +43,13 (at)(at)
                 };
             });
 
+            jQuery('#composeAddr input').keyup(function() {
+                self.set_dirty(true);
+            });
+            jQuery('#composeAddr select').change(function() {
+                self.set_dirty(true);
+            });
+
             // Initialize the rich text editor for the body.
             self.editor = new YAHOO.widget.SimpleEditor(
                 self.getControl('Body').id);
(at)(at) -58,6 +72,16 (at)(at)
             self.list_attachments();
         },
 
+        set_dirty: function(dirty) {
+            var self = this;
+            self.dirty = dirty;
+            if (dirty) {
+                YAHOO.gocept.webmailer.util.enable_button('save');
+            } else {
+                YAHOO.gocept.webmailer.util.disable_button('save');
+            }
+        },
+
         resize_editor: function() {
             if (!YAHOO.util.Dom.getElementsByClassName('yui-toolbar-subcont'))
{
                 // This happens if the resize handler was fired before wthe
(at)(at) -85,6 +109,7 (at)(at)
         },
 
         handleEditorKey: function(event) {
+            var self = this;
             // Handle key events relevant for the editor.
             if (event.ev.keyCode == 13) {
                 split = this.splitBlockQuote();
(at)(at) -92,6 +117,7 (at)(at)
                     YAHOO.util.Event.stopEvent(event.ev);
                 };
             };
+            self.set_dirty(true);
         },
 
         splitBlockQuote: function() {
(at)(at) -210,6 +236,7 (at)(at)
                 self.draft_url+'/(at)(at)save', self._prepare_data(),
                 function () {
                     self.reload_draft_folder();
+                    self.set_dirty();
                 }
             );
         },

SVN: r30653 - in webmailer/gocept.restmail/trunk/gocept/restmail: . browser
Thomas Lotze <tl(at)gocept.com>
2010-03-04 17:41:19 [ FULL ]
Author: thomas
Date: Thu Mar  4 17:41:17 2010
New Revision: 30653

Log:
no longer create empty drafts in the ZODB (fixes #6839, re #6939)


Modified:
   webmailer/gocept.restmail/trunk/gocept/restmail/browser/configure.zcml
   webmailer/gocept.restmail/trunk/gocept/restmail/browser/draft.py
   webmailer/gocept.restmail/trunk/gocept/restmail/browser/message.txt
   webmailer/gocept.restmail/trunk/gocept/restmail/browser/traversal.py
   webmailer/gocept.restmail/trunk/gocept/restmail/draft.py
   webmailer/gocept.restmail/trunk/gocept/restmail/interfaces.py
   webmailer/gocept.restmail/trunk/gocept/restmail/profile.py
   webmailer/gocept.restmail/trunk/gocept/restmail/test_draft.py

Modified:
webmailer/gocept.restmail/trunk/gocept/restmail/browser/configure.zcml
==============================================================================
---
webmailer/gocept.restmail/trunk/gocept/restmail/browser/configure.zcml	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/browser/configure.zcml	Thu
Mar  4 17:41:17 2010
(at)(at) -163,6 +163,13 (at)(at)
     factory=".traversal.BodyPartTraverser"
     />
 
+  <adapter
+    for="..draft.DraftFolder
+         *"
+    provides="zope.publisher.interfaces.IPublishTraverse"
+    factory=".traversal.DraftFolderTraverser"
+    />
+
   <!-- absolute_url for folders and messages -->
   <view
     for="gocept.imapapi.interfaces.IAccountContent"

Modified: webmailer/gocept.restmail/trunk/gocept/restmail/browser/draft.py
==============================================================================
--- webmailer/gocept.restmail/trunk/gocept/restmail/browser/draft.py	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/browser/draft.py	Thu Mar  4
17:41:17 2010
(at)(at) -77,6 +77,7 (at)(at)
     (at)gocept.restmail.browser.json.view
     def save(self, identity, to, cc, bcc, subject, body):
         """Update the draft."""
+        self.context.store()
         self.context.identity = identity
         self.context.to = to
         self.context.cc = cc

Modified: webmailer/gocept.restmail/trunk/gocept/restmail/browser/message.txt
==============================================================================
---
webmailer/gocept.restmail/trunk/gocept/restmail/browser/message.txt	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/browser/message.txt	Thu Mar
 4 17:41:17 2010
(at)(at) -293,22 +293,6 (at)(at)
  'to': ''}
 
 
-Getting a list of existing draft messages
------------------------------------------
-
->>> pprint.pprint(json_request('http://localhost/profile/(at)(at)drafts'))
-{'batch_size': 10,
- 'batch_start': 0,
- 'messages': [{'date': '<ISO DATE>',
-               'subject': '',
-               'to': '',
-               'url': 'http://localhost/profile/drafts/<GUID>'}],
- 'returned': 1,
- 'sort_dir': 'desc',
- 'sort_key': 'date',
- 'total': 1}
-
-
 Updating draft messages and retrieving raw data
 -----------------------------------------------
 
(at)(at) -388,6 +372,22 (at)(at)
 {'raw': '<pre>MIME-Version: 1.0\nContent-Type: text/html;
charset="utf-8"\nContent-Transfer-Encoding: quoted-printable\nFrom: "Ben Utzer"
<ben(at)example.com>\nTo: ct(at)gocept.com\nCC: sw(at)gocept.com\nBCC:
tl(at)gocept.com\nSubject:
=?utf-8?q?asdf=C3=A4?=\n\nHelloHello=C3=A4</pre>'}
 
 
+Getting a list of existing draft messages
+-----------------------------------------
+
+>>> pprint.pprint(json_request('http://localhost/profile/(at)(at)drafts'))
+{'batch_size': 10,
+ 'batch_start': 0,
+ 'messages': [{'date': '<ISO DATE>',
+               'subject': u'asdf\xe4',
+               'to': 'ct(at)gocept.com',
+               'url': 'http://localhost/profile/drafts/<GUID>'}],
+ 'returned': 1,
+ 'sort_dir': 'desc',
+ 'sort_key': 'date',
+ 'total': 1}
+
+
 Editing attachments
 -------------------
 
(at)(at) -469,9 +469,8 (at)(at)
 After successfully sending a message, its draft will be deleted, but the sent
 message will be in the account's `Sent` folder:
 
->>> browser.open(draft['url']+'/(at)(at)data')
-Traceback (most recent call last):
-HTTPError: HTTP Error 404: Not Found
+>>> pprint.pprint(json_request('http://localhost/profile/(at)(at)drafts'))
+{... 'messages': [],...
 
 >>> pprint.pprint(json_request('http://localhost/profile/test-localhost/+Sent/(at)(at)messages'))
 {'batch_size': 10,
(at)(at) -728,9 +727,8 (at)(at)
 HelloHello
 {'status': 'OK'}
 
->>> browser.open(draft['url']+'/(at)(at)data')
-Traceback (most recent call last):
-HTTPError: HTTP Error 404: Not Found
+>>> pprint.pprint(json_request('http://localhost/profile/(at)(at)drafts'))
+{... 'messages': [],...
 
 >>> pprint.pprint(json_request(
 ...     'http://localhost/profile/test-localhost/+mySentFolder/(at)(at)messages'))

Modified: webmailer/gocept.restmail/trunk/gocept/restmail/browser/traversal.py
==============================================================================
---
webmailer/gocept.restmail/trunk/gocept/restmail/browser/traversal.py	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/browser/traversal.py	Thu
Mar  4 17:41:17 2010
(at)(at) -59,6 +59,17 (at)(at)
             return self.context.parts()[partnumber]
 
 
+class DraftFolderTraverser(Traverser):
+    """Browser traverser for draft folders."""
+
+    def publishTraverse(self, request, name):
+        try:
+            return self.context[name]
+        except KeyError:
+            profile = gocept.restmail.interfaces.IProfile(self.context)
+            return profile.new_draft(id=name)
+
+
 class AbsoluteURL(Acquisition.Explicit):
 
     zope.interface.implements(

Modified: webmailer/gocept.restmail/trunk/gocept/restmail/draft.py
==============================================================================
--- webmailer/gocept.restmail/trunk/gocept/restmail/draft.py	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/draft.py	Thu Mar  4
17:41:17 2010
(at)(at) -156,6 +156,7 (at)(at)
             references += ' ' + msgid
         if references:
             self.references = references
+        self.store()
 
     def _forward(self, message):
         self.orig_message_path = (message.folder().names(), message.name)
(at)(at) -283,14 +284,23 (at)(at)
         # 3. Store in `Sent` Folder
         account.get_function_folder('sent', create=True).add_message(message)
 
-        # 4. Delete draft
-        self.delete()
+        # 4. Delete draft if it is stored
+        if self.__name__ in self.__parent__.objectIds():
+            self.delete()
 
     def delete(self):
         self.aq_inner.getParentNode().manage_delObjects([self.getId()])
 
+    def store(self):
+        # If this draft hasn't been stored since it was created on the fly,
+        # store it inside its traversal parent.
+        if self.id not in self.__parent__.objectIds():
+            self.__parent__._setObject(self.id, self)
+
     def add_attachment(self):
-        return new_attachment(self)
+        self.store()
+        attachment = new_attachment(self)
+        return attachment
 
     (at)property
     def formatted_date(self):
(at)(at) -304,12 +314,17 (at)(at)
             return self.date.isoformat(' ')
 
 
-def new_draft(container, message=None, forward=False):
-    id = str(uuid.uuid1())
-    while id in container.objectIds():
+def new_draft(container, message=None, forward=False, id=None):
+    if not id:
         id = str(uuid.uuid1())
+        # Protect somewhat against ID collision, can't check for colliding IDs
+        # of two drafts both of which haven't yet been stored
+        while id in container.objectIds():
+            id = str(uuid.uuid1())
 
     draft = DraftMessage(id)
+    draft.__parent__ = container
+    draft.__name__ = id
     if message is not None:
         if forward:
             draft._forward(message)
(at)(at) -317,8 +332,7 (at)(at)
             draft._reply_to(message)
         draft.identity = (gocept.restmail.interfaces.IIMAPAccount(message)
                           .default_identity)
-    container._setObject(id, draft)
-    return container[id]
+    return draft.__of__(container)
 
 
 def manage_addDraft(context):

Modified: webmailer/gocept.restmail/trunk/gocept/restmail/interfaces.py
==============================================================================
--- webmailer/gocept.restmail/trunk/gocept/restmail/interfaces.py	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/interfaces.py	Thu Mar  4
17:41:17 2010
(at)(at) -10,11 +10,13 (at)(at)
 class IProfile(zope.interface.Interface):
     """A multi-account profile for one person."""
 
-    def new_draft(message=None):
+    def new_draft(message=None, forward=None, id=None):
         """Add a draft message to the account.
 
         If message is not None, the new draft message is prepared as a reply
-        to it.
+        to it. If forward is True, the new draft message will forward the
+        message instead. If id is not None, the new draft message will be
+        created with that ID.
 
         """
 
(at)(at) -200,6 +202,11 (at)(at)
 
         """
 
+    def store():
+        """Store the draft message in the ZODB if it hasn't been stored yet.
+
+        """
+
     def delete():
         """Delete the draft."""
 

Modified: webmailer/gocept.restmail/trunk/gocept/restmail/profile.py
==============================================================================
--- webmailer/gocept.restmail/trunk/gocept/restmail/profile.py	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/profile.py	Thu Mar  4
17:41:17 2010
(at)(at) -40,8 +40,9 (at)(at)
             'View', 'Access contents information', 'Use webmail']:
             self.manage_permission(permission, ['Manager', 'Owner'], False)
 
-    def new_draft(self, message=None, forward=False):
-        return gocept.restmail.draft.new_draft(self.drafts, message, forward)
+    def new_draft(self, message=None, forward=False, id=None):
+        return gocept.restmail.draft.new_draft(
+            self.drafts, message, forward, id)
 
     def purge_drafts(self, maxdays):
         return gocept.restmail.draft.purge_drafts(self.drafts, maxdays)

Modified: webmailer/gocept.restmail/trunk/gocept/restmail/test_draft.py
==============================================================================
--- webmailer/gocept.restmail/trunk/gocept/restmail/test_draft.py	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/test_draft.py	Thu Mar  4
17:41:17 2010
(at)(at) -1,4 +1,4 (at)(at)
-# Copyright (c) 2009 gocept gmbh & co. kg
+# Copyright (c) 2009-2010 gocept gmbh & co. kg
 # See also LICENSE.txt
 
 import gocept.restmail.draft
(at)(at) -8,10 +8,15 (at)(at)
 class DraftFolderTest(unittest.TestCase):
     def test_filter(self):
         folder = gocept.restmail.draft.DraftFolder()
-        draft = gocept.restmail.draft.new_draft(folder)
-        draft.subject = 'B'
-        draft = gocept.restmail.draft.new_draft(folder)
-        draft.subject = 'A'
+        draftB = gocept.restmail.draft.new_draft(folder)
+        draftB.subject = 'B'
+        draftA = gocept.restmail.draft.new_draft(folder)
+        draftA.subject = 'A'
+        self.assertEquals(
+            [],
+            [x.subject for x in folder.filtered_messages('subject')])
+        draftB.store()
+        draftA.store()
         self.assertEquals(
             ['A', 'B'],
             [x.subject for x in folder.filtered_messages('subject')])

SVN: r30654 - in webmailer/gocept.restmail/trunk/gocept/restmail: . browser testmessages
Thomas Lotze <tl(at)gocept.com>
2010-03-08 23:44:29 [ FULL ]
Author: thomas
Date: Mon Mar  8 23:44:27 2010
New Revision: 30654

Log:
re #6862: remove conditional comments from HTML messages manually as
beautifulsoup doesn't cope with them


Added:
  
webmailer/gocept.restmail/trunk/gocept/restmail/testmessages/35-invalid-ie-conditionals
Modified:
   webmailer/gocept.restmail/trunk/gocept/restmail/browser/inline.txt
   webmailer/gocept.restmail/trunk/gocept/restmail/render.py

Modified: webmailer/gocept.restmail/trunk/gocept/restmail/browser/inline.txt
==============================================================================
---
webmailer/gocept.restmail/trunk/gocept/restmail/browser/inline.txt	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/browser/inline.txt	Mon Mar 
8 23:44:27 2010
(at)(at) -546,6 +546,25 (at)(at)
 </div>
 
 
+HTML message with syntactically broken IE conditionals
+------------------------------------------------------
+
+This message was synthesised using a real-world HTML body that contains
+``<![`` style conditional comments understood only by IE:
+
+>>> r = render_message(folder, '35 - Syntactically invalid IE
conditionals')
+>>> print r['body']
+<div class="messagepart">
+  <div><div><div><font size="2">I fully concur and
everthing Mauro says is
+  correct.</font></div>
+...
+  <p><font
size="2"></font></p></blockquote></div></div>
+  <div><div class="footer">
+</div>
+</div>
+</div>
+
+
 Artificial message, broken HTML, fallback to text/plain
 -------------------------------------------------------
 

Modified: webmailer/gocept.restmail/trunk/gocept/restmail/render.py
==============================================================================
--- webmailer/gocept.restmail/trunk/gocept/restmail/render.py	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/render.py	Mon Mar  8
23:44:27 2010
(at)(at) -244,6 +244,7 (at)(at)
     (at)classmethod
     def parse(cls, text, encoding):
         __traceback_info__ = 'Encoding: %s' % encoding
+        text = remove_ie_conditionals(text)
         try:
             parser = lxml.html.HTMLParser(encoding=encoding)
         except LookupError:
(at)(at) -340,3 +341,60 (at)(at)
             except IndexError:
                 line = ''
         return level, line
+
+
+def remove_ie_conditionals(text):
+    """Remove malformed syntax that makes beautifulsoup fail.
+
+    Stuff like this is used as conditionals for detecting IE.
+
+    >>> remove_ie_conditionals('a<![shit]>b<![shit]>c')
+    'abc'
+    >>> remove_ie_conditionals('a<![shit]>b<!--[shit]>c')
+    'abc'
+    >>> remove_ie_conditionals('a<![shit]-->b<![shit]>c')
+    'abc'
+    >>>
remove_ie_conditionals('a<![shit]-->b<!--[shit]>c')
+    'abc'
+    >>> remove_ie_conditionals('a<!--[shit]>b<![shit]>c')
+    'abc'
+    >>>
remove_ie_conditionals('a<!--[shit]>b<!--[shit]>c')
+    'abc'
+    >>>
remove_ie_conditionals('a<!--[shit]-->b<![shit]>c')
+    'abc'
+    >>>
remove_ie_conditionals('a<!--[shit]-->b<!--[shit]>c')
+    'abc'
+    >>>
remove_ie_conditionals('a<!--[shit]-->b<!--[shit]-->c')
+    'abc'
+    >>>
remove_ie_conditionals('a<!--[shit]-->b<![shit]-->c')
+    'abc'
+    >>>
remove_ie_conditionals('a<!--[shit]>b<!--[shit]-->c')
+    'abc'
+    >>>
remove_ie_conditionals('a<!--[shit]>b<![shit]-->c')
+    'abc'
+    >>>
remove_ie_conditionals('a<![shit]-->b<!--[shit]-->c')
+    'abc'
+    >>>
remove_ie_conditionals('a<![shit]-->b<![shit]-->c')
+    'abc'
+    >>>
remove_ie_conditionals('a<![shit]>b<!--[shit]-->c')
+    'abc'
+    >>> remove_ie_conditionals('a<![shit]>b<![shit]-->c')
+    'abc'
+
+    """
+    while True:
+        for sub in ('<![', '<!--['):
+            start = text.find(sub)
+            if start != -1:
+                break
+        else:
+            return text
+        stops = []
+        for sub in (']>', ']-->'):
+            stop = text.find(sub, start)
+            if stop != -1:
+                stops.append(stop + len(sub))
+        if stops:
+            text = text[:start] + text[min(stops):]
+        else:
+            return text[:start]

Added:
webmailer/gocept.restmail/trunk/gocept/restmail/testmessages/35-invalid-ie-conditionals
==============================================================================
--- (empty file)
+++
webmailer/gocept.restmail/trunk/gocept/restmail/testmessages/35-invalid-ie-conditionals	Mon
Mar  8 23:44:27 2010
(at)(at) -0,0 +1,7 (at)(at)
+To: Thomas Lotze <tl(at)gocept.com>
+Content-Type: text/html
+Subject: 35 - Syntactically invalid IE conditionals
+Mime-Version: 1.0
+Date: Thu, 25 Feb 2010 13:50:58 +0200
+
+<![if !supportLists]><![endif]><![if
!supportLists]><![endif]> <DIV><FONT face=Arial size=2>I
fully concur and everthing Mauro says is correct.</FONT></DIV>
<DIV><FONT face=Arial size=2>I did notice the errors, but
previously I nearly had my head bitten off !!</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>Ivan Marais</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>Traveller diseases, so including
waterborne diseases, are a complex matter and need to be properly
discussed.</FONT></DIV> <BLOCKQUOTE style="PADDING-RIGHT: 0px;
PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #000000 2px solid;
MARGIN-RIGHT: 0px"> <DIV><FONT face=Arial size=2>So, please,
give proper clinical information or rather do not give any, and refer to proper
bibliography ( e.g. INTERNATIONAL TRAVEL AND HEALTH, BY WORLD HEALTH
ORGANISATION AVAILABLE AT: <A href="http://www.who.int/ith/en/">http://www.who.int/ith/en/</A></FONT></DIV>
<DIV><FONT face=Arial size=2>Two examples in T4A
discussion:</FONT></DIV> <DIV><SPAN lang=EN
style="FONT-SIZE: 10pt; FONT-FAMILY:
'Arial','sans-serif'"><EM>1-"Waterborne disease can be caused by
protozoa, viruses, or bacteria, many of which are intestinal
parasites</EM>."</SPAN></DIV> <DIV><SPAN lang=EN
style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'">This is
incorrect:</SPAN></DIV> <DIV><SPAN lang=EN
style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'">Protozoa are
parasites ( e.g.Giardia lamblia, but among parasites there are also worms);
then we have viruses (e.g. hepatitis A, that is not a diarrhoeal disease); then
bacteria (e.g. cholera, Escherichia coli, etc). Dysentery is a symptom (bloody
diarrhoea by Amoeba, Shigella, some E.coli, etc) not a
microorganism.</SPAN></DIV> <DIV><SPAN lang=EN
style="FONT-SIZE: 10pt; FONT-FAMILY:
'Arial','sans-serif'"><EM>2-"Flagil seems to be the preferred method
of treatment for mostly waterborne nastiest</EM>"
</SPAN></DIV> <DIV><SPAN lang=EN style="FONT-SIZE: 10pt;
FONT-FAMILY: 'Arial','sans-serif'">Incorrect:</SPAN></DIV>
<DIV><SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY:
'Arial','sans-serif'">Metronidazole (Flagyl) has a limited antibacterial
spectrum and it is active against a few protozoa ( Giardia,
Amoeba).</SPAN></DIV> <DIV><SPAN lang=EN style="FONT-SIZE:
10pt; FONT-FAMILY: 'Arial','sans-serif'"><SPAN lang=EN style="FONT-SIZE:
10pt; FONT-FAMILY: 'Arial','sans-serif'"></SPAN></SPAN>
</DIV> <DIV><SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY:
'Arial','sans-serif'"><SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY:
'Arial','sans-serif'">Remember that there are other waterborne diseases that
are not acquired by drinking contaminated water.
</SPAN></SPAN></DIV> <DIV><SPAN lang=EN
style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'"><SPAN lang=EN
style="FONT-SIZE: 10pt; FONT-FAMILY:
'Arial','sans-serif'"></SPAN></SPAN> </DIV>
<DIV><SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY:
'Arial','sans-serif'"><SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY:
'Arial','sans-serif'">This kind of information is fundamental when choosing
purifying methods because filters alone do not stop viruses and some of them
neither bacteria.</SPAN></SPAN></DIV> <DIV><SPAN
lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'"><SPAN
lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'">In WHO
website you can find daily updates on health situation in all
countries.</SPAN></SPAN></DIV> <DIV><SPAN lang=EN
style="FONT-SIZE: 10pt; FONT-FAMILY: 'Arial','sans-serif'"><SPAN lang=EN
style="FONT-SIZE: 10pt; FONT-FAMILY:
'Arial','sans-serif'"></SPAN></SPAN> </DIV>
<DIV><SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY:
'Arial','sans-serif'"><SPAN lang=EN style="FONT-SIZE: 10pt; FONT-FAMILY:
'Arial','sans-serif'">Mauro</SPAN></SPAN></DIV>
<P><FONT face=Arial
size=2></FONT></P></BLOCKQUOTE></BODY></HTML>
<p></p> -- <br /> To STOP getting T4A Mail, make sure that
you are sending mail from the SAME ADDRESS that you used when you joined the
T4A list and then click on this link:<br />
mailto:tracks4africa+unsubscribe(at)googlegroups.com<br /> If that does
NOT work, then please try mailto:moderator(at)tracks4africa.co.za
\ No newline at end of file

SVN: r30655 - webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources
Thomas Lotze <tl(at)gocept.com>
2010-03-09 08:03:51 [ FULL ]
Author: thomas
Date: Tue Mar  9 08:03:49 2010
New Revision: 30655

Log:
fixed keeping track of the folder name when renaming a folder


Modified:
  
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/management-main.js
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/webmailer.js

Modified:
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/management-main.js
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/management-main.js	(original)
+++
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/management-main.js	Tue
Mar  9 08:03:49 2010
(at)(at) -354,7 +354,7 (at)(at)
                 return true;
             });
             self.treeview.subscribe('labelClick', function(node) {
-                document.getElementById('accountSentFolderDisplay').value =
node.data.label;
+                document.getElementById('accountSentFolderDisplay').value =
node.folder.name;
                 document.App.account_edit_form.sent_folder = node.names;
             });
         },

Modified:
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/webmailer.js
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/webmailer.js	(original)
+++
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/webmailer.js	Tue
Mar  9 08:03:49 2010
(at)(at) -185,19 +185,23 (at)(at)
             var self = this;
             var label = data.inputElement.value;
             var node = data.node;
-    
+
+            // for instantaneous feedback, tentatively rename the tree node
now
+            var old_label = node.label;
+            node.label = label;
+
             // propagate to the server
             document.Connection.post(
                     node.url + '/(at)(at)rename', {name: label},
function(result) {
                 result = YAHOO.lang.JSON.parse(result.responseText);
                 if (result['status'] == 'OK') {
                     // change the webmail interface
-                    node.label = label;
-                    node.data.label = label;
+                    node.folder.name = label;
                     node.url = result['url'];
                     document.getElementById(node.labelElId).innerHTML = label;
                     document.App.tree.treeview.removeChildren(node);
                 } else {
+                    node.label = old_label;
                     alert(result['message']);
                 }
                 document.App.tree.initDragDrop();

SVN: r30656 - webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources
Thomas Lotze <tl(at)gocept.com>
2010-03-09 08:10:09 [ FULL ]
Author: thomas
Date: Tue Mar  9 08:10:03 2010
New Revision: 30656

Log:
fixed #6871: after renaming a folder, actually store the new URL on the folder
object


Modified:
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/webmailer.js

Modified:
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/webmailer.js
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/webmailer.js	(original)
+++
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/webmailer.js	Tue
Mar  9 08:10:03 2010
(at)(at) -197,6 +197,7 (at)(at)
                 if (result['status'] == 'OK') {
                     // change the webmail interface
                     node.folder.name = label;
+                    node.folder.url = result['url'];
                     node.url = result['url'];
                     document.getElementById(node.labelElId).innerHTML = label;
                     document.App.tree.treeview.removeChildren(node);

SVN: r30657 - webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources
Thomas Lotze <tl(at)gocept.com>
2010-03-09 08:17:00 [ FULL ]
Author: thomas
Date: Tue Mar  9 08:16:55 2010
New Revision: 30657

Log:
fire the onFolderInfoUpdated event after successfully renaming a folder


Modified:
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/webmailer.js

Modified:
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/webmailer.js
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/webmailer.js	(original)
+++
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/webmailer.js	Tue
Mar  9 08:16:55 2010
(at)(at) -198,6 +198,7 (at)(at)
                     // change the webmail interface
                     node.folder.name = label;
                     node.folder.url = result['url'];
+                   
YAHOO.gocept.webmailer.onFolderInfoUpdated.fire(node.folder);
                     node.url = result['url'];
                     document.getElementById(node.labelElId).innerHTML = label;
                     document.App.tree.treeview.removeChildren(node);

SVN: r30658 - webmailer/gocept.restmail/trunk/gocept/restmail
Thomas Lotze <tl(at)gocept.com>
2010-03-10 08:31:58 [ FULL ]
Author: thomas
Date: Wed Mar 10 08:31:57 2010
New Revision: 30658

Log:
removed stuff unnecessary for gocept.restmail, in particular the emergency user


Modified:
   webmailer/gocept.restmail/trunk/gocept/restmail/tests.py

Modified: webmailer/gocept.restmail/trunk/gocept/restmail/tests.py
==============================================================================
--- webmailer/gocept.restmail/trunk/gocept/restmail/tests.py	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/tests.py	Wed Mar 10
08:31:57 2010
(at)(at) -1,5 +1,5 (at)(at)
 # vim:fileencoding=utf-8
-# Copyright (c) 2008-2009 gocept gmbh & co. kg
+# Copyright (c) 2008-2010 gocept gmbh & co. kg
 # See also LICENSE.txt
 """Test harness for gocept.restmail."""
 
(at)(at) -11,14 +11,10 (at)(at)
 
 from zope.testing import doctest
 import zope.testing.renormalizing
-import ZODB.DemoStorage
 import ZODB.blob
-import Zope2
 
-import Products.Five.zcml
 import Testing.ZopeTestCase
 import Testing.ZopeTestCase.layer
-import Testing.ZopeTestCase.utils
 import Products.MailHost.MailHost
 
 import gocept.imapapi.tests
(at)(at) -47,21 +43,6 (at)(at)
 
         Testing.ZopeTestCase.installPackage('gocept.restmail')
 
-        import AccessControl.User
-        emergency = AccessControl.User.UnrestrictedUser(
-            'admin', 'admin', ('manage', ), [])
-        AccessControl.User.emergency_user = emergency
-        AccessControl.User.super = emergency
-        AccessControl.User.SpecialUsers.emergency_user = emergency
-        AccessControl.User.SpecialUsers.super = emergency
-        AccessControl.User.BasicUserFolder._emergency_user = emergency
-        AccessControl.User.BasicUserFolder._super = emergency
-
-        host, port = Testing.ZopeTestCase.utils.startZServer()
-        zope_root_url = 'http://%s:%d' % (host,
port)
-
-        self.base_url = zope_root_url
-
         # Monkey patch the mail host for printing.
         def new_send(self, message, *args, **kw):
             print message

SVN: r30659 - in webmailer/gocept.webmail/trunk/gocept/webmail: . browser
Thomas Lotze <tl(at)gocept.com>
2010-03-10 08:34:05 [ FULL ]
Author: thomas
Date: Wed Mar 10 08:34:01 2010
New Revision: 30659

Log:
call the user 'admin' instead of mgr to reduce the number of names in use


Modified:
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/webmailer.txt
   webmailer/gocept.webmail/trunk/gocept/webmail/tests.py

Modified: webmailer/gocept.webmail/trunk/gocept/webmail/browser/webmailer.txt
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/webmailer.txt	(original)
+++ webmailer/gocept.webmail/trunk/gocept/webmail/browser/webmailer.txt	Wed Mar
10 08:34:01 2010
(at)(at) -10,12 +10,12 (at)(at)
 
 >>> from Products.Five.testbrowser import Browser
 >>> browser = Browser()
->>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+>>> browser.addHeader('Authorization', 'Basic admin:admin')
 >>> browser.open('http://localhost/mail')
 >>> browser.url
-'http://localhost/mail/mgr'
+'http://localhost/mail/admin'
 >>> print browser.contents
 <?xml version="1.0" encoding="utf-8" ?>
 <!DOCTYPE...
 <html class="webmailer">...
-<title>Webmail client for user mgr</title>...
+<title>Webmail client for user admin</title>...

Modified: webmailer/gocept.webmail/trunk/gocept/webmail/tests.py
==============================================================================
--- webmailer/gocept.webmail/trunk/gocept/webmail/tests.py	(original)
+++ webmailer/gocept.webmail/trunk/gocept/webmail/tests.py	Wed Mar 10 08:34:01
2010
(at)(at) -1,5 +1,5 (at)(at)
 # vim:fileencoding=utf-8
-# Copyright (c) 2008-2009 gocept gmbh & co. kg
+# Copyright (c) 2008-2010 gocept gmbh & co. kg
 # See also LICENSE.txt
 """testsuite for webmailer product."""
 
(at)(at) -22,8 +22,8 (at)(at)
 
 def setUp(test):
     app = test.app
-    app['acl_users'].userFolderAddUser('mgr', 'mgrpw', ['Manager'], '')
-    user = app['acl_users'].getUser('mgr').__of__(app['acl_users'])
+    app['acl_users'].userFolderAddUser('admin', 'admin', ['Manager'], '')
+    user = app['acl_users'].getUser('admin').__of__(app['acl_users'])
     AccessControl.SecurityManagement.noSecurityManager()
     AccessControl.SecurityManagement.newSecurityManager(None, user)

SVN: r30660 - webmailer/gocept.webmail/trunk/gocept/webmail/browser
Thomas Lotze <tl(at)gocept.com>
2010-03-10 08:34:48 [ FULL ]
Author: thomas
Date: Wed Mar 10 08:34:47 2010
New Revision: 30660

Log:
made selenium tests run (but not yet pass) again


Modified:
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/testing.py

Modified: webmailer/gocept.webmail/trunk/gocept/webmail/browser/testing.py
==============================================================================
--- webmailer/gocept.webmail/trunk/gocept/webmail/browser/testing.py	(original)
+++ webmailer/gocept.webmail/trunk/gocept/webmail/browser/testing.py	Wed Mar 10
08:34:47 2010
(at)(at) -1,7 +1,8 (at)(at)
-# Copyright (c) 2009 gocept gmbh & co. kg
+# Copyright (c) 2009-2010 gocept gmbh & co. kg
 # See also LICENSE.txt
 
 import Testing.ZopeTestCase
+import Testing.ZopeTestCase.utils
 import gocept.restmail.tests
 import gocept.selenium.zope2
 import gocept.webmail.webmailer
(at)(at) -10,8 +11,12 (at)(at)
 
 class WebmailLayer(gocept.restmail.tests.Zope2FunctionalLayer):
 
+    __name__ = 'WebmailLayer'
+
     def setUp(self):
+        gocept.restmail.tests.Zope2FunctionalLayer.setUp(self)
         Testing.ZopeTestCase.installPackage('gocept.webmail')
+        Testing.ZopeTestCase.utils.startZServer()
 
 
 webmail_layer = WebmailLayer()

SVN: r30661 - webmailer/gocept.webmail/trunk/gocept/webmail/browser/tests
Thomas Lotze <tl(at)gocept.com>
2010-03-10 09:27:10 [ FULL ]
Author: thomas
Date: Wed Mar 10 09:27:09 2010
New Revision: 30661

Log:
made the drafts folder selenium test pass again


Modified:
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/tests/test_draft.py

Modified:
webmailer/gocept.webmail/trunk/gocept/webmail/browser/tests/test_draft.py
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/tests/test_draft.py	(original)
+++
webmailer/gocept.webmail/trunk/gocept/webmail/browser/tests/test_draft.py	Wed
Mar 10 09:27:09 2010
(at)(at) -1,4 +1,5 (at)(at)
-# Copyright (c) 2009 gocept gmbh & co. kg
+# -*- coding: utf-8 -*-
+# Copyright (c) 2009-2010 gocept gmbh & co. kg
 # See also LICENSE.txt
 
 import gocept.webmail.browser.testing
(at)(at) -14,8 +15,8 (at)(at)
         drafts = '//*[text() = "Drafts"]'
         s.waitForElementPresent(drafts)
         s.click(drafts)
-        s.waitForElementPresent('//div[(at)class = "yui-dt"]')
-        s.verifyTextPresent('No records found.')
+        s.waitForElementPresent('css=#gbox_message-table thead tr')
+        s.verifyElementNotPresent('css=#message-table tbody tr')
 
 
 def test_suite():

SVN: r30662 - in webmailer/gocept.webmail/trunk/gocept/webmail/browser: . tests
Thomas Lotze <tl(at)gocept.com>
2010-03-10 09:41:59 [ FULL ]
Author: thomas
Date: Wed Mar 10 09:41:58 2010
New Revision: 30662

Log:
gave up on YUI unit tests as they were only rudimentary and YUI is on its way
out anyway


Removed:
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/tests/configure.zcml
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/tests/connection.pt
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/tests/dummy.pt
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/tests/echo.py
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/tests/index.pt
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/tests/test_yui.py
Modified:
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/configure.zcml

Modified: webmailer/gocept.webmail/trunk/gocept/webmail/browser/configure.zcml
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/configure.zcml	(original)
+++ webmailer/gocept.webmail/trunk/gocept/webmail/browser/configure.zcml	Wed
Mar 10 09:41:58 2010
(at)(at) -60,7 +60,4 (at)(at)
     permission="zope2.View"
     />
 
-  <include package=".tests"
-           zcml:condition="installed gocept.selenium" />
-
 </configure>

SVN: r30664 - in webmailer/gocept.webmail/trunk/gocept/webmail/browser: . resources
Thomas Lotze <tl(at)gocept.com>
2010-03-11 15:02:54 [ FULL ]
Author: thomas
Date: Thu Mar 11 15:02:52 2010
New Revision: 30664

Log:
fixed #5930: avoid FOUC on loading the webmailer or any pop-up windows


Modified:
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/layout.pt
  
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer-main.js
  
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/management-main.js
  
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/webmailer-main.js

Modified: webmailer/gocept.webmail/trunk/gocept/webmail/browser/layout.pt
==============================================================================
--- webmailer/gocept.webmail/trunk/gocept/webmail/browser/layout.pt	(original)
+++ webmailer/gocept.webmail/trunk/gocept/webmail/browser/layout.pt	Thu Mar 11
15:02:52 2010
(at)(at) -42,7 +42,7 (at)(at)
       <a href=".">reload this page</a>.
     </div>
 
-    <div id="yui-layout">
+    <div id="yui-layout" style="display:none;">
       <metal:block define-slot="layout" />
     </div>
   </body>

Modified:
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer-main.js
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer-main.js	(original)
+++
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer-main.js	Thu
Mar 11 15:02:52 2010
(at)(at) -20,6 +20,7 (at)(at)
                 ]});
             self.layout.on('render', function() {
                 YAHOO.gocept.webmailer.util.hide('yui-layout-loading');
+                YAHOO.gocept.webmailer.util.show('yui-layout');
                 self.compose_bar = new
YAHOO.widget.TabView('yui-layout-center');
                 self.tab_attachments =
document.getElementById("composeBarTabAttachments");
                 self.composer = new YAHOO.gocept.webmailer.Composer(

Modified:
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/management-main.js
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/management-main.js	(original)
+++
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/management-main.js	Thu
Mar 11 15:02:52 2010
(at)(at) -20,6 +20,7 (at)(at)
                 ]});
             self.layout.on('render', function() {
                 YAHOO.gocept.webmailer.util.hide('yui-layout-loading');
+                YAHOO.gocept.webmailer.util.show('yui-layout');
                 // Initialize DOM nodes first, as the business models
                 // rely on them.
                 self.domNodes.account_list =
document.getElementById('accountList');

Modified:
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/webmailer-main.js
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/webmailer-main.js	(original)
+++
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/webmailer-main.js	Thu
Mar 11 15:02:52 2010
(at)(at) -21,6 +21,8 (at)(at)
                         body: ''}]});
             // XXX make src and height configurable on the server
             self.outer_layout.on('render', function() {
+                YAHOO.gocept.webmailer.util.hide('yui-layout-loading');
+                YAHOO.gocept.webmailer.util.show('yui-layout');
                 self.layout = new YAHOO.widget.Layout(
                     self.outer_layout.getUnitByPosition('center').body,
                     {parent: self.outer_layout,

SVN: r30665 - webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources
Thomas Lotze <tl(at)gocept.com>
2010-03-11 17:11:38 [ FULL ]
Author: thomas
Date: Thu Mar 11 17:11:37 2010
New Revision: 30665

Log:
display the editor only after fields have been filled with the draft's data


Modified:
  
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer-main.js
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js

Modified:
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer-main.js
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer-main.js	(original)
+++
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer-main.js	Thu
Mar 11 17:11:37 2010
(at)(at) -19,8 +19,6 (at)(at)
                       scroll: true},
                 ]});
             self.layout.on('render', function() {
-                YAHOO.gocept.webmailer.util.hide('yui-layout-loading');
-                YAHOO.gocept.webmailer.util.show('yui-layout');
                 self.compose_bar = new
YAHOO.widget.TabView('yui-layout-center');
                 self.tab_attachments =
document.getElementById("composeBarTabAttachments");
                 self.composer = new YAHOO.gocept.webmailer.Composer(

Modified:
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js	(original)
+++
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js	Thu
Mar 11 17:11:37 2010
(at)(at) -200,6 +200,8 (at)(at)
                     self.getControl('Body').value = body;
                     self.editor.setEditorHTML(body);
                     self.reload_draft_folder();
+                    YAHOO.gocept.webmailer.util.hide('yui-layout-loading');
+                    YAHOO.gocept.webmailer.util.show('yui-layout');
             });
         },

SVN: r30666 - webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources
Thomas Lotze <tl(at)gocept.com>
2010-03-11 17:14:00 [ FULL ]
Author: thomas
Date: Thu Mar 11 17:13:59 2010
New Revision: 30666

Log:
no more need to reload the drafts folder immediately after loading a draft into
the editor


Modified:
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js

Modified:
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js	(original)
+++
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js	Thu
Mar 11 17:13:59 2010
(at)(at) -199,7 +199,6 (at)(at)
                     var body = draft['body'];
                     self.getControl('Body').value = body;
                     self.editor.setEditorHTML(body);
-                    self.reload_draft_folder();
                     YAHOO.gocept.webmailer.util.hide('yui-layout-loading');
                     YAHOO.gocept.webmailer.util.show('yui-layout');
             });

SVN: r30667 - webmailer/gocept.webmail/trunk/gocept/webmail
Thomas Lotze <tl(at)gocept.com>
2010-03-17 15:21:16 [ FULL ]
Author: thomas
Date: Wed Mar 17 15:21:14 2010
New Revision: 30667

Log:
purge_drafts: fixed interface test, made variable names consistent with related
code


Modified:
   webmailer/gocept.webmail/trunk/gocept/webmail/webmailer.py

Modified: webmailer/gocept.webmail/trunk/gocept/webmail/webmailer.py
==============================================================================
--- webmailer/gocept.webmail/trunk/gocept/webmail/webmailer.py	(original)
+++ webmailer/gocept.webmail/trunk/gocept/webmail/webmailer.py	Wed Mar 17
15:21:14 2010
(at)(at) -25,10 +25,10 (at)(at)
         """foo"""
         return self, ["index_html"]
 
-    def purge_drafts(self, maxage):
+    def purge_drafts(self, maxdays):
         for profile in self.objectValues():
-            if gocept.restmail.interfaces.IProfile.implementedBy(profile):
-                profile.purge_drafts(maxage)
+            if gocept.restmail.interfaces.IProfile.providedBy(profile):
+                profile.purge_drafts(maxdays)
 
 
 manage_addWebmailerForm = PageTemplateFile('www/add_webmailer.pt', globals())

SVN: r30668 - webmailer/gocept.webmail/trunk/gocept/webmail
Thomas Lotze <tl(at)gocept.com>
2010-03-17 15:32:10 [ FULL ]
Author: thomas
Date: Wed Mar 17 15:32:09 2010
New Revision: 30668

Log:
aggregate number of purged draft messages


Modified:
   webmailer/gocept.webmail/trunk/gocept/webmail/webmailer.py

Modified: webmailer/gocept.webmail/trunk/gocept/webmail/webmailer.py
==============================================================================
--- webmailer/gocept.webmail/trunk/gocept/webmail/webmailer.py	(original)
+++ webmailer/gocept.webmail/trunk/gocept/webmail/webmailer.py	Wed Mar 17
15:32:09 2010
(at)(at) -26,9 +26,10 (at)(at)
         return self, ["index_html"]
 
     def purge_drafts(self, maxdays):
+        count = 0
         for profile in self.objectValues():
             if gocept.restmail.interfaces.IProfile.providedBy(profile):
-                profile.purge_drafts(maxdays)
+                count += profile.purge_drafts(maxdays)
 
 
 manage_addWebmailerForm = PageTemplateFile('www/add_webmailer.pt', globals())

SVN: r30669 - webmailer/mytum.webmail/trunk/scripts
Thomas Lotze <tl(at)gocept.com>
2010-03-17 15:32:25 [ FULL ]
Author: thomas
Date: Wed Mar 17 15:32:25 2010
New Revision: 30669

Log:
report number of purged draft messages


Modified:
   webmailer/mytum.webmail/trunk/scripts/purge-drafts.py

Modified: webmailer/mytum.webmail/trunk/scripts/purge-drafts.py
==============================================================================
--- webmailer/mytum.webmail/trunk/scripts/purge-drafts.py	(original)
+++ webmailer/mytum.webmail/trunk/scripts/purge-drafts.py	Wed Mar 17 15:32:25
2010
(at)(at) -23,7 +23,8 (at)(at)
     except (IndexError, ValueError):
         maxdays = 90
     webmailer = root['TUM_Portal']['webmail_beta']
-    webmailer.purge_drafts(maxdays)
+    count = webmailer.purge_drafts(maxdays)
+    print "Removed %s draft messages."
 
 
 if __name__ == '__main__':

SVN: r30670 - webmailer/mytum.webmail/trunk/scripts
Thomas Lotze <tl(at)gocept.com>
2010-03-17 15:40:55 [ FULL ]
Author: thomas
Date: Wed Mar 17 15:40:47 2010
New Revision: 30670

Log:
fixed report on purged drafts


Modified:
   webmailer/mytum.webmail/trunk/scripts/purge-drafts.py

Modified: webmailer/mytum.webmail/trunk/scripts/purge-drafts.py
==============================================================================
--- webmailer/mytum.webmail/trunk/scripts/purge-drafts.py	(original)
+++ webmailer/mytum.webmail/trunk/scripts/purge-drafts.py	Wed Mar 17 15:40:47
2010
(at)(at) -24,7 +24,7 (at)(at)
         maxdays = 90
     webmailer = root['TUM_Portal']['webmail_beta']
     count = webmailer.purge_drafts(maxdays)
-    print "Removed %s draft messages."
+    print "Removed %s draft messages." % count
 
 
 if __name__ == '__main__':

SVN: r30671 - webmailer/gocept.webmail/trunk/gocept/webmail
Thomas Lotze <tl(at)gocept.com>
2010-03-17 16:35:45 [ FULL ]
Author: thomas
Date: Wed Mar 17 16:35:44 2010
New Revision: 30671

Log:
fixed another stupid mistake that happened in a hurry


Modified:
   webmailer/gocept.webmail/trunk/gocept/webmail/webmailer.py

Modified: webmailer/gocept.webmail/trunk/gocept/webmail/webmailer.py
==============================================================================
--- webmailer/gocept.webmail/trunk/gocept/webmail/webmailer.py	(original)
+++ webmailer/gocept.webmail/trunk/gocept/webmail/webmailer.py	Wed Mar 17
16:35:44 2010
(at)(at) -30,6 +30,7 (at)(at)
         for profile in self.objectValues():
             if gocept.restmail.interfaces.IProfile.providedBy(profile):
                 count += profile.purge_drafts(maxdays)
+        return count
 
 
 manage_addWebmailerForm = PageTemplateFile('www/add_webmailer.pt', globals())

SVN: r30672 - webmailer/gocept.restmail/trunk/gocept/restmail
Thomas Lotze <tl(at)gocept.com>
2010-03-17 16:42:53 [ FULL ]
Author: thomas
Date: Wed Mar 17 16:42:52 2010
New Revision: 30672

Log:
purge_drafts: fixed a stupid mistake that arose from using and/or to fake a
conditional


Modified:
   webmailer/gocept.restmail/trunk/gocept/restmail/draft.py

Modified: webmailer/gocept.restmail/trunk/gocept/restmail/draft.py
==============================================================================
--- webmailer/gocept.restmail/trunk/gocept/restmail/draft.py	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/draft.py	Wed Mar 17
16:42:52 2010
(at)(at) -347,8 +347,10 (at)(at)
     limit = datetime.datetime.now() - datetime.timedelta(days=maxdays)
     count = 0
     for id, draft in container.objectItems():
-        if (draft.last_modified is None and draft.date <= limit # BBB
-            or draft.last_modified <= limit):
+        comp_date = draft.last_modified
+        if comp_date is None: #BBB
+            comp_date = draft.date
+        if comp_date <= limit:
             container._delObject(id)
             count += 1
     return count

SVN: r30673 - webmailer/gocept.webmail/trunk/gocept/webmail
Thomas Lotze <tl(at)gocept.com>
2010-03-18 13:45:48 [ FULL ]
Author: thomas
Date: Thu Mar 18 13:45:46 2010
New Revision: 30673

Log:
purging all old drafts from the webmailer in one go was a stupid idea as this
will be run against live databases with a lot of active users, thereby very
likely producing ConflictErrors


Modified:
   webmailer/gocept.webmail/trunk/gocept/webmail/interfaces.py
   webmailer/gocept.webmail/trunk/gocept/webmail/webmailer.py

Modified: webmailer/gocept.webmail/trunk/gocept/webmail/interfaces.py
==============================================================================
--- webmailer/gocept.webmail/trunk/gocept/webmail/interfaces.py	(original)
+++ webmailer/gocept.webmail/trunk/gocept/webmail/interfaces.py	Thu Mar 18
13:45:46 2010
(at)(at) -10,7 +10,7 (at)(at)
 
     banner_url = zope.interface.Attribute("URL of the CI banner.")
 
-    def purge_drafts(maxdays):
-        """Delete all draft messages last touched more than maxdays days ago.
+    def profiles():
+        """Returns an iterable of all profiles that exist within the
webmailer.
 
         """

Modified: webmailer/gocept.webmail/trunk/gocept/webmail/webmailer.py
==============================================================================
--- webmailer/gocept.webmail/trunk/gocept/webmail/webmailer.py	(original)
+++ webmailer/gocept.webmail/trunk/gocept/webmail/webmailer.py	Thu Mar 18
13:45:46 2010
(at)(at) -25,12 +25,10 (at)(at)
         """foo"""
         return self, ["index_html"]
 
-    def purge_drafts(self, maxdays):
-        count = 0
+    def profiles(self):
         for profile in self.objectValues():
             if gocept.restmail.interfaces.IProfile.providedBy(profile):
-                count += profile.purge_drafts(maxdays)
-        return count
+                yield profile
 
 
 manage_addWebmailerForm = PageTemplateFile('www/add_webmailer.pt', globals())

SVN: r30674 - webmailer/mytum.webmail/trunk/scripts
Thomas Lotze <tl(at)gocept.com>
2010-03-18 13:47:16 [ FULL ]
Author: thomas
Date: Thu Mar 18 13:47:16 2010
New Revision: 30674

Log:
purge old drafts from the webmailer profile by profile, committing transactions
each time, retrying on ConflictError


Modified:
   webmailer/mytum.webmail/trunk/scripts/purge-drafts.py

Modified: webmailer/mytum.webmail/trunk/scripts/purge-drafts.py
==============================================================================
--- webmailer/mytum.webmail/trunk/scripts/purge-drafts.py	(original)
+++ webmailer/mytum.webmail/trunk/scripts/purge-drafts.py	Thu Mar 18 13:47:16
2010
(at)(at) -23,10 +23,22 (at)(at)
     except (IndexError, ValueError):
         maxdays = 90
     webmailer = root['TUM_Portal']['webmail_beta']
-    count = webmailer.purge_drafts(maxdays)
+    count = 0
+    profiles = list(webmailer.profiles())
+    for profile in profiles:
+        while True:
+            deleted = profile.purge_drafts(maxdays)
+            if not deleted:
+                break
+            try:
+                transaction.commit()
+            except ZODB.POSException.ConflictError:
+                continue
+            else:
+                count += deleted
+                break
     print "Removed %s draft messages." % count
 
 
 if __name__ == '__main__':
     purge_drafts(app)
-    transaction.commit()

SVN: r30675 - webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources
Thomas Lotze <tl(at)gocept.com>
2010-03-18 17:19:51 [ FULL ]
Author: thomas
Date: Thu Mar 18 17:19:49 2010
New Revision: 30675

Log:
minor refactoring: perform the dance to get at the parent app only in one place


Modified:
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js

Modified:
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js	(original)
+++
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js	Thu
Mar 18 17:19:49 2010
(at)(at) -22,6 +22,7 (at)(at)
     YAHOO.gocept.webmailer.Composer = Class({
         construct: function(draft_url, profile_url) {
             var self = this;
+            self.parent_app = window.opener.document.App;
             self.draft_url = draft_url;
             self.profile_url = profile_url;
             self.set_dirty(false);
(at)(at) -220,13 +221,12 (at)(at)
 
         reload_draft_folder: function() {
             var self = this;
-            var parent_app = window.opener.document.App;
             window.setTimeout(function() {
             // YAHOO.util.Connect.asyncRequest does not wait for a response,
             // so the callback is fired a moment before the submitted data is
             // saved at the server. Set a timeout here to give the server its
             // time to save the submitted data.
-            parent_app.gocept.webmailer.onDraftModified.fire(
+            self.parent_app.gocept.webmailer.onDraftModified.fire(
                 self.draft_url, self.get('To'), self.get('Subject'));
             }, 60);
         },
(at)(at) -342,8 +342,7 (at)(at)
 
         close_draft: function(ev) {
             var self = this;
-            var parent_app = window.opener.document.App;
-            parent_app.gocept.webmailer.onMessageDeleted.fire(self.draft_url);
+           
self.parent_app.gocept.webmailer.onMessageDeleted.fire(self.draft_url);
             window.close();
         },

SVN: r30681 - webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources
Thomas Lotze <tl(at)gocept.com>
2010-03-29 17:22:31 [ FULL ]
Author: thomas
Date: Mon Mar 29 17:22:30 2010
New Revision: 30681

Log:
less sloppy handling of function arguments


Modified:
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js

Modified:
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js	(original)
+++
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js	Mon
Mar 29 17:22:30 2010
(at)(at) -237,7 +237,7 (at)(at)
                 self.draft_url+'/(at)(at)save', self._prepare_data(),
                 function () {
                     self.reload_draft_folder();
-                    self.set_dirty();
+                    self.set_dirty(false);
                 }
             );
         },
(at)(at) -327,7 +327,7 (at)(at)
             );
         },
 
-        send_message: function(ev) {
+        send_message: function() {
             var self = this;
             self.save_draft();
             document.Connection.post(self.draft_url+'/(at)(at)send', null,
function(result) {

SVN: r30687 - webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources
Thomas Lotze <tl(at)gocept.com>
2010-03-30 08:16:25 [ FULL ]
Author: thomas
Date: Tue Mar 30 08:16:24 2010
New Revision: 30687

Log:
brought back sent folder selection that was broken during some refactoring
earlier this year


Modified:
  
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/management-main.js

Modified:
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/management-main.js
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/management-main.js	(original)
+++
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/management-main.js	Tue
Mar 30 08:16:24 2010
(at)(at) -355,7 +355,7 (at)(at)
                 return true;
             });
             self.treeview.subscribe('labelClick', function(node) {
-                document.getElementById('accountSentFolderDisplay').value =
node.folder.name;
+                    document.getElementById('accountSentFolderDisplay').value
= node.data.label;
                 document.App.account_edit_form.sent_folder = node.names;
             });
         },

SVN: r30688 - webmailer/gocept.restmail/trunk/gocept/restmail/browser
Thomas Lotze <tl(at)gocept.com>
2010-03-30 08:26:48 [ FULL ]
Author: thomas
Date: Tue Mar 30 08:26:46 2010
New Revision: 30688

Log:
re #6583: list sent folder with folder type 'sent' and its messages with
recipient instead of sender address


Modified:
   webmailer/gocept.restmail/trunk/gocept/restmail/browser/account.txt
   webmailer/gocept.restmail/trunk/gocept/restmail/browser/folder.py
   webmailer/gocept.restmail/trunk/gocept/restmail/browser/message.py
   webmailer/gocept.restmail/trunk/gocept/restmail/browser/profile.txt

Modified: webmailer/gocept.restmail/trunk/gocept/restmail/browser/account.txt
==============================================================================
---
webmailer/gocept.restmail/trunk/gocept/restmail/browser/account.txt	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/browser/account.txt	Tue Mar
30 08:26:46 2010
(at)(at) -65,7 +65,7 (at)(at)
  {'children': 0,
   'name': 'Sent',
   'names': ['Sent'],
-  'type': 'inbox',
+  'type': 'sent',
   'url': 'http://localhost/profile/test-localhost/+Sent'},
  {'children': 0,
   'name': 'Testmessages',

Modified: webmailer/gocept.restmail/trunk/gocept/restmail/browser/folder.py
==============================================================================
---
webmailer/gocept.restmail/trunk/gocept/restmail/browser/folder.py	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/browser/folder.py	Tue Mar
30 08:26:46 2010
(at)(at) -1,5 +1,5 (at)(at)
 # vim:fileencoding=utf-8
-# Copyright (c) 2008 gocept gmbh & co. kg
+# Copyright (c) 2008-2010 gocept gmbh & co. kg
 # See also LICENSE.txt
 """Folder methods."""
 
(at)(at) -8,18 +8,28 (at)(at)
 import zope.app.zapi
 import gocept.restmail.browser.json
 import gocept.restmail.browser.traversal
+import gocept.restmail.interfaces
 
 
 class ContainerWebAPI(object):
     """Web API for folder containers."""
 
     def folder_dict(self, folder):
+        account = gocept.restmail.interfaces.IIMAPAccount(self.context)
+        folder_type = 'inbox'
+        try:
+            sent_folder = account.get_function_folder('sent')
+        except Exception:
+            pass
+        else:
+            if folder == sent_folder:
+                folder_type = 'sent'
         return dict(
             url=zope.app.zapi.absoluteURL(folder, self.request),
             children=len(folder.folders()),
             name=folder.name,
             names=folder.names(),
-            type='inbox'
+            type=folder_type,
             )
 
     (at)gocept.restmail.browser.json.view

Modified: webmailer/gocept.restmail/trunk/gocept/restmail/browser/message.py
==============================================================================
---
webmailer/gocept.restmail/trunk/gocept/restmail/browser/message.py	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/browser/message.py	Tue Mar
30 08:26:46 2010
(at)(at) -69,6 +69,16 (at)(at)
         if rows > 100:
             rows = 10
 
+        account = gocept.restmail.interfaces.IIMAPAccount(self.context)
+        address_key = 'From'
+        try:
+            sent_folder = account.get_function_folder('sent')
+        except Exception:
+            pass
+        else:
+            if self.context == sent_folder:
+                address_key = 'To'
+
         messages = []
         for message in self.context.filtered_messages(
             sidx, sord, (page-1)*rows, page*rows):
(at)(at) -78,7 +88,7 (at)(at)
                     cell=[
                         dict(flags=list(message.flags),
                              num_attachments=message.estimated_attachments),
-                        from_name(message.headers.get('From')),
+                        from_name(message.headers.get(address_key)),
                         message.headers.get('Subject'),
                         message.formatted_date,
                         ],

Modified: webmailer/gocept.restmail/trunk/gocept/restmail/browser/profile.txt
==============================================================================
---
webmailer/gocept.restmail/trunk/gocept/restmail/browser/profile.txt	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/browser/profile.txt	Tue Mar
30 08:26:46 2010
(at)(at) -134,7 +134,7 (at)(at)
  {'children': 0,
   'name': 'Sent',
   'names': ['Sent'],
-  'type': 'inbox',
+  'type': 'sent',
   'url': 'http://localhost/profile/test-localhost/+Sent'},
  {'children': 0,
   'name': 'Testmessages',

SVN: r30689 - webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources
Thomas Lotze <tl(at)gocept.com>
2010-03-30 08:30:06 [ FULL ]
Author: thomas
Date: Tue Mar 30 08:30:01 2010
New Revision: 30689

Log:
re #6583: interpret folder type 'sent'


Modified:
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/message.js
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/webmailer.js

Modified:
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/message.js
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/message.js	(original)
+++
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/message.js	Tue
Mar 30 08:30:01 2010
(at)(at) -96,12 +96,16 (at)(at)
     }
 });
 
-YAHOO.gocept.webmailer.DraftsFolder = Class(
+YAHOO.gocept.webmailer.OutFolder = Class(
     YAHOO.gocept.webmailer.Folder,
 {
     address_name: 'to',
-    address_heading: 'Empfänger',
+    address_heading: 'Empfänger'
+});
 
+YAHOO.gocept.webmailer.DraftsFolder = Class(
+    YAHOO.gocept.webmailer.OutFolder,
+{
     allowed_operations: {'raw': null,
                          'edit': null,
                          'delete': null},

Modified:
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/webmailer.js
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/webmailer.js	(original)
+++
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/webmailer.js	Tue
Mar 30 08:30:01 2010
(at)(at) -171,6 +171,7 (at)(at)
             var folder_class = {
                 account: YAHOO.gocept.webmailer.Account,
                 inbox: YAHOO.gocept.webmailer.Folder,
+                sent: YAHOO.gocept.webmailer.OutFolder,
                 drafts: YAHOO.gocept.webmailer.DraftsFolder
             }[list_type];
             tempNode.folder = new folder_class(url, name);

SVN: r30690 - webmailer/gocept.restmail/trunk/gocept/restmail/browser
Thomas Lotze <tl(at)gocept.com>
2010-03-30 08:32:30 [ FULL ]
Author: thomas
Date: Tue Mar 30 08:32:29 2010
New Revision: 30690

Log:
don't break trying to reformat a recipient address


Modified:
   webmailer/gocept.restmail/trunk/gocept/restmail/browser/message.py

Modified: webmailer/gocept.restmail/trunk/gocept/restmail/browser/message.py
==============================================================================
---
webmailer/gocept.restmail/trunk/gocept/restmail/browser/message.py	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/browser/message.py	Tue Mar
30 08:32:29 2010
(at)(at) -157,7 +157,12 (at)(at)
                 url in message_urls]
 
 def from_name(value):
-    name, addr = email.Utils.parseaddr(value)
+    try:
+        name, addr = email.Utils.parseaddr(value)
+    except Exception:
+        # XXX since rev. 30688, this may be applied to recipient addresses as
+        # well, which may actually be lists of addresses
+        return value
     if name:
         return '%s (%s)' % (name, addr)
     else:

SVN: r30691 - webmailer/gocept.webmail/trunk/gocept/webmail/browser/tests
Thomas Lotze <tl(at)gocept.com>
2010-03-30 17:22:27 [ FULL ]
Author: thomas
Date: Tue Mar 30 17:22:26 2010
New Revision: 30691

Log:
removed unnecessary page load in test


Modified:
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/tests/test_draft.py

Modified:
webmailer/gocept.webmail/trunk/gocept/webmail/browser/tests/test_draft.py
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/tests/test_draft.py	(original)
+++
webmailer/gocept.webmail/trunk/gocept/webmail/browser/tests/test_draft.py	Tue
Mar 30 17:22:26 2010
(at)(at) -11,7 +11,6 (at)(at)
 
     def test_empty_drafts_folder(self):
         s = self.selenium
-        s.open('/webmail/admin')
         drafts = '//*[text() = "Drafts"]'
         s.waitForElementPresent(drafts)
         s.click(drafts)

SVN: r30692 - in webmailer/gocept.webmail/trunk/gocept/webmail/browser: . resources tests
Thomas Lotze <tl(at)gocept.com>
2010-03-30 17:36:34 [ FULL ]
Author: thomas
Date: Tue Mar 30 17:36:33 2010
New Revision: 30692

Log:
added a basic composer test, set up an account with an identity for this, use a
flag to signal that the composer has loaded the draft


Added:
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/tests/test_composer.py
  (contents, props changed)
Modified:
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/testing.py

Modified:
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js	(original)
+++
webmailer/gocept.webmail/trunk/gocept/webmail/browser/resources/composer.js	Tue
Mar 30 17:36:33 2010
(at)(at) -183,6 +183,7 (at)(at)
 
         load_draft: function() {
             var self = this;
+            self.loaded = false; // indicator examined by tests
             document.Connection.get(self.draft_url+'/(at)(at)data',
function(result) {
                     var draft = YAHOO.lang.JSON.parse(result.responseText);
                     self.getControl('To').value = draft['to'];
(at)(at) -200,6 +201,7 (at)(at)
                     var body = draft['body'];
                     self.getControl('Body').value = body;
                     self.editor.setEditorHTML(body);
+                    self.loaded = true;
                     YAHOO.gocept.webmailer.util.hide('yui-layout-loading');
                     YAHOO.gocept.webmailer.util.show('yui-layout');
             });

Modified: webmailer/gocept.webmail/trunk/gocept/webmail/browser/testing.py
==============================================================================
--- webmailer/gocept.webmail/trunk/gocept/webmail/browser/testing.py	(original)
+++ webmailer/gocept.webmail/trunk/gocept/webmail/browser/testing.py	Tue Mar 30
17:36:33 2010
(at)(at) -3,6 +3,9 (at)(at)
 
 import Testing.ZopeTestCase
 import Testing.ZopeTestCase.utils
+import gocept.restmail.identity
+import gocept.restmail.imapaccount
+import gocept.restmail.profile
 import gocept.restmail.tests
 import gocept.selenium.zope2
 import gocept.webmail.webmailer
(at)(at) -32,10 +35,19 (at)(at)
         app = self.app
         app._setObject('webmail',
gocept.webmail.webmailer.Webmailer('webmail'))
         app['acl_users'].userFolderAddUser('admin', 'admin', ['Manager'], [])
+        app['webmail']._setObject(
+            'admin', gocept.restmail.profile.Profile('admin'))
+        app['webmail']['admin']._setObject(
+            'test-localhost', gocept.restmail.identity.Identity(
+                'test-localhost', 'Adolf Admin', 'test(at)localhost', '', ''))
+        app['webmail']['admin']._setObject(
+            'localhost', gocept.restmail.imapaccount.IMAPAccount(
+                'localhost', 'localhost', 10143, 'admin' ,'admin',
+                identity_id='test-localhost', title='localhost'))
         transaction.commit()
-        # create the admin profile
+        # authenticate
         s = self.selenium
-        s.open('http://admin:admin(at)%s/webmail' % s.server)
+        s.open('http://admin:admin(at)%s/webmail/admin' %
s.server)
 
     def tearDown(self):
         self.app._delObject('webmail')

Added:
webmailer/gocept.webmail/trunk/gocept/webmail/browser/tests/test_composer.py
==============================================================================
--- (empty file)
+++
webmailer/gocept.webmail/trunk/gocept/webmail/browser/tests/test_composer.py	Tue
Mar 30 17:36:33 2010
(at)(at) -0,0 +1,43 (at)(at)
+# -*- coding: utf-8 -*-
+# Copyright (c) 2010 gocept gmbh & co. kg
+# See also LICENSE.txt
+
+import gocept.webmail.browser.testing
+import unittest
+
+
+class ComposerTest(gocept.webmail.browser.testing.TestCase):
+    """ComposerTest"""
+
+    def setUp(self):
+        super(ComposerTest, self).setUp()
+        s = self.selenium
+        drafts = '//*[text() = "Drafts"]'
+        s.waitForElementPresent(drafts)
+        s.click('link=New')
+        s.selectPopUp()
+        s.waitForCondition("""\
+((selenium.browserbot.getCurrentWindow().document.App != undefined)
+ &&
selenium.browserbot.getCurrentWindow().document.App.composer.loaded)
+""")
+
+    def tearDown(self):
+        s = self.selenium
+        try:
+            s.selectPopUp(wait=False)
+        except Exception:
+            pass
+        if s.getLocation().endswith('/webmail_composer'):
+            s.close()
+            s.deselectPopUp()
+        self.app['webmail']['admin'].purge_drafts(0)
+        super(ComposerTest, self).tearDown()
+
+    def test_composer_init(self):
+        s = self.selenium
+        s.verifySelectedLabel(
+            'css=#composeFrom', u'"Adolf Admin" <test(at)localhost>')
+
+
+def test_suite():
+    return unittest.makeSuite(ComposerTest)

SVN: r30693 - in webmailer/gocept.restmail/trunk/gocept/restmail: . browser
Thomas Lotze <tl(at)gocept.com>
2010-03-31 09:19:52 [ FULL ]
Author: thomas
Date: Wed Mar 31 09:19:51 2010
New Revision: 30693

Log:
fixes #6391: compute size of drafts folder correctly


Modified:
   webmailer/gocept.restmail/trunk/gocept/restmail/browser/profile.py
   webmailer/gocept.restmail/trunk/gocept/restmail/draft.txt

Modified: webmailer/gocept.restmail/trunk/gocept/restmail/browser/profile.py
==============================================================================
---
webmailer/gocept.restmail/trunk/gocept/restmail/browser/profile.py	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/browser/profile.py	Wed Mar
31 09:19:51 2010
(at)(at) -150,7 +150,7 (at)(at)
                 } for message in messages]
         data = {
             'messages': messages,
-            'total': len(self.context.drafts),
+            'total': len(self.context.drafts.messages()),
             'returned': len(messages),
             'batch_start': batch_start,
             'batch_size': batch_size,
(at)(at) -187,7 +187,7 (at)(at)
                         ],
                     ))
 
-        records = len(self.context.drafts)
+        records = len(self.context.drafts.messages())
         total = math.ceil(records/float(rows))
 
         data = dict(

Modified: webmailer/gocept.restmail/trunk/gocept/restmail/draft.txt
==============================================================================
--- webmailer/gocept.restmail/trunk/gocept/restmail/draft.txt	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/draft.txt	Wed Mar 31
09:19:51 2010
(at)(at) -75,10 +75,10 (at)(at)
 
 To delete a draft, simply call its delete method:
 
->>> len(reply.aq_inner.getParentNode().objectValues())
+>>> len(reply.aq_inner.getParentNode().messages())
 5
 >>> reply.delete()
->>> len(reply.aq_inner.getParentNode().objectValues())
+>>> len(reply.aq_inner.getParentNode().messages())
 4
 
 
(at)(at) -264,7 +264,7 (at)(at)
 maximum number of days a draft is allowed to stick around untouched. It
 returns the number of drafts deleted:
 
->>> len(profile['drafts'].objectValues())
+>>> len(profile['drafts'].messages())
 6
 
 >>> import datetime
(at)(at) -277,7 +277,7 (at)(at)
 >>> purge_drafts(profile['drafts'], 2)
 2
 
->>> len(profile['drafts'].objectValues())
+>>> len(profile['drafts'].messages())
 4

SVN: r30694 - webmailer/gocept.restmail/trunk/gocept/restmail/browser
Thomas Lotze <tl(at)gocept.com>
2010-03-31 09:28:31 [ FULL ]
Author: thomas
Date: Wed Mar 31 09:28:30 2010
New Revision: 30694

Log:
re #6931: added another test for the drafts folder size


Modified:
   webmailer/gocept.restmail/trunk/gocept/restmail/browser/message.txt

Modified: webmailer/gocept.restmail/trunk/gocept/restmail/browser/message.txt
==============================================================================
---
webmailer/gocept.restmail/trunk/gocept/restmail/browser/message.txt	(original)
+++ webmailer/gocept.restmail/trunk/gocept/restmail/browser/message.txt	Wed Mar
31 09:28:30 2010
(at)(at) -297,7 +297,16 (at)(at)
 -----------------------------------------------
 
 The draft's data can be updated; we'll look at the draft's raw content for an
-ASCII-only message and different combinations of Unicode body and subject:
+ASCII-only message and different combinations of Unicode body and subject.
+Also, when saving a draft for the first time, it will be made permanent within
+the drafts folder, so let's compare the drafts folder's size before and after:
+
+>>> pprint.pprint(json_request('http://localhost/profile/(at)(at)drafts'))
+{...
+ 'messages': [],
+ 'returned': 0,
+ ...
+ 'total': 0}
 
 >>> json_request(draft['url']+'/(at)(at)save',
 ...              to='ct(at)gocept.com',
(at)(at) -371,6 +380,16 (at)(at)
 >>> pprint.pprint(json_request(draft['url']+'/(at)(at)raw'))
 {'raw': '<pre>MIME-Version: 1.0\nContent-Type: text/html;
charset="utf-8"\nContent-Transfer-Encoding: quoted-printable\nFrom: "Ben Utzer"
<ben(at)example.com>\nTo: ct(at)gocept.com\nCC: sw(at)gocept.com\nBCC:
tl(at)gocept.com\nSubject:
=?utf-8?q?asdf=C3=A4?=\n\nHelloHello=C3=A4</pre>'}
 
+>>> pprint.pprint(json_request('http://localhost/profile/(at)(at)drafts'))
+{...
+ 'messages': [{'date': '2010-03-31 09:27:17.077363',
+               'subject': u'asdf\xe4',
+               'to': 'ct(at)gocept.com',
+               'url': 'http://localhost/profile/drafts/d591fd8c-3c96-11df-9d01-495e914e718c'}],
+ 'returned': 1,
+ ...
+ 'total': 1}
+
 
 Getting a list of existing draft messages
 -----------------------------------------

SVN: r30695 - webmailer/gocept.webmail/trunk/gocept/webmail/browser/tests
Thomas Lotze <tl(at)gocept.com>
2010-03-31 17:14:16 [ FULL ]
Author: thomas
Date: Wed Mar 31 17:14:15 2010
New Revision: 30695

Log:
added a basic selenium test for the round-trip of saving a draft and re-editing
it later


Modified:
   webmailer/gocept.webmail/trunk/gocept/webmail/browser/tests/test_composer.py

Modified:
webmailer/gocept.webmail/trunk/gocept/webmail/browser/tests/test_composer.py
==============================================================================
---
webmailer/gocept.webmail/trunk/gocept/webmail/browser/tests/test_composer.py	(original)
+++
webmailer/gocept.webmail/trunk/gocept/webmail/browser/tests/test_composer.py	Wed
Mar 31 17:14:15 2010
(at)(at) -38,6 +38,27 (at)(at)
         s.verifySelectedLabel(
             'css=#composeFrom', u'"Adolf Admin" <test(at)localhost>')
 
+    def test_save_reedit(self):
+        s = self.selenium
+        # XXX we do need both of the following two lines due to a Selenium bug
+        s.typeKeys('css=#composeTo', 'foo(at)example.org')
+        s.type('css=#composeTo', 'foo(at)example.org')
+        s.click('css=#menuitem-save')
+        s.waitForCondition("""\
+!selenium.browserbot.getCurrentWindow().document.App.composer.dirty
+""")
+        s.close()
+        s.deselectPopUp()
+        s.click('//*[text() = "Drafts"]')
+        s.click('//*[text()="foo(at)example.org"]')
+        s.click('link=Edit message')
+        s.selectPopUp()
+        s.waitForCondition("""\
+((selenium.browserbot.getCurrentWindow().document.App != undefined)
+ &&
selenium.browserbot.getCurrentWindow().document.App.composer.loaded)
+""")
+        s.verifyValue('css=#composeTo', 'foo(at)example.org')
+
 
 def test_suite():
     return unittest.makeSuite(ComposerTest)

MailBoxer