def frontpage(self): if not self.enabled: return template('disabled') return template('frontpage', local_url=self.url_link, local_uuid=self.kn.uuid[9:], menu=self.menu)
def remote_action(self): if not self.enabled: return template("disabled") qry = request.GET action_dict = { "enable": self.kn.enable_remote, "disable": self.kn.disable_remote, "remove": self.kn.remove_remote, "add": self.kn.register_remote, } valk = validate_keys(["host", "port", "action"], qry) if not valk is True: return valk try: validate( [ ( qry["port"], lambda p: p.isdigit() and int(p) < 65536, "Parameter 'port' has to be between 0 and 65535.", ), (qry["action"], lambda a: a in action_dict, "Invalid value for parameter 'action': %s"), ] ) except ValueError, valerr: return template("message", heading="Parameter Error", message=valerr.args[0], back_url="/remotes/")
def summary(self): if not self.enabled: return template("disabled") qry = request.GET val_id = validate_keys(["id"], qry) if not val_id is True: return val_id if qry["id"].endswith(".field"): return self.fieldcontainer(qry["id"]) elif qry["id"].endswith(".sample"): return self.samplecontainer(qry["id"]) else: return template("message", heading="Parameter Error", back_url="/", message="Not an emd5: '%s'" % qry["id"])
def summary(self): if not self.enabled: return template('disabled') qry = request.GET val_id = validate_keys(['id'], qry) if not val_id is True: return val_id if qry['id'].endswith('.field'): return self.fieldcontainer(qry['id']) elif qry['id'].endswith('.sample'): return self.samplecontainer(qry['id']) else: return template( 'message', heading='Parameter Error', back_url='/', message="Not an emd5: '%s'" % qry['id'])
def remotes(self): if not self.enabled: return template("disabled") remote_rows = [[("URL", 2), "UUID", ("Action", 2)]] for remote in self.kn.remotes: endisstr = cond(remote._status == 2, ("enable", "disable")) qdict = {"host": remote.host, "port": remote.port, "action": endisstr} endis = HTMLLink("/remote_action?" + urlencode(qdict), endisstr) qdict["action"] = "remove" rem = HTMLLink("/remote_action?" + urlencode(qdict), "remove") uuid = remote.uuid if uuid != None: uuid = uuid[9:] remote_rows.append([HTMLStatus(remote.status), HTMLLink(remote.url, remote.url), uuid, endis, rem]) remote_table = HTMLTable(remote_rows) return template("remotes", remote_table=remote_table.getHTML())
def validate_keys(keys, mapping): try: validate([(k, lambda k: k in mapping, "Missing parameter: %s") \ for k in keys]) except ValueError, verr: return template('message', heading='Parameter Error', message=verr.args[0], back_url='/')
def images(self, filename): if not self.enabled: return template("disabled") send_file( filename, os.path.join(self.rootdir, "images"), guessmime=False, mimetype=self.kn.mimetypes.guess_type(filename)[0], )
def common_summary(self, dc_id): dctype = cond(dc_id.endswith('field'), ('field', 'sample')) keys = ['id', 'machine', 'creator', 'date', 'hash', 'longname'] result = self.kn.km.search(keys, {'type':dctype, 'id':dc_id}) if result == []: raise DCNotFoundError(template( 'message', heading='Parameter Error', back_url='/', message="Could not find data container '%s'" % dc_id)) return zip(keys, result[0])
def remotes(self): if not self.enabled: return template('disabled') remote_rows = [[('URL', 2), 'UUID', ('Action', 2)]] for remote in self.kn.remotes: endisstr = cond(remote._status == 2, ('enable', 'disable')) qdict = {'host':remote.host, 'port':remote.port, 'action':endisstr} endis = HTMLLink('/remote_action?' + urlencode(qdict), endisstr) qdict['action'] = 'remove' rem = HTMLLink('/remote_action?' + urlencode(qdict), 'remove') uuid = remote.uuid if uuid != None: uuid = uuid[9:] remote_rows.append([HTMLStatus(remote.status), HTMLLink(remote.url, remote.url), uuid, endis, rem]) remote_table = HTMLTable(remote_rows) return template('remotes', remote_table=remote_table.getHTML())
def remote_action(self): if not self.enabled: return template('disabled') qry = request.GET action_dict = {'enable':self.kn.enable_remote, 'disable':self.kn.disable_remote, 'remove':self.kn.remove_remote, 'add':self.kn.register_remote} valk = validate_keys(['host', 'port', 'action'], qry) if not valk is True: return valk try: validate([(qry['port'], lambda p: p.isdigit() and int(p) < 65536, "Parameter 'port' has to be between 0 and 65535."), (qry['action'], lambda a: a in action_dict, "Invalid value for parameter 'action': %s")] ) except ValueError, valerr: return template('message', heading='Parameter Error', message=valerr.args[0], back_url='/remotes/')
def common_summary(self, dc_id): dctype = cond(dc_id.endswith("field"), ("field", "sample")) keys = ["id", "machine", "creator", "date", "hash", "longname"] result = self.kn.km.search(keys, {"type": dctype, "id": dc_id}) if result == []: raise DCNotFoundError( template( "message", heading="Parameter Error", back_url="/", message="Could not find data container '%s'" % dc_id, ) ) return zip(keys, result[0])
def log(self): if not self.enabled: return template('disabled') with open(os.path.join(getPyphantPath(), 'pyphant.log')) as logfile: loglines = logfile.readlines() return template('log', loglines=''.join(loglines), url=self.url_link)
def script(self, filename): if not self.enabled: return template('disabled') send_file(filename, os.path.join(self.rootdir, 'script'), guessmime=False, mimetype='application/javascript')
def search(self): if not self.enabled: return template('disabled') # --- qry verification and completion --- common_keys = ['type', 'machine', 'creator', 'longname', 'shortname'] complete = dict([(key, self.anystr) for key in common_keys]) complete.update({ 'order_by': 'date', 'order_asc': 'True', 'offset': '0', 'jump': 'False', 'date_from': '', 'date_to': '', 'shorten': 'False', 'add_attr': 'False', 'rem_attr': 'None' }) qry = request.GET for key in complete: if not key in qry: qry[key] = complete[key] do_shorten = (qry['shorten'] == 'True') add_attr = (qry['add_attr'] == 'True') order_asc = (qry['order_asc'] == 'True') order_by = qry['order_by'] body_onload = cond( qry['jump'] == 'True', (""" onload="window.location.hash='result_view';" """, "")) offset = max(int(qry['offset']), 0) limit = 500 search_dict = dict([(key, qry[key]) for key in common_keys \ if qry[key] != self.anystr]) if qry['date_from'] != '': search_dict['date_from'] = qry['date_from'] if qry['date_to'] != '': search_dict['date_to'] = qry['date_to'] attr_post = [key[8:] for key in qry if key.startswith('attr_key')] attr_post.sort(key=lambda x: int(x)) if qry['rem_attr'] != 'None': attr_post.remove(qry['rem_attr']) qry.pop('attr_key' + qry['rem_attr']) qry.pop('attr_value' + qry['rem_attr']) if add_attr: if attr_post == []: last_index = -1 else: last_index = int(attr_post[-1]) attr_post.append(str(last_index + 1)) qry['attr_key' + attr_post[-1]] = '' qry['attr_value' + attr_post[-1]] = '' from pyphant.core.Helpers import utf82uc def testany(str1): str2 = utf82uc(str1) if str2 == u"": str2 = self.kn.km.any_value return str2 search_dict['attributes'] = dict( [(qry['attr_key' + apost], testany(qry['attr_value' + apost])) \ for apost in attr_post] ) #print search_dict # --- common search keys --- optionss = [[(self.anystr, )] \ + self.kn.km.search([key], search_dict, distinct=True) \ for key in common_keys] rows = [common_keys[:3]] rows.append([HTMLDropdown( key, [opt[0] for opt in opts], qry[key], "document.search_form.submit();") \ for key, opts in zip(common_keys[:3], optionss[:3])]) common = HTMLTable(rows).getHTML() rows = [common_keys[3:]] rows.append([HTMLDropdown( key, [opt[0] for opt in opts], qry[key], "document.search_form.submit();") \ for key, opts in zip(common_keys[3:], optionss[3:])]) common += "<br />" + HTMLTable(rows).getHTML() # --- date search keys --- date_table = HTMLTable( [['date from', 'date to'], [ HTMLTextInput('date_from', 26, 26, qry['date_from'], "document.search_form.submit();"), HTMLTextInput('date_to', 26, 26, qry['date_to'], "document.search_form.submit();") ]]) date = date_table.getHTML() # --- attribute search keys rows = [[ 'attribute', 'value', HTMLJSButton('--add--', 'add_attribute();') ]] rows.extend([[HTMLTextInput('attr_key' + apost, 20, 100, qry['attr_key' + apost]), HTMLTextInput('attr_value' + apost, 50, 1000, qry['attr_value' + apost], 'document.search_form.submit();'), HTMLJSButton('--remove--', "remove_attribute('%s');" % (apost, ))] \ for apost in attr_post]) attributes = HTMLTable(rows).getHTML() # --- results --- missing_keys = ['date'] \ + [key for key in common_keys \ if qry[key] == self.anystr] \ + ['id'] if not order_by in missing_keys: order_by = 'date' search_result = self.kn.km.search(missing_keys, search_dict, order_by=order_by, order_asc=order_asc, limit=limit, offset=offset) rows = [order_bar(missing_keys[:-1], order_by, order_asc)\ + ['details', 'tmp']] rows.extend([nice(srow[:-1], missing_keys[:-1], do_shorten) \ + (HTMLSummaryLink((srow[-1], 'click')), self.kn.km.isTemporary(srow[-1])) \ for srow in search_result]) bbar = HTMLBrowseBar(offset, limit).getHTML() result = bbar + "<br />" + HTMLTable(rows).getHTML() + "<br />" + bbar return template('search', common=common, date=date, attributes=attributes, special='special...', result=result, order_by=order_by, order_asc=qry['order_asc'], body_onload=body_onload, shorten=cond(do_shorten, ('checked', '')), offset=qry['offset'])
raise DCNotFoundError(template( 'message', heading='Parameter Error', back_url='/', message="Could not find data container '%s'" % dc_id)) return zip(keys, result[0]) def fieldcontainer(self, fc_id): try: common_rows = self.common_summary(fc_id) except DCNotFoundError, dcnferr: return dcnferr.args[0] rows = [['scheme', HTMLFCScheme(fc_id, self.kn)]] rows.extend(common_rows[:-1]) rows.append(['dimensions', HTMLChildrenTable(fc_id, self.kn)]) rows.append(['attributes', HTMLAttrTable(fc_id, self.kn)]) htmlsumm = HTMLTable(rows, headings=False) return template('fieldcontainer', summary=htmlsumm, longname=common_rows[5][1]) def samplecontainer(self, sc_id): try: common_rows = self.common_summary(sc_id) except DCNotFoundError, dcnferr: return dcnferr.args[0] scheme = HTMLSCScheme(sc_id, self.kn) rows = [['scheme', scheme]] rows.extend(common_rows[:-1]) rows.append(['columns', HTMLChildrenTable(sc_id, self.kn)]) rows.append(['attributes', HTMLAttrTable(sc_id, self.kn)]) htmlsumm = HTMLTable(rows, headings=False) return template('samplecontainer', summary=htmlsumm, longname=common_rows[5][1])
class WebInterface(object): """ Web interface for the KnowledgeNode class. """ anystr = '-- any --' def __init__(self, knowledge_node, enabled): """ knowledge_node -- KN instance the web interface is bound to enabled -- whether the web interface should be enabled upon start. """ self.enabled = enabled self.kn = knowledge_node self.rootdir = pkg_resources.resource_filename('pyphant', 'web') self.url_link = HTMLLink(self.kn.url, self.kn.url).getHTML() self.menu = HTMLTable([[ HTMLLink('/search?shorten=True', 'Browse Data Containers'), HTMLLink('/remotes/', 'Manage Remotes'), HTMLLink('/log/', 'Show Log') ]], headings=False, border=0).getHTML() self._setup_routes() def _setup_routes(self): self.kn.app.add_route('/', self.frontpage) self.kn.app.add_route('/images/:filename', self.images) self.kn.app.add_route('/remote_action', self.remote_action) self.kn.app.add_route('/favicon.ico', self.favicon) self.kn.app.add_route('/log/', self.log) self.kn.app.add_route('/remotes/', self.remotes) self.kn.app.add_route('/summary', self.summary) self.kn.app.add_route('/script/:filename', self.script) self.kn.app.add_route('/search', self.search) def frontpage(self): if not self.enabled: return template('disabled') return template('frontpage', local_url=self.url_link, local_uuid=self.kn.uuid[9:], menu=self.menu) def remotes(self): if not self.enabled: return template('disabled') remote_rows = [[('URL', 2), 'UUID', ('Action', 2)]] for remote in self.kn.remotes: endisstr = cond(remote._status == 2, ('enable', 'disable')) qdict = { 'host': remote.host, 'port': remote.port, 'action': endisstr } endis = HTMLLink('/remote_action?' + urlencode(qdict), endisstr) qdict['action'] = 'remove' rem = HTMLLink('/remote_action?' + urlencode(qdict), 'remove') uuid = remote.uuid if uuid != None: uuid = uuid[9:] remote_rows.append([ HTMLStatus(remote.status), HTMLLink(remote.url, remote.url), uuid, endis, rem ]) remote_table = HTMLTable(remote_rows) return template('remotes', remote_table=remote_table.getHTML()) def images(self, filename): if not self.enabled: return template('disabled') send_file(filename, os.path.join(self.rootdir, 'images'), guessmime=False, mimetype=self.kn.mimetypes.guess_type(filename)[0]) def script(self, filename): if not self.enabled: return template('disabled') send_file(filename, os.path.join(self.rootdir, 'script'), guessmime=False, mimetype='application/javascript') def remote_action(self): if not self.enabled: return template('disabled') qry = request.GET action_dict = { 'enable': self.kn.enable_remote, 'disable': self.kn.disable_remote, 'remove': self.kn.remove_remote, 'add': self.kn.register_remote } valk = validate_keys(['host', 'port', 'action'], qry) if not valk is True: return valk try: validate([(qry['port'], lambda p: p.isdigit() and int(p) < 65536, "Parameter 'port' has to be between 0 and 65535."), (qry['action'], lambda a: a in action_dict, "Invalid value for parameter 'action': %s")]) except ValueError, valerr: return template('message', heading='Parameter Error', message=valerr.args[0], back_url='/remotes/') port = int(qry['port']) try: action_dict[qry['action']](qry['host'], port) except RemoteError, remerr: return template('message', heading='Error', message=remerr.args[0], back_url='/remotes/')
def search(self): if not self.enabled: return template('disabled') # --- qry verification and completion --- common_keys = ['type', 'machine', 'creator', 'longname', 'shortname'] complete = dict([(key, self.anystr) for key in common_keys]) complete.update({'order_by':'date', 'order_asc':'True', 'offset':'0', 'jump':'False', 'date_from':'', 'date_to':'', 'shorten':'False', 'add_attr':'False', 'rem_attr':'None'}) qry = request.GET for key in complete: if not key in qry: qry[key] = complete[key] do_shorten = (qry['shorten'] == 'True') add_attr = (qry['add_attr'] == 'True') order_asc = (qry['order_asc'] == 'True') order_by = qry['order_by'] body_onload = cond( qry['jump'] == 'True', (""" onload="window.location.hash='result_view';" """, "")) offset = max(int(qry['offset']), 0) limit = 500 search_dict = dict([(key, qry[key]) for key in common_keys \ if qry[key] != self.anystr]) if qry['date_from'] != '': search_dict['date_from'] = qry['date_from'] if qry['date_to'] != '': search_dict['date_to'] = qry['date_to'] attr_post = [key[8:] for key in qry if key.startswith('attr_key')] attr_post.sort(key=lambda x: int(x)) if qry['rem_attr'] != 'None': attr_post.remove(qry['rem_attr']) qry.pop('attr_key' + qry['rem_attr']) qry.pop('attr_value' + qry['rem_attr']) if add_attr: if attr_post == []: last_index = -1 else: last_index = int(attr_post[-1]) attr_post.append(str(last_index + 1)) qry['attr_key' + attr_post[-1]] = '' qry['attr_value' + attr_post[-1]] = '' from pyphant.core.Helpers import utf82uc def testany(str1): str2 = utf82uc(str1) if str2 == u"": str2 = self.kn.km.any_value return str2 search_dict['attributes'] = dict([(qry['attr_key' + apost], testany(qry['attr_value' + apost])) \ for apost in attr_post]) #print search_dict # --- common search keys --- optionss = [[(self.anystr, )] \ + self.kn.km.search([key], search_dict, distinct=True) \ for key in common_keys] rows = [common_keys[:3]] rows.append([HTMLDropdown( key, [opt[0] for opt in opts], qry[key], "document.search_form.submit();") \ for key, opts in zip(common_keys[:3], optionss[:3])]) common = HTMLTable(rows).getHTML() rows = [common_keys[3:]] rows.append([HTMLDropdown( key, [opt[0] for opt in opts], qry[key], "document.search_form.submit();") \ for key, opts in zip(common_keys[3:], optionss[3:])]) common += "<br />" + HTMLTable(rows).getHTML() # --- date search keys --- date_table = HTMLTable( [['date from', 'date to'], [HTMLTextInput('date_from', 26, 26, qry['date_from'], "document.search_form.submit();"), HTMLTextInput('date_to', 26, 26, qry['date_to'], "document.search_form.submit();")]]) date = date_table.getHTML() # --- attribute search keys rows = [['attribute', 'value', HTMLJSButton('--add--', 'add_attribute();')]] rows.extend([[HTMLTextInput('attr_key' + apost, 20, 100, qry['attr_key' + apost]), HTMLTextInput('attr_value' + apost, 50, 1000, qry['attr_value' + apost], 'document.search_form.submit();'), HTMLJSButton('--remove--', "remove_attribute('%s');" % (apost, ))] \ for apost in attr_post]) attributes = HTMLTable(rows).getHTML() # --- results --- missing_keys = ['date'] \ + [key for key in common_keys \ if qry[key] == self.anystr] \ + ['id'] if not order_by in missing_keys: order_by = 'date' search_result = self.kn.km.search( missing_keys, search_dict, order_by=order_by, order_asc=order_asc, limit=limit, offset=offset) rows = [order_bar(missing_keys[:-1], order_by, order_asc)\ + ['details', 'tmp']] rows.extend([nice(srow[:-1], missing_keys[:-1], do_shorten) \ + (HTMLSummaryLink((srow[-1], 'click')), self.kn.km.isTemporary(srow[-1])) \ for srow in search_result]) bbar = HTMLBrowseBar(offset, limit).getHTML() result = bbar + "<br />" + HTMLTable(rows).getHTML() + "<br />" + bbar return template('search', common=common, date=date, attributes=attributes, special='special...', result=result, order_by=order_by, order_asc=qry['order_asc'], body_onload=body_onload, shorten=cond(do_shorten, ('checked', '')), offset=qry['offset'])
def log(self): if not self.enabled: return template("disabled") with open(os.path.join(getPyphantPath(), "pyphant.log")) as logfile: loglines = logfile.readlines() return template("log", loglines="".join(loglines), url=self.url_link)
def search(self): if not self.enabled: return template("disabled") # --- qry verification and completion --- common_keys = ["type", "machine", "creator", "longname", "shortname"] complete = dict([(key, self.anystr) for key in common_keys]) complete.update( { "order_by": "date", "order_asc": "True", "offset": "0", "jump": "False", "date_from": "", "date_to": "", "shorten": "False", "add_attr": "False", "rem_attr": "None", } ) qry = request.GET for key in complete: if not key in qry: qry[key] = complete[key] do_shorten = qry["shorten"] == "True" add_attr = qry["add_attr"] == "True" order_asc = qry["order_asc"] == "True" order_by = qry["order_by"] body_onload = cond(qry["jump"] == "True", (""" onload="window.location.hash='result_view';" """, "")) offset = max(int(qry["offset"]), 0) limit = 500 search_dict = dict([(key, qry[key]) for key in common_keys if qry[key] != self.anystr]) if qry["date_from"] != "": search_dict["date_from"] = qry["date_from"] if qry["date_to"] != "": search_dict["date_to"] = qry["date_to"] attr_post = [key[8:] for key in qry if key.startswith("attr_key")] attr_post.sort(key=lambda x: int(x)) if qry["rem_attr"] != "None": attr_post.remove(qry["rem_attr"]) qry.pop("attr_key" + qry["rem_attr"]) qry.pop("attr_value" + qry["rem_attr"]) if add_attr: if attr_post == []: last_index = -1 else: last_index = int(attr_post[-1]) attr_post.append(str(last_index + 1)) qry["attr_key" + attr_post[-1]] = "" qry["attr_value" + attr_post[-1]] = "" from pyphant.core.Helpers import utf82uc def testany(str1): str2 = utf82uc(str1) if str2 == u"": str2 = self.kn.km.any_value return str2 search_dict["attributes"] = dict( [(qry["attr_key" + apost], testany(qry["attr_value" + apost])) for apost in attr_post] ) # print search_dict # --- common search keys --- optionss = [[(self.anystr,)] + self.kn.km.search([key], search_dict, distinct=True) for key in common_keys] rows = [common_keys[:3]] rows.append( [ HTMLDropdown(key, [opt[0] for opt in opts], qry[key], "document.search_form.submit();") for key, opts in zip(common_keys[:3], optionss[:3]) ] ) common = HTMLTable(rows).getHTML() rows = [common_keys[3:]] rows.append( [ HTMLDropdown(key, [opt[0] for opt in opts], qry[key], "document.search_form.submit();") for key, opts in zip(common_keys[3:], optionss[3:]) ] ) common += "<br />" + HTMLTable(rows).getHTML() # --- date search keys --- date_table = HTMLTable( [ ["date from", "date to"], [ HTMLTextInput("date_from", 26, 26, qry["date_from"], "document.search_form.submit();"), HTMLTextInput("date_to", 26, 26, qry["date_to"], "document.search_form.submit();"), ], ] ) date = date_table.getHTML() # --- attribute search keys rows = [["attribute", "value", HTMLJSButton("--add--", "add_attribute();")]] rows.extend( [ [ HTMLTextInput("attr_key" + apost, 20, 100, qry["attr_key" + apost]), HTMLTextInput( "attr_value" + apost, 50, 1000, qry["attr_value" + apost], "document.search_form.submit();" ), HTMLJSButton("--remove--", "remove_attribute('%s');" % (apost,)), ] for apost in attr_post ] ) attributes = HTMLTable(rows).getHTML() # --- results --- missing_keys = ["date"] + [key for key in common_keys if qry[key] == self.anystr] + ["id"] if not order_by in missing_keys: order_by = "date" search_result = self.kn.km.search( missing_keys, search_dict, order_by=order_by, order_asc=order_asc, limit=limit, offset=offset ) rows = [order_bar(missing_keys[:-1], order_by, order_asc) + ["details", "tmp"]] rows.extend( [ nice(srow[:-1], missing_keys[:-1], do_shorten) + (HTMLSummaryLink((srow[-1], "click")), self.kn.km.isTemporary(srow[-1])) for srow in search_result ] ) bbar = HTMLBrowseBar(offset, limit).getHTML() result = bbar + "<br />" + HTMLTable(rows).getHTML() + "<br />" + bbar return template( "search", common=common, date=date, attributes=attributes, special="special...", result=result, order_by=order_by, order_asc=qry["order_asc"], body_onload=body_onload, shorten=cond(do_shorten, ("checked", "")), offset=qry["offset"], )
back_url='/', message="Could not find data container '%s'" % dc_id)) return zip(keys, result[0]) def fieldcontainer(self, fc_id): try: common_rows = self.common_summary(fc_id) except DCNotFoundError, dcnferr: return dcnferr.args[0] rows = [['scheme', HTMLFCScheme(fc_id, self.kn)]] rows.extend(common_rows[:-1]) rows.append(['dimensions', HTMLChildrenTable(fc_id, self.kn)]) rows.append(['attributes', HTMLAttrTable(fc_id, self.kn)]) htmlsumm = HTMLTable(rows, headings=False) return template('fieldcontainer', summary=htmlsumm, longname=common_rows[5][1]) def samplecontainer(self, sc_id): try: common_rows = self.common_summary(sc_id) except DCNotFoundError, dcnferr: return dcnferr.args[0] scheme = HTMLSCScheme(sc_id, self.kn) rows = [['scheme', scheme]] rows.extend(common_rows[:-1]) rows.append(['columns', HTMLChildrenTable(sc_id, self.kn)]) rows.append(['attributes', HTMLAttrTable(sc_id, self.kn)]) htmlsumm = HTMLTable(rows, headings=False) return template('samplecontainer', summary=htmlsumm,