7 years agoREADME: Remove duplicate Gentoo hyperlink target master
W. Trevor King [Sun, 20 Jan 2013 19:01:08 +0000 (14:01 -0500)]
README: Remove duplicate Gentoo hyperlink target

7 years agoREADME: Fix 'pycomedi' -> 'pygrader' copy/paste error
W. Trevor King [Sun, 20 Jan 2013 18:48:14 +0000 (13:48 -0500)]
README: Fix 'pycomedi' -> 'pygrader' copy/paste error

7 years agoREADME: document submodule usage
W. Trevor King [Tue, 11 Dec 2012 19:43:31 +0000 (14:43 -0500)]
README: document submodule usage

This tells people who didn't read the commit message what to do with
the changes from:

  commit 8e10f59d36ea9c619241efaf3213156406dd74f9
  Author: W. Trevor King <>
  Date:   Tue Dec 11 11:30:24 2012 -0500

    dep: add pygrader dependencies as submodules

7 years handle command-less invocation cleanly
W. Trevor King [Tue, 11 Dec 2012 16:49:53 +0000 (11:49 -0500)] handle command-less invocation cleanly

This avoids:

  Traceback (most recent call last):
    File "/.../", line 202, in <module>
      func_args = _inspect.getargspec(args.func).args
  AttributeError: 'Namespace' object has no attribute 'func'

7 years agodep: add pygrader dependencies as submodules
W. Trevor King [Tue, 11 Dec 2012 16:30:24 +0000 (11:30 -0500)]
dep: add pygrader dependencies as submodules

With the submodules checked out, you can run:

  $ PYTHONPATH=dep ./bin/ ...

to run pygrader without installing any external pacakges on your
system.  With Gentoo's Python 3.3 support still flaky [1,2], this is
less painful than maintaining the dependencies by hand.

Checkout updated submodules with:

  $ git submodule update --init

The jinja2 repository is my local branch, which applies 2to3 directly
to the source (because we are loading jinja2 directly from the
submodule source).  I will rebase my jinja2 branch against new
upstream versions, so don't do any Jinja development based on my


7 years agomailpipe: fix _get_message_subject() doctest for "-ascii part".
W. Trevor King [Mon, 22 Oct 2012 00:19:37 +0000 (20:19 -0400)]
mailpipe: fix _get_message_subject() doctest for "-ascii part".

In both Python 3.2.3 and 3.3 the doctest subject is encoded as

  '=?utf-8?q?unicode_part?= -ascii part'

In Python 3.3, this is now correctly decoded (I think) to retain the
space.  It seems to me that the encoded version should actually be:

  '=?utf-8?q?unicode_part?=-ascii part'

but I don't care enough to track that down ;).

7 years agotabulate: fix sval -> return typo in _statistic().
W. Trevor King [Mon, 22 Oct 2012 00:16:22 +0000 (20:16 -0400)]
tabulate: fix sval -> return typo in _statistic().

7 years agopgp: don't assume protocol/micalg ordering in doctest output.
W. Trevor King [Mon, 22 Oct 2012 00:13:12 +0000 (20:13 -0400)]
pgp: don't assume protocol/micalg ordering in doctest output.

The Content-Type header is eventually set by Message.add_header(),
which gets extra parameters from **_params and iterates over them with
_params.items().  _params is a dict, so .items() is not sorted.  I
forced the ordering in the pgp-mime doctests, so here I assume the
micalg field is correct and just use ELLIPSIS.

7 years agotabulate: fix iterabale -> iterable typo in _statistic().
W. Trevor King [Mon, 22 Oct 2012 00:09:54 +0000 (20:09 -0400)]
tabulate: fix iterabale -> iterable typo in _statistic().

7 years agotabulate: fix stat -> statistic in _statistic().
W. Trevor King [Mon, 22 Oct 2012 00:06:40 +0000 (20:06 -0400)]
tabulate: fix stat -> statistic in _statistic().

