Section 15.1.


15.1. "Use the Source, Luke"

The preceding chapter introduced Python's client-side Internet tool setthe standard library modules available for email, FTP, network news, and more, from within a Python script. This chapter picks up where the last one left off and presents a complete client-side examplePyMailGUI, a Python program that sends, receives, composes, and parses Internet email messages.

Although the end result is a working program that you can actually use for your email, this chapter also has a few additional agendas worth noting before we get started:


Client-side scripting

For one thing, PyMailGUI implements a full-featured GUI that runs on your machine, and communicates with your mail servers when necessary. As such, it is a network client program that further illustrates some of the preceding chapter's topics, and it will help us contrast server-side solutions introduced in the next chapter.


Code reuse

Additionally, PyMailGUI ties together a number of the utility modules we've been writing in the book so far, and demonstrates the power of code reuse in the processit uses a thread module to allow mail transfers to overlap in time, a set of mail modules to process message content and route it across networks, a window protocol module to handle icons, and so on. Moreover, it inherits the power of tools in the Python standard library, such as the email package; message construction and parsing, for example, is trivial here.


Programming in the large

And finally, because PyMailGUI is a relatively large-scale program (at least as Python programs go), it shows by example some of the code structuring techniques that come in handy once we leave the realm of the small. Object-oriented programming (OOP) and modular design work well here to divide the system in smaller, self-contained units.

Ultimately, though, PyMailGUI serves to illustrate just how far the combination of GUIs, networking, and Python can take us. Like all Python programs, this system is scriptableonce you've learned its general structure, you can easily change it to work as you like, by modifying its source code. And like all Python programs, this one is portable across platformsyou can run it on any system with Python and a network connection, without having to change its code. Such advantages become automatic when your software is coded in an open source, portable, and readable language like Python.

15.1.1. Source Code Modules

This chapter is something of a self-study exercise. Because PyMailGUI is fairly large and mostly applies concepts we've already learned, we won't go into much detail about its actual code. Instead, it is listed for you to read on your own. I encourage you to study the source and comments and to run this program on your own to get a feel for its operation. Also, be sure to refer back to the modules we introduced earlier in the book and are reusing here, to gain a full understanding of the system. For reference, here are the major examples that will see new action in this chapter:


Example 14-21: PP3E.Internet.Email.mailtools (package)

Server sends and receives, parsing, construction (Chapter 14)


Example 11-17: PP3E.Gui.Tools.threadtools.py

Thread queue management for GUI callbacks (Chapter 11)


Example 11-13: PP3E.Gui.Tools.windows.py

Border configuration for top-level window (Chapter 11)


Example 12-4: PP3E.Gui.TextEditor.textEditor.py

Text widget used in mail view windows, and in some pop ups (Chapter 12)

Some of these modules in turn use additional examples we coded earlier, but that are not imported by PyMailGUI itself (textEditor, for instance, uses guimaker to create its windows and toolbar). We'll also be coding new modules here. The following new modules are intended to be useful in other programs:


utilities.py

Various pop-up windows, written for general use


messagecache.py

A cache that keeps track of mail already loaded


wraplines.py

A utility for wrapping long lines of messages


mailconfig.py

User configuration parametersserver names, fonts, and so on (augmented here)

Finally, the following are new modules coded in this chapter and are specific to the PyMailGUI program:


SharedNames.py

Program-wide globals used by multiple files


ViewWindows.py

The implementation of View, Write, Reply, and Forward message view windows


ListWindows.py

The implementation of mail-server and local-file message list windows


PyMailGuiHelp2.py

User-oriented help text, opened by the main window's bar button


PyMailGui2.py

The main, top-level file of the program, run to launch the main window

All told, PythonMailGUI comprises the nine new modules in the preceding two lists and is composed of some 2,200 lines of source code (including comments, whitespace, and 530 lines of help text). This doesn't include the four other book examples in the previous list that are reused in PyMailGUI, which themselves constitute 1,600 additional lines.[*] This is the largest example we'll see in this book, but you shouldn't be deterred by its size. Because it uses modular and OOP techniques, the code is simpler than you may think:

[*] And remember: you would have to multiply these line counts by a factor of four or five to get the equivalent in a language like C or C++. If you've done much programming, you probably recognize that the fact that we can implement a fairly full-featured mail processing program in roughly 2,000 lines of code speaks volumes about the power of the Python language and its libraries. For comparison, the original version of this program from the second edition of this book was just 725 lines in 3 new modules, but also was very limitedit did not support PyMailGUI2's attachments, thread overlap, local mail files, and so on.

  • Python's modules allow us to divide the system into files that have a cohesive purpose, with minimal coupling between themcode is easier to locate and understand if your modules have a logical, self-contained structure.

  • Python's OOP support allows us to factor code for reuse, and avoid redundancyas you'll see, code is customized, not repeated, and the classes we will code reflect the actual components of the GUI to make them easy to follow.

