Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slip Calculator Jobs for Assignment and Course #1148

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Prev Previous commit
Next Next commit
output csv string
  • Loading branch information
epai committed May 4, 2017
commit 82c50fa880b2a263d10f00fe436fff087dacf68a
7 changes: 1 addition & 6 deletions server/controllers/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -993,14 +993,9 @@ def calculate_slips(cid, aid):
description='Calculate Slip {} for {}'.format(timescale, assign.display_name),
timeout=600,
course_id=cid,
# user_id=current_user.id,
user_id=current_user.id,
assign_id=assign.id,
timescale=timescale,
# score=form.score.data,
# kind=form.kind.data,
# message=form.message.data,
# deadline=form.deadline.data,
# include_backups=form.include_backups.data
)
return redirect(url_for('.course_job', cid=cid, job_id=job.id))

Expand Down
39 changes: 30 additions & 9 deletions server/jobs/slips.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,50 @@

from datetime import datetime as dt
import math
import io
import csv

from server import jobs
from server.models import Assignment
from server.constants import TIMESCALES
from datetime import datetime as dt
from math import ceil

timescales = {'days':86400, 'hours':3600, 'minutes':60}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should go in constants as TIMESCALES, so there's not both TIMESCALES and timescales that have the same keys

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did this originally, but realized if I would then have to use the dictionary keys to fill in the form options, which wouldn't have a guaranteed ordering.

Now that I've thought about it, I think I'll just use an OrderedDict to preserve the ordering of the keys for display on the form.


def timediff(created, deadline, timescale):
secs_over = (created - deadline).total_seconds()
return ceil(secs_over / timescales[timescale.lower()])
return math.ceil(secs_over / timescales[timescale.lower()])

def csv_data(header, rows):
output = io.StringIO()
writer = csv.writer(output, quoting=csv.QUOTE_NONNUMERIC)
writer.writerow(header)
[writer.writerow(row) for row in rows]
return output.getvalue()

@jobs.background_job
def calculate_slips(assign_id, timescale):
logger = jobs.get_job_logger()
job = jobs.get_current_job()

logger.info('Calculating slip {}...'.format(timescale))

logger.info('Calculating Slip {}...'.format(timescale.title()))

assignment = Assignment.query.get(assign_id)
subms = assignment.course_submissions(include_empty=False)
deadline = assignment.due_date
for subm in subms:

def get_row(subm):
email = subm['user']['email']
created = subm['backup']['created']
logger.info('{} {}'
.format(email, timediff(created, deadline, timescale)))
slips = min(0, timediff(created, deadline, timescale))
return [email, slips]

header = ('User Email', 'Slip {} Used'.format(timescale.title()))
rows = (get_row(subm) for subm in subms)
data = csv_data(header, rows)

logger.info(repr(data))

# upload = ExternalFile.upload(csv_data, user_id=1, course_id=1,
# name='temp.okfile', prefix='jobs/example/')