7 years agoemail: remove `header` option to get_address.
W. Trevor King [Sat, 20 Oct 2012 18:37:26 +0000 (14:37 -0400)]
email: remove `header` option to get_address.

The new function acts like the old one with `header=True`.

Since Python 3.3, formataddr uses RFC 2047 encoding of the realname
(for non-ASCII names), so there's no need for a separate Header call

7 years agoREADME: mention Jinja dependency for sending email.
W. Trevor King [Sat, 20 Oct 2012 18:30:45 +0000 (14:30 -0400)]
README: mention Jinja dependency for sending email.

7 years agoREADME: mention that NumPy is now optional.
W. Trevor King [Sat, 20 Oct 2012 18:27:01 +0000 (14:27 -0400)]
README: mention that NumPy is now optional.

7 years agotabulate: work around missing NumPy.
W. Trevor King [Sat, 20 Oct 2012 18:24:11 +0000 (14:24 -0400)]
tabulate: work around missing NumPy.

7 years ago.update-copyright.conf: update to pipe separators.
W. Trevor King [Sat, 20 Oct 2012 11:15:21 +0000 (07:15 -0400)]
.update-copyright.conf: update to pipe separators.

This brings the config file up to speed with the following
update-copyright commit:

  commit 3c68a1a48419d8b2bbc2ce0e7f1700b996ec30e9
  Author: W. Trevor King <>
  Date:   Fri Oct 19 21:52:48 2012 -0400

    project: for consistency, also separate ignored paths with pipes

7 years agohandler: expand kwargs when initializing InvalidAssignmentSubject.
W. Trevor King [Sat, 13 Oct 2012 11:24:25 +0000 (07:24 -0400)]
handler: expand kwargs when initializing InvalidAssignmentSubject.

7 years agomailpipe: fix course -> error.course in InvalidAssignmentSubject handling.
W. Trevor King [Sat, 13 Oct 2012 11:08:49 +0000 (07:08 -0400)]
mailpipe: fix course -> error.course in InvalidAssignmentSubject handling.

7 years add --continue-after-invalid-message (used to be hardcoded True).
W. Trevor King [Sat, 13 Oct 2012 11:00:27 +0000 (07:00 -0400)] add --continue-after-invalid-message (used to be hardcoded True).

7 years make `--version` a stand alone argument (for Python 3.3).
W. Trevor King [Wed, 10 Oct 2012 14:42:25 +0000 (10:42 -0400)] make `--version` a stand alone argument (for Python 3.3).

7 years agotemplate: remove use_color from template functions.
W. Trevor King [Sat, 6 Oct 2012 20:02:43 +0000 (16:02 -0400)]
template: remove use_color from template functions.

This catches these functions up with

  commit 2c8c64a90009b50ee9f9708846b29c1f3b53a28f
  Author: W. Trevor King <>
  Date:   Sat Sep 1 19:14:12 2012 -0400

    color: add ColoredFormatter for more transparent coloring.

and avoids

  TypeError: send_emails() got an unexpected keyword argument 'use_color'

7 years agomailpipe: add trust_admin_from option to _get_message_person().
W. Trevor King [Sat, 6 Oct 2012 17:07:59 +0000 (13:07 -0400)]
mailpipe: add trust_admin_from option to _get_message_person().

This allows me to resend troublesome emails on behalf of students.

7 years agomailpipe: update fingerprint access for pgp-mime `Key`s.
W. Trevor King [Sat, 6 Oct 2012 17:02:29 +0000 (13:02 -0400)]
mailpipe: update fingerprint access for pgp-mime `Key`s.

Catching up with pgp-mime commit

  commit 1048b3045526d355ac0314597cc98713874b4e5d
  Author: W. Trevor King <>
  Date:   Sat Oct 6 10:47:52 2012 -0400

    key: flesh out to use KEYLIST's output XML.

7 years agomodel:person: add Person.is_admin() to simplify authorization checks.
W. Trevor King [Sat, 6 Oct 2012 16:59:51 +0000 (12:59 -0400)]
model:person: add Person.is_admin() to simplify authorization checks.

