def show_request(request_id): request_id = request_id.lstrip('#') # receive subscription form_errors = [] submitted_email = None if request.method == 'POST': submitted_email = request.form.get('update_email') if submitted_email: success = subscribe_to_sr(request_id, submitted_email) if not success: form_errors.append('Please use a valid e-mail address.') # TODO: Should probably use Three or something nice for this... url = '%s/requests/%s.json' % (app.config['OPEN311_SERVER'], request_id) params = {'extensions': 'true', 'legacy': 'false'} if app.config['OPEN311_API_KEY']: params['api_key'] = app.config['OPEN311_API_KEY'] r = requests.get(url, params=params) if r.status_code == 404: # TODO: how to generalize this? # Chicago's SR IDs are always \d\d-\d{8}, if we get just digits, reformat and try again request_id_digits = re.sub(r'\D', '', request_id) if len(request_id_digits) == 8: # Try prepending the year if it's only 8 digits request_id_digits = datetime.date.today().strftime( '%y') + request_id_digits if len(request_id_digits) == 10: reformatted = '%s-%s' % (request_id_digits[:2], request_id_digits[2:]) if reformatted != request_id: return redirect(url_for('show_request', request_id=reformatted)) # It would be nice to log this for analytical purposes (what requests are being checked that we can't show?) # but that would be better done through GA or KISS Metrics than through server logging services = open311tools.services(app.config['OPEN311_SERVER'], app.config['OPEN311_API_KEY']) return render_app_template('error_no_sr.html', request_id=request_id, services=services), 404 elif r.status_code != 200: app.logger.error('OPEN311: Error (not 404) loading data for SR %s', request_id) return render_app_template('error_311_api.html', request_id=request_id), 500 srs = r.json if srs: sr = fixup_sr(srs[0], request_id) if 'requested_datetime' in sr: sr['requested_datetime'] = iso8601.parse_date( sr['requested_datetime']) # sometimes an SR doesn't include notes even though there should always be an "opened" note if 'notes' not in sr: sr['notes'] = [] relevant_notes = 0 for note in sr['notes']: note['datetime'] = iso8601.parse_date(note['datetime']) if note['type'] in ('follow_on', 'follow_on_created', 'activity', 'closed'): relevant_notes += 1 # add follow-on closure data, fix types, etc, etc by_id = {} follow_on_open_count = 0 follow_on_close_count = 0 for note in sr['notes']: if note['type'] in ('follow_on', 'follow_on_created', 'follow_on_closed'): note_sr_id = note['extended_attributes']['service_request_id'] # old-style is just "follow_on" for everything related to follow-ons # new-style is "follow_on_created" and "follow_on_closed" # update old notes so templates don't get crazy complicated :( if note['type'] == 'follow_on_created' or note[ 'description'].endswith('Created'): note['type'] = 'follow_on_created' follow_on_open_count += 1 by_id[note_sr_id] = note elif note['type'] == 'follow_on_closed' or note[ 'description'].endswith('Closed'): follow_on_close_count += 1 note['type'] = 'follow_on_closed' if note_sr_id in by_id: original = by_id[note_sr_id] original['extended_attributes'][ 'closed_datetime'] = note['datetime'] # if we hit any follow_on_opened notes if follow_on_open_count > 0: # remove the notes that claim the request is closed sr['notes'] = [n for n in sr['notes'] if not n['type'] == 'closed'] # set the request to open sr['status'] = 'open' # if we hit as many follow_on_closed as follow_on_opened notes, then request is really closed if follow_on_open_count == follow_on_close_count: # set the request status to closed sr['status'] = 'closed' tmp_note = {} # add a closing note tmp_note['type'] = 'closed' tmp_note['summary'] = 'Request Completed' # this is brittle, but shouldn't break tmp_datetime = sorted([ n['extended_attributes']['closed_datetime'] for n in by_id.values() ]) # set the closed datetime to be the datetime of the last-closed follow-on tmp_note['datetime'] = tmp_datetime[0] # add the extra note sr['notes'].append(tmp_note) # if there's no activity yet, show 'under review' if relevant_notes == 0: sr['notes'].append({ 'type': 'activity', 'summary': 'Under review by %s staff' % sr.get('agency_responsible', '') }) subscribed = False if sr['status'] == 'open' and session.get('addr', None): # TODO: when subscription service supports more than e-mail, # we should probably be able to show all your subscriptions here subscribed = updater.subscription_exists(request_id, 'email', session.get('addr', '')) # test media # sr['media_url'] = sr['media_url'] or 'http://farm5.staticflickr.com/4068/4286605571_c1a1751fdc_n.jpg' body = render_app_template('service_request.html', sr=sr, subscribed=subscribed, errors=form_errors, submitted_email=submitted_email) return (body, 200, None) else: return render_app_template('error_no_sr.html', request_id=request_id), 404
def show_request(request_id): request_id = request_id.lstrip('#') # receive subscription form_errors = [] submitted_email = None if request.method == 'POST': submitted_email = request.form.get('update_email') if submitted_email: success = subscribe_to_sr(request_id, submitted_email) if not success: form_errors.append('Please use a valid e-mail address.') # TODO: Should probably use Three or something nice for this... url = '%s/requests/%s.json' % (app.config['OPEN311_SERVER'], request_id) params = {'extensions': 'true', 'legacy': 'false'} if app.config['OPEN311_API_KEY']: params['api_key'] = app.config['OPEN311_API_KEY'] r = requests.get(url, params=params) if r.status_code == 404: # TODO: how to generalize this? # Chicago's SR IDs are always \d\d-\d{8}, if we get just digits, reformat and try again request_id_digits = re.sub(r'\D', '', request_id) if len(request_id_digits) == 8: # Try prepending the year if it's only 8 digits request_id_digits = datetime.date.today().strftime('%y') + request_id_digits if len(request_id_digits) == 10: reformatted = '%s-%s' % (request_id_digits[:2], request_id_digits[2:]) if reformatted != request_id: return redirect(url_for('show_request', request_id=reformatted)) # It would be nice to log this for analytical purposes (what requests are being checked that we can't show?) # but that would be better done through GA or KISS Metrics than through server logging services = open311tools.services(app.config['OPEN311_SERVER'], app.config['OPEN311_API_KEY']) return render_app_template('error_no_sr.html', request_id=request_id, services=services), 404 elif r.status_code != 200: app.logger.error('OPEN311: Error (not 404) loading data for SR %s', request_id) return render_app_template('error_311_api.html', request_id=request_id), 500 srs = r.json if srs: sr = fixup_sr(srs[0], request_id) if 'requested_datetime' in sr: sr['requested_datetime'] = iso8601.parse_date(sr['requested_datetime']) # sometimes an SR doesn't include notes even though there should always be an "opened" note if 'notes' not in sr: sr['notes'] = [] relevant_notes = 0 for note in sr['notes']: note['datetime'] = iso8601.parse_date(note['datetime']) if note['type'] in ('follow_on', 'follow_on_created', 'activity', 'closed'): relevant_notes += 1 # add follow-on closure data, fix types, etc, etc by_id = {} follow_on_open_count = 0 follow_on_close_count = 0 for note in sr['notes']: if note['type'] in ('follow_on', 'follow_on_created', 'follow_on_closed'): note_sr_id = note['extended_attributes']['service_request_id'] # old-style is just "follow_on" for everything related to follow-ons # new-style is "follow_on_created" and "follow_on_closed" # update old notes so templates don't get crazy complicated :( if note['type'] == 'follow_on_created' or note['description'].endswith('Created'): note['type'] = 'follow_on_created' follow_on_open_count += 1 by_id[note_sr_id] = note elif note['type'] == 'follow_on_closed' or note['description'].endswith('Closed'): follow_on_close_count += 1 note['type'] = 'follow_on_closed' if note_sr_id in by_id: original = by_id[note_sr_id] original['extended_attributes']['closed_datetime'] = note['datetime'] # if we hit any follow_on_opened notes if follow_on_open_count >0: # remove the notes that claim the request is closed sr['notes'] = [n for n in sr['notes'] if not n['type'] == 'closed'] # set the request to open sr['status'] = 'open' # if we hit as many follow_on_closed as follow_on_opened notes, then request is really closed if follow_on_open_count == follow_on_close_count: # set the request status to closed sr['status'] = 'closed' tmp_note = {} # add a closing note tmp_note['type'] = 'closed' tmp_note['summary'] = 'Request Completed' # this is brittle, but shouldn't break tmp_datetime = sorted([n['extended_attributes']['closed_datetime'] for n in by_id.values()]) # set the closed datetime to be the datetime of the last-closed follow-on tmp_note['datetime'] = tmp_datetime[0] # add the extra note sr['notes'].append(tmp_note) # if there's no activity yet, show 'under review' if relevant_notes == 0: sr['notes'].append({ 'type': 'activity', 'summary': 'Under review by %s staff' % sr.get('agency_responsible', '') }) subscribed = False if sr['status'] == 'open' and session.get('addr', None): # TODO: when subscription service supports more than e-mail, # we should probably be able to show all your subscriptions here subscribed = updater.subscription_exists(request_id, 'email', session.get('addr', '')) # test media # sr['media_url'] = sr['media_url'] or 'http://farm5.staticflickr.com/4068/4286605571_c1a1751fdc_n.jpg' body = render_app_template('service_request.html', sr=sr, subscribed=subscribed, errors=form_errors, submitted_email=submitted_email) return (body, 200, None) else: return render_app_template('error_no_sr.html', request_id=request_id), 404
def show_request(request_id): request_id = request_id.lstrip('#') # TODO: Should probably use Three or something nice for this... url = '%s/requests/%s.json' % (app.config['OPEN311_SERVER'], request_id) params = {'extensions': 'true', 'legacy': 'false'} if app.config['OPEN311_API_KEY']: params['api_key'] = app.config['OPEN311_API_KEY'] r = requests.get(url, params=params) if r.status_code == 404: # TODO: need a template # logger.error("There is no service request on file for #%s" % request_id) # debugresponse (r) # debugrequest (request) return render_template('no_service_request_found.html', rid=request_id) elif r.status_code != 200: # TODO: need a template logger.error("There was an error getting data about service request #%s" % request_id) debugresponse (r) debugrequest (request) return ("There was an error getting data about service request #%s" % request_id, 404, None) srs = r.json if srs: # debug the data logger.debug("got data %s" % pp.pformat(srs)) # check the return data, it should be a list if (not isinstance(srs, types.ListType)): return ("There was an error getting data about service request #%s" % request_id, 404, None) sr = srs[0] sr['requested_datetime'] = iso8601.parse_date(sr['requested_datetime']) for note in sr['notes']: note['datetime'] = iso8601.parse_date(note['datetime']) # add follow-on closure data by_id = {} for note in sr['notes']: if(note['extended_attributes']['closed_datetime']): note['extended_attributes']['closed_datetime']= iso8601.parse_date( note['extended_attributes']['closed_datetime'] ) if note['type'] == 'follow_on': note_sr_id = note['extended_attributes']['service_request_id'] if note_sr_id in by_id: if note['description'].endswith('Closed'): original = by_id[note_sr_id] original['extended_attributes']['closed_datetime'] = note['datetime'] else: by_id[note_sr_id] = note sr['notes'].reverse() subscribed = False if sr['status'] == 'open' and session.get('email', None): # TODO: when subscription service supports more than e-mail, # we should probably be able to show all your subscriptions here subscribed = updater.subscription_exists(request_id, 'email', session.get('email', '')) #more checks that should not be in the template, but in the app. lets have some type of logical separation here. assert(sr['address']) assert isinstance(sr['address'], types.StringTypes) assert(sr['service_name']) assert(sr['description']) assert(sr['status']) assert(sr['extended_attributes']) assert(sr['extended_attributes']['channel']) assert(sr['agency_responsible']) assert(sr['service_request_id']) body = render_template('service_request.html', sr=sr, subscribed=subscribed) return (body, 200, None) else: return render_template('no_service_request_found.html', rid=request_id)
def show_request(request_id): request_id = request_id.lstrip("#") # receive subscription form_errors = [] submitted_email = None if request.method == "POST": submitted_email = request.form.get("update_email") if submitted_email: success = subscribe_to_sr(request_id, submitted_email) if not success: form_errors.append("Please use a valid e-mail address.") # TODO: Should probably use Three or something nice for this... url = "%s/requests/%s.json" % (app.config["OPEN311_SERVER"], request_id) params = {"extensions": "true", "legacy": "false"} if app.config["OPEN311_API_KEY"]: params["api_key"] = app.config["OPEN311_API_KEY"] r = requests.get(url, params=params) if r.status_code == 404: # TODO: how to generalize this? # Chicago's SR IDs are always \d\d-\d{8}, if we get just digits, reformat and try again request_id_digits = re.sub(r"\D", "", request_id) if len(request_id_digits) == 8: # Try prepending the year if it's only 8 digits request_id_digits = datetime.date.today().strftime("%y") + request_id_digits if len(request_id_digits) == 10: reformatted = "%s-%s" % (request_id_digits[:2], request_id_digits[2:]) if reformatted != request_id: return redirect(url_for("show_request", request_id=reformatted)) # It would be nice to log this for analytical purposes (what requests are being checked that we can't show?) # but that would be better done through GA or KISS Metrics than through server logging services = open311tools.services(app.config["OPEN311_SERVER"], app.config["OPEN311_API_KEY"]) return render_app_template("error_no_sr.html", request_id=request_id, services=services), 404 elif r.status_code != 200: app.logger.error("OPEN311: Error (not 404) loading data for SR %s", request_id) return render_app_template("error_311_api.html", request_id=request_id), 500 srs = r.json if srs: sr = fixup_sr(srs[0], request_id) if "requested_datetime" in sr: sr["requested_datetime"] = iso8601.parse_date(sr["requested_datetime"]) # sometimes an SR doesn't include notes even though there should always be an "opened" note if "notes" not in sr: sr["notes"] = [] relevant_notes = 0 for note in sr["notes"]: note["datetime"] = iso8601.parse_date(note["datetime"]) if note["type"] in ("follow_on", "follow_on_created", "activity", "closed"): relevant_notes += 1 # add follow-on closure data, fix types, etc, etc by_id = {} follow_on_open_count = 0 follow_on_close_count = 0 for note in sr["notes"]: if note["type"] in ("follow_on", "follow_on_created", "follow_on_closed"): note_sr_id = note["extended_attributes"]["service_request_id"] # old-style is just "follow_on" for everything related to follow-ons # new-style is "follow_on_created" and "follow_on_closed" # update old notes so templates don't get crazy complicated :( if note["type"] == "follow_on_created" or note["description"].endswith("Created"): note["type"] = "follow_on_created" follow_on_open_count += 1 by_id[note_sr_id] = note elif note["type"] == "follow_on_closed" or note["description"].endswith("Closed"): follow_on_close_count += 1 note["type"] = "follow_on_closed" if note_sr_id in by_id: original = by_id[note_sr_id] original["extended_attributes"]["closed_datetime"] = note["datetime"] # if we hit any follow_on_opened notes if follow_on_open_count > 0: # remove the notes that claim the request is closed sr["notes"] = [n for n in sr["notes"] if not n["type"] == "closed"] # set the request to open sr["status"] = "open" # if we hit as many follow_on_closed as follow_on_opened notes, then request is really closed if follow_on_open_count == follow_on_close_count: # set the request status to closed sr["status"] = "closed" tmp_note = {} # add a closing note tmp_note["type"] = "closed" tmp_note["summary"] = "Request Completed" # this is brittle, but shouldn't break tmp_datetime = sorted([n["extended_attributes"]["closed_datetime"] for n in by_id.values()]) # set the closed datetime to be the datetime of the last-closed follow-on tmp_note["datetime"] = tmp_datetime[0] # add the extra note sr["notes"].append(tmp_note) # if there's no activity yet, show 'under review' if relevant_notes == 0: sr["notes"].append( {"type": "activity", "summary": "Under review by %s staff" % sr.get("agency_responsible", "")} ) subscribed = False if sr["status"] == "open" and session.get("addr", None): # TODO: when subscription service supports more than e-mail, # we should probably be able to show all your subscriptions here subscribed = updater.subscription_exists(request_id, "email", session.get("addr", "")) # test media # sr['media_url'] = sr['media_url'] or 'http://farm5.staticflickr.com/4068/4286605571_c1a1751fdc_n.jpg' body = render_app_template( "service_request.html", sr=sr, subscribed=subscribed, errors=form_errors, submitted_email=submitted_email ) return (body, 200, None) else: return render_app_template("error_no_sr.html", request_id=request_id), 404