Read Programming Python Online

Authors: Mark Lutz

Tags: #COMPUTERS / Programming Languages / Python

Programming Python (147 page)

BOOK: Programming Python
9.11Mb size Format: txt, pdf, ePub
ads
Ideas for Improvement

Although I
use the 3.0 version of PyMailGUI as is on a regular basis
for both personal and business communications, there is always room for
improvement to software, and this system is no exception. If you wish to
experiment with its code, here are a few suggested projects to close out
this chapter:

Column sorts and list layout

Mail list windows could be sorted by columns on demand. This
may require a more sophisticated list window structure which
presents columns more distinctly. The current display of mail lists
seems like the most obvious candidate for cosmetic upgrade in
general, and any column sorting solution would likely address this
as well. tkinter extensions such as the
Tix
HList
widget
may show promise here, and the third-party
TkinterTreectrl
supports multicolumn sortable listboxes, too, but is
available only for Python 2.X today; consult the Web and other
resources for pointers and details.

Mail save file (and sent file) size

The implementation of
save-mail
files
limits their size by loading them into memory all at once; a DBM
keyed-access implementation may work around this constraint. See the
list windows module comments for ideas. This also applies to
sent-mail
save files, though the user can limit
their sizes with periodic deletions; users might also benefit from a
prompt for deletions if they grow too large.

Embedded links

Hyperlink URLs within
messages could be highlighted visually and made to
spawn a web browser automatically when clicked by using the launcher
tools we met in the GUI and system parts of this book (tkinter’s
text widget supports links directly).

Help text redundancy

In this version, the help text had grown so large that it is
also implemented as HTML and displayed in a web browser using
Python’s
webbrowser
module
(instead of or in addition to text, per
mailconfig
settings). That means there are
currently two copies of the basic help text: simple text and HTML.
This is less than ideal from a maintenance perspective going
forward.

We may want to either drop the simple text version altogether,
or attempt to extract the simple text from the HTML with Python’s
html.parser
module to avoid
redundant copies; see
Chapter 19
for more
on HTML parsing in general, and see PyMailGUI’s new
html2text
module for a plain-text extraction tool prototype. The
HTML help version also does not include links to display source
files; these could be inserted into the HTML automatically with
string formatting, though it’s not clear what all browsers will do
with Python source code (some may try to run it).

More threading contexts

Message Save and Split file writes could also be threaded for
worst-case scenarios. For pointers on making Saves parallel, see the
comments in the file class of
ListWindows.py
;
there may be some subtle issues that require both
thread locks and general file locking for potentially concurrent
updates. List window index fills might also be threaded for
pathologically large mailboxes and woefully slow machines
(optimizing to avoid reparsing headers may help here, too).

Attachment list deletes

There is currently no way to delete an attachment once it has
been added in compose windows. This might be supported by adding
quick-access part buttons to compose windows, too, which could
verify and delete the part when clicked.

Spam filtering

We could add an automatic spam
filter for mails fetched, in addition to any provided
at the email server or ISP. The Python-based
SpamBayes
might help. This is often better
implemented by servers than clients, but not all ISPs filter
spam.

Improve multiple account usage

Per the prior section, the current system selects one of
multiple email accounts and uses its corresponding mail
configuration module by running special code in the
altconfigs
subdirectory. This works for a book example, but it would be fairly
straightforward to improve for broader audiences.

Increased visibility for sent file

We may want to add an explicit button for opening the
sent-mails file. PyMailGUI already does save sent messages to a text
file automatically, which may be opened currently with the list
window’s Open button. Frankly, though, this feature may be a
too-well-kept secret—I forgot about it myself when I revisited the
program for this edition! It might also be useful to allow sent-mail
saves to be
disabled in
mailconfig
for users who might never
delete from this file (it can grow large fairly quickly; see the
earlier prompt-for-deletion suggestion as well).

Thread queue speed tuning

As mentioned when describing version 3.0 changes, the thread
queue has been sped up by as much as a factor of 10 in this version
to quicken initial header downloads. This is achieved both by
running more than one callback per timer event and scheduling timer
events to occur twice as often as before. Checking the queue too
often, however, might increase CPU utilization beyond acceptable
levels on some machines. On my Windows laptop, this overhead is
negligible (the program’s CPU utilization is 0% when idle), but you
may want to tune this if it’s significant on your platform.

See the list windows code for speed settings, and
threadtools.py
in
Chapter 10
for the base code. In general,
increasing the number of callbacks per event and decreasing timer
frequency will decrease CPU drain without sacrificing
responsiveness. (And if I had a nickel for every time I said
that…)

Mailing lists

We could add support for mailing lists, allowing users to
associate multiple email addresses with a saved list name. On sends
to a list name, the mail would be sent to all on the list (the To
addresses passed to
smtplib
), but
the email list could be used for the email’s To header line. See
Chapter 13
’s SMTP coverage for mailing
list–related examples.

HTML main text views and edits

PyMailGUI is still oriented toward supporting only plain text
for the main text of a message, despite the fact that some mailers
today are more HTML-biased in this regard. This partly stems from
the fact that PyMailGUI uses a simple tkinter
Text
widget for
main text composition. PyMailGUI can display such messages’ HTML in
a popped-up web browser, and it attempts to extract text from the
HTML for display per the next note, but it doesn’t come with its own
HTML editor. Fully supporting HTML for main message text will likely
require a tkinter extension (or, regrettably, a port to another GUI
toolkit with working support for this feature).

HTML parser honing