For instance, the implementation of mail list windows is easy to read and change, because it has been factored into a common shared superclass, which is customized by subclasses for mail-server and save-file lists; since these are mostly just variations on a theme, most of the code appears in just one place. Similarly, the code that implements the message view window is a superclass shared by write, reply, and forward composition windows; subclasses simply tailor it for writing rather than viewing.

Although we'll deploy these techniques in the context of a mail processing program here, such techniques will apply to any nontrivial program you'll write in Python.

To help get you started, the PyMailGuiHelp2.py module listed last in this chapter includes a help text string that describes how this program is used, as well as its major features. Experimenting with the system, while referring to its code, is probably the best and quickest way to uncover its secrets.

15.1.2. Why PyMailGUI?

PyMailGUI is a Python program that implements a client-side email processing user interface with the standard Tkinter GUI toolkit. It is presented both as an instance of Python Internet scripting and as a realistically scaled example that ties together other tools we've already seen, such as threads and Tkinter GUIs.

Like the pymail console-based program we wrote in Chapter 14, PyMailGUI runs entirely on your local computer. Your email is fetched from and sent to remote mail servers over sockets, but the program and its user interface run locally. As a result, PyMailGUI is called an email client: like pymail, it employs Python's client-side tools to talk to mail servers from the local machine. Unlike pymail, though, PyMailGUI is a full-featured user interface: email operations are performed with point-and-click operations and advanced mail processing such as attachments and save files is supported.

Like many examples presented in this text, PyMailGUI is a practical, useful program. In fact, I run it on all kinds of machines to check my email while traveling around the world teaching Python classes. Although PyMailGUI won't put Microsoft Outlook out of business anytime soon, it has two key pragmatic features that have nothing to do with email itself: portability and scriptability, which are attractive features in their own right and they merit a few additional words here.


It's portable

PyMailGUI runs on any machine with sockets and a Python with Tkinter installed. Because email is transferred with the Python libraries, any Internet connection that supports Post Office Protocol (POP) and Simple Mail Transfer Protocol (SMTP) access will do. Moreover, because the user interface is coded with Tkinter, PyMailGUI should work, unchanged, on Windows, the X Window System (Unix, Linux), and the Macintosh (classic and OS X).

Microsoft Outlook may be a more feature-rich package, but it has to be run on Windows, and more specifically, on a single Windows machine. Because it generally deletes email from a server as it is downloaded and stores it on the client, you cannot run Outlook on multiple machines without spreading your email across all those machines. By contrast, PyMailGUI saves and deletes email only on request, and so it is a bit friendlier to people who check their email in an ad hoc fashion on arbitrary computers.


It's scriptable

PyMailGUI can become anything you want it to be because it is fully programmable. In fact, this is the real killer feature of PyMailGUI and of open source software like Python in generalbecause you have full access to PyMailGUI's source code, you are in complete control of where it evolves from here. You have nowhere near as much control over commercial, closed products like Outlook; you generally get whatever a large company decided you need, along with whatever bugs that company might have introduced.

As a Python script, PyMailGUI is a much more flexible tool. For instance, we can change its layout, disable features, and add completely new functionality quickly by changing its Python source code. Don't like the mail-list display? Change a few lines of code to customize it. Want to save and delete your mail automatically as it is loaded? Add some more code and buttons. Tired of seeing junk mail? Add a few lines of text processing code to the load function to filter spam. These are just a few examples. The point is that because PyMailGUI is written in a high-level, easy-to-maintain scripting language, such customizations are relatively simple, and might even be fun.

At the end of the day, because of such features, this is a realistic Python program that I actually useboth as a primary email tool and as a fallback option when my ISP's webmail system goes down (which, as I mentioned in the prior chapter, has a way of happening at the worst possible times).[*] Python scripting is an enabling skill to have.

[*] In fact, my ISP's webmail send system went down the very day I had to submit this edition of the book to my publisher! No worriesI fired up PyMailGUI and used it to send the book as attachment files through a different server. In a sense, this book submitted itself.

It's also worth mentioning that PyMailGUI achieves its portability and scriptability, and implements a full-featured email interface along the way, in roughly 2,200 lines of program code. It may not have all the bells and whistles of some commercial products, but the fact that it gets as close as it does in so few lines of code is a testament to the power of both the Python language and its libraries.

15.1.3. Running PyMailGUI

