1 Return-Path: <patricktotzke@googlemail.com>
\r
2 X-Original-To: notmuch@notmuchmail.org
\r
3 Delivered-To: notmuch@notmuchmail.org
\r
4 Received: from localhost (localhost [127.0.0.1])
\r
5 by olra.theworths.org (Postfix) with ESMTP id 43591431FAF
\r
6 for <notmuch@notmuchmail.org>; Wed, 21 Mar 2012 02:07:28 -0700 (PDT)
\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org
\r
11 X-Spam-Status: No, score=-0.799 tagged_above=-999 required=5
\r
12 tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1,
\r
13 FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled
\r
14 Received: from olra.theworths.org ([127.0.0.1])
\r
15 by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)
\r
16 with ESMTP id QiFZfOGmUaQm for <notmuch@notmuchmail.org>;
\r
17 Wed, 21 Mar 2012 02:07:27 -0700 (PDT)
\r
18 Received: from mail-wi0-f179.google.com (mail-wi0-f179.google.com
\r
19 [209.85.212.179]) (using TLSv1 with cipher RC4-SHA (128/128 bits))
\r
20 (No client certificate requested)
\r
21 by olra.theworths.org (Postfix) with ESMTPS id 3FCE7431FAE
\r
22 for <notmuch@notmuchmail.org>; Wed, 21 Mar 2012 02:07:27 -0700 (PDT)
\r
23 Received: by wibhn6 with SMTP id hn6so938225wib.2
\r
24 for <notmuch@notmuchmail.org>; Wed, 21 Mar 2012 02:07:26 -0700 (PDT)
\r
25 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
\r
26 d=googlemail.com; s=20120113;
\r
27 h=content-type:mime-version:content-transfer-encoding:to:message-id
\r
28 :from:user-agent:subject:date;
\r
29 bh=fKKVWMfpPhBa+YjVOMkXNQETWGr8KdMJXHAPWEAg2V4=;
\r
30 b=zAnBO89XvQgv/sstFTsGIajSZSd79qBQCjSigiRSyHDyrvNZMQaZfyyoXwRU1STXvy
\r
31 w4kk1FwF0kwh60eLGO4Yz9RcCV7rfBIXsBJiIb7BSaty+a2wsYLTgkCgMU2ETPofnNvH
\r
32 4TRh4In7/6MsWcws0B/ax1TQ0PujNFyCr+Wy3NU3FbJ1ivnM5lac2JBoNP3UJCD2hBLo
\r
33 rwsiJRqoXu8Co7QDoBtMqGOEGwUGssCHQxO5bvepKZ+yl/GOzNp9FD966Gwm/78DROxl
\r
34 N0iXc89Y3SvhJqWjIFhoFl98FpPLFP0zeYLzULGW/VLmtIpvpIcC/MPuN/BXF2+9yAbR
\r
36 Received: by 10.180.100.2 with SMTP id eu2mr7238366wib.1.1332320845915;
\r
37 Wed, 21 Mar 2012 02:07:25 -0700 (PDT)
\r
38 Received: from localhost (cpc1-sgyl2-0-0-cust548.18-2.cable.virginmedia.com.
\r
40 by mx.google.com with ESMTPS id e6sm2985347wix.8.2012.03.21.02.07.24
\r
41 (version=TLSv1/SSLv3 cipher=OTHER);
\r
42 Wed, 21 Mar 2012 02:07:24 -0700 (PDT)
\r
43 Content-Type: text/plain; charset="utf-8"
\r
45 Content-Transfer-Encoding: quoted-printable
\r
46 To: Notmuch Mail <notmuch@notmuchmail.org>
\r
47 Message-ID: <20120321090722.6892.24383@brick.lan>
\r
48 From: Patrick Totzke <patricktotzke@googlemail.com>
\r
49 User-Agent: alot/0.3
\r
50 Subject: [RFC][alot] design decisions
\r
51 Date: Wed, 21 Mar 2012 09:07:22 +0000
\r
52 X-BeenThere: notmuch@notmuchmail.org
\r
53 X-Mailman-Version: 2.1.13
\r
55 List-Id: "Use and development of the notmuch mail system."
\r
56 <notmuch.notmuchmail.org>
\r
57 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,
\r
58 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
59 List-Archive: <http://notmuchmail.org/pipermail/notmuch>
\r
60 List-Post: <mailto:notmuch@notmuchmail.org>
\r
61 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
62 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,
\r
63 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
64 X-List-Received-Date: Wed, 21 Mar 2012 09:07:28 -0000
\r
68 with alot 0.3 released, I started thinking seriously about proper=E2=84=A2 =
\r
69 MIME-display and gnupg
\r
70 integration for alot. I have to make a few design decisions here and could =
\r
72 some informed opinions from more experienced UI developers. My question in =
\r
76 How do I best integrate calls to external mime-handlers into my MVC event =
\r
79 I mostly know how to implement the individual parts but I struggle coming u=
\r
81 consistent way of organizing it all without compromising my current layout.
\r
87 Model. Alot uses an abstraction layer over notmuch's thread, message and da=
\r
89 to make them less fragile and generally behave more OOP-y: You can e.g. dir=
\r
91 message.add_tags(['foo','bar']) and so on. This is made possible by a "Data=
\r
93 that maintains centralized and queued access to the notmuch index and deals=
\r
95 exceptions like a locked index [0].
\r
97 View/Controler. We use an event-driven interface (urwid.TwistedEventLoop, [=
\r
99 handles user input and maintains a tree of widgets that knows how to render=
\r
101 Twisted offers a neat concept of "Deferreds" to organize call- and errbacks=
\r
103 already make use of [2]. Alot has a "MessageWidget" that displays a single=
\r
106 We can easily access and parse email messages into MIME-trees (msg.get_emai=
\r
108 email.message object; pythons email module allows extensive and RFC complia=
\r
112 We already offer full compatibility with the mailcap protocol to constuct s=
\r
114 of external MIME handlers.
\r
116 We know how to call external commands asynchronously; `alot.helper.call_cmd=
\r
118 and returns a Deferred to which we can connect callback functions.
\r
123 We want to turn a email.message into nicely rendered text and display it as=
\r
125 Calls to renderers should be done asynchronously, so that displaying large =
\r
127 does not block the interface unnecessarily.
\r
128 The text representation should be stored in a way that can be incrementally=
\r
130 for use with message parts decrypted at a later point.
\r
136 1. Current solution: walk the MIME-tree depth-first, use blocking calls to =
\r
138 and create a fixed "body" string that is displayed in the widget.
\r
139 A silly and hackish solution that we want to get rid of for obvious reasons.
\r
141 2. Use a "PartWidget" that is able to display a node in the MIME-tree:
\r
142 Its constructor creates the representation in a RFC compliant way, that is,
\r
143 it decodes 'text/plain' parts, stacks other widgets of the same kind on top=
\r
145 for multipart parts or calls external renderer to get a text representation.
\r
148 * widgets should not be clever and contain/construct any kind of additiona=
\r
150 * its hard to update these widgets when a part gets decrypted; =
\r
152 * decrypted parts are not available outside the displaying widget, widgets=
\r
154 replaced completely when one rebuilds the buffer (refresh cmd)
\r
156 * we can use Deferreds relatively painlessly in the ui (as opposed to the =
\r
159 3. Accumulate rendered text in a tree structure *inside* message-objects an=
\r
161 massage update the widget that displays it. One could let the widget regist=
\r
163 some update-callback with the widget that rebuilds the widgets content.
\r
164 These callbacks are called after the external handler has finished and the =
\r
166 internal text-representation has been updated.
\r
170 * rendered text/decrypted message parts end up in the message and are avai=
\r
172 and redisplay at will
\r
174 * the calls to MIME-handlers are dealt with as Deferreds which depend on t=
\r
176 loop and indirectly on urwid. This is exactly the kind of tight coupling=
\r
177 I'm trying to avoid:
\r
178 Messages should be independent of the interface.
\r
179 * Messages with multiple externally rendered parts will rebuild their widg=
\r
181 * references to old widgets (replaced e.g. after a buffer rebuild) will be=
\r
183 them from being garbage-collected
\r
185 I'm surely missing an easy and elegant solution here.
\r
186 Any pointers or comments are much appreciated.
\r
191 [0]: http://alot.readthedocs.org/en/latest/api/database.html
\r
192 [1]: http://excess.org/urwid/
\r
193 [2]: http://twistedmatrix.com/documents/current/core/howto/defer.html
\r
194 [3]: http://docs.python.org/library/email
\r