Software I've written myself, or projects to which I've made a reasonable contribution.
Available in a git repository.
Repository: rss2email
Browsable repository: rss2email
Author: W. Trevor King
Since November 2012 I've been maintaining rss2email, a package that converts RSS or Atom feeds to email so you can follow them with your mail user agent. Rss2email was created by the late Aaron Swartz and maintained for several years by Lindsey Smith. I've added a mailing list (hosted with mlmmj) and PyPI package and made the GitHub location the homepage.
Overall, setting up the standard project infrastructure has been fun, and it's nice to see interest in the newly streamlined code picking up. The timing also works out well, since the demise of Google Reader may push some talented folks in our direction. I'm not sure how visible rss2email is, especially the fresh development locations, hence this post ;). If you know anyone who might be interested in using (or contributing to!) rss2email, please pass the word.
Available in a git repository.
Repository: mutt-ldap
Browsable repository: mutt-ldap
Author: W. Trevor King
I wrote this Python script to query an LDAP server for addresses from Mutt. In December 2012, I got some patches from Wade Berrier and Niels de Vos. Anything interesting enough for others to hack on deserves it's own repository, so I pulled it out of my blog repository (linked above, and mirrored on GitHub).
The README
is posted on the PyPI page.
Available in a git repository.
Repository: curses-check-for-keypress
Browsable repository: curses-check-for-keypress
Author: W. Trevor King
There are some points in my experiment control code where the program does something for an arbitrary length of time (e.g, waits while the operator manually adjusts a laser's alignment). For these situations, I wanted to be able to loop until the user pressed a key. This is a simple enough idea, but the implementation turned out to be complicated enough for me to spin it out as a stand-alone module.
Available in a git repository.
Repository: pyassuan
Browsable repository: pyassuan
Author: W. Trevor King
I've been trying to come up with a clean way to verify detached PGP signatures from Python. There are a number of existing approaches to this problem. Many of them call gpg using Python's multiprocessing or subprocess modules, but to verify detached signatures, you need to send the signature in on a separate file descriptor, and handling that in a way safe from deadlocks is difficult. The other approach, taken by PyMe is to wrap GPGME using SWIG, which is great as far as it goes, but development seems to have stalled, and I find the raw GPGME interface excessively complicated.
The GnuPG tools themselves often communicate over sockets using the
Assuan protocol, and I'd already written an Assuan server to
handle pinentry (originally for my gpg-agent post, not part of
pyassuan). I though it would be natural if there was a gpgme-agent
which would handle cryptographic tasks over this protocol, which would
make the pgp-mime implementation easier. It turns out that there
already is such an agent (gpgme-tool), so I turned my pinentry
script into the more general pyassuan package. Now using Assuan from
Python should be as easy (or easier?) than using it from C via
libassuan.
The README
is posted on the PyPI page.
Available in a git repository.
Repository: pygrader
Browsable repository: pygrader
Author: W. Trevor King
The last two courses I've TAd at Drexel have been scientific computing courses where the students are writing code to solve homework problems. When they're done, they email the homework to me, and I grade it and email them back their grade and comments. I've played around with developing a few grading frameworks over the years (a few years back, one of the big intro courses kept the grades in an Excel file on a Samba share, and I wrote a script to automatically sync local comma-separated-variable data with that spreadsheet. Yuck :p), so I figured this was my change to polish up some old scripts into a sensible system to help me stay organized. This system is pygrader.
During the polishing phase, I was searching around looking for prior art ;), and found that Alex Heitzmann had already created pygrade, which is the name I under which I had originally developed my own project. While they are both grade databases written in Python, Alex's project focuses on providing a more integrated grading environment.
Pygrader accepts assignment submissions from students through its
mailpipe
command, which you can run on your email inbox (or from
procmail). Students submit assignments with an email subject like
[submit] <assignment name>
mailpipe
automatically drops the submissions into a
student/assignment/mail
mailbox, extracts any MIME attachments
into the student/assignment/
directory (without clobbers, with
proper timestamps), and leaves you to get to work.
Pygrader also supports multiple graders through the mailpipe
command. The other graders can request a student's submission(s) with
an email subject like
[get] <student name>, <assignment name>
Then they can grade the submission and mail the grade back with an email subject like
[grade] <student name>, <assignment name>
The grade-altering messages are also stored in the
student/assignment/mail
mailbox, so you can peruse them later.
Pygrader doesn't spawn editors or GUIs to help you browse through submissions or assigning grades. As far as I am concerned, this is a good thing.
When you're done grading, pygrader can email (email
) your grades and
comments back to the students, signing or encrypting with pgp-mime
if either party has configured a PGP key. It can also email a
tab-delimited table of grades to the professors to keep them up to
speed. If you're running mailpipe
via procmail, responses to grade
request are sent automatically.
While you're grading, pygrader can search for ungraded assignments, or
for grades that have not yet been sent to students (todo
). It can
also check for resubmissions, where new submissions come in response
to earlier grades.
The README
is posted on the PyPI page.
Some of the classes I TA use Maple. (Caveat: I prefer Python,
as a more general language. Use SymPy or Sage if you need
symbolic processing.) Anyhow, I get Maple worksheets to grade.
SSHing into the department computer lab to fire up xmaple
is a
pain, so I wrote mw2txt.py to extract the Maple commands from the
worksheet. It benefits from the fact that worksheets are fairly clean
XML. Graphs and equations are more difficult, since they have
complicated layout and are stored as encoded blobs. Other than that,
things work pretty well. Here's the output from my example.mw
example worksheet, picking out the math-mode sections (in red) and
unprocessed blocks (in yellow) from the comments (uncolored).
$ mw2txt.py --color example.mw
Hi there
> restart;
> interface(prettyprint=0):
> 1;# one + plus 2 two ;
1
> 3 + 4; bold
7
Equation
Available in a git repository.
Repository: update-copyright
Browsable repository: update-copyright
Author: W. Trevor King
A few years ago I was getting tired of having missing or out-of-date copyright blurbs in packages that I was involved with (old license text, missing authors, etc.). This is important stuff, but not the kind of thing that is fun to maintain by hand. I wrote a script for bugs everywhere that automated the process, using the version control system to extract lists of authors and dates for each file. The script was great, so I ported it into a few other projects I was involved in.
This month I realized that it would be much easier to just break the script out into its own package, and only maintain a config file in each of the projects that use it. I don't know why this didn't occur to me years ago :p. Anyhow, here it is! Enjoy.
The README
, with usage details, is posted on the PyPI page.
Mailcap files, defined in RFC 1524, allow you to tell you mail clients, web browsers, and other programs how you want to view and edit various MIME types. Since interaction with your mailcap files often occurs deep within the bowels of your program, I've written up a very simple Python script to test your mailcap entries: mailcap-test.py. Enjoy!
Related utilities include xdg-open, mimeopen, and sensible-utils.
Quoting
Quoting in mailcap files is a tricky issue. From the Mutt man page:
Secure use of mailcap
The interpretion of shell meta-characters embedded in MIME parameters can lead to security problems in general. Mutt tries to quote parameters in expansion of
%s
syntaxes properly, and avoids risky characters by substituting them, see themailcap_sanitize
variable.Although mutt's procedures to invoke programs with mailcap seem to be safe, there are other applications parsing mailcap, maybe taking less care of it. Therefore you should pay attention to the following rules:
Keep the %-expandos away from shell quoting. Don't quote them with single or double quotes. Mutt does this for you, the right way, as should any other program which interprets mailcap. Don't put them into backtick expansions. Be highly careful with eval statements, and avoid them if possible at all. Trying to fix broken behaviour with quotes introduces new leaks - there is no alternative to correct quoting in the first place.
If you have to use the %-expandos' values in context where you need quoting or backtick expansions, put that value into a shell variable and reference the shell variable where necessary, as in the following example (using $charset inside the backtick expansion is safe, since it is not itself subject to any further expansion):
text/test-mailcap-bug; cat %s; copiousoutput; test=charset=%{charset} \ && test "`echo $charset | tr '[A-Z]' '[a-z]'`" != iso-8859-1
In the course of my research, I've spend a good deal of time developing clean, Python interfaces to much of our lab equipment. I also tend to have strong opinions on the One True Way® to solve a problem. This means that I occasionaly end up writing script to run other people's experiment, especially when they don't take all that much time to write.
I wrote slow_bend
for Liming Zhao, who was a postdoc in our lab
from 2008 to 2010. Liming coated one side of an AFM cantilever with a
film of cellulose and used slow bend.py (version 0.2) to monitor
the cantilever deflection as he flushed in different buffers
(paper). Unfortunately, the paper claims the data aquisition was
carried out in LabView.
slow_bend
is not a complicated program; it polls analog input
channels using pycomedi (and optionally reads temperatures using
backends from pypid). The polling continues until slow_bend
recieves a KeyboardInterrupt.
$ slow_bend.py --version
0.4
$ slow_bend.py 0 3
#time (second) chan 0 (bit) chan 0 (volt) chan 3 (bit) chan 3 (volt)
1.81198e-05 34727 0.598001 39679 2.10925
4.00409 34956 0.667887 38033 1.60693
8.00408 35074 0.703899 36780 1.22454
12.0041 35041 0.693828 35814 0.929732
16.0041 34917 0.655985 35044 0.694743
^C
Available in a git repository.
Repository: cookbook
Browsable repository: cookbook
Author: W. Trevor King
I've been running a home-rolled recipe webapp for a year now, and it
worked fairly well in a bare-bones sort of way. However, I recently
had to make some changes to my personal website (since EveryDNS and
aparently most other free DNS providers were bought by Dyn), which
prompted me to translate cookbook
into a Django app. Thanks to
the wonders of Django, Grappelli, and django-taggit, the code
is now leaner, meaner, and prettier!
See the README for details.