7 years agomodel:person: if not given, Person.emails and .groups default to [].
W. Trevor King [Sat, 6 Oct 2012 16:56:22 +0000 (12:56 -0400)]
model:person: if not given, Person.emails and .groups default to [].

This avoids problems with trying to iterate None.

7 years agopygrader: fix pygrade -> pygrader LOG name.
W. Trevor King [Mon, 24 Sep 2012 19:22:43 +0000 (15:22 -0400)]
pygrader: fix pygrade -> pygrader LOG name.

7 years agomailpipe: don't raise UnverifiedSignatureMessage for valid signatures.
W. Trevor King [Thu, 20 Sep 2012 17:24:01 +0000 (13:24 -0400)]
mailpipe: don't raise UnverifiedSignatureMessage for valid signatures.

Before this patch, signatures like:

  ... signature
      CRL missing: False
      CRL too old: False
      bad policy: False
      green: True
      key expired: False
      key missing: False
      key revoked: False
      red: False
      signature expired: False
      system error: False
      valid: True

would raise the exception.  Now they won't.

7 years agoREADME: mention Numpy dependency.
W. Trevor King [Thu, 20 Sep 2012 17:20:17 +0000 (13:20 -0400)]
README: mention Numpy dependency.

7 years agomailpipe: don't bail if a message is signed by a subkey.
W. Trevor King [Thu, 20 Sep 2012 16:35:00 +0000 (12:35 -0400)]
mailpipe: don't bail if a message is signed by a subkey.

Also strips off a leading '0x' before matching fingerprint tails.

You should normally be using primary keys in the `pgp_key` field of
the course configuration file.  Before this commit, messages signed by
a subkey would raise WrongSignatureMessage (i.e. we were looking for a
signature by your primary key, but we only got a signature from your
subkey).  Now we look for the listed signature not only in the signing
keys but also in their primaries.

This requires pgp-mime commit:

  commit eab8b88fe3f4940a9f8285cfb8b88070cd5c0050
  Author: W. Trevor King <>
  Date:   Thu Sep 20 12:24:27 2012 -0400

    key: add pgp_mime.key wrapping gpgme-tool's KEYLIST command.

7 years agomailpipe: flesh out reponse text for invalid messages and signing errors.
W. Trevor King [Thu, 20 Sep 2012 14:37:21 +0000 (10:37 -0400)]
mailpipe: flesh out reponse text for invalid messages and signing errors.

This may be a user's first exposure to PGP, so it's a bad idea to be
cryptic ;).

7 years agomailpipe: convert to pgp-mime's new Signature verification.
W. Trevor King [Thu, 20 Sep 2012 14:29:42 +0000 (10:29 -0400)]
mailpipe: convert to pgp-mime's new Signature verification.

This brings us up to date with the following pgp-mime commit:

  commit 7d4ff835519e6a8fa4273c364b571c2874bd31d5
  Author: W. Trevor King <>
  Date:   Thu Sep 20 10:12:38 2012 -0400

    signature: add Signature class for more Pythonic verification.

    Now verify_bytes() returns a list of `Signature`s instead of XML.
    This should be much easier for callers to handle, and it provides a
    layer of insulation between the gpgme-tool output and Python code.

7 years agomailpipe: standardize error responses with 'We got' -> 'We received'.
W. Trevor King [Thu, 20 Sep 2012 11:27:53 +0000 (07:27 -0400)]
mailpipe: standardize error responses with 'We got' -> 'We received'.

7 years agostorage: only try and load grades for students.
W. Trevor King [Thu, 20 Sep 2012 00:37:20 +0000 (20:37 -0400)]
storage: only try and load grades for students.

7 years agostorage: make [course] parameters optional (e.g. no assistants).
W. Trevor King [Thu, 20 Sep 2012 00:08:00 +0000 (20:08 -0400)]
storage: make [course] parameters optional (e.g. no assistants).

