def display_indexingrun(self, trans, runids, fmt): runid = runids[0] database = create_database("sqlite:%s" % self.db_path) store = Store(database) def render_list(t, item): t.additions.content = unicode(item.adds) t.time.content = u"%6f" % item.time def render(t): items = store.find(IndexingItem, IndexingItem.run_id == runid) t.runs.repeat(render_list, items) if hasattr(t, 'csv_link'): t.csv_link.atts["href"] = "../csv/" + ids_to_str(runids) if hasattr(t, 'chart_link'): t.chart_link.atts["href"] = "../chart/" + ids_to_str(runids) if hasattr(t, 'ratechart_link'): t.ratechart_link.atts["href"] = "../ratechart/" + ids_to_str( runids) out = trans.get_response_stream() if fmt == 'view': trans.set_content_type(ContentType("text/html", "utf-8")) out.write(render_template(render, "indexingrun.html")) elif fmt == 'csv': trans.set_content_type(ContentType("text/csv", "utf-8")) out.write(render_template(render, "indexingrun.csv"))
def display_indexingrun_cmp(self, trans, runids, fmt=None): database = create_database("sqlite:%s" % self.db_path) store = Store(database) def render_times(t, time): if time is None: t.time.content = u"" else: t.time.content = u"%6f" % time def render_list(t, item): t.additions.content = unicode(item['adds']) t.times.repeat(render_times, item['times']) def render_heading(t, runid): t.content = u"Time (%d)" % runid def gen_items(): items = store.find(IndexingItem, IndexingItem.run_id.is_in(runids)).order_by( IndexingItem.adds) result = None adds = 0 for item in items: if item.adds != adds: adds = item.adds if result is not None: yield result result = { 'adds': adds, 'times': [None] * len(runids), } result['times'][runids.index(item.run_id)] = item.time if result is not None: yield result def render(t): t.timeheadings.repeat(render_heading, runids) t.runs.repeat(render_list, gen_items()) if hasattr(t, 'csv_link'): t.csv_link.atts["href"] = "../csv/" + ids_to_str(runids) if hasattr(t, 'chart_link'): t.chart_link.atts["href"] = "../chart/" + ids_to_str(runids) if hasattr(t, 'ratechart_link'): t.ratechart_link.atts["href"] = "../ratechart/" + ids_to_str( runids) out = trans.get_response_stream() if fmt is None: trans.set_content_type(ContentType("text/html", "utf-8")) out.write(render_template(render, "indexingrun_cmp.html")) else: trans.set_content_type(ContentType("text/csv", "utf-8")) out.write(render_template(render, "indexingrun_cmp.csv"))
def handle(self, trans): trans.hide_post = True trans.set_content_type(ContentType("text/plain", self.encoding)) if (not "user" in self.query) or (not "pass" in self.query): if "cookie" in self.query: trans.set_content_type(ContentType("text/html", self.encoding)) print >> self.out, u"""<html> <head> <title>{0}</title> </head> <body> <form name="login" action="getSession?cookie" method="POST"> Username: <input type="text" name="user" value="" /><br /> Password: <input type="password" name="pass" value="" /><br /> <input type="submit" name="submit" value="Login" /> </form> </body> </html>""".format(self.model.formatHTMLTitle(u"Login")).encode( self.encoding, 'replace') return else: print >> self.out, ( u"failed: need user and pass arguments").encode( self.encoding) return userName = self.query["user"] password = self.query["pass"] user = self.store.find(APIUser, APIUser.UserName == userName).any() if user is None: print >> self.out, (u"failed: user (%s) not found" % userName).encode(self.encoding) return if not user.checkPassword(password): print >> self.out, (u"failed: password invalid").encode( self.encoding) return password = None session = user.getSession() if "cookie" in self.query: trans.set_cookie_value("priyom-api-session", trans.encode_cookie_value(session.Key), '/', session.Expires) trans.set_content_type(ContentType("text/plain", self.encoding)) print >> self.out, u"You are now logged in (a cookie has been set).".encode( self.encoding, 'replace') else: print >> self.out, session.Key.encode(self.encoding, 'replace')
def handle(self, trans): stationId = self.getQueryInt("stationId", "must be integer") station = self.store.get(Station, stationId) if station is None: self.parameterError("stationId", "Station does not exist") lastModified, frequencies = self.priyomInterface.getStationFrequencies( station, notModifiedCheck=self.autoNotModified, head=self.head) trans.set_content_type(ContentType("application/xml", self.encoding)) trans.set_header_value("Last-Modified", self.model.formatHTTPTimestamp(lastModified)) if self.head: return doc = self.model.getExportTree("station-frequencies") rootNode = doc.getroot() for (freq, modulation, state, timestamp) in frequencies: node = XMLIntf.appendTextElement(rootNode, u"station-frequency", unicode(freq), attrib={ u"modulation": modulation, u"state": state }) if state != ONAIR: node.set(u"unix", unicode(timestamp)) self.model.etreeToFile(self.out, doc, encoding=self.encoding)
def doc(self, trans, breadcrumbs): self.out = trans.get_response_stream() breadcrumbs = None docSubstitute = self.handleDocSubstitute if hasattr( self, "handleDocSubstitute") else u"No further documentation available." trans.set_response_code(200) trans.set_content_type(ContentType("text/html", "utf-8")) print >> self.out, ( u"""<html> <head> <title>{0}{1}{2}</title> </head> <body> <h1>Documentation</h1>""" + (u""" <div class="doc-breadcrumbs">{3}</div>""" if breadcrumbs is not None else u"") + u""" <h2>{0}</h2> <p>{4}</p> {5} </body> </html>""").format( self.title, (misc.get("titleSeparator", u" ") + application["name"] + u" documentation") if "name" in application else u"", (misc.get("titleSeparator", u" ") + application["host"]) if "host" in application else u"", u"", self.shortDescription if hasattr(self, "shortDescription") else u"", self.handleDoc() or docSubstitute if hasattr( self, "handleDoc") else docSubstitute).encode("utf-8")
def handle(self, trans): path = trans.get_virtual_path_info().split('/') if len(path) == 1: trans.set_response_code(404) return elif len(path) > 2: trans.set_response_code(404) return try: objId = int(path[1].decode("utf-8")) except ValueError: trans.set_response_code(404) return obj = self.store.get(self.classType, objId) if obj is None: trans.set_response_code(404) return obj.validate() self.autoNotModified(obj.Modified) trans.set_header_value("Last-Modified", self.model.formatHTTPTimestamp(obj.Modified)) trans.set_content_type(ContentType("application/xml", self.encoding)) self.model.exportToFile(self.out, obj, encoding=self.encoding)
def handle(self, trans): stationId = self.getQueryInt("stationId", "must be integer") year = self.getQueryInt("year", "must be integer") month = self.getQueryInt("month", "must be integer") if month < 1 or month > 12: self.parameterError("month", "Month %d out of bounds (1..12)" % (month)) return lastModified, transmissions = self.priyomInterface.getTransmissionsByMonth( stationId, year, month, limiter=None, notModifiedCheck=self.autoNotModified, head=self.head) trans.set_header_value( 'Last-Modified', self.model.formatHTTPTimestamp(float(lastModified))) trans.set_content_type(ContentType('application/xml', self.encoding)) if self.head: return self.model.exportListToFile(self.out, transmissions, Transmission, encoding=self.encoding, flags={"with-freqs"})
def handle(self, trans): stationId = self.getQueryInt("stationId", "must be integer") lastModified, months = self.priyomInterface.getTransmissionStats( stationId, notModifiedCheck=self.autoNotModified, head=self.head) trans.set_content_type(ContentType("application/xml", self.encoding)) trans.set_header_value( 'Last-Modified', self.model.formatHTTPTimestamp(float(lastModified))) if self.head: return doc = self.model.getExportTree("transmission-stats") rootNode = doc.getroot() for month in months: XMLIntf.appendTextElement(rootNode, u"transmission-count", unicode(month[2]), attrib={ u"year": unicode(month[0]), u"month": unicode(month[1]) }) self.model.etreeToFile(self.out, doc, encoding=self.encoding)
def handle(self, trans): stationId = self.getQueryInt("stationId", "must be integer") year = self.getQueryInt("year", "must be integer") lastModified, transmissions = self.priyomInterface.getTransmissionsByMonth( stationId, year, None, limiter=None, notModifiedCheck=self.autoNotModified, head=self.head) if lastModified is not None: trans.set_header_value( 'Last-Modified', self.model.formatHTTPTimestamp(float(lastModified))) trans.set_content_type(ContentType('application/xml', self.encoding)) if self.head: return self.model.exportListToFile(self.out, transmissions, Transmission, encoding=self.encoding, flags={"with-freqs"})
def display_indexingrun_rate_chart(self, trans, runids, avglen=None): database = create_database("sqlite:%s" % self.db_path) store = Store(database) svg = plot.indexingrun_rate_chart(store, runids, avglen) out = trans.get_response_stream() trans.set_content_type(ContentType("image/svg+xml", "utf-8")) out.write(svg)
def display_index(self, trans): trans.set_content_type(ContentType("text/html", "utf-8")) def render(t): pass out = trans.get_response_stream() out.write(render_template(render, "index.html"))
def send_error(self, trans): trans.rollback() trans.set_response_code(404) trans.set_content_type(ContentType("text/plain", "utf-8")) print >> trans.get_response_stream( ), u"Resource not found: \"{0}\".".format( trans.get_path_info(self.path_encoding)) raise EndOfResponse
def handle(self, trans): args = {} query = self.query.copy() for tuple in self.queryArgs: queryName, typecast, kwName = tuple[:3] try: if not queryName in self.query: if len(tuple) == 4: args[kwName] = tuple[3] else: self.parameterError(queryName, u"must be {0}".format(typecast)) else: args[kwName] = query[ queryName] if typecast is None else typecast( query[queryName]) del query[queryName] except TypeError as e: self.parameterError(queryName, unicode(e)) except ValueError as e: self.parameterError(queryName, unicode(e)) if len(query): self.customParameterError(u"Unknown arguments:\n {0}".format( u"\n ".join(query.iterkeys()))) tmpArgs = self.plotArgs.copy() tmpArgs.update(args) lastModified = self.dataSource.getLastModified(**tmpArgs) try: if lastModified is None: raise NoDataArgError(tmpArgs) trans.set_content_type(self.contentType) trans.set_header_value( "Last-Modified", self.model.formatHTTPTimestamp(lastModified)) self.autoNotModified(lastModified) item = APIFileResource.createOrFind(self.store, self.resourceType, tmpArgs, lastModified, self.fileFormat, self.plot) except NoDataError as e: trans.set_response_code(404) trans.set_content_type(ContentType("text/plain", self.encoding)) print >> self.out, unicode(e).encode(self.encoding) raise EndOfResponse if item is not None: img = open(item.FileName, "rb") map = mmap.mmap(img.fileno(), 0, flags=mmap.MAP_SHARED, prot=mmap.PROT_READ) trans.disableCompression() print >> self.out, map.read(map.size()) map.close() img.close() else: raise Exception(u"Could not create resource.")
def catch(self, trans, error): self.store.rollback() trans.rollback() self.nesting += 1 if self.nesting >= CatchDisconnectSelector.maxNesting: trans.rollback() trans.set_response_code(503) trans.set_content_type(ContentType("text/plain", "utf-8")) print >> trans.get_response_stream(), error.encode("utf-8") else: self.handle(trans)
def handle(self, trans): stationId = self.getQueryInt("stationId", "must be a station id") station = self.store.get(Station, stationId) if station is None: self.parameterError("stationId", "Station does not exist") tableId = self.getQueryInt("tableId", "must be a class table id") table = self.store.get(TransmissionTable, tableId) if table is None: self.parameterError("tableId", "Table does not exist") matchFields = [s for s in (item.lstrip().rstrip() for item in self.query.get("equalFields", u"").split(u",")) if len(s) > 0] if len(matchFields) == 0: matchFields = None else: for field in matchFields: if not hasattr(table, field): self.parameterError("equalFields", "{0} is not a valid field for this table.".format(field)) includeOtherStationsWithin = self.getQueryIntDefault("includeOtherStationsWithin", 86400, "must be integer seconds") lastModified, items = self.priyomInterface.getDuplicateTransmissions(table, station, matchFields, includeOtherStationsWithin, notModifiedCheck=self.autoNotModified, head=self.head) trans.set_content_type(ContentType("application/xml", self.encoding)) trans.set_header_value("Last-Modified", self.model.formatHTTPTimestamp(float(lastModified))) if self.head: return doc = self.model.getExportTree("duplicated-transmissions") rootNode = doc.getroot() dupeDict = {} for bc1, tx1, txItem1, bc2, tx2, txItem2 in items: if matchFields is None: key = unicode(txItem1) else: key = u" ".join((getattr(txItem1, field) for field in matchFields)) if key in dupeDict: rec = dupeDict[key] rec.add(bc1, tx1, txItem1) rec.add(bc2, tx2, txItem2) dupeDict[key] = rec continue node = XMLIntf.SubElement(rootNode, u"duplicated-transmission") #node.setAttribute("key", key) rec = DupeRecord(doc, node) rec.add(bc1, tx1, txItem1) rec.add(bc2, tx2, txItem2) dupeDict[key] = rec self.model.etreeToFile(self.out, doc, encoding=self.encoding)
def respond(self, trans): if hasattr(self.resource, "doc"): trans.encoding = "utf-8" breadcrumbs = None if doc.get("breadcrumbs", {}).get("enabled", False): breadcrumbs = list() return self.resource.doc(trans, breadcrumbs) else: trans.rollback() trans.set_response_code(501) trans.set_content_type(ContentType("text/plain", "utf-8")) print >> trans.get_response_stream( ), u"Documentation not implemented.".encode("utf-8")
def respond(self, trans): super(ContinueSelector, self).respond(trans) if not "100-continue" in self.getHeaderValuesSplitted("Expect"): return self.resource.respond(trans) else: #trans.rollback() #trans.set_response_code(417) #trans.set_content_type(ContentType("text/plain", "ascii")) # print >>self.out, u"We do not support 100-continue (its a WebStack issue afaik).".encode("ascii") trans.set_response_code(417) trans.set_content_type(ContentType("text/plain", "ascii")) print >> self.out, u"We do not support 100-continue (its a WebStack issue afaik).".encode( "ascii") raise EndOfResponse
def display_indexingrun_chart(self, trans, runids): database = create_database("sqlite:%s" % self.db_path) store = Store(database) #svg = plot.indexingrun_chart(store, runids) #png = plot.svg_to_png(svg) #out = trans.get_response_stream() #trans.set_content_type(ContentType("image/png")) #out.write(png) svg = plot.indexingrun_chart(store, runids) out = trans.get_response_stream() trans.set_content_type(ContentType("image/svg+xml", "utf-8")) out.write(svg)
def handle(self, trans): if trans.get_request_method() == "GET": trans.set_response_code(405) trans.set_header_value("Allow", "POST") trans.set_content_type(ContentType("text/plain")) print >> self.out, "POST your transaction data either as application/xml or as application/json according to priyom.org transaction specification" return trans.set_content_type(ContentType("text/plain", self.encoding)) contentType = str(trans.get_content_type()).split(' ', 1)[0].split(';', 1)[0] try: method = { "application/xml": self.model.importFromXmlStr, "application/json": self.model.importFromJsonStr }[contentType] except KeyError: trans.set_response_code(415) raise EndOfResponse data = trans.get_request_stream().read() context = method(data) print >> self.out, context.log.get()
def handle(self, trans): stationId = self.getQueryInt("stationId", "int; id of the station") time = self.getQueryInt("time", "int; unix timestamp at which to look") jitter = self.getQueryIntDefault("jitter", 600, "int; jitter in seconds") if jitter < 0 or jitter > 600: self.parameterError("jitter", "jitter %d out of bounds (0..600)" % (jitter)) lastModified, broadcasts = self.priyomInterface.getCloseBroadcasts(stationId, time, jitter, notModifiedCheck=self.autoNotModified, head=self.head) trans.set_content_type(ContentType("application/xml", self.encoding)) trans.set_header_value("Last-Modified", self.model.formatHTTPTimestamp(lastModified)) if self.head: return self.model.exportListToFile(self.out, broadcasts, Broadcast, encoding=self.encoding)
def handle(self, trans): lastModified = self.model.getLastUpdate() trans.set_content_type(ContentType("application/xml", self.encoding)) trans.set_header_value( "Last-Modified", self.model.formatHTTPTimestamp(float(lastModified))) if self.head: return self.autoNotModified(lastModified) items = self.store.find(Modulation) self.model.limitResults(items) doc = self.model.getExportTree("priyom-modulations") rootNode = doc.getroot() for modulation in items: modulation.toDom(rootNode) self.model.etreeToFile(self.out, doc, encoding=self.encoding)
def __init__(self, model, dataSource, renderer, queryArgs, resourceType, fileFormat=u"{0}/{{1}}.png", contentType=ContentType("image/png"), **kwargs): super(API, self).__init__(model) self.dataSource = dataSource self.renderer = renderer self.plotArgs = kwargs self.allowedMethods = frozenset(['GET']) self.queryArgs = queryArgs self.resourceType = resourceType self.fileFormat = fileFormat.format(application["plots"]) self.contentType = contentType
def handle(self, trans): lastModified, items = self.priyomInterface.listObjects( self.cls, limiter=self.model, notModifiedCheck=self.autoNotModified, head=self.head) trans.set_content_type(ContentType("application/xml", self.encoding)) trans.set_header_value( "Last-Modified", self.model.formatHTTPTimestamp(float(lastModified))) if self.head: return # flags must not be enabled here; otherwise a permission leak # is possible. self.model.exportListToFile(self.out, items, self.cls, flags=frozenset(), encoding=self.encoding)
def listing(self, trans): self.out = trans.get_response_stream() trans.set_response_code(200) trans.set_content_type(ContentType("text/html", "utf-8")) print >> self.out, u"""<html> <head> <title>{0}{1}{2}</title> </head> <body> <h1>Index of {0}</h1> <ul> {3} </ul> </body> </html>""".format(self.title, (misc.get("titleSeparator", u" ") + application["name"]) if "name" in application else u"", (misc.get("titleSeparator", u" ") + application["host"]) if "host" in application else u"", self.formatListing()).encode("utf-8")
def handle(self, trans): trans.set_content_type( ContentType(self.xhtmlContentType, self.encoding)) doc = ElementTree.ElementTree( ElementTree.Element(u"{{{0}}}html".format(XMLIntf.xhtmlNamespace))) self.html = doc.getroot() self.head = self.SubElement(self.html, u"head") self.title = self.SubElement(self.head, u"title") self.body = self.SubElement(self.html, u"body") self.buildDoc(trans, (self.html, self.head, self.body)) self.model.etreeToFile(self.out, doc, self.encoding, XMLIntf.xhtmlNamespace, serializer=self.model.xhtmlSerializer)
def handle(self, trans): path = trans.get_virtual_path_info().split('/') if len(path) == 1: trans.set_response_code(404) return elif len(path) > 2: trans.set_response_code(404) return stationDesignator = path[1].decode("utf-8") if len(stationDesignator) == 0: return None (lastModified, station) = self.priyomInterface.getStation( stationDesignator, notModifiedCheck=self.autoNotModified) if station is None: trans.set_response_code(404) return trans.set_header_value("Last-Modified", self.model.formatHTTPTimestamp(lastModified)) trans.set_content_type(ContentType("application/xml", self.encoding)) self.model.exportToFile(self.out, station, encoding=self.encoding)
def handle(self, trans): stationId = self.getQueryIntDefault("stationId", None, "must be integer") trans.set_content_type(ContentType("text/plain", self.encoding)) if self.head: return if trans.get_request_method() == "GET": print >> self.out, u"failed: Call this resource with POST to perform instanciation.".encode( self.encoding) return generatedUntil = 0 if stationId is None: generatedUntil = self.priyomInterface.scheduleMaintainer.updateSchedules( None) else: generatedUntil = self.priyomInterface.scheduleMaintainer.updateSchedule( self.store.get(Station, stationId), None) print >> self.out, u"success: valid until {0}".format( datetime.fromtimestamp(generatedUntil).strftime( priyomdate)).encode(self.encoding)
def docListing(self, trans, breadcrumbs): self.out = trans.get_response_stream() trans.set_response_code(200) trans.set_content_type(ContentType("text/html", "utf-8")) print >> self.out, (u"""<html> <head> <title>{0}{1}{2}</title> </head> <body> <h1>Documentation</h1>""" + (u""" <div class="doc-breadcrumbs">{3}</div>""" if breadcrumbs is not None else u"") + u""" <h2>{0}</h2> <ul> {4} </ul> </body> </html>""").format(self.title, (misc.get("titleSeparator", u" ") + application["name"] + u" documentation") if "name" in application else u"", (misc.get("titleSeparator", u" ") + application["host"]) if "host" in application else u"", u"", self.formatListing()).encode("utf-8")
def display_indexingruns(self, trans): trans.set_content_type(ContentType("text/html", "utf-8")) database = create_database("sqlite:%s" % self.db_path) store = Store(database) def render_list(t, item): t.test_link.atts['href'] = 'indexrun/view/' + unicode(item.id) if item.testname == item.dbname: t.test_link.test_name.content = item.testname else: t.test_link.test_name.content = "%s (%s)" % (item.testname, item.dbname) t.backend.content = item.backend t.rep_num.content = unicode(item.rep_num) t.machine_link.atts['href'] = 'machine/' + unicode(item.machine_id) t.machine_link.machine_name.content = unicode(item.machine.name) def render(t): t.runs.repeat(render_list, store.find(IndexingRun)) out = trans.get_response_stream() out.write(render_template(render, "indexingruns.html"))
def get_site_map(priyomInterface): rootPath = application["root"] model = WebModel(priyomInterface) for table in virtualTables.itervalues(): table.Model = model apiMap = MapSelector( "calls", { "getUpcomingBroadcasts": UpcomingBroadcastsAPI(model), "import": AuthorizationSelector(ImportAPI(model), "transaction"), "listStations": ListAPI(model, libPriyom.Station), "listBroadcasts": AuthorizationSelector(ListAPI(model, libPriyom.Broadcast, "list"), "list"), "listTransmissionClasses": ListAPI(model, libPriyom.TransmissionClass), "listTransmissions": AuthorizationSelector( ListAPI(model, libPriyom.Transmission, "list"), "list"), "listModulations": ListModulationsAPI(model), "getSession": SessionAPI(model), "getTransmissionStats": TransmissionStatsAPI(model), "getTransmissionsByMonth": TransmissionsByMonthAPI(model), "getCloseBroadcasts": CloseBroadcastsAPI(model), "getStationFrequencies": StationFrequenciesAPI(model), "instanciateSchedules": AuthorizationSelector(InstanciateSchedulesAPI(model), "instanciate"), "getTransmissionsByYear": TransmissionsByYearAPI(model), "getDuplicatedTransmissionItems": DuplicatedTransmissionItemsAPI(model), "plot": MapSelector( "plots", { "station": MapSelector( "station", { "hourWeekPunchCard": PlotAPI( model, PlotDataSources.PlotDataWeekHourPunch( model.store), Plots.PlotPunchCard(), [("station", Typecasts.ValidStation( model.store), "station")], u"punchcard-hw"), "hourMonthPunchCard": PlotAPI( model, PlotDataSources.PlotDataMonthHourPunch( model.store), Plots.PlotPunchCard(), [("station", Typecasts.ValidStation( model.store), "station")], u"punchcard-mw"), "hourWeekColourCard": PlotAPI( model, PlotDataSources.PlotDataWeekHourPunch( model.store), Plots.PlotColourCard(), [("station", Typecasts.ValidStation( model.store), "station")], u"colourcard-hw", subdivision=32, levels=23, mirrored=2), "hourMonthColourCard": PlotAPI( model, PlotDataSources.PlotDataMonthHourPunch( model.store), Plots.PlotColourCard(), [("station", Typecasts.ValidStation( model.store), "station")], u"colourcard-mw", subdivision=32, levels=23, mirrored=2) }), "uptime": PlotAPI(model, PlotDataSources.PlotDataUptime(model.store), Plots.PlotStackedGraph(), [("station", Typecasts.ValidStation( model.store), "station", None), ("years", Typecasts.RangeCheck(int, 1, 10), "years", 5)], u"uptime", years=5) }) }) apiMap[""] = apiMap apiRoot = MapSelector( "API root", { "station": StationResource(model), "broadcast": IDResource(model, libPriyom.Broadcast), "transmission": IDResource(model, libPriyom.Transmission), "transmissionClass": IDResource(model, libPriyom.TransmissionClass), "schedule": IDResource(model, libPriyom.Schedule), "submit": AuthorizationSelector( MapSelector( u"submit", { "log": SubmitLogResource(model), "event": SubmitEventResource(model) }), ["log", "log-moderated"]), "admin": AuthorizationSelector( MapSelector( u"admin", { "": AdminHomeResource(model), "tables": AuthorizationSelector(AdminTablesResource(model), ["admin"]), }), ["moderate", "admin"]), "call": apiMap, "doc": DocumentationSelector(apiMap), "": HomeResource(model), "css": MapResource({ "home.css": FileResource(os.path.join(rootPath, "www-files/css/home.css"), ContentType("text/css", "utf-8")), "error.css": FileResource(os.path.join(rootPath, "www-files/css/error.css"), ContentType("text/css", "utf-8")), "submit.css": FileResource( os.path.join(rootPath, "www-files/css/submit.css"), ContentType("text/css", "utf-8")), "admin.css": FileResource(os.path.join(rootPath, "www-files/css/admin.css"), ContentType("text/css", "utf-8")) }), "js": MapResource({ "jquery.js": FileResource(os.path.join(rootPath, "www-files/js/jquery.js"), ContentType("text/javascript", "utf-8")) }) }) apiRoot["submit"][""] = apiRoot["submit"].resource return ContinueSelector( CompressionSelector( ExceptionSelector( CatchDisconnectSelector( ResetSelector(model, AuthenticationSelector(model.store, apiRoot)), model.store), model)))