Of course, to script PyMailGUI on your own, you'll need to be able to run it. PyMailGUI requires only a computer with some sort of Internet connectivity (a PC with a broadband or dial-up account will do) and an installed Python with the Tkinter extension enabled. The Windows port of Python has this capability, so Windows PC users should be able to run this program immediately by clicking its icon.

Two notes on running the system: first, you'll want to change the file mailconfig.py in the program's source directory to reflect your account's parameters, if you wish to send or receive mail from a live server; more on this as we interact with the system. Second, you can still experiment with the system without a live Internet connectionfor a quick look at message view windows, use the main window's Open buttons to open saved-mail files stored in the program's SavedMail directory. In fact, the PyDemos launcher script at the top of the book's examples directory forces PyMailGUI to open saved-mail files by passing filenames on the command line.

15.1.4. Presentation Strategy

PyMailGUI is easily the largest program in this book, but it doesn't introduce many library interfaces that we haven't already seen in this book. For instance:

  • The PyMailGUI interface is built with Python's Tkinter, using the familiar listboxes, buttons, and text widgets we met earlier.

  • Python's email package is applied to pull-out headers, text, and attachments of messages, and to compose the same.

  • Python's POP and SMTP library modules are used to fetch, send, and delete mail over sockets.

  • Python threads, if installed in your Python interpreter, are put to work to avoid blocking during potentially overlapping, long-running mail operations.

We're also going to reuse the TextEditor object we wrote in Chapter 12 to view and compose messages, the mailtools package's tools we wrote in Chapter 14 to load and delete mail from the server, and the mailconfig module strategy introduced in Chapter 14 to support end-user settings. PyMailGUI is largely an exercise in combining existing tools.

On the other hand, because this program is so long, we won't exhaustively document all of its code. Instead, we'll begin by describing how PyMailGUI works from an end user's perspectivea brief demo of its windows in action. After that, we'll list the system's new source code modules without many additional comments, for further study.

Like most of the longer case studies in this book, this section assumes that you already know enough Python to make sense of the code on your own. If you've been reading this book linearly, you should also know enough about Tkinter, threads, and mail interfaces to understand the library tools applied here. If you get stuck, you may wish to brush up on the presentation of these topics earlier in the book.

15.1.5. New in This Edition

The 2.1 version of PyMailGUI presented in this third edition of the book is a complete rewrite of the 1.0 version of the prior edition. The main script in the second edition's version was only some 500 lines long, and was really something of a toy or prototype, written mostly to serve as a book example. In this edition, PyMailGUI is a much more realistic and full-featured program that can be used for day-to-day email processing. It has grown to 2,200 source lines (3,800 including related modules that are reused). Among its new weapons are these:

  • MIME multipart mails with attachments may be both viewed and composed.

  • Mail transfers are no longer blocking, and may overlap in time.

  • Mail may be saved and processed offline from a local file.

  • Message parts may now be opened automatically within the GUI.

  • Multiple messages may be selected for processing in list windows.

  • Initial downloads fetch mail headers only; full mails are fetched on request.

  • View window headers and list window columns are configurable.

  • Deletions are performed immediately, not delayed until program exit.

  • Most server transfers report their progress in the GUI.

  • Long lines are intelligently wrapped in viewed and quoted text.

  • Fonts and colors in list and view windows may be configured by the user.

  • Authenticating SMTP mail-send servers that require login are supported.

  • Sent messages are saved in a local file, which may be opened in the GUI.

  • View windows intelligently pick a main text part to be displayed.

  • Already fetched mail headers and full mails are cached for speed.

  • Date strings and addresses in composed mails are formatted properly.

  • View windows now have quick-access buttons for attachments/parts (2.1).

  • Inbox out-of-sync errors are detected on deletes, and on index and mail loads (2.1).

  • Save-mail file loads and deletes are threaded, to avoid pauses for large files (2.1).

The last three items on this list were added in version 2.1; the rest were part of the 2.0 rewrite. Some of these changes were made simple by growth in standard library tools (e.g., support for attachments is straightforward with the new email package), but most represent changes in PyMailGUI itself. There have also been a few genuine fixes: addresses are parsed more accurately, and date and time formats in sent mails are now standards conforming, because these tasks use new tools in the email package.

Although there is still room for improvement (see the list at the end of this chapter), the program provides a full-featured interface, represents the most substantial example in this book, and serves to demonstrate a realistic application of the Python language. As its users often attest, Python may be fun to work with, but it's also useful for writing practical and nontrivial software.




Programming Python
Programming Python
ISBN: 0596009259
EAN: 2147483647
Year: 2004
Pages: 270
Authors: Mark Lutz

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net