W. Trevor King [Mon, 22 Oct 2012 00:09:54 +0000 (20:09 -0400)]
tabulate: fix iterabale -> iterable typo in _statistic().
W. Trevor King [Mon, 22 Oct 2012 00:06:40 +0000 (20:06 -0400)]
tabulate: fix stat -> statistic in _statistic().
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
anymore.
W. Trevor King [Sat, 20 Oct 2012 18:30:45 +0000 (14:30 -0400)]
README: mention Jinja dependency for sending email.
W. Trevor King [Sat, 20 Oct 2012 18:27:01 +0000 (14:27 -0400)]
README: mention that NumPy is now optional.
W. Trevor King [Sat, 20 Oct 2012 18:24:11 +0000 (14:24 -0400)]
tabulate: work around missing NumPy.
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 <wking@tremily.us>
Date: Fri Oct 19 21:52:48 2012 -0400
project: for consistency, also separate ignored paths with pipes
W. Trevor King [Sat, 13 Oct 2012 11:24:25 +0000 (07:24 -0400)]
handler: expand kwargs when initializing InvalidAssignmentSubject.
W. Trevor King [Sat, 13 Oct 2012 11:08:49 +0000 (07:08 -0400)]
mailpipe: fix course -> error.course in InvalidAssignmentSubject handling.
W. Trevor King [Sat, 13 Oct 2012 11:00:27 +0000 (07:00 -0400)]
pg.py: add --continue-after-invalid-message (used to be hardcoded True).
W. Trevor King [Wed, 10 Oct 2012 14:42:25 +0000 (10:42 -0400)]
pg.py: make `--version` a stand alone argument (for Python 3.3).
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 <wking@tremily.us>
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'
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.
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 <wking@tremily.us>
Date: Sat Oct 6 10:47:52 2012 -0400
key: flesh out to use KEYLIST's output XML.
W. Trevor King [Sat, 6 Oct 2012 16:59:51 +0000 (12:59 -0400)]
model:person: add Person.is_admin() to simplify authorization checks.
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.
W. Trevor King [Mon, 24 Sep 2012 19:22:43 +0000 (15:22 -0400)]
pygrader: fix pygrade -> pygrader LOG name.
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
summary:
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.
W. Trevor King [Thu, 20 Sep 2012 17:20:17 +0000 (13:20 -0400)]
README: mention Numpy dependency.
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 <wking@tremily.us>
Date: Thu Sep 20 12:24:27 2012 -0400
key: add pgp_mime.key wrapping gpgme-tool's KEYLIST command.
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 ;).
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 <wking@tremily.us>
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.
W. Trevor King [Thu, 20 Sep 2012 11:27:53 +0000 (07:27 -0400)]
mailpipe: standardize error responses with 'We got' -> 'We received'.
W. Trevor King [Thu, 20 Sep 2012 00:37:20 +0000 (20:37 -0400)]
storage: only try and load grades for students.
W. Trevor King [Thu, 20 Sep 2012 00:08:00 +0000 (20:08 -0400)]
storage: make [course] parameters optional (e.g. no assistants).
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:
[course]
...
assistants:
...
where the `assistants` field exists but lists no names.
W. Trevor King [Wed, 19 Sep 2012 23:54:31 +0000 (19:54 -0400)]
pg.py: make default --encoding 'utf-8' to avoid clobbering ENCODING with None.
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.
W. Trevor King [Wed, 19 Sep 2012 21:33:48 +0000 (17:33 -0400)]
pg.py: add --encoding to override pygrader.ENCODING if you don't like UTF-8.
W. Trevor King [Wed, 19 Sep 2012 21:33:13 +0000 (17:33 -0400)]
Use pygrader.ENCODING when loading ConfigParser files.
W. Trevor King [Wed, 19 Sep 2012 18:18:22 +0000 (14:18 -0400)]
py.py: add -s/--syslog to redirect logging to syslog (/dev/log).
This is useful for logging requests spawned by procmail or your MDA.
W. Trevor King [Wed, 19 Sep 2012 17:57:57 +0000 (13:57 -0400)]
pg.py: 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.
W. Trevor King [Sun, 2 Sep 2012 20:06:42 +0000 (16:06 -0400)]
Bump to version 0.3.
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).
W. Trevor King [Sun, 2 Sep 2012 19:29:49 +0000 (15:29 -0400)]
Ran update-copyright.py.
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.
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.
W. Trevor King [Sun, 2 Sep 2012 18:12:15 +0000 (14:12 -0400)]
storage: add save_grade (useful for upcoming `grade` handler).
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.
W. Trevor King [Sun, 2 Sep 2012 17:17:06 +0000 (13:17 -0400)]
mailpipe|handler: centralize student/course extraction from subjects.
W. Trevor King [Sun, 2 Sep 2012 16:19:44 +0000 (12:19 -0400)]
handler: remove TypeError check InvalidSubjectMessage.__init__.
Leftover debugging cruft.
W. Trevor King [Sun, 2 Sep 2012 15:34:50 +0000 (11:34 -0400)]
mailpipe: don't double-repr subjects for InvalidHandlerMessage responses.
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.
W. Trevor King [Sun, 2 Sep 2012 15:21:21 +0000 (11:21 -0400)]
handler:get: sort submission messages chronologically.
W. Trevor King [Sun, 2 Sep 2012 15:18:26 +0000 (11:18 -0400)]
mailpipe: use `messages.sort(...)`, not `m = sorted(m, ...)`.
W. Trevor King [Sun, 2 Sep 2012 15:16:12 +0000 (11:16 -0400)]
handler:get: skip .gitignore messages a la mailpipe._load_messages.
W. Trevor King [Sun, 2 Sep 2012 15:11:37 +0000 (11:11 -0400)]
test:mail-in: request Frodo's assignment 1 (better data).
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.
W. Trevor King [Sun, 2 Sep 2012 15:07:00 +0000 (11:07 -0400)]
test:mail-in: replace tremily with tower addresses.
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
W. Trevor King [Sun, 2 Sep 2012 14:52:15 +0000 (10:52 -0400)]
test:mail-in: add test emails excercising `handler.get`.
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.
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.
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.
W. Trevor King [Sun, 2 Sep 2012 14:18:33 +0000 (10:18 -0400)]
handler:get: log email construction to troubleshoot parsing.
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
messages).
W. Trevor King [Sun, 2 Sep 2012 14:00:25 +0000 (10:00 -0400)]
storage: cleanup StubCourse after load_course doctest.
W. Trevor King [Sun, 2 Sep 2012 13:33:57 +0000 (09:33 -0400)]
pg.py|mailpipe: add --trust-email-infrastructure.
W. Trevor King [Sun, 2 Sep 2012 13:32:34 +0000 (09:32 -0400)]
pg.py: send_emails (and thus, Responder) no longer takes use_color.
W. Trevor King [Sun, 2 Sep 2012 13:26:22 +0000 (09:26 -0400)]
pg.py: fix incomming -> incoming typo for --respond help.
W. Trevor King [Sun, 2 Sep 2012 13:16:22 +0000 (09:16 -0400)]
mailpipe: sort messages chronologically before processing.
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.
W. Trevor King [Sun, 2 Sep 2012 13:03:33 +0000 (09:03 -0400)]
pg.py: 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
`continue_after_invalid_message`.
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 `pg.py`, and the process hangs waiting for a message on stdin.
W. Trevor King [Sun, 2 Sep 2012 12:46:39 +0000 (08:46 -0400)]
gitignore: add `dist` (created by `setup.py sdist`).
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.
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.
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
traceback.
W. Trevor King [Sun, 2 Sep 2012 12:32:12 +0000 (08:32 -0400)]
handler: add InvalidMessage.message_id convenience method.
W. Trevor King [Sun, 2 Sep 2012 11:43:02 +0000 (07:43 -0400)]
test:mail-in: add example emails for manual testing.
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.
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`.
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 pygrader.email:
_construct_email -> construct_email
construct_email -> construct_text_email
* Pulled _get_assignment out of submission.run.
W. Trevor King [Sat, 1 Sep 2012 15:06:05 +0000 (11:06 -0400)]
handler:get: add `get` handler for grade requests.
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.
W. Trevor King [Sat, 1 Sep 2012 13:40:01 +0000 (09:40 -0400)]
template: add targets argument to construct_student_email.
W. Trevor King [Sat, 1 Sep 2012 12:45:50 +0000 (08:45 -0400)]
README: elaborate on grade file format and mailpipe processing.
W. Trevor King [Sat, 1 Sep 2012 12:08:40 +0000 (08:08 -0400)]
handler:submission: add doctest to run().
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
comments.
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.
W. Trevor King [Sat, 1 Sep 2012 10:39:25 +0000 (06:39 -0400)]
mailpipe: clarify the source of missing `Return-Path` (bad email)
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.
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.
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).
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.
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.
W. Trevor King [Fri, 31 Aug 2012 18:23:12 +0000 (14:23 -0400)]
setup.py: explicitly list Python 3.2 and 3.3 as supported.
W. Trevor King [Sun, 22 Jul 2012 16:42:04 +0000 (12:42 -0400)]
Bump to version 0.2.
W. Trevor King [Sun, 22 Jul 2012 16:40:00 +0000 (12:40 -0400)]
Add MANIFEST.in to distribute COPYING.
W. Trevor King [Tue, 24 Apr 2012 22:02:09 +0000 (18:02 -0400)]
Add --respond option to pg.py's mailpipe command.
W. Trevor King [Tue, 24 Apr 2012 21:45:10 +0000 (17:45 -0400)]
Finish mailpipe respond() doctests.
Also:
* Add course.name configuration to README example.
* Standardize course.name examples on the more formal `Physics 101`.
* Standardize robot nickname examples on `phys-101 robot`.
W. Trevor King [Tue, 24 Apr 2012 21:16:25 +0000 (17:16 -0400)]
Document course.robot and assignment.submittable in the README.
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 <wking@tremily.us>
Date: Tue Apr 24 16:48:56 2012 -0400
Add Assignment.submittable attribute to configure student submission.
W. Trevor King [Tue, 24 Apr 2012 21:00:30 +0000 (17:00 -0400)]
Initial `respond` implementation in the `mailpipe` module.
W. Trevor King [Tue, 24 Apr 2012 20:48:56 +0000 (16:48 -0400)]
Add Assignment.submittable attribute to configure student submission.
If `Assignment.submittable` is `True`, mailpipe will accept student
submissions for that assignment. However, there may also be
assignments where you don't want to accept direct submissions
(e.g. attendance and written, in-class exams). For these assignments,
you should leave the `submittable` option at its default `False`
value.
Note that `mailpipe` doesn't use this value yet (implementation coming
soon).
W. Trevor King [Tue, 24 Apr 2012 20:11:57 +0000 (16:11 -0400)]
pgp_mime.pgp.verify() no longer needs deepcopy().
Since the pgp-mime commit:
commit
49802119d7846c7ffd6d72a46068aff014361b59
Author: W. Trevor King <wking@tremily.us>
Date: Tue Apr 24 16:01:17 2012 -0400
Always return a new Message instance from pgp.verify().
W. Trevor King [Tue, 24 Apr 2012 19:27:08 +0000 (15:27 -0400)]
Add Course.robot attribute (for automatic email generation).
I'm getting things set up to send automatic responses when mailpipe
processes incoming email, which means someone's going to have to be
signing that email for security. Since you probably don't want to
leave your secret PGP key on the mailserver, you can now setup a new
(and less important) PGP key for each course. The Course.robot is
just a Person instance to hold that key and an appropriate nickname.
If you want to use your own key when you call pg.py from the command
line, you can always setup a shell alias. In Bash:
alias pg.py='/usr/bin/pg.py --author="John Doe"'
W. Trevor King [Tue, 24 Apr 2012 19:09:49 +0000 (15:09 -0400)]
Pull _construct_email out of construct_email and add construct_response.
_construct_email() handles general tasks for setting up the main email
header. construct_email() combines this with a simple text/plain body,
while construct_response() uses a multipart/mixed format suitable for
sending message receipts to users.
W. Trevor King [Tue, 24 Apr 2012 18:43:30 +0000 (14:43 -0400)]
Fix Built -> Build typo in construct_email docstring.
W. Trevor King [Tue, 24 Apr 2012 18:34:52 +0000 (14:34 -0400)]
Add docstring and doctest to message_time().
W. Trevor King [Tue, 24 Apr 2012 18:33:28 +0000 (14:33 -0400)]
Add Course.name attribute (for clearer email generation).