7 years agostorage: don't try to load empty names.
W. Trevor King [Wed, 19 Sep 2012 23:58:51 +0000 (19:58 -0400)]
storage: don't try to load empty names.

This avoids problems with configuration files like:


where the `assistants` field exists but lists no names.

7 years make default --encoding 'utf-8' to avoid clobbering ENCODING with None.
W. Trevor King [Wed, 19 Sep 2012 23:54:31 +0000 (19:54 -0400)] make default --encoding 'utf-8' to avoid clobbering ENCODING with None.

7 years agoImport pygrader, instead of pygrader.ENCODING.
W. Trevor King [Wed, 19 Sep 2012 21:37:33 +0000 (17:37 -0400)]
Import pygrader, instead of pygrader.ENCODING.

If your just import ENCODING, changing the value rebinds the local
copy, but other modules will still see the original value.

7 years add --encoding to override pygrader.ENCODING if you don't like UTF-8.
W. Trevor King [Wed, 19 Sep 2012 21:33:48 +0000 (17:33 -0400)] add --encoding to override pygrader.ENCODING if you don't like UTF-8.

7 years agoUse pygrader.ENCODING when loading ConfigParser files.
W. Trevor King [Wed, 19 Sep 2012 21:33:13 +0000 (17:33 -0400)]
Use pygrader.ENCODING when loading ConfigParser files.

7 years add -s/--syslog to redirect logging to syslog (/dev/log).
W. Trevor King [Wed, 19 Sep 2012 18:18:22 +0000 (14:18 -0400)] add -s/--syslog to redirect logging to syslog (/dev/log).

This is useful for logging requests spawned by procmail or your MDA.

7 years set color.USE_COLOR depending on the --color argument.
W. Trevor King [Wed, 19 Sep 2012 17:57:57 +0000 (13:57 -0400)] set color.USE_COLOR depending on the --color argument.

Otherwise the course loading and other things that avoid use_color
keyword args will end up getting printed in color by default.

7 years agoBump to version 0.3. v0.3
W. Trevor King [Sun, 2 Sep 2012 20:06:42 +0000 (16:06 -0400)]
Bump to version 0.3.

7 years agotest: rename maildir messages to have integer unique portions.
W. Trevor King [Sun, 2 Sep 2012 19:39:43 +0000 (15:39 -0400)]
test: rename maildir messages to have integer unique portions.

The `:2,S` portion of the filename means the messages have version 2
status flags (2), and the messages have been seen (S).

7 years agoRan
W. Trevor King [Sun, 2 Sep 2012 19:29:49 +0000 (15:29 -0400)]

7 years agoupdate-copyright: add */.gitignore so maildir placeholders don't get tweaked.
W. Trevor King [Sun, 2 Sep 2012 19:29:05 +0000 (15:29 -0400)]
update-copyright: add */.gitignore so maildir placeholders don't get tweaked.

7 years agohandler:grade: add new handler for submitting grades.
W. Trevor King [Sun, 2 Sep 2012 18:29:02 +0000 (14:29 -0400)]
handler:grade: add new handler for submitting grades.

Now profs and TAs can submit grades (points and comments) via email.

7 years agostorage: add save_grade (useful for upcoming `grade` handler).
W. Trevor King [Sun, 2 Sep 2012 18:12:15 +0000 (14:12 -0400)]
storage: add save_grade (useful for upcoming `grade` handler).

7 years agostorage: split load_grade out from load_grades.
W. Trevor King [Sun, 2 Sep 2012 18:10:48 +0000 (14:10 -0400)]
storage: split load_grade out from load_grades.

Also rename _load_grade to parse_grade.

These functions will be useful in the upcoming `grade` handler.

7 years agomailpipe|handler: centralize student/course extraction from subjects.
W. Trevor King [Sun, 2 Sep 2012 17:17:06 +0000 (13:17 -0400)]
mailpipe|handler: centralize student/course extraction from subjects.

