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"'
help="Don't actually send emails, create files, etc.")
email_parser.add_argument(
'-a', '--author',
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')
email_parser.add_argument(
'--cc', action='append', help='People to carbon copy')
email_subparsers = email_parser.add_subparsers(title='type')
if hasattr(args, attr):
name = getattr(args, attr)
if name is None and attr == 'author':
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']:
else:
kwargs[attr] = course.person(name=name)
for attr in ['targets']:
- 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 = []
self.name = name
if assignments is None:
assignments = []
if grades is None:
grades = []
self.grades = sorted(grades)
if grades is None:
grades = []
self.grades = sorted(grades)
def assignment(self, name):
for assignment in self.assignments:
def assignment(self, name):
for assignment in self.assignments:
[<pygrader.model.person.Person object at 0x...>, ...]
>>> course.grades
[]
[<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')
"""
_LOG.debug('loading course from {}'.format(basedir))
config = _configparser.ConfigParser()
config.read([_os_path.join(basedir, 'course.conf')])
name = config.get('course', 'name')
+ 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(',')]
for option in ['assignments', 'professors', 'assistants', 'students']:
names[option] = [
a.strip() for a in config.get('course', option).split(',')]
assignments.append(load_assignment(
name=assignment, data=dict(config.items(assignment))))
people = {}
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(
for person in names[group]:
if person in people:
_LOG.debug('adding person {} to group {}'.format(
name=person, data=dict(config.items(person)))
people[person].groups = [group]
people = people.values()
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(
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.
def parse_date(string):
"""Parse dates given using the W3C DTF profile of ISO 8601.
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
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
professors: Gandalf
assistants: Sauron
students: Bilbo Baggins, Frodo Baggins, Aragorn
professors: Gandalf
assistants: Sauron
students: Bilbo Baggins, Frodo Baggins, Aragorn
weight: 0.4/2
due: 2011-10-17
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
[Gandalf]
nickname: G-Man
emails: g@grey.edu
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
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
professors: Gandalf
assistants: Sauron
students: Bilbo Baggins, Frodo Baggins, Aragorn
professors: Gandalf
assistants: Sauron
students: Bilbo Baggins, Frodo Baggins, Aragorn
weight: 0.4/2
due: 2011-10-17
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
[Gandalf]
nickname: G-Man
emails: g@grey.edu