Add Course.robot attribute (for automatic email generation).
authorW. Trevor King <wking@tremily.us>
Tue, 24 Apr 2012 19:27:08 +0000 (15:27 -0400)
committerW. Trevor King <wking@tremily.us>
Tue, 24 Apr 2012 19:36:26 +0000 (15:36 -0400)
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"'

bin/pg.py
pygrader/model/course.py
pygrader/storage.py
pygrader/test/course.py
test/course.conf

index 163f43d290956376528fb0f2f16e74d53b54e0d7..5980b01c04f14a6c3728f0c0146e64f5cb7bda74 100755 (executable)
--- a/bin/pg.py
+++ b/bin/pg.py
@@ -89,7 +89,7 @@ if __name__ == '__main__':
         help="Don't actually send emails, create files, etc.")
     email_parser.add_argument(
         '-a', '--author',
-        help='Your name (email author), defaults to first assistant')
+        help='Your name (email author), defaults to course robot')
     email_parser.add_argument(
         '--cc', action='append', help='People to carbon copy')
     email_subparsers = email_parser.add_subparsers(title='type')
@@ -178,8 +178,7 @@ if __name__ == '__main__':
             if hasattr(args, attr):
                 name = getattr(args, attr)
                 if name is None and attr == 'author':
-                    kwargs[attr] = list(
-                        course.find_people(group='assistants'))[0]
+                    kwargs[attr] = course.robot
                 else:
                     kwargs[attr] = course.person(name=name)
         for attr in ['targets']:
index 652592ff0c072d232bc3da5b6c1c501616fc22bd..559be78aa4fd4caaa3da5a69435a21baeeb413e3 100644 (file)
@@ -18,7 +18,8 @@ from .. import LOG as _LOG
 
 
 class Course (object):
-    def __init__(self, name=None, assignments=None, people=None, grades=None):
+    def __init__(self, name=None, assignments=None, people=None, grades=None,
+                 robot=None):
         self.name = name
         if assignments is None:
             assignments = []
@@ -29,6 +30,7 @@ class Course (object):
         if grades is None:
             grades = []
         self.grades = sorted(grades)
+        self.robot = robot
 
     def assignment(self, name):
         for assignment in self.assignments:
index 7bc9a17d8bde544275b4ffacf6d2734c2c21a427..2b1e185083821131fab99e4c811ed00b56de3a08 100644 (file)
@@ -52,12 +52,14 @@ def load_course(basedir):
     [<pygrader.model.person.Person object at 0x...>, ...]
     >>> course.grades
     []
+    >>> print(course.robot)
+    <Person Robot101>
     """
     _LOG.debug('loading course from {}'.format(basedir))
     config = _configparser.ConfigParser()
     config.read([_os_path.join(basedir, 'course.conf')])
     name = config.get('course', 'name')
-    names = {}
+    names = {'robot': [config.get('course', 'robot').strip()]}
     for option in ['assignments', 'professors', 'assistants', 'students']:
         names[option] = [
         a.strip() for a in config.get('course', option).split(',')]
@@ -67,7 +69,7 @@ def load_course(basedir):
         assignments.append(load_assignment(
                 name=assignment, data=dict(config.items(assignment))))
     people = {}
-    for group in ['professors', 'assistants', 'students']:
+    for group in ['robot', 'professors', 'assistants', 'students']:
         for person in names[group]:
             if person in people:
                 _LOG.debug('adding person {} to group {}'.format(
@@ -80,9 +82,11 @@ def load_course(basedir):
                     name=person, data=dict(config.items(person)))
                 people[person].groups = [group]
     people = people.values()
+    robot = [p for p in people if 'robot' in p.groups][0]
     grades = list(load_grades(basedir, assignments, people))
     return _Course(
-        name=name, assignments=assignments, people=people, grades=grades)
+        name=name, assignments=assignments, people=people, grades=grades,
+        robot=robot)
 
 def parse_date(string):
     """Parse dates given using the W3C DTF profile of ISO 8601.
index 2f1379fd1cf829192605644f5e913b2defbd15f7..1c6e7800c05bc86697afa8387e842ddafb699ef7 100644 (file)
@@ -14,6 +14,7 @@ name: phys101
 assignments: Attendance 1, Attendance 2, Attendance 3, Attendance 4,
   Attendance 5, Attendance 6, Attendance 7, Attendance 8, Attendance 9,
   Assignment 1, Assignment 2, Exam 1, Exam 2
+robot: Robot101
 professors: Gandalf
 assistants: Sauron
 students: Bilbo Baggins, Frodo Baggins, Aragorn
@@ -83,6 +84,11 @@ points: 10
 weight: 0.4/2
 due: 2011-10-17
 
+[Robot101]
+nickname: phys-101 robot
+emails: phys101@tower.edu
+pgp-key: 4332B6E3
+
 [Gandalf]
 nickname: G-Man
 emails: g@grey.edu
index 93999ca9c33b321501e4d39d94af5276fc11c00e..375de456e29104cd975d2702c16b3db6de276cfa 100644 (file)
@@ -3,6 +3,7 @@ name: phys101
 assignments: Attendance 1, Attendance 2, Attendance 3, Attendance 4,
   Attendance 5, Attendance 6, Attendance 7, Attendance 8, Attendance 9,
   Assignment 1, Assignment 2, Exam 1, Exam 2
+robot: Robot101
 professors: Gandalf
 assistants: Sauron
 students: Bilbo Baggins, Frodo Baggins, Aragorn
@@ -72,6 +73,11 @@ points: 10
 weight: 0.4/2
 due: 2011-10-17
 
+[Robot101]
+nickname: phys101 robot
+emails: phys101@tower.edu
+pgp-key: 4332B6E3
+
 [Gandalf]
 nickname: G-Man
 emails: g@grey.edu