7 years agohandler: remove TypeError check InvalidSubjectMessage.__init__.
W. Trevor King [Sun, 2 Sep 2012 16:19:44 +0000 (12:19 -0400)]
handler: remove TypeError check InvalidSubjectMessage.__init__.

Leftover debugging cruft.

7 years agomailpipe: don't double-repr subjects for InvalidHandlerMessage responses.
W. Trevor King [Sun, 2 Sep 2012 15:34:50 +0000 (11:34 -0400)]
mailpipe: don't double-repr subjects for InvalidHandlerMessage responses.

7 years agomailpipe: add extra attributes to errors even if current attribute is None.
W. Trevor King [Sun, 2 Sep 2012 15:30:50 +0000 (11:30 -0400)]
mailpipe: add extra attributes to errors even if current attribute is None.

With the old impementation, a default value of None would keep the
attribute from being added.  For example, if the error is raised with

  error.subject == None

`mailpipe` and `_parse_message` would not override that with their
known value.  Now they will.

7 years agohandler:get: sort submission messages chronologically.
W. Trevor King [Sun, 2 Sep 2012 15:21:21 +0000 (11:21 -0400)]
handler:get: sort submission messages chronologically.

7 years agomailpipe: use `messages.sort(...)`, not `m = sorted(m, ...)`.
W. Trevor King [Sun, 2 Sep 2012 15:18:26 +0000 (11:18 -0400)]
mailpipe: use `messages.sort(...)`, not `m = sorted(m, ...)`.

7 years agohandler:get: skip .gitignore messages a la mailpipe._load_messages.
W. Trevor King [Sun, 2 Sep 2012 15:16:12 +0000 (11:16 -0400)]
handler:get: skip .gitignore messages a la mailpipe._load_messages.

7 years agotest:mail-in: request Frodo's assignment 1 (better data).
W. Trevor King [Sun, 2 Sep 2012 15:11:37 +0000 (11:11 -0400)]
test:mail-in: request Frodo's assignment 1 (better data).

7 years agotest:frodo: add a comment and submission emails.
W. Trevor King [Sun, 2 Sep 2012 15:09:37 +0000 (11:09 -0400)]
test:frodo: add a comment and submission emails.

We can use the new data to excercise the 'get submission' handling.

7 years agotest:mail-in: replace tremily with tower addresses.
W. Trevor King [Sun, 2 Sep 2012 15:07:00 +0000 (11:07 -0400)]
test:mail-in: replace tremily with tower addresses.

7 years agohandler:get: only add comment to submission response if it exists.
W. Trevor King [Sun, 2 Sep 2012 14:55:42 +0000 (10:55 -0400)]
handler:get: only add comment to submission response if it exists.

This avoids potentially confusing responses like:

> Assignment 1 grade: 8.0
> None

7 years agotest:mail-in: add test emails excercising `handler.get`.
W. Trevor King [Sun, 2 Sep 2012 14:52:15 +0000 (10:52 -0400)]
test:mail-in: add test emails excercising `handler.get`.

7 years agohandler:get: Responses from this handler are complete.
W. Trevor King [Sun, 2 Sep 2012 14:33:09 +0000 (10:33 -0400)]
handler:get: Responses from this handler are complete.

This avoids double-signing emails and other atrocities.

7 years agomailpipe|handler: add `complete` option to control Response mangling.
W. Trevor King [Sun, 2 Sep 2012 14:32:29 +0000 (10:32 -0400)]
mailpipe|handler: add `complete` option to control Response mangling.

Some handlers may return their emails fully formed, and we won't want
to mess with them.

7 years agomailpipe: respond with the fleshed out message, not the original.
W. Trevor King [Sun, 2 Sep 2012 14:22:26 +0000 (10:22 -0400)]
mailpipe: respond with the fleshed out message, not the original.

We've just added an author, targets, subject, etc.  None of that
matters if you send the original version.