On a related note, as described earlier, this version includes
a simple-minded HTML parser, applied to extract text from HTML main
(or only) text parts when they are displayed or quoted in replies
and forwards. As also mentioned earlier, this parser is nowhere near
complete or robust; for production-level quality, this would have to
be improved by testing over a large set of HTML emails. Better yet,
watch for a Python 3.X–compatible version of more robust and
complete open source alternatives, such as the
html2text.py
same-named third-party
utility described in this chapter’s earlier note. The open source
BeautifulSoup
system offers another lenient and forgiving HTML
parser, but is based on SGMLParser tools available in 2.X only
(removed in 3.X).

Text/HTML alternative mails

Also in the HTML department, there is presently no support for
sending both text and HTML versions of a mail as a MIME
multipart/alternative message—a popular scheme which supports both
text- and HTML-based clients and allows users to choose which to
use. Such messages can be viewed (both parts are offered in the
GUI), but cannot be composed. Again, since there is no support for
HTML editing anyhow, this is a moot point; if such an editor is ever
added, we’d need to support this sort of mail structure in
mailtools
message object construction code
and refactor parts of its current send logic so that it can be
shared.

Internationalized headers throw list columns
off

As is so often true in software, one feature added in this
version broke another already present: the fonts used for display of
some non-ASCII Unicode header fields is large enough to throw off
the fixed-width columns in mail index list windows. They rely on the
assumption that N characters is always the same width among all
mails, and this is no longer true for some Chinese and other
character set encodings.

This isn’t a showstopper—it only occurs when some i18n headers
are displayed, and simply means that “|” column separators are askew
for such mails only, but could still be addressed. The fix here is
probably to move to a more sophisticated list display, and might be
resolved as a side effect of allowing for the column sorts described
earlier.

Address books

PyMailGUI has no notion of automatically filling in an email
address from an address book, as many modern email clients do.
Adding this would be an interesting extension; low-level keyboard
event binding may allow matching as addresses are typed, and
Python’s
pickle
and
shelve
modules of Chapters
1
and
17
might come in handy for data
storage.

Spelling checker

There is currently no
spelling checker of the sort most email programs have
today. This could be added in PyMailGUI, but it would probably be
more appropriate to add it in the PyEdit text edit component/program
that it uses, so the spell-checking would be inherited by all PyEdit
clients. A quick web search reveals a variety of options, including
the interesting
PyEnchant
third-party package, none of which we have space to
explore here.

Mail searches

Similarly, there is no support for searching emails’ content
(headers or bodies) for a given string. It’s not clear how this
should be provided given that the system fetches and caches just
message headers until a mail is requested, but searching large
inboxes can be convenient. As is, this can be performed manually by
running a Save to store fetched mails in a text file and searching
in that file externally.

Frozen binary distribution

As a desktop
program, PyMailGUI seems an ideal candidate for
packing as a self-contained frozen binary executable, using tools
such as PyInstaller, Py2Exe, and others. When distributed this way,
users need not install Python, since the Python runtime is embedded
in the executable.

Selecting Reply versus Reply-All in the
GUI

As described in the 3.0 changes overview earlier, in this
version, Reply by default now copies all the original mail’s
recipients by prefilling the Cc line, in addition to replying to the
original sender. This Cc feature can be turned off in
mailconfig
because it may not be desirable
in all cases. Ideally, though, this should be selectable in the GUI
on a mail-by-mail basis, not per session. Adding another button to
list windows for ReplyAll would suffice; since this feature was
added too late in this project for GUI changes, though, this will
have to be relegated to the domain of suggested exercise.

Propagating attachments?

When replying to or
forwarding an email, PyMailGUI discards any
attachments on the original message. This is by design, partly
because there is currently no way to delete attached parts in the
GUI prior to sending (you couldn’t remove selectively and couldn’t
remove all), and partly because this system’s current sole user
prefers to work this way.

Users can work around this by running a Split to save all
parts in a directory, and then adding any desired attachments to the
mail from there. Still, it might be better to allow the user to
choose that this happen automatically for replies and forwards.
Similarly, forwarding HTML mails well currently requires saving and
attaching the HTML part to avoid quoting the text; this might be
similarly addressed by parts propagation in general.

Disable editing for viewed mails?

Mail text is editable in message view windows, even though a
new mail is not being composed. This is deliberate—users can
annotate the message’s text and save it in a text file with the Save
button at the bottom of the window, or simply cut-and-paste portions
of it into other windows. This might be confusing, though, and is
redundant (we can also edit and save by clicking on the main text’s
quick-access part button). Removing edit tools would require
extending PyEdit. Using PyEdit for display in general is a useful
design—users also have access to all of PyEdit’s tools for the mail
text, including save, find, goto, grep, replace, undo/redo, and so,
though edits might be superfluous in this context.

Automatic periodic new mail check?

It would be straightforward to add the ability to
automatically check for and fetch new incoming email periodically,
by registering long-duration timer events with either the
after
widget method or the
threading
module’s timer object. I haven’t
done so because I have a personal bias against being surprised by
software, but your mileage may vary.

BOOK: Programming Python
9.11Mb size Format: txt, pdf, ePub
ads

Other books

Aiden's Charity by Leigh, Lora
The Backpacker by John Harris
The Beast Loves Curves by J. S. Scott
The War of Wars by Robert Harvey
4 Terramezic Energy by John O'Riley
A Kind of Vanishing by Lesley Thomson
Good Sex Illustrated by Tony Duvert