def new_incident(self, request): if self.config.ReadOnly: set_response_header( request, HeaderName.contentType, ContentType.plain ) request.setResponseCode(http.FORBIDDEN) return "Server is in read-only mode." incident = Incident.from_json_io( request.content, number=self.storage.next_incident_number() ) # Edit report entrys to add author for entry in incident.report_entries: entry.author = self.avatarId.decode("utf-8") self.storage.write_incident(incident) request.setResponseCode(http.CREATED) request.setHeader( HeaderName.incidentNumber.value, incident.number ) request.setHeader( HeaderName.location.value, url_for(request, "get_incident", {"number": incident.number}) ) return ""
def notFoundHandler(f): f.trap(KeyError) request.setResponseCode(http.NOT_FOUND) set_response_header( request, HeaderName.contentType, ContentType.plain ) return "Not found."
def get_incident(self, request, number): # FIXME: For debugging #import time #time.sleep(0.3) set_response_header( request, HeaderName.etag, self.storage.etag_for_incident_with_number(number) ) set_response_header( request, HeaderName.contentType, ContentType.JSON ) if False: # # This is faster, but doesn't benefit from any cleanup or # validation code, so it's only OK if we know all data in the # store is clean by this server version's standards. # return self.storage.read_incident_with_number_raw(number) else: # # This parses the data from the store, validates it, then # re-serializes it. # incident = self.storage.read_incident_with_number(number) return incident.to_json_text()
def list_incidents(self, request): #set_response_header(request, HeaderName.etag, "*") # FIXME set_response_header(request, HeaderName.contentType, ContentType.JSON) return to_json_text(sorted( incidents_from_query(self, request), cmp=lambda a, b: cmp(a[0], b[0]), reverse=True, ))
def dispatchQueue(self, request): if not request.args: request.args["show_closed"] = ["false"] set_response_header( request, HeaderName.contentType, ContentType.HTML ) return DispatchQueueElement(self)
def ping(self, request): ack = "ack" set_response_header( request, HeaderName.etag, ack ) set_response_header( request, HeaderName.contentType, ContentType.JSON ) return to_json_text(ack)
def doc_with_name(self, request, name): filePath = self.config.Resources.child("docs").child(name) if filePath.exists(): if name.endswith(".xhtml"): set_response_header(request, HeaderName.contentType, ContentType.HTML) return FileElement(filePath) request.setResponseCode(http.NOT_FOUND) set_response_header(request, HeaderName.contentType, ContentType.plain) return "Not found."
def links(self, request): #set_response_header(request, HeaderName.etag, ????) set_response_header(request, HeaderName.contentType, ContentType.JSON) return to_json_text([ {JSON.name.value: name, JSON.url.value: value} for name, value in ( ("Home page", "/"), ("Dispatch Queue", "/queue"), ("Daily Incident Summary (Table)", "/reports/daily"), ("Daily Incident Summary (Chart)", "/charts/daily"), ) ])
def list_rangers(self, request): set_response_header(request, HeaderName.etag, str(self.dms.rangers_updated)) set_response_header(request, HeaderName.contentType, ContentType.JSON) d = self.dms.rangers() d.addCallback(lambda rangers: to_json_text(tuple( { "handle": ranger.handle, "name" : ranger.name, "status": ranger.status, } for ranger in rangers )) ) return d
def list_incident_types(self, request): #set_response_header(request, HeaderName.etag, "*") # FIXME set_response_header(request, HeaderName.contentType, ContentType.JSON) return self.config.IncidentTypesJSON
def shift_report(self, request): set_response_header(request, HeaderName.contentType, ContentType.HTML) return ShiftReportElement(self, "report_shift")
def daily_chart(self, request): set_response_header(request, HeaderName.contentType, ContentType.HTML) return DailyReportElement(self, "chart_daily")
def root(self, request): set_response_header(request, HeaderName.contentType, ContentType.HTML) return HomePageElement(self)
def edit_incident(self, request, number): number = int(number) incident = self.storage.read_incident_with_number(number) # # Handle the changes requested by the client # edits_json = from_json_io(request.content) edits = Incident.from_json(edits_json, number=number, validate=False) user_entries = [] system_messages = [] state_changes = [] def log_edit_value(key, old, new): if key is JSON.number: return if old == new: #print "Client submitted unchaged value for {0}: {1}".format(JSON.describe(key), new) return if key in JSON.states(): state_changes.append((key, new)) return system_messages.append(u"Changed {0} to: {1}".format(JSON.describe(key), new if new else u"<no value>")) def diff_set(key, old, new): old = frozenset(old if old else ()) new = frozenset(new if new else ()) unchanged = old & new removed = old ^ unchanged added = new ^ unchanged return added, removed def log_edit_set(key, added, removed): if added: system_messages.append(u"Added to {0}: {1}".format(JSON.describe(key), ", ".join(added))) if removed: system_messages.append(u"Removed from {0}: {1}".format(JSON.describe(key), ", ".join(removed))) for key in edits_json.keys(): key = JSON.lookupByValue(key) if key is JSON.report_entries: if edits.report_entries is not None: for entry in edits.report_entries: # Edit report entries to add author entry.author = self.avatarId.decode("utf-8") user_entries.append(entry) elif key is JSON.location_name: if edits.location.name is not None: log_edit_value(key, incident.location.name, edits.location.name) incident.location.name = edits.location.name elif key is JSON.location_address: if edits.location.address is not None: log_edit_value(key, incident.location.address, edits.location.address) incident.location.address = edits.location.address elif key is JSON.ranger_handles: if edits.rangers is not None: added, removed = diff_set(key, incident.rangers, edits.rangers) log_edit_set(key, [r.handle for r in added], [r.handle for r in removed]) incident.rangers = edits.rangers elif key is JSON.incident_types: if edits.incident_types is not None: log_edit_set(key, *diff_set(key, incident.incident_types, edits.incident_types)) incident.incident_types = edits.incident_types else: attr_name = key.name attr_value = getattr(edits, attr_name) if key in (JSON.created, JSON.dispatched, JSON.on_scene, JSON.closed): if edits.created is None: # If created is None, then we aren't editing state. # (It would be weird if others were not None here.) continue elif attr_value is None: # None values should not cause edits. continue log_edit_value(key, getattr(incident, attr_name), attr_value) setattr(incident, attr_name, attr_value) # # Figure out what to report about state changes # highest_change = None lowest_change = None for state_changed, state_time in state_changes: if state_time is None: if lowest_change is None or JSON.cmpStates(lowest_change, state_changed) > 0: lowest_change = state_changed else: if highest_change is None or JSON.cmpStates(highest_change[0], state_changed) < 0: highest_change = (state_changed, state_time) if highest_change is not None: system_messages.append(u"State changed to: {0}".format(JSON.describe(highest_change[0]))) elif lowest_change is not None: # We need one state less than lowest_change last = None for state in JSON.states(): if state == lowest_change: break last = state system_messages.append(u"State changed to: {0}".format(JSON.describe(last))) # # Add system report entries, then user entries # if system_messages: incident.report_entries.append( ReportEntry( author = self.avatarId.decode("utf-8"), text = u"\n".join(system_messages), system_entry = True, ) ) incident.report_entries.extend(user_entries) # # Write to disk # self.storage.write_incident(incident) # # Respond # set_response_header(request, HeaderName.contentType, ContentType.JSON) request.setResponseCode(http.OK) return "";
def list_incidents(self, request): #set_response_header(request, HeaderName.etag, "*") # FIXME set_response_header(request, HeaderName.contentType, ContentType.JSON) return to_json_text(tuple(incidents_from_query(self, request)))
def queue_incident(self, request, number): set_response_header( request, HeaderName.contentType, ContentType.HTML ) return IncidentElement(self, number)