Also print check that the subject is not None before we remove any
subject fields.  This shouldn't matter (del-ing a None subject should
be a no-op), but it seems safer to print the offending message before
messing with it.

7 years agohandler:get: log email construction to troubleshoot parsing.
W. Trevor King [Sun, 2 Sep 2012 14:18:33 +0000 (10:18 -0400)]
handler:get: log email construction to troubleshoot parsing.

7 years agomailpipe|handler: raise exceptions during PGP message verification.
W. Trevor King [Sun, 2 Sep 2012 14:07:42 +0000 (10:07 -0400)]
mailpipe|handler: raise exceptions during PGP message verification.

This avoids the silly "return None on error" convention and allows for
more detailed handling of unsigned messages (vs. improperly signed

7 years agostorage: cleanup StubCourse after load_course doctest.
W. Trevor King [Sun, 2 Sep 2012 14:00:25 +0000 (10:00 -0400)]
storage: cleanup StubCourse after load_course doctest.

7 years|mailpipe: add --trust-email-infrastructure.
W. Trevor King [Sun, 2 Sep 2012 13:33:57 +0000 (09:33 -0400)]|mailpipe: add --trust-email-infrastructure.

7 years send_emails (and thus, Responder) no longer takes use_color.
W. Trevor King [Sun, 2 Sep 2012 13:32:34 +0000 (09:32 -0400)] send_emails (and thus, Responder) no longer takes use_color.

7 years fix incomming -> incoming typo for --respond help.
W. Trevor King [Sun, 2 Sep 2012 13:26:22 +0000 (09:26 -0400)] fix incomming -> incoming typo for --respond help.

7 years agomailpipe: sort messages chronologically before processing.
W. Trevor King [Sun, 2 Sep 2012 13:16:22 +0000 (09:16 -0400)]
mailpipe: sort messages chronologically before processing.

7 years agomailpipe: print error messages when we continue_after_invalid_message.
W. Trevor King [Sun, 2 Sep 2012 13:06:17 +0000 (09:06 -0400)]
mailpipe: print error messages when we continue_after_invalid_message.

Since we're not raising the message, we should log it.  Otherwise the
user may not know that something is amiss.

7 years default to continue_after_invalid_message=True when calling mailpipe.
W. Trevor King [Sun, 2 Sep 2012 13:03:33 +0000 (09:03 -0400)] default to continue_after_invalid_message=True when calling mailpipe.

This lets us process a whole mailbox without dying on every invalid
message.  Consider an unfiltered, general-purpose mailbox with lots of
unrelated emails, which can be successfully parsed with

7 years agomailpipe: add a warning message before loading a message from a stream.
W. Trevor King [Sun, 2 Sep 2012 12:59:05 +0000 (08:59 -0400)]
mailpipe: add a warning message before loading a message from a stream.

This reminds you if you forget to use the `--mailbox` option when
calling ``, and the process hangs waiting for a message on stdin.

7 years agogitignore: add `dist` (created by ` sdist`).
W. Trevor King [Sun, 2 Sep 2012 12:46:39 +0000 (08:46 -0400)]
gitignore: add `dist` (created by ` sdist`).

7 years agomailpipe: skip `.gitignore` files in Maildir mailboxes.
W. Trevor King [Sun, 2 Sep 2012 12:38:13 +0000 (08:38 -0400)]
mailpipe: skip `.gitignore` files in Maildir mailboxes.

I use empty `.gitignore` files so Git will create the
`test/mail-in/new` and `test/mail-in/tmp` directories on checkout, but
the Maildir mailbox thinks they are messages.  Since the files are
*not* messages, skip them when constucting the Maildir message list.

I don't foresee any side effects from this (it's an odd filename for
real Maildir delivery), but I log the skipped filenames just in case.

7 years agomailpipe: flesh out InvalidMessage attributes before raising exceptions.
W. Trevor King [Sun, 2 Sep 2012 12:35:50 +0000 (08:35 -0400)]
mailpipe: flesh out InvalidMessage attributes before raising exceptions.

