"""Convenient URL delegators.
These are used to build up the URL structure of the application by analyzing
an URL path arc as the ID of an admin unit, sitting, examination, or room.
"""
from uw.web.wsgi.delegate import int_from_arc, delegate_value, always, file_dir_redirect
[docs]def admin_from_arc (arc, cursor, term=None, **params):
"""Interpret a URL path arc into an admin_id.
Parameters:
arc -- the URL path arc;
cursor -- DB connection cursor;
term -- the relevant term, if any;
params -- any additional context not needed for this arc parser.
First converts the arc to an integer.
If a term is in context, looks up an offering based on the term and the
parsed integer as admin_id. If not, looks up an admin unit just based on
the parsed integer as admin_id.
"""
arc = int_from_arc (arc)
if arc is None:
return None
if term is None:
return cursor.admin_by_id (admin_id=arc)
else:
return cursor.offering_by_id (admin_id=arc, term_id=term.code ())
[docs]def admin_delegate (dir_handler, arc_handler):
"""Delegate to URL handler based on admin_id in URL.
"""
return delegate_value ('admin', dir_handler, always (arc_handler),
convert_arc=admin_from_arc)
[docs]def sitting_from_arc (arc, cursor, offering=None, exam=None, **params):
"""Interpret a URL path arc as a sitting_id.
Parameters:
arc -- the URL path arc;
cursor -- DB connection cursor;
offering -- the relevant offering, if any;
exam -- the relevant examination, if any;
params -- any additional context not needed for this arc parser.
First converts the arc to an integer.
If there is no offering or examination in context, this will find any
sitting. If there is no offering in context but there is an examination
in context, it will find only sittings for the examination. If there is
an offering in context, it will find only sittings owned by the offering.
**TODO: I think the offering stuff doesn't do anything yet because
nowhere is an "offering" in context; instead a term and an admin unit
will be in context.**
"""
arc = int_from_arc (arc)
if arc is None:
return None
if offering is None:
if exam is None:
return cursor.sitting_by_id (sitting_id=arc)
else:
return cursor.exam_sitting_by_id (exam_id=exam.exam_id, sitting_id=arc)
else:
return cursor.offering_sitting_by_id (term_id=offering.term_id, admin_id=offering.admin_id, sitting_id=arc)
[docs]def sitting_delegate (dir_handler, arc_handler):
"""Delegate to URL handler based on sitting_id in URL.
"""
return delegate_value ('sitting', dir_handler, always (arc_handler),
convert_arc=sitting_from_arc)
[docs]def division_from_arc (arc, cursor, term, admin, **params):
'''Interpret a URL path arc as a division_seq.
:param arc: The URL path arc.
:param cursor: DB connection cursor.
:param term: The term of the offering.
:param admin: The admin unit of the offering.
:param params: Any additional context not needed for this arc parser.
'''
arc = int_from_arc (arc)
if arc is None:
return None
if 'exam' in params:
return cursor.execute_optional_tuple ("select * from division_division_exam where (term_id, admin_id, exam_id, division_seq) = (%(term_id)s, %(admin_id)s, %(exam_id)s, %(division_seq)s)", term_id=term.code (), admin_id=admin.admin_id, exam_id=params['exam'].exam_id, division_seq=arc)
return cursor.execute_optional_tuple ("select * from division_division where (term_id, admin_id, division_seq) = (%(term_id)s, %(admin_id)s, %(division_seq)s)", term_id=term.code (), admin_id=admin.admin_id, division_seq=arc)
[docs]def division_delegate (dir_handler, arc_handler):
'''Delegate to URL handler based on division_seq in URL.
'''
return delegate_value ('division', dir_handler, always (arc_handler),
convert_arc=division_from_arc)
[docs]def exam_from_arc (arc, cursor, offering=None, sitting=None, **params):
"""Interpret a URL path arc as an exam_id.
Parameters:
arc -- the URL path arc;
cursor -- DB connection cursor;
offering -- the relevant offering, if any;
sitting -- the relevant sitting, if any;
params -- any additional context not needed for this arc parser.
First converts the arc to an integer.
If there is no offering or sitting in context, this will find any
examination. If there is no offering in context but there is a sitting
in context, it will find only examinations for the sitting. If there is
an offering in context, it will find only examinations owned by the
offering.
**TODO: I think the offering stuff doesn't do anything yet because
nowhere is an "offering" in context; instead a term and an admin unit
will be in context.**
"""
arc = int_from_arc (arc)
if arc is None:
return None
if offering is None:
if sitting is None:
return cursor.exam_by_id (exam_id=arc)
else:
return cursor.sitting_exam_by_id (sitting_id=sitting.sitting_id, exam_id=arc)
else:
return cursor.offering_exam_by_id (term_id=offering.term_id, admin_id=offering.admin_id, exam_id=arc)
[docs]def exam_delegate (dir_handler, arc_handler):
"""Delegate to URL handler based on exam_id in URL.
"""
return delegate_value ('exam', dir_handler, always (arc_handler),
convert_arc=exam_from_arc, file_handler=file_dir_redirect)
[docs]def room_from_arc (arc, cursor, sitting=None, exam=None, form=None, **params):
"""Interpret a URL path arc as a room_id.
Parameters:
arc -- the URL path arc;
cursor -- DB connection cursor;
sitting -- the relevant sitting, if any;
exam -- the relevant examination, if any;
form -- the form results, if any;
params -- any additional context not needed for this arc parser.
First converts the arc to an integer.
If an examination is in context, a sitting also needs to be in context.
The room will be found only if it is in use by the examination and sitting.
If no examination is in context, a loading standard is determined from the
form results with a default in the event no form results are in context.
In this case, if a sitting is in context, the room will be found only if it
is attached to the sitting; if no sitting is in context, any room will be
found.
**TODO: the loading standard affects the results only when no
examination and no sitting is in context.**
"""
arc = int_from_arc (arc)
if arc is None:
return None
if exam is None:
# *** TODO: This is handy for the room index but seems questionable
if form is None:
allow_tablet_seats = False
allow_single_seating = False
checkerboard = False
else:
allow_tablet_seats = 'ts' in form
allow_single_seating = 'ss' in form
checkerboard = 'cb' in form
if sitting is None:
return cursor.room_by_id (room_id=arc, allow_tablet_seats=allow_tablet_seats, allow_single_seating=allow_single_seating, checkerboard=checkerboard)
else:
return cursor.sitting_room_by_id (sitting_id=sitting.sitting_id, room_id=arc)
else:
return cursor.exam_sitting_room_by_id (exam_id=exam.exam_id, sitting_id=sitting.sitting_id, room_id=arc)
[docs]def room_delegate (dir_handler, arc_handler):
"""Delegate to URL handler based on room_id in URL.
"""
return delegate_value ('room', dir_handler, always (arc_handler),
convert_arc=room_from_arc)
[docs]def print_from_arc (arc, cursor, **params):
arc = make_int_from_arc (5) (arc)
if arc is None:
return None
return cursor.print_by_id (print_id=arc)
[docs]def print_delegate (dir_handler, arc_handler):
"""Obsolete.
**TODO: Finish eliminating obsolete print-related stuff.**
"""
return delegate_value ('print_', dir_handler, always (arc_handler),
convert_arc=print_from_arc)
[docs]def taeval_from_arc (arc, cursor, **params):
'''Interprets a URL path arc into an eval_id.
:param arc: The URL path arc.
:param cursor: DB connection cursor.
:param params: Any additional context not needed for this arc parser.
:return: a database row if an eval_id is found in the URL otherwise None.
'''
if arc is None:
return None
return cursor.execute_optional_tuple ("select ta_eval.*, job_description from ta_eval natural join ta_job where eval_id = %(eval_id)s", eval_id=arc)
[docs]def taeval_delegate (dir_handler, arc_handler):
'''Delegate URL handler based on eval_id in URL.
'''
return delegate_value ('taeval', dir_handler, always (arc_handler), convert_arc=taeval_from_arc)
[docs]def deadline_from_arc (arc, cursor, **params):
"""Returns the period_id from the given URL path arc.
"""
return int_from_arc (arc)
[docs]def deadline_delegate (dir_handler, arc_handler):
"""Delegate to URL handler based on period_id for deadline in URL.
"""
return delegate_value ('period_id', dir_handler, always (arc_handler), convert_arc=deadline_from_arc)