Source code for uw.local.grad.webui.view_comments

"""Application dispay comments page implementation.

Routines for formatting application comments section.  These are now part of
the main application page.  For historical reasons they are in a separate file
from the rest of the main page.
"""

from ll.xist.ns import html

from uw.web.html.bootstrapform import  render_bootstrap_submit
from uw.web.html.form import render_select, render_hidden
from uw.web.html.format import format_datetime
from uw.web.html.join import english_join, html_join
from uw.web.wsgi import status
from uw.web.wsgi.form import use_form_param
from uw.web.wsgi.function import return_html

from ...util.identity import use_remote_identity
from ...util.format import format_mailto_url, format_person

from ..db import notification

[docs]def render_opinion_select (cursor, name, value, class_=""): """Render an opinion of an application as an HTML form select control. :param cursor: DB connection cursor. :param name: the form control name. :param value: the form control value, the current opinion. If the current opinion is "WTL" (waitlisted), it will be displayed as "INT" (interested) instead. The selector will not include the choices that correspond to waitlisting or accepting the application. **TODO: what if the current opinion is "ACC" (accepted)?** """ if value == 'WTL': value = 'INT' return render_select (name, cursor.execute_tuples ("select view_state, view_state_description from work_application_faculty_state where view_state not in ('ACC', 'WTL') order by view_state_sequence"), value, class_=class_)
[docs]def render_opinion (unitapp, remote_identity, is_faculty): """Render the user's opinion of an application as HTML. :param unitapp: the candidate application. :param remote_identity: the user's remote identity. :param is_faculty: whether the user is viewing the application as a faculty member. Displays the user's opinion along with related information, including who has recommended the application to the user and been recommended the application by the user. There are also forms for changing the opinion, waitlisting or accepting the application, and recommending the application. """ result = [html.h2 ('Opinion')] faculty_info = unitapp.get_faculty_information (remote_identity.person_id) if is_faculty: # Faculty opinion of the application result.append ( html.p ('Your opinion of this application is: ', faculty_info['view_state'].view_state_description) ) view_state = faculty_info['view_state'].view_state if view_state != 'ACC': waitlisted = view_state == 'WTL' if unitapp.faculty_can_accept (view_state): accept_link = html.a ('accept', href="accept/") else: accept_link = None if unitapp.faculty_can_waitlist and not waitlisted: waitlist_link = html.a ('waitlist', href="accept/?waitlist=") else: waitlist_link = None link = html_join ([waitlist_link, accept_link], ' or ') if link is not None: link = ['; or ', link, ' this applicant.'] result.append (html.form ( html.p ( 'Remove from waitlist and change opinion to ' if waitlisted else 'Change opinion to ', render_opinion_select (unitapp.cursor, '!opinion', faculty_info['view_state'].view_state, class_="form-control input-inline vertical-align"), ' ', render_bootstrap_submit("Change!"), link or '.', ), action="", method="post" )) # Who has accepted the application waitlist = english_join (*[format_person (unitapp.cursor, person_id) for person_id in faculty_info['waitlist']]) if waitlist is not None: waitlist = ['waitlisted by ', waitlist] accepted = english_join (*[format_person (unitapp.cursor, row.person_id) for row in faculty_info['accepted_by']]) if accepted is not None: accepted = ['accepted by ', accepted] if waitlist is not None or accepted is not None: person_ids = faculty_info['waitlist'] + tuple (r.person_id for r in faculty_info['accepted_by']) result.append (html.p ( 'This application has been ', english_join (waitlist, accepted), '. ', html.a ('Send email…', href=format_mailto_url (unitapp.cursor, person_ids, unitapp.title)) )) if is_faculty: # Faculty recommendation information if faculty_info['recommended_to']: result.append ( html.p ('You have recommended this application to ', english_join (*[ format_person (unitapp.cursor, row.person_id) for row in faculty_info['recommended_to'] ]), '.' ) ) result.append ( html.form ( html.p ( 'Recommend this application to: ', render_select ('!recommend', faculty_info['could_recommend_to'], class_="form-control input-inline vertical-align"), ' ', render_bootstrap_submit ("Recommend!") ), action="", method="post" ) ) if faculty_info['recommended_by']: result.append ( html.p ('You have been recommended to consider this application by ', english_join (*[ format_person (unitapp.cursor, row.person_id) for row in faculty_info['recommended_by'] ]), '.' ) ) return result
[docs]def render_comments (unitapp, remote_identity, is_admin): """Render the comments on an application as HTML. :param unitapp: the candidate application. :param remote_identity: The identification for the currently logged-in user :param is_admin: whether the user is an administrator. Displays general comments already made on the application, and provides a form for submitting new comments. If is_admin is specified, internal comments are shown and a form is provided for submitting internal comments. """ result = [html.h2 ('Comments')] comment_info = unitapp.get_comments () def render_comment_form (comment, comment_internal): background_colour = "#FCC" if comment_internal else "#DDD" div = html.div (style="background: {}; padding: 0.5em; margin: 0.5em 0;".format(background_colour), class_="comment_row") div.append ( html.p ( "At %s, " % format_datetime (comment.comment_time), format_person (unitapp.cursor, comment.person_id), " said:" ) ) div.append ( html.pre ( html.tt ( comment.comment_text ) ) ) return html.form (div, action="", method="post") def render_comment_div (comment, comment_internal): editable = comment.person_id == remote_identity.person_id and unitapp.cursor.user_has_role (role_codes=['DIR'], person_id=remote_identity.person_id) edited_comment = " (edited %s) " % format_datetime(comment.edit_comment_time) if comment.original_comment_time != comment.edit_comment_time else " " background_colour = "#FCC" if comment_internal else "#DDD" div = html.div ( render_hidden("comment_internal", comment_internal), render_hidden("comment_id", comment.comment_id), render_hidden("comment", comment.comment_text), html.div ( html.label( "At %s, %s" % (format_datetime (comment.original_comment_time), edited_comment), format_person (unitapp.cursor, comment.person_id), " said:", class_="line-height-adjust", for_="!edit" ), class_="col-xs-9 col-sm-7" ), html.div( html.div( render_bootstrap_submit ("Edit", class_="btn-xs edit-btn", name="!edit") if editable else None, class_ = "pull-right" ), class_="col-xs-offset-1 col-xs-2 col-sm-off-set-1 col-sm-4" ), html.div( html.pre ( html.tt ( comment.comment_text, class_ = "comment" ) ), class_="col-xs-12" ), class_="row comment_row", style="background: {}; padding: 0.5em; margin: 0.5em 0;".format(background_colour), ) return html.form(div, action="", method="post") # Comments and comment form if is_admin: for comment in comment_info['comments-internal']: comment_div = render_comment_div (comment, True) result.append (comment_div) for comment in comment_info['comments']: comment_div = render_comment_div (comment, False) result.append (comment_div) def comment_area (comment_internal): addition = "" if comment_internal else "faculty and " description = "You may comment on this application (visible to {}Admissions staff only)".format(addition) return html.form ( html.div ( render_hidden ("internal", comment_internal) if comment_internal else None, html.label (description, for_="!comment"), html.br (), html.textarea (name="!comment", cols=75, rows=10, wrap="hard", class_="form-control"), html.br (), html.div( render_bootstrap_submit ("Comment!", class_="pull-right bottom-buffer"), class_="row col-xs-12" ) ), action="", method="post", class_ = "buffer-bottom" ) result.append ( comment_area (False) ) if is_admin: result.append ( comment_area (True) ) return result
@return_html def view_comments_get_handler (cursor, unitapp, remote_identity, roles): """Comments page GET URL handler. Simply issues a redirect back to the main page as that is where comments are now displayed. """ raise status.HTTPFound ("..") @use_remote_identity @use_form_param @return_html def view_comments_post_handler (cursor, unitapp, remote_identity, form, roles): """Comments page POST URL handler. This is responsible for handling recommendation submissions, general comments, "internal" comments, and opinion changes. """ def add_comment(ua, cursor, remote_identity, comment_text, comment_internal): """ Inserts comment_text into the comment database and notifies concerned staff and admissions. """ cursor.execute_none ("insert into work_application_faculty_comment (uw_id, appl_id, faculty_person_id, comment_text, comment_internal) values (%(uw_id)s, %(appl_id)s, %(faculty_person_id)s, %(comment_text)s, %(comment_internal)s)", uw_id=ua.uw_id, appl_id=ua.appl_id, faculty_person_id=remote_identity.person_id, comment_text=comment_text, comment_internal=comment_internal) comment_type = 'ACO' if comment_internal else 'COM' comment_target = ua.find_authorized (['DIR', 'ADC']) if comment_internal else ua.find_concerned (include_unviewed=False) comment_target -= set([remote_identity.person_id]) # remove commenter from notification target notification.notify (cursor, comment_target, comment_type, 'A comment has been made on the application of %s %s.' % (ua.applicant.first_name, ua.applicant.last_name), ua.base_url ()) if '!recommend' in form: # Recommend faculty member to look at application recommendee_person_id = form.required_field_value ('!recommend') # Send a recommendation (REC) notification email to the faculty member notification.notify (cursor, [recommendee_person_id], 'REC', '%s %s has recommended you to consider the application for %s %s.' % (remote_identity.givennames, remote_identity.surname, unitapp.applicant.first_name, unitapp.applicant.last_name), unitapp.base_url() ) cursor.execute_none ("insert into work_faculty_recommendation values (%(uw_id)s, %(appl_id)s, %(recommender_person_id)s, %(recommendee_person_id)s)", uw_id=unitapp.uw_id, appl_id=unitapp.appl_id, recommender_person_id=remote_identity.person_id, recommendee_person_id=recommendee_person_id) elif '!comment' in form: # Comment on the application comment_text = form.required_field_value ('!comment') comment_internal = form.optional_field_value ('internal') is not None add_comment(unitapp, cursor, remote_identity, comment_text, comment_internal) elif '!opinion' in form: unitapp.set_faculty_opinion (remote_identity.person_id, form.required_field_value ('!opinion')) elif '!edit' in form: comment = form.required_field_value ('comment') comment_id = form.required_field_value ('comment_id') comment_internal = form.required_field_value ('comment_internal') if cursor.user_has_role (role_codes=['DIR'], person_id=remote_identity.person_id): cursor.execute_none ("INSERT into work_application_faculty_comment (uw_id, appl_id, faculty_person_id, comment_text, comment_internal, comment_id) values (%(uw_id)s, %(appl_id)s, %(faculty_person_id)s, %(comment_text)s, %(comment_internal)s, %(comment_id)s)", uw_id=unitapp.uw_id, appl_id=unitapp.appl_id, faculty_person_id=remote_identity.person_id, comment_text=comment, comment_internal=comment_internal, comment_id=comment_id) raise status.HTTPFound ("")