This tacks on all the interesting attribute data which the function
that originally raised the exception may not have known about.  We
want this metadata in all cases, not just those where we are
constructing a response message.

7 years agomailpipe: fix InvalidHandlerMessage error message construction.
W. Trevor King [Sun, 2 Sep 2012 12:32:46 +0000 (08:32 -0400)]
mailpipe: fix InvalidHandlerMessage error message construction.

`target` is an explicit argument, not in `**kwargs`.

I also removed the InvalidHandlerMessage error logging, because we're
raising an exception.  The calling function can log the exception if
it catches it.  If it doesn't, the user will see the message in the

7 years agohandler: add InvalidMessage.message_id convenience method.
W. Trevor King [Sun, 2 Sep 2012 12:32:12 +0000 (08:32 -0400)]
handler: add InvalidMessage.message_id convenience method.

7 years agotest:mail-in: add example emails for manual testing.
W. Trevor King [Sun, 2 Sep 2012 11:43:02 +0000 (07:43 -0400)]
test:mail-in: add example emails for manual testing.

7 years agocolor: add ColoredFormatter for more transparent coloring.
W. Trevor King [Sat, 1 Sep 2012 23:14:12 +0000 (19:14 -0400)]
color: add ColoredFormatter for more transparent coloring.

This way we don't have to pass use_color around all over the place.

7 years agomailpipe|handler: with the Response framework, handlers don't need `original`.
W. Trevor King [Sat, 1 Sep 2012 19:40:16 +0000 (15:40 -0400)]
mailpipe|handler: with the Response framework, handlers don't need `original`.

7 years agomailpipe: replace `respond` callback with exceptions.
W. Trevor King [Sat, 1 Sep 2012 19:25:58 +0000 (15:25 -0400)]
mailpipe: replace `respond` callback with exceptions.

Now mailpipe sub-functions will raise Response or InvalidMessage when
they want to respond to the incoming email.  This takes advantage of
Python's exception handling to avoid passing the `respond` callback
all over the place.  It also allows us consolidate error message
construction in `_get_error_response`, which will lead to both simpler
program logic and more consistent response messages.

Other changes to make this cleaner:

* Renamed functions in
    _construct_email -> construct_email
    construct_email -> construct_text_email
* Pulled _get_assignment out of

7 years agohandler:get: add `get` handler for grade requests.
W. Trevor King [Sat, 1 Sep 2012 15:06:05 +0000 (11:06 -0400)]
handler:get: add `get` handler for grade requests.

7 years agohandler:submission: fix non-lowercase subject assignment matching.
W. Trevor King [Sat, 1 Sep 2012 14:50:10 +0000 (10:50 -0400)]
handler:submission: fix non-lowercase subject assignment matching.

Also accept (and ignore) unrecognized keyword arguments in run().
This will allow interoperability with other handlers which may take
other arguments.

7 years agotemplate: add targets argument to construct_student_email.
W. Trevor King [Sat, 1 Sep 2012 13:40:01 +0000 (09:40 -0400)]
template: add targets argument to construct_student_email.

7 years agoREADME: elaborate on grade file format and mailpipe processing.
W. Trevor King [Sat, 1 Sep 2012 12:45:50 +0000 (08:45 -0400)]
README: elaborate on grade file format and mailpipe processing.

7 years agohandler:submission: add doctest to run().
W. Trevor King [Sat, 1 Sep 2012 12:08:40 +0000 (08:08 -0400)]
handler:submission: add doctest to run().

7 years agotemplate: remove extra blank lines from construct student email.
W. Trevor King [Sat, 1 Sep 2012 12:03:48 +0000 (08:03 -0400)]
template: remove extra blank lines from construct student email.

By fixing STUDENT_TEMPLATE to remove blank lines due to grades without

Also remove NORMALIZE_WHITESPACE from template doctests, which had
been there to match tabs (doctest expands hard tab characters to
spaces using 8-column tab stops).  However, with NORMALIZE_WHITESPACE
it was impossible to test for extra blank lines.

7 years agomailpipe: clarify the source of missing `Return-Path` (bad email)
W. Trevor King [Sat, 1 Sep 2012 10:39:25 +0000 (06:39 -0400)]
mailpipe: clarify the source of missing `Return-Path` (bad email)

7 years agomailpipe: add .authenticated attribute to _get_verified_message results.
W. Trevor King [Sat, 1 Sep 2012 00:51:04 +0000 (20:51 -0400)]
mailpipe: add .authenticated attribute to _get_verified_message results.

This will allow message handlers to easily determine if the message
they're processing is from an authenticated user.

7 years agomailpipe: add support for multi-part subjects in _get_message_subject.
W. Trevor King [Sat, 1 Sep 2012 00:46:54 +0000 (20:46 -0400)]
mailpipe: add support for multi-part subjects in _get_message_subject.

7 years agomailpipe|handler: split mailpipe's submission handler into its own module.
W. Trevor King [Fri, 31 Aug 2012 20:24:23 +0000 (16:24 -0400)]
mailpipe|handler: split mailpipe's submission handler into its own module.

Now you must use a tag target (e.g. `[submit]`) in your email header
to let mailpipe know which handler you want processing your email.
With the new setup, we can easily add additional handlers (e.g. for
grade requests).

7 years agomailpipe: split initial _parse_message processing into sub-functions.
W. Trevor King [Fri, 31 Aug 2012 18:34:16 +0000 (14:34 -0400)]
mailpipe: split initial _parse_message processing into sub-functions.

New functions:

* _get_message_person_and_subject  (which calls the others internally)
* _get_message_person
* _get_decoded_message
* _get_message_subject

With the previous implementation, all the inline error handling was
making the intended logic of _parse_message difficult to follow.

7 years agomailpipe: update doctests now that I'm using GnuPG v2.0.19.
W. Trevor King [Fri, 31 Aug 2012 18:33:23 +0000 (14:33 -0400)]
mailpipe: update doctests now that I'm using GnuPG v2.0.19.

7 years explicitly list Python 3.2 and 3.3 as supported.
W. Trevor King [Fri, 31 Aug 2012 18:23:12 +0000 (14:23 -0400)] explicitly list Python 3.2 and 3.3 as supported.

7 years agoBump to version 0.2. v0.2
W. Trevor King [Sun, 22 Jul 2012 16:42:04 +0000 (12:42 -0400)]
Bump to version 0.2.

7 years agoAdd to distribute COPYING.
W. Trevor King [Sun, 22 Jul 2012 16:40:00 +0000 (12:40 -0400)]
Add to distribute COPYING.

8 years agoAdd --respond option to's mailpipe command.
W. Trevor King [Tue, 24 Apr 2012 22:02:09 +0000 (18:02 -0400)]
Add --respond option to's mailpipe command.

8 years agoFinish mailpipe respond() doctests.
W. Trevor King [Tue, 24 Apr 2012 21:45:10 +0000 (17:45 -0400)]
Finish mailpipe respond() doctests.

* Add configuration to README example.
* Standardize examples on the more formal `Physics 101`.
* Standardize robot nickname examples on `phys-101 robot`.

8 years agoDocument course.robot and assignment.submittable in the README.
W. Trevor King [Tue, 24 Apr 2012 21:16:25 +0000 (17:16 -0400)]
Document course.robot and assignment.submittable in the README.

8 years agoReject attempted submissions for unsubmittable assignments in mailpipe.
W. Trevor King [Tue, 24 Apr 2012 21:14:05 +0000 (17:14 -0400)]
Reject attempted submissions for unsubmittable assignments in mailpipe.

This implements the expected behaviour for the option created by:

  commit 80639ff31b3bc6780659f526d518526cf63fcaec
  Author: W. Trevor King <>
  Date:   Tue Apr 24 16:48:56 2012 -0400

    Add Assignment.submittable attribute to configure student submission.