def document(self): """Render the error document""" icode = 404 code= "404" status = "Not Found" resp = request.environ.get('pylons.original_response') if resp and resp.body: content = literal(resp.body) else: content = request.GET.get('message', '') if content: content = cgi.escape(content) if resp and resp.status_int: icode = resp.status_int code = str(resp.status_int) elif request.GET.get('code', ''): code = request.GET.get('code') if code: code = cgi.escape(code) else: code = 404 if resp and resp.status: status = resp.status c.message = request.GET.get('message', '') if c.message: c.message = cgi.escape(c.message) else: c.message = content accept_list = None if 'HTTP_ACCEPT' in request.environ: try: accept_list = conneg_parse(request.environ['HTTP_ACCEPT']) except: accept_list= [MT("text", "plain")] if not accept_list: accept_list= [MT("text", "plain")] mimetype = accept_list.pop(0) while(mimetype): if str(mimetype).lower() in ["text/html", "text/xhtml"]: #page = error_document_template % \ #dict(prefix=request.environ.get('SCRIPT_NAME', ''), # code=code, # message=content) #return page c.status = status.replace(c.code, '').strip() return render('/error.html') elif str(mimetype).lower() in ["text/plain", "application/json"]: response.content_type = 'text/plain; charset="UTF-8"' response.status_int = icode response.status = status return content try: mimetype = accept_list.pop(0) except IndexError: mimetype = None #Whoops nothing satisfies - return text/plain response.content_type = 'text/plain; charset="UTF-8"' response.status_int = resp.status_int response.status = resp.status return content
def siloview(self, silo): if not ag.granary.issilo(silo): abort(404) ident = request.environ.get('repoze.who.identity') c.ident = ident c.silo_name = silo c.editor = False if ag.metadata_embargoed: if not ident: abort(401, "Not Authorised") silos = ag.authz(ident) if silo not in silos: abort(403, "Forbidden") c.editor = True elif ident: silos = ag.authz(ident) if silo in silos: c.editor = True rdfsilo = ag.granary.get_rdf_silo(silo) state_info = ag.granary.describe_silo(silo) if 'title' in state_info and state_info['title']: c.title = state_info['title'] c.embargos = {} c.items = [] for item in rdfsilo.list_items(): c.embargos[item] = None try: c.embargos[item] = is_embargoed(rdfsilo, item) except: pass c.items.append(item) #c.embargos[item] = () # conneg return accept_list = None if 'HTTP_ACCEPT' in request.environ: try: accept_list = conneg_parse(request.environ['HTTP_ACCEPT']) except: accept_list= [MT("text", "html")] if not accept_list: accept_list= [MT("text", "html")] mimetype = accept_list.pop(0) while(mimetype): if str(mimetype).lower() in ["text/html", "text/xhtml"]: return render('/siloview.html') elif str(mimetype).lower() in ["text/plain", "application/json"]: response.content_type = 'application/json; charset="UTF-8"' response.status_int = 200 response.status = "200 OK" return simplejson.dumps(c.embargos) try: mimetype = accept_list.pop(0) except IndexError: mimetype = None #Whoops nothing satisfies - return text/html return render('/siloview.html')
def siloview(self, silo): if not request.environ.get('repoze.who.identity'): abort(401, "Not Authorised") if not ag.granary.issilo(silo): abort(404) ident = request.environ.get('repoze.who.identity') c.ident = ident silos = ag.authz(ident, permission=['administrator', 'manager']) if not silo in silos: abort(403, "Do not have administrator or manager credentials for silo %s"%silo) user_groups = list_user_groups(ident['user'].user_name) if ('*', 'administrator') in user_groups: c.roles = ["admin", "manager", "user"] elif (silo, 'administrator') in user_groups: c.roles = ["admin", "manager", "user"] elif (silo, 'manager') in user_groups: c.roles = ["manager", "user"] else: abort(403, "Do not have administrator or manager credentials for silo %s"%silo) c.silo = silo http_method = request.environ['REQUEST_METHOD'] if http_method == "GET": c.users = list_group_users(silo) accept_list = None if 'HTTP_ACCEPT' in request.environ: try: accept_list = conneg_parse(request.environ['HTTP_ACCEPT']) except: accept_list= [MT("text", "html")] if not accept_list: accept_list= [MT("text", "html")] mimetype = accept_list.pop(0) while(mimetype): if str(mimetype).lower() in ["text/html", "text/xhtml"]: return render("/silo_users.html") elif str(mimetype).lower() in ["text/plain", "application/json"]: response.content_type = 'application/json; charset="UTF-8"' response.status_int = 200 response.status = "200 OK" return simplejson.dumps(c.users) try: mimetype = accept_list.pop(0) except IndexError: mimetype = None #Whoops nothing satisfies - return text/plain response.content_type = 'application/json; charset="UTF-8"' response.status_int = 200 response.status = "200 OK" return simplejson.dumps(c.users)
def index(self): ident = request.environ.get('repoze.who.identity') c.ident = ident #granary_list = ag.granary.silos #c.silos = granary_list c.silos = list_silos() if ag.metadata_embargoed: if not ident: abort(401, "Not Authorised") c.silos = ag.authz(ident) c.silo_infos = {} for silo in c.silos: c.silo_infos[silo] = [] state_info = ag.granary.describe_silo(silo) if 'title' in state_info and state_info['title']: c.silo_infos[silo].append(state_info['title']) else: c.silo_infos[silo].append(silo) c.silo_infos[silo].append(get_datasets_count(silo)) c.silo_infos[silo].append(getSiloModifiedDate(silo)) # conneg return accept_list = None if 'HTTP_ACCEPT' in request.environ: try: accept_list = conneg_parse(request.environ['HTTP_ACCEPT']) except: accept_list= [MT("text", "html")] if not accept_list: accept_list= [MT("text", "html")] mimetype = accept_list.pop(0) while(mimetype): if str(mimetype).lower() in ["text/html", "text/xhtml"]: return render('/list_of_silos.html') elif str(mimetype).lower() in ["text/plain", "application/json"]: response.content_type = 'application/json; charset="UTF-8"' response.status_int = 200 response.status = "200 OK" return simplejson.dumps(c.silos) try: mimetype = accept_list.pop(0) except IndexError: mimetype = None #Whoops nothing satisfies - return text/html return render('/list_of_silos.html')
def datasetview(self, silo, id): """Get a list of zipfiles in dataset 'id' within the silo 'silo' and unpack a dataset.""" if not ag.granary.issilo(silo): abort(404) rdfsilo = ag.granary.get_rdf_silo(silo) if not rdfsilo.exists(id): abort(404) # tmpl_context variables needed: c.silo_name, c.zipfiles, c.ident, c.id, c.path c.silo_name = silo c.id = id ident = request.environ.get("repoze.who.identity") c.ident = ident dataset = rdfsilo.get_item(id) creator = None if ( dataset.manifest and dataset.manifest.state and "metadata" in dataset.manifest.state and dataset.manifest.state["metadata"] and "createdby" in dataset.manifest.state["metadata"] and dataset.manifest.state["metadata"]["createdby"] ): creator = dataset.manifest.state["metadata"]["createdby"] http_method = request.environ["REQUEST_METHOD"] if http_method == "GET": c.editor = False if ag.metadata_embargoed: if not ident: abort(401, "Not Authorised") silos = ag.authz(ident) if silo not in silos: abort(403, "Forbidden") silos_admin = ag.authz(ident, permission="administrator") silos_manager = ag.authz(ident, permission="manager") # if ident['repoze.who.userid'] == creator or ident.get('role') in ["admin", "manager"]: if ident["repoze.who.userid"] == creator or silo in silos_admin or silo in silos_manager: c.editor = True elif ident: silos = ag.authz(ident) if silo in silos: silos_admin = ag.authz(ident, permission="administrator") silos_manager = ag.authz(ident, permission="manager") # if ident['repoze.who.userid'] == creator or ident.get('role') in ["admin", "manager"]: if ident["repoze.who.userid"] == creator or silo in silos_admin or silo in silos_manager: c.editor = True else: # identity management of item if not ident: abort(401, "Not Authorised") silos = ag.authz(ident) if silo not in silos: abort(403, "Forbidden") silos_admin = ag.authz(ident, permission="administrator") silos_manager = ag.authz(ident, permission="manager") # if not (ident['repoze.who.userid'] == creator or ident.get('role') in ["admin", "manager"]): if not (ident["repoze.who.userid"] == creator or silo in silos_admin or silo in silos_manager): abort(403, "Forbidden") if http_method == "GET": c.zipfiles = get_zipfiles_in_dataset(dataset) # conneg return accept_list = None if "HTTP_ACCEPT" in request.environ: try: accept_list = conneg_parse(request.environ["HTTP_ACCEPT"]) except: accept_list = [MT("text", "html")] if not accept_list: accept_list = [MT("text", "html")] mimetype = accept_list.pop(0) while mimetype: if str(mimetype).lower() in ["text/html", "text/xhtml"]: return render("/list_of_zipfiles.html") elif str(mimetype).lower() in ["text/plain", "application/json"]: response.content_type = 'application/json; charset="UTF-8"' response.status_int = 200 response.status = "200 OK" # return simplejson.dumps(dict(c.zipfiles)) return simplejson.dumps(list(c.zipfiles.keys())) try: mimetype = accept_list.pop(0) except IndexError: mimetype = None # Whoops nothing satisfies - return text/html return render("/list_of_zipfiles.html") elif http_method == "POST": params = request.POST if not (params.has_key("filename") and params["filename"]): abort(400, "You must supply a filename to unpack") item_real_filepath = dataset.to_dirpath() target_filepath = "%s/%s" % (item_real_filepath, params["filename"]) if not os.path.isfile(target_filepath): abort(404, "File to unpack not found") if not check_file_mimetype(target_filepath, "application/zip"): abort(415, "File is not of type application/zip") if params.has_key("id") and params["id"]: target_dataset_name = params["id"] else: # (head, fn) = os.path.split(params['filename']) # (fn, ext) = os.path.splitext(fn) # target_dataset_name = "%s-%s"%(id,fn) target_dataset_name = id # step 1: Create / initialize target dataset if not rdfsilo.exists(target_dataset_name): if not allowable_id2(target_dataset_name): response.content_type = "text/plain" response.status_int = 400 response.status = "400 Bad request. Data package name not valid" return ( "Data package name can contain only the following characters - %s and has to be more than 1 character" % ag.naming_rule_humanized ) target_dataset = create_new(rdfsilo, target_dataset_name, ident["repoze.who.userid"]) response.status_int = 201 response.status = "201 Created" response.headers["Content-Location"] = url( controller="datasets", action="datasetview", silo=silo, id=target_dataset_name ) response_message = "201 Created" else: target_dataset = rdfsilo.get_item(target_dataset_name) response.status = "204 Updated" response.status_int = 204 response_message = None # step 2: Unpack zip item try: unpack_zip_item(target_dataset, dataset, params["filename"], rdfsilo, ident["repoze.who.userid"]) except BadZipfile: abort(400, "BadZipfile: Couldn't unpack zipfile") target_dataset.sync() target_dataset.sync() target_dataset.sync() if response.status_int == 201: try: ag.b.creation(silo, id, ident=ident["repoze.who.userid"]) except: pass else: try: ag.b.change(silo, id, ident=ident["repoze.who.userid"]) except: pass # conneg return accept_list = None if "HTTP_ACCEPT" in request.environ: try: accept_list = conneg_parse(request.environ["HTTP_ACCEPT"]) except: accept_list = [MT("text", "html")] if not accept_list: accept_list = [MT("text", "html")] mimetype = accept_list.pop(0) while mimetype: if str(mimetype).lower() in ["text/html", "text/xhtml"]: redirect(url(controller="datasets", action="datasetview", silo=silo, id=target_dataset_name)) elif str(mimetype).lower() in ["text/plain", "application/json"]: response.content_type = "text/plain" return response_message try: mimetype = accept_list.pop(0) except IndexError: mimetype = None # Whoops - nothing satisfies - return text/plain response.content_type = "text/plain" return response_message
def itemview(self, silo, id, path): """API call to GET - read the contents of a zip-file (without having to unpack) and POST- unpack a zip file into a new / existing dataset PUT - Add the zipfile and unpack it onto the existing dataset""" # tmpl_context variables needed: c.silo_name, c.zipfile_contents c.ident, c.id, c.path if not path: abort(400, "You must supply a filename to unpack") if not ag.granary.issilo(silo): abort(404) rdfsilo = ag.granary.get_rdf_silo(silo) if not rdfsilo.exists(id): abort(404) c.silo_name = silo c.id = id c.path = path ident = request.environ.get("repoze.who.identity") c.ident = ident dataset = rdfsilo.get_item(id) creator = None if ( dataset.manifest and dataset.manifest.state and "metadata" in dataset.manifest.state and dataset.manifest.state["metadata"] and "createdby" in dataset.manifest.state["metadata"] and dataset.manifest.state["metadata"]["createdby"] ): creator = dataset.manifest.state["metadata"]["createdby"] http_method = request.environ["REQUEST_METHOD"] if http_method == "GET": if dataset.metadata.get("embargoed") not in ["false", 0, False]: if not ident: abort(401, "Not Authorised") silos = ag.authz(ident) if silo not in silos: abort(403, "Forbidden") else: if not ident: abort(401, "Not Authorised") silos = ag.authz(ident) if silo not in silos: abort(403, "Forbidden") silos_admin = ag.authz(ident, permission="administrator") silos_manager = ag.authz(ident, permission="manager") # if not (ident['repoze.who.userid'] == creator or ident.get('role') in ["admin", "manager"]): if not (ident["repoze.who.userid"] == creator or silo in silos_admin or silo in silos_manager): abort(403, "Forbidden") item_real_filepath = dataset.to_dirpath() target_filepath = "%s/%s" % (item_real_filepath, path) # c.parts = dataset.list_parts(detailed=False) if http_method in ["GET", "POST"]: if not dataset.isfile(path): abort(404, "File not found") if not os.path.isfile(target_filepath): abort(404, "File not found") if not check_file_mimetype(target_filepath, "application/zip"): abort(415, "File is not of type application/zip") if http_method == "GET": try: c.zipfile_contents = read_zipfile(target_filepath) except BadZipfile: abort(400, "Could not read zipfile") # conneg return accept_list = None if "HTTP_ACCEPT" in request.environ: try: accept_list = conneg_parse(request.environ["HTTP_ACCEPT"]) except: accept_list = [MT("text", "html")] if not accept_list: accept_list = [MT("text", "html")] mimetype = accept_list.pop(0) while mimetype: if str(mimetype).lower() in ["text/html", "text/xhtml"]: return render("/zipfileview.html") elif str(mimetype).lower() in ["text/plain", "application/json"]: response.content_type = 'application/json; charset="UTF-8"' response.status_int = 200 response.status = "200 OK" return simplejson.dumps(c.zipfile_contents) try: mimetype = accept_list.pop(0) except IndexError: mimetype = None # Whoops - nothing satisfies - return text/html return render("/zipfileview.html") elif http_method == "POST": params = request.POST # if not (params.has_key("filename") and params['filename']): # abort(400, "You must supply a filename to unpack") if params.has_key("id") and params["id"]: target_dataset_name = params["id"] else: # (head, fn) = os.path.split(path) # (fn, ext) = os.path.splitext(fn) # target_dataset_name = "%s-%s"%(id,fn) target_dataset_name = id # step 1: Create / initialize target dataset if not rdfsilo.exists(target_dataset_name): if not allowable_id2(target_dataset_name): response.content_type = "text/plain" response.status_int = 400 response.status = "400 Bad request. Data package name not valid" return ( "Data package name can contain only the following characters - %s and has to be more than 1 character" % ag.naming_rule_humanized ) target_dataset = create_new(rdfsilo, target_dataset_name, ident["repoze.who.userid"]) response.status_int = 201 response.status = "201 Created" response.headers["Content-Location"] = url( controller="datasets", action="datasetview", silo=silo, id=target_dataset_name ) response_message = "201 Created" else: target_dataset = rdfsilo.get_item(target_dataset_name) response.status = "204 Updated" response.status_int = 204 response_message = None # step 2: Unpack zip item try: unpack_zip_item(target_dataset_name, dataset, path, rdfsilo, ident["repoze.who.userid"]) except BadZipfile: abort(400, "Couldn't unpack zipfile") target_dataset.sync() target_dataset.sync() target_dataset.sync() if response.status_int == 201: try: ag.b.creation(silo, id, ident=ident["repoze.who.userid"]) except: pass else: try: ag.b.change(silo, id, ident=ident["repoze.who.userid"]) except: pass # conneg return accept_list = None if "HTTP_ACCEPT" in request.environ: try: accept_list = conneg_parse(request.environ["HTTP_ACCEPT"]) except: accept_list = [MT("text", "html")] if not accept_list: accept_list = [MT("text", "html")] mimetype = accept_list.pop(0) while mimetype: if str(mimetype).lower() in ["text/html", "text/xhtml"]: redirect(url(controller="datasets", action="datasetview", silo=silo, id=target_dataset_name)) elif str(mimetype).lower() in ["text/plain", "application/json"]: response.content_type = "text/plain" return response_message try: mimetype = accept_list.pop(0) except IndexError: mimetype = None # Whoops - nothing satisfies - return text/plain response.content_type = "text/plain" return response_message elif http_method == "PUT": # Pylons loads the request body into request.body... # This is not going to work for large files... ah well # POST will handle large files as they are pushed to disc, # but this won't content = request.body if JAILBREAK.search(path) != None: abort(400, "'..' cannot be used in the path") # Step 1: Put zipfile in dataset if dataset.isdir(path): response.content_type = "text/plain" response.status_int = 403 response.status = "403 Forbidden" return "Cannot PUT a file on to an existing directory" if dataset.isfile(path): code = 204 else: code = 201 if code == 204: dataset.increment_version_delta(clone_previous_version=True, copy_filenames=["manifest.rdf", path]) else: dataset.increment_version_delta(clone_previous_version=True, copy_filenames=["manifest.rdf"]) dataset.put_stream(path, content) dataset.del_triple(dataset.uri, u"dcterms:modified") dataset.add_triple(dataset.uri, u"dcterms:modified", datetime.now()) dataset.del_triple(dataset.uri, u"oxds:currentVersion") dataset.add_triple(dataset.uri, u"oxds:currentVersion", dataset.currentversion) dataset.sync() target_dataset = rdfsilo.get_item(id) # step 2: Unpack zip item if not check_file_mimetype(target_filepath, "application/zip"): abort(415, "File is not of type application/zip") try: unpack_zip_item(target_dataset, dataset, path, rdfsilo, ident["repoze.who.userid"]) except BadZipfile: abort(400, "Couldn't unpack zipfile") target_dataset.sync() target_dataset.sync() target_dataset.sync() response.status = "204 Updated" response.status_int = 204 response_message = None try: ag.b.change(silo, id, path, ident=ident["repoze.who.userid"]) except: pass # conneg return accept_list = None if "HTTP_ACCEPT" in request.environ: try: accept_list = conneg_parse(request.environ["HTTP_ACCEPT"]) except: accept_list = [MT("text", "html")] if not accept_list: accept_list = [MT("text", "html")] mimetype = accept_list.pop(0) while mimetype: if str(mimetype).lower() in ["text/html", "text/xhtml"]: redirect(url(controller="datasets", action="datasetview", silo=silo, id=id)) elif str(mimetype).lower() in ["text/plain", "application/json"]: response.content_type = "text/plain" return response_message try: mimetype = accept_list.pop(0) except IndexError: mimetype = None # Whoops - nothing satisfies - return text/plain response.content_type = "text/plain" return response_message
def raw(self): ident = request.environ.get('repoze.who.identity') c.ident = ident silos = None if ag.metadata_embargoed: if not ident: abort(401, "Not Authorised") silos = ag.authz(ident) if silos and not isinstance(silos, basestring) and type(silos).__name__ == 'list': silos = ' '.join(silos) http_method = request.environ['REQUEST_METHOD'] if http_method == "GET": params = request.GET elif http_method == "POST": params = request.POST if not "q" in params: abort(400, "Parameter 'q' is not available") #If ag.metadata_embargoed, search only within your silos if params['q'] == '*': if silos: params['q'] = """silo:(%s)"""%silos else: params['q'] = "*:*" elif silos and not 'silo:' in params['q']: params['q'] = """%s AND silo:(%s)"""%(params['q'], silos) accept_list = None if 'wt' in params and params['wt'] == "json": accept_list = [MT("application", "json")] elif 'wt' in params and params['wt'] == "xml": accept_list = [MT("text", "xml")] else: if 'HTTP_ACCEPT' in request.environ: try: accept_list = conneg_parse(request.environ['HTTP_ACCEPT']) except: accept_list= [MT("text", "html")] if not accept_list: accept_list= [MT("text", "html")] mimetype = accept_list.pop(0) while(mimetype): if str(mimetype).lower() in ["text/html", "text/xhtml"]: params['wt'] = 'json' accept_list= [MT("text", "html")] break elif str(mimetype).lower() in ["text/plain", "application/json"]: params['wt'] = 'json' accept_list= [MT("application", "json")] break elif str(mimetype).lower() in ["application/rdf+xml", "text/xml"]: params['wt'] = 'xml' accept_list = [MT("text", "xml")] break # Whoops - nothing satisfies try: mimetype = accept_list.pop(0) except IndexError: mimetype = None if not 'wt' in params or not params['wt'] in ['json', 'xml']: params['wt'] = 'json' accept_list= [MT("text", "html")] if not 'fl' in params or not params['fl']: #Also include the following fields - date modified, publication year / publication date, embargo status, embargo date, version params['fl'] = "id,silo,mediator,creator,title,score" if not 'start' in params or not params['start']: params['start'] = '0' if not 'rows' in params or not params['rows']: params['rows'] = '100' try: result = ag.solr.raw_query(**params) except: result = {} mimetype = accept_list.pop(0) while(mimetype): if str(mimetype).lower() in ["text/html", "text/xhtml"]: c.result = result return render('/raw_search.html') elif str(mimetype).lower() in ["text/plain", "application/json"]: response.content_type = 'application/json; charset="UTF-8"' response.status_int = 200 response.status = "200 OK" return result elif str(mimetype).lower() in ["application/rdf+xml", "text/xml"]: response.content_type = 'text/xml; charset="UTF-8"' response.status_int = 200 response.status = "200 OK" return result # Whoops - nothing satisfies try: mimetype = accept_list.pop(0) except IndexError: mimetype = None #Whoops - nothing staisfies - default to text/html c.result = result return render('/raw_search.html')
def detailed(self, query=None, additional_fields=[]): if query: c.q = query else: c.q = request.params.get('q', None) try: c.q = unquote(c.q) except: pass c.typ = 'all' if request.params.get("type", None): c.typ = request.params.get("type") if not c.q or c.q == '*' or c.q == "": c.q = "*:*" # Search controls truncate = request.params.get('truncate', None) start = request.params.get('start', None) rows = request.params.get('rows', None) sort = request.params.get('sort', None) fields = request.params.get('fl', None) res_format = request.params.get('format', None) if not res_format: accept_list = None if 'HTTP_ACCEPT' in request.environ: try: accept_list = conneg_parse(request.environ['HTTP_ACCEPT']) except: accept_list= [MT("text", "html")] if not accept_list: accept_list= [MT("text", "html")] mimetype = accept_list.pop(0) while(mimetype): if str(mimetype).lower() in ["text/html", "text/xhtml"]: res_format = 'html' break elif str(mimetype).lower() in ["text/plain", "application/json"]: res_format = 'json' break elif str(mimetype).lower() in ["text/xml"]: res_format = 'xml' break elif str(mimetype).lower() in ["text/csv"]: res_format = 'csv' break try: mimetype = accept_list.pop(0) except IndexError: mimetype = None # Whoops - nothing satisfies - return text/plain if not res_format: res_format = 'html' c.sort = 'score desc' # Lock down the sort parameter. if sort and sort in c.sort_options: c.sort = sort c.sort_text = c.sort_options[c.sort] c.chosen_fields = [] c.chosen_fields.extend(c.search_fields) if fields: fields = fields.split(',') if fields and type(fields).__name__ == 'list': fields = [x.strip() for x in fields] for fld in fields: if fld in c.all_fields and not fld in c.chosen_fields: c.chosen_fields.append(fld) for fld in additional_fields: if not fld in c.chosen_fields: c.chosen_fields.append(fld) c.fields_to_facet = [] c.fields_to_facet.extend(c.facetable_fields) c.facet_limit = 10 c.chosen_facets = {} query_filter = "" #Setup to capture all the url parameters needed to regenerate this search c.search = {} filter_url = "" for field in c.all_fields: if request.params.get("filter"+field, None): multi = request.params.getall("filter"+field) c.chosen_facets[field] = [] #c.search["filter"+field] = "" for m in multi: try: m = unquote(m) except: pass m = m.strip() m = m.strip('"') c.chosen_facets[field].append(m) query_filter += ' AND %s:"%s"'%(field, m) try: filter_url += '&filter%s=%s'%(field, quote('"%s"'%m)) except: filter_url += '&filter%s=%s'%(field, '"%s"'%m) #if field in c.fields_to_facet: # del c.fields_to_facet[field] for field in c.chosen_facets: if field not in c.chosen_fields: c.chosen_fields.append(field) c.truncate = 450 c.start = 0 c.rows = 25 # Parse/Validate search controls if truncate: try: c.truncate = int(truncate) except ValueError: pass if c.truncate < 10: c.truncate = 10 if c.truncate > 1000: c.truncate = 1000 if start: try: c.start = int(start) except ValueError: pass if c.start < 0: c.start = 0 if rows: try: c.rows = int(rows) except ValueError: pass if c.rows < 5: c.rows = 5 elif c.rows > 5000: c.rows=5000 #c.search['rows'] = c.rows c.search['truncate'] = c.truncate c.search['type'] = c.typ #c.search['start'] = c.start #c.search['sort'] = c.sort #if c.q: # c.search['q'] = c.q.encode('utf-8') solr_params = {} if c.q: if c.typ and 'silo' in c.typ: solr_params['q'] = c.q.encode('utf-8')+query_filter+" AND type:silo" elif c.typ and 'dataset' in c.typ: solr_params['q'] = c.q.encode('utf-8')+query_filter+" AND type:dataset" elif c.typ and 'item' in c.typ and c.q != "*:*": #solr_params['q'] = """aggregatedResource:"%s" %s"""%(c.q.encode('utf-8'),query_filter) solr_params['q'] = """filename:"%s" %s"""%(c.q.encode('utf-8'),query_filter) else: solr_params['q'] = c.q.encode('utf-8')+query_filter if res_format in ['json', 'xml', 'python', 'php']: solr_params['wt'] = res_format else: solr_params['wt'] = 'json' solr_params['fl'] = ','.join(c.chosen_fields) solr_params['rows'] = c.rows solr_params['start'] = c.start if c.sort: solr_params['sort'] = c.sort if c.fields_to_facet: solr_params['facet'] = 'true' solr_params['facet.limit'] = c.facet_limit solr_params['facet.mincount'] = 1 solr_params['facet.field'] = [] for facet in c.fields_to_facet: solr_params['facet.field'].append(facet) solr_response = None try: solr_response = ag.solr.raw_query(**solr_params) except: pass c.add_facet = u"%s%ssearch/detailed?q=%s&" % (ag.root, ag.base, c.q.encode('utf-8')) c.add_facet = c.add_facet + urlencode(c.search) + filter_url if not solr_response: # conneg return response.status_int = 200 response.status = "200 OK" if res_format == "html": c.numFound = 0 c.message = 'Sorry, either that search "%s" resulted in no matches, or the search service is not functional.' % c.q return render('/search.html') elif res_format == 'xml': response.headers['Content-Type'] = 'application/xml' response.charset = 'utf8' c.atom = {} return render('/atom_results.html') elif res_format == 'json': response.headers['Content-Type'] = 'application/json' response.charset = 'utf8' return {} else: response.headers['Content-Type'] = 'application/text' response.charset = 'utf8' return solr_response response.status_int = 200 response.status = "200 OK" if res_format == 'xml': response.headers['Content-Type'] = 'application/xml' response.charset = 'utf8' c.atom = solr_response return render('/atom_results.html') elif res_format == 'json': response.headers['Content-Type'] = 'application/json' response.charset = 'utf8' return solr_response elif res_format in ['csv', 'python', 'php']: response.headers['Content-Type'] = 'application/text' response.charset = 'utf8' return solr_response search = json.loads(solr_response) numFound = search['response'].get('numFound',None) c.numFound = 0 c.permissible_offsets = [] c.pages_to_show = 5 try: c.numFound = int(numFound) remainder = c.numFound % c.rows if remainder > 0: c.lastPage = c.numFound - remainder else: c.lastPage = c.numFound - c.rows if c.numFound > c.rows: offset_start = c.start - ( (c.pages_to_show/2) * c.rows ) if offset_start < 0: offset_start = 0 offset_end = offset_start + (c.pages_to_show * c.rows) if offset_end > c.numFound: offset_end = c.numFound if remainder > 0: offset_start = c.lastPage - (c.pages_to_show * c.rows) else: offset_start = c.lastPage - ((c.pages_to_show-1) * c.rows) if offset_start < 0: offset_start = 0 c.permissible_offsets = list( xrange( offset_start, offset_end, c.rows) ) except ValueError: pass c.docs = search['response'].get('docs',None) if c.fields_to_facet: c.returned_facets = {} for facet in search['facet_counts']['facet_fields']: facet_list = search['facet_counts']['facet_fields'][facet] keys = facet_list[::2] values = facet_list[1::2] c.returned_facets[facet] = [] for index in range(len(keys)): c.returned_facets[facet].append((keys[index],values[index])) return render('/search.html')
def index(self): if not request.environ.get('repoze.who.identity'): abort(401, "Not Authorised") ident = request.environ.get('repoze.who.identity') c.ident = ident c.granary_list = ag.authz(ident, permission=['administrator', 'manager']) http_method = request.environ['REQUEST_METHOD'] if http_method == 'GET': if not 'administrator' in ident['permissions'] and not 'manager' in ident['permissions']: abort(403, "Do not have administrator or manager credentials") else: if not 'administrator' in ident['permissions']: abort(403, "Do not have administrator credentials") if http_method == "GET": #c.granary = ag.granary # conneg return accept_list = None if 'HTTP_ACCEPT' in request.environ: try: accept_list = conneg_parse(request.environ['HTTP_ACCEPT']) except: accept_list= [MT("text", "html")] if not accept_list: accept_list= [MT("text", "html")] mimetype = accept_list.pop(0) while(mimetype): if str(mimetype).lower() in ["text/html", "text/xhtml"]: return render("/admin_silos.html") elif str(mimetype).lower() in ["text/plain", "application/json"]: response.content_type = 'application/json; charset="UTF-8"' response.status_int = 200 response.status = "200 OK" return simplejson.dumps(list(c.granary_list)) try: mimetype = accept_list.pop(0) except IndexError: mimetype = None #Whoops nothing satisfies - return text/html return render("admin_silos.html") elif http_method == "POST": params = request.POST if 'silo' in params: if ag.granary.issilo(params['silo']): abort(403, "The silo %s exists"%params['silo']) if not allowable_id2(params['silo']): response.content_type = "text/plain" response.status_int = 400 response.status = "400 Bad request. Silo name not valid" return "Silo name can contain only the following characters - %s and has to be more than 1 character"%ag.naming_rule_humanized #NOTE: #If any userid in params['administrators']/params['managers']/params['submitters'] does not exist, return 403 #if administartor list is empty, append current user to administartor list #Owner is the superset of adminstrators, managers and submitters existing_users = list_usernames() owners = [] admins = [] managers = [] submitters = [] #if 'owners' in params and params['owners']: # owners = [x.strip() for x in kw['owners'].split(",") if x] if 'administrators' in params and params['administrators']: admins = [x.strip() for x in params['administrators'].split(",") if x] owners.extend(admins) if 'managers' in params and params['managers']: managers = [x.strip() for x in params['managers'].split(",") if x] owners.extend(managers) if 'submitters' in params and params['submitters']: submitters = [x.strip() for x in params['submitters'].split(",") if x] owners.extend(submitters) if not admins: owners.append(ident['user'].user_name) admins.append(ident['user'].user_name) owners = list(set(owners)) for o in owners: if not o in existing_users: abort (403, "User %s does not exist"%o) admins = list(set(admins)) managers = list(set(managers)) submitters = list(set(submitters)) # Create new silo silo = params['silo'] g_root = config.get("granary.uri_root", "info:") c.silo = ag.granary.get_rdf_silo(silo, uri_base="%s%s/datasets/" % (g_root, silo)) ag.granary._register_silos() kw = {} for term in accepted_params: if term in params: kw[term] = params[term] kw['owners'] = ','.join(owners) kw['administrators'] = ','.join(admins) kw['managers'] = ','.join(managers) kw['submitters'] = ','.join(submitters) du = ag.granary.disk_usage_silo(silo) kw['disk_usage'] = du ag.granary.describe_silo(silo, **kw) ag.granary.sync() # Add silo to database add_silo(silo) try: ag.b.silo_creation(silo, ident=ident['repoze.who.userid']) except: pass #Add users belonging to the silo, to the database all_silo_users = [] for a in admins: all_silo_users.append((a, 'administrator')) for a in managers: all_silo_users.append((a, 'manager')) for a in submitters: all_silo_users.append((a, 'submitter')) add_group_users(params['silo'], all_silo_users) ag.granary.state.revert() ag.granary._register_silos() # conneg return accept_list = None if 'HTTP_ACCEPT' in request.environ: try: accept_list = conneg_parse(request.environ['HTTP_ACCEPT']) except: accept_list= [MT("text", "html")] if not accept_list: accept_list= [MT("text", "html")] mimetype = accept_list.pop(0) while(mimetype): if str(mimetype).lower() in ["text/html", "text/xhtml"]: redirect(url(controller="datasets", action="siloview", silo=silo)) elif str(mimetype).lower() in ["text/plain", "application/json"]: response.content_type = "text/plain" response.status_int = 201 response.status = "201 Created" response.headers['Content-Location'] = url(controller="datasets", action="siloview", silo=silo) return "201 Created Silo %s" % silo try: mimetype = accept_list.pop(0) except IndexError: mimetype = None # Whoops - nothing satisfies - return text/plain response.content_type = "text/plain" response.status_int = 201 response.status = "201 Created" response.headers['Content-Location'] = url(controller="datasets", action="siloview", silo=silo) return "201 Created Silo %s" % silo else: response.content_type = "text/plain" response.status_int = 400 response.status = "400 Bad Request" return "400 Bad request. No valid parameters found."
def siloview(self, silo): if not request.environ.get('repoze.who.identity'): abort(401, "Not Authorised") if not ag.granary.issilo(silo): abort(404) ident = request.environ.get('repoze.who.identity') c.ident = ident c.silo = silo silos = ag.authz(ident, permission=['administrator', 'manager']) if not silo in silos: abort(403, "Do not have administrator or manager credentials for silo %s"%silo) user_groups = list_user_groups(ident['user'].user_name) if ('*', 'administrator') in user_groups: #User is super user c.roles = ["admin", "manager", "user"] elif (silo, 'administrator') in user_groups: c.roles = ["admin", "manager", "user"] elif (silo, 'manager') in user_groups: c.roles = ["manager", "user"] else: abort(403, "Do not have administrator or manager credentials for silo %s"%silo) http_method = request.environ['REQUEST_METHOD'] c.kw = ag.granary.describe_silo(silo) if http_method == "GET": accept_list = None if 'HTTP_ACCEPT' in request.environ: try: accept_list = conneg_parse(request.environ['HTTP_ACCEPT']) except: accept_list= [MT("text", "html")] if not accept_list: accept_list= [MT("text", "html")] mimetype = accept_list.pop(0) while(mimetype): if str(mimetype).lower() in ["text/html", "text/xhtml"]: return render("/admin_siloview.html") elif str(mimetype).lower() in ["text/plain", "application/json"]: response.content_type = 'application/json; charset="UTF-8"' response.status_int = 200 response.status = "200 OK" return simplejson.dumps(dict(c.kw)) try: mimetype = accept_list.pop(0) except IndexError: mimetype = None #Whoops nothing satisfies - return text/html return render("/admin_siloview.html") elif http_method == "POST": params = request.POST #Get existing owners, admins, managers and submitters owners = [] admins = [] managers = [] submitters = [] if 'owners' in c.kw and c.kw['owners']: owners = [x.strip() for x in c.kw['owners'].split(",") if x] if 'administrators' in c.kw and c.kw['administrators']: admins = [x.strip() for x in c.kw['administrators'].split(",") if x] if 'managers' in c.kw and c.kw['managers']: managers = [x.strip() for x in c.kw['managers'].split(",") if x] if 'submitters' in c.kw and c.kw['submitters']: submitters = [x.strip() for x in c.kw['submitters'].split(",") if x] #Get new members new_owners = [] #Get new admins new_admins = [] if 'administrators' in params and params['administrators']: returned_admins = [x.strip() for x in params['administrators'].split(",") if x] new_admins = [x for x in returned_admins if not x in admins] new_owners.extend(new_admins) #Get new managers new_managers = [] if 'managers' in params and params['managers']: returned_managers = [x.strip() for x in params['managers'].split(",") if x] new_managers = [x for x in returned_managers if not x in managers] new_owners.extend(new_managers) #Get new submitters new_submitters = [] if 'submitters' in params and params['submitters']: returned_submitters = [x.strip() for x in params['submitters'].split(",") if x] new_submitters = [x for x in returned_submitters if not x in submitters] new_owners.extend(new_submitters) #Check if the new members exist. If not return 403 existing_users = list_usernames() new_owners = list(set(new_owners)) for o in new_owners: if not o in existing_users: abort (403, "User %s does not exist"%o) if new_admins and not 'admin' in c.roles: abort (403, "Only administrators can assing users to role 'administrator'") owners.extend(new_owners) new_admins = list(set(new_admins)) admins.extend(new_admins) new_managers = list(set(new_managers)) managers.extend(new_managers) new_submitters = list(set(new_submitters)) submitters.extend(new_submitters) # Update silo info updateMetadata = False for term in accepted_params: if term in params and not term in ['owners', 'administrators', 'managers', 'submitters'] and params[term]: c.kw[term] = params[term] updateMetadata = True if new_owners or new_admins or new_managers or new_submitters or updateMetadata: new_silo_users = [] if new_owners: c.kw['owners'] = ','.join(owners) if new_admins: c.kw['administrators'] = ','.join(admins) for a in new_admins: new_silo_users.append((a, 'administrator')) if new_managers: c.kw['managers'] = ','.join(managers) for a in new_managers: new_silo_users.append((a, 'manager')) if new_submitters: c.kw['submitters'] = ','.join(submitters) for a in new_submitters: new_silo_users.append((a, 'submitter')) #Add metadat changes to the silo ag.granary.describe_silo(silo, **c.kw) ag.granary.sync() #Add new silo users into database if new_silo_users: add_group_users(silo, new_silo_users) if updateMetadata: try: ag.b.silo_change(silo, ident=ident['repoze.who.userid']) except: pass # conneg return accept_list = None if 'HTTP_ACCEPT' in request.environ: try: accept_list = conneg_parse(request.environ['HTTP_ACCEPT']) except: accept_list= [MT("text", "html")] if not accept_list: accept_list= [MT("text", "html")] mimetype = accept_list.pop(0) while(mimetype): if str(mimetype).lower() in ["text/html", "text/xhtml"]: c.message = "Metadata updated" c.kw = ag.granary.describe_silo(silo) return render("/admin_siloview.html") elif str(mimetype).lower() in ["text/plain", "application/json"]: response.content_type = "text/plain" response.status_int = 204 response.status = "204 Updated" #return "Updated Silo %s" % silo return try: mimetype = accept_list.pop(0) except IndexError: mimetype = None # Whoops - nothing satisfies - return text/plain response.content_type = "text/plain" response.status_int = 204 response.status = "204 Updated" return elif http_method == "DELETE": # Deletion of an entire Silo... # Serious consequences follow this action # Walk through all the items, emit a delete msg for each # and then remove the silo todelete_silo = ag.granary.get_rdf_silo(silo) #for item in todelete_silo.list_items(): # try: # ag.b.deletion(silo, item, ident=ident['repoze.who.userid']) # except: # pass ag.granary.delete_silo(silo) try: ag.b.silo_deletion(silo, ident=ident['repoze.who.userid']) except: pass try: del ag.granary.state[silo] except: pass ag.granary.sync() ag.granary._register_silos() #Delete silo from database delete_silo(silo) # conneg return accept_list = None response.content_type = "text/plain" response.status_int = 200 response.status = "200 OK" return "{'ok':'true'}"
def index(self): if not request.environ.get('repoze.who.identity'): abort(401, "Not Authorised") ident = request.environ.get('repoze.who.identity') if not ('administrator' in ident['permissions'] or 'manager' in ident['permissions']): abort(403, "Do not have administrator or manager credentials") c.ident = ident #silos = ag.authz(ident, permission=['administrator', 'manager']) c.users = list_users() if 'administrator' in ident['permissions']: c.roles = ["admin", "manager", "user"] else: c.roles = ["manager", "user"] http_method = request.environ['REQUEST_METHOD'] if http_method == "GET": accept_list = None if 'HTTP_ACCEPT' in request.environ: try: accept_list = conneg_parse(request.environ['HTTP_ACCEPT']) except: accept_list= [MT("text", "html")] if not accept_list: accept_list= [MT("text", "html")] mimetype = accept_list.pop(0) while(mimetype): if str(mimetype).lower() in ["text/html", "text/xhtml"]: return render("/users.html") elif str(mimetype).lower() in ["text/plain", "application/json"]: response.content_type = 'application/json; charset="UTF-8"' response.status_int = 200 response.status = "200 OK" return simplejson.dumps(c.users) try: mimetype = accept_list.pop(0) except IndexError: mimetype = None #Whoops nothing satisfies - return text/plain response.content_type = 'application/json; charset="UTF-8"' response.status_int = 200 response.status = "200 OK" return simplejson.dumps(c.users) elif http_method == "POST": params = request.POST if not ('username' in params and params['username'] and 'password' in params and params['password']): abort(400, "username and password not supplied") if not allowable_id2(params['username']): response.content_type = "text/plain" response.status_int = 400 response.status = "400 Bad request. Username not valid" return "username can contain only the following characters - %s and has to be more than 1 character"%ag.naming_rule_humanized existing_users = list_usernames() if params['username'] in existing_users: abort(403, "User exists") if (('firstname' in params and params['firstname'] and 'lastname' in params and params['lastname']) \ or 'name' in params and params['name']): add_user(params) else: abort(400, "The following parameters have to be supplied: username, pasword and name (or firstname and lastname)") response.status_int = 201 response.status = "201 Created" response.headers['Content-Location'] = url(controller="users", action="userview", username=params['username']) response_message = "201 Created" if 'HTTP_ACCEPT' in request.environ: try: accept_list = conneg_parse(request.environ['HTTP_ACCEPT']) except: accept_list= [MT("text", "html")] if not accept_list: accept_list= [MT("text", "html")] mimetype = accept_list.pop(0) while(mimetype): if str(mimetype).lower() in ["text/html", "text/xhtml"]: redirect(url(controller="users", action="userview", username=params['username'])) elif str(mimetype).lower() in ["text/plain", "application/json"]: response.content_type = "text/plain" return response_message try: mimetype = accept_list.pop(0) except IndexError: mimetype = None # Whoops - nothing satisfies - return text/plain response.content_type = "text/plain" return response_message
def silouserview(self, silo, username): if not request.environ.get('repoze.who.identity'): abort(401, "Not Authorised") if not ag.granary.issilo(silo): abort(404) ident = request.environ.get('repoze.who.identity') http_method = request.environ['REQUEST_METHOD'] if http_method == 'GET': silos = ag.authz(ident) if not silo in silos: abort(403, "User is not a member of the silo %s"%silo) if not ('administrator' in ident['permissions'] or \ 'manager' in ident['permissions'] or ident['user'].user_name == username): abort(403, "Do not have administrator or manager credentials to view profiles of other users") else: silos = ag.authz(ident, permission=['administrator', 'manager']) if not silo in silos: abort(403, "Do not have administrator or manager credentials for silo %s"%silo) if not ('administrator' in ident['permissions'] or 'manager' in ident['permissions']): abort(403, "Do not have administrator or manager credentials") existing_users = list_usernames() if not username in existing_users: abort(404, "User not found") c.ident = ident c.silo = silo c.username = username if http_method == "GET": a, m, s = list_group_usernames(silo) if not (username in a or username in m or username in s): abort(404, "User not found in silo") c.user = list_user(username) #if 'groups' in c.user and c.user['groups']: # for i in c.user['groups']: # if i[0] != silo: # c.user['groups'].remove(i) accept_list = None if 'HTTP_ACCEPT' in request.environ: try: accept_list = conneg_parse(request.environ['HTTP_ACCEPT']) except: accept_list= [MT("text", "html")] if not accept_list: accept_list= [MT("text", "html")] mimetype = accept_list.pop(0) while(mimetype): if str(mimetype).lower() in ["text/html", "text/xhtml"]: return render("/silo_user.html") elif str(mimetype).lower() in ["text/plain", "application/json"]: response.content_type = 'application/json; charset="UTF-8"' response.status_int = 200 response.status = "200 OK" return simplejson.dumps(c.user) try: mimetype = accept_list.pop(0) except IndexError: mimetype = None #Whoops nothing satisfies - return text/plain response.content_type = 'application/json; charset="UTF-8"' response.status_int = 200 response.status = "200 OK" return simplejson.dumps(c.user) elif http_method == "POST": params = request.POST if not ('role' in params and params['role'] and params['role'] in ['administrator', 'manager', 'submitter']): abort(400, "Parameters 'role' not found or is invalid") kw = ag.granary.describe_silo(silo) #Get existing owners, admins, managers and users owners = [] admins = [] managers = [] submitters = [] if 'owners' in kw and kw['owners']: owners = [x.strip() for x in kw['owners'].split(",") if x] if 'administrators' in kw and kw['administrators']: admins = [x.strip() for x in kw['administrators'].split(",") if x] if 'managers' in kw and kw['managers']: managers = [x.strip() for x in kw['managers'].split(",") if x] if 'submitters' in kw and kw['submitters']: submitters = [x.strip() for x in kw['submitters'].split(",") if x] to_remove = [] to_add = [] if params['role'] == 'administrator': if not 'administrator' in ident['permissions']: abort(403, "Need to be administrator to add user to role admin") if not username in admins: to_add.append((username, 'administrator')) admins.append(username) if not username in owners: owners.append(username) if username in managers: managers.remove(username) to_remove.append((username, 'manager')) if username in submitters: submitters.remove(username) to_remove.append((username, 'submitter')) elif params['role'] == 'manager': if not username in managers: to_add.append((username, 'manager')) managers.append(username) if not username in owners: owners.append(username) if username in admins: if not 'administrator' in ident['permissions']: abort(403, "Need to be admin to modify user of role admin") if len(admins) == 1: abort(403, "Add another administrator to silo before updating user role") admins.remove(username) to_remove.append((username, 'administrator')) if username in submitters: submitters.remove(username) to_remove.append((username, 'submitter')) elif params['role'] == 'submitter': if not username in submitters: to_add.append((username, 'submitter')) submitters.append(username) if not username in owners: owners.append(username) if username in admins: if not 'administrator' in ident['permissions']: abort(403, "Need to be admin to modify user of role admin") if len(admins) == 1: abort(403, "Add another administrator to silo before updating user role") admins.remove(username) to_remove.append((username, 'administrator')) if username in managers: if len(managers) == 1 and len(admins) == 0: abort(403, "Add another administrator or manager to silo before updating user role") managers.remove(username) to_remove.append((username, 'manager')) owners = list(set(owners)) admins = list(set(admins)) managers = list(set(managers)) submitters = list(set(submitters)) # Update silo info if to_remove or to_add: kw['owners'] = ','.join(owners) kw['administrators'] = ','.join(admins) kw['managers'] = ','.join(managers) kw['submitters'] = ','.join(submitters) ag.granary.describe_silo(silo, **kw) ag.granary.sync() #Add new silo users into database if to_add: add_group_users(silo, to_add) response.status_int = 201 response.status = "201 Created" response.headers['Content-Location'] = url(controller="users", action="silouserview", silo=silo, username=username) response_message = "201 Created" if to_remove: delete_group_users(silo, to_remove) response.status_int = 204 response.status = "204 Updated" response_message = None else: response.status_int = 400 response.status = "400 Bad Request" response_message = "No updates to user role" #Conneg return accept_list = None if 'HTTP_ACCEPT' in request.environ: try: accept_list = conneg_parse(request.environ['HTTP_ACCEPT']) except: accept_list= [MT("text", "html")] if not accept_list: accept_list= [MT("text", "html")] mimetype = accept_list.pop(0) while(mimetype): if str(mimetype).lower() in ["text/html", "text/xhtml"]: redirect(url(controller="users", action="silouserview", silo=silo, username=username)) elif str(mimetype).lower() in ["text/plain", "application/json"]: response.content_type = 'application/json; charset="UTF-8"' return response_message try: mimetype = accept_list.pop(0) except IndexError: mimetype = None #Whoops nothing satisfies - return text/plain response.content_type = 'application/json; charset="UTF-8"' return response_message elif http_method == "DELETE": kw = ag.granary.describe_silo(silo) #Get existing owners, admins, managers and users owners = [] admins = [] managers = [] submitters = [] if 'owners' in kw and kw['owners']: owners = [x.strip() for x in kw['owners'].split(",") if x] if 'administrators' in kw and kw['administrators']: admins = [x.strip() for x in kw['administrators'].split(",") if x] if 'managers' in kw and kw['managers']: managers = [x.strip() for x in kw['managers'].split(",") if x] if 'submitters' in kw and kw['submitters']: submitters = [x.strip() for x in kw['submitters'].split(",") if x] #Gather user roles to delete to_remove = [] if username in admins: if not 'administrator' in ident['permissions']: abort(403, "Need to be admin to modify user of role admin") if len(admins) == 1: abort(403, "Add another administrator to silo before deleting user") to_remove.append((username, 'administrator')) admins.remove(username) if username in managers: if len(managers) == 1 and len(admins) == 0: abort(403, "Add another administrator or manager to silo before deleting user") managers.remove(username) to_remove.append((username, 'manager')) if username in submitters: submitters.remove(username) to_remove.append((username, 'submitter')) if username in owners: owners.remove(username) owners = list(set(owners)) admins = list(set(admins)) managers = list(set(managers)) submitters = list(set(submitters)) if to_remove: # Update silo info kw['owners'] = ','.join(owners) kw['administrators'] = ','.join(admins) kw['managers'] = ','.join(managers) kw['submitters'] = ','.join(submitters) ag.granary.describe_silo(silo, **kw) ag.granary.sync() delete_group_users(silo, to_remove) else: abort(400, "No user to delete") accept_list = None response.content_type = "text/plain" response.status_int = 200 response.status = "200 OK" return "{'ok':'true'}"
def userview(self, username): if not request.environ.get('repoze.who.identity'): abort(401, "Not Authorised") ident = request.environ.get('repoze.who.identity') http_method = request.environ['REQUEST_METHOD'] if http_method == 'GET' or 'DELETE': #Admins, managers and user can see user data / delete the user if not ('administrator' in ident['permissions'] or \ 'manager' in ident['permissions'] or ident['user'].user_name == username): abort(403, "Do not have administrator or manager credentials to view profiles of other users") elif http_method == 'POST': #Only user can updte their data if not ident['user'].user_name == username: abort(403, "Login as %s to edit profile"%username) existing_users = list_usernames() if not username in existing_users: abort(404, "User not found") c.ident = ident c.username = username if http_method == "GET": c.user = list_user(username) accept_list = None if 'HTTP_ACCEPT' in request.environ: try: accept_list = conneg_parse(request.environ['HTTP_ACCEPT']) except: accept_list= [MT("text", "html")] if not accept_list: accept_list= [MT("text", "html")] mimetype = accept_list.pop(0) while(mimetype): if str(mimetype).lower() in ["text/html", "text/xhtml"]: return render("/admin_user.html") elif str(mimetype).lower() in ["text/plain", "application/json"]: response.content_type = 'application/json; charset="UTF-8"' response.status_int = 200 response.status = "200 OK" return simplejson.dumps(c.user) try: mimetype = accept_list.pop(0) except IndexError: mimetype = None #Whoops nothing satisfies - return text/html response.content_type = 'application/json; charset="UTF-8"' response.status_int = 200 response.status = "200 OK" return simplejson.dumps(c.user) elif http_method == "POST": params = request.POST if not('password' in params or 'name' in params or \ 'email' in params or 'firstname' in params or 'lastname' in params): abort(400, "No valid parameters found") params['username'] = username update_user(params) response.status_int = 204 response.status = "204 Updated" response_message = None # conneg return accept_list = None if 'HTTP_ACCEPT' in request.environ: try: accept_list = conneg_parse(request.environ['HTTP_ACCEPT']) except: accept_list= [MT("text", "html")] if not accept_list: accept_list= [MT("text", "html")] mimetype = accept_list.pop(0) while(mimetype): if str(mimetype).lower() in ["text/html", "text/xhtml"]: redirect(url(controller="users", action="userview", username=username)) elif str(mimetype).lower() in ["text/plain", "application/json"]: response.content_type = "text/plain" return response_message try: mimetype = accept_list.pop(0) except IndexError: mimetype = None # Whoops - nothing satisfies - return text/plain response.content_type = "text/plain" return response_message elif http_method == "DELETE": user_groups = list_user_groups(username) if user_groups: abort(403, "User is member of silos. Remove user from all silos before deleting them") #Delete user from database delete_user(username) #Get all the silos user belomgs to, remove them from each silo and sync silo metadata # conneg return accept_list = None response.content_type = "text/plain" response.status_int = 200 response.status = "200 OK" return "{'ok':'true'}"
def datasetview(self, silo, id): c.silo_name = silo c.id = id http_method = request.environ['REQUEST_METHOD'] granary_list = list_silos() if not silo in granary_list: abort(404) c_silo = ag.granary.get_rdf_silo(silo) if not c_silo.exists(id): abort(404) if ag.metadata_embargoed: abort(403, "DOIs cannot be issued to data packages whose metadata ia also under embargo") ident = request.environ.get('repoze.who.identity') c.ident = ident item = c_silo.get_item(id) creator = None if item.manifest and item.manifest.state and 'metadata' in item.manifest.state and item.manifest.state['metadata'] and \ 'createdby' in item.manifest.state['metadata'] and item.manifest.state['metadata']['createdby']: creator = item.manifest.state['metadata']['createdby'] c.version = item.currentversion c.version_doi = None c.editor = False #Get version number vnum = request.params.get('version', '') or "" if vnum: vnum = str(vnum) if not vnum in item.manifest['versions']: abort(404, "Version %s of data package %s not found"%(vnum, c.silo_name)) c.version = vnum if not (http_method == "GET"): #identity management of item if not request.environ.get('repoze.who.identity'): abort(401, "Not Authorised") silos = ag.authz(ident) if silo not in silos: abort(403, "Forbidden") silos_admin = ag.authz(ident, permission='administrator') silos_manager = ag.authz(ident, permission='manager') #if not (ident['repoze.who.userid'] == creator or ident.get('role') in ["admin", "manager"]): if not (ident['repoze.who.userid'] == creator or silo in silos_admin or silo in silos_manager): abort(403, "Forbidden") elif http_method == "GET": silos_admin = ag.authz(ident, permission='administrator') silos_manager = ag.authz(ident, permission='manager') #if ident['repoze.who.userid'] == creator or ident.get('role') in ["admin", "manager"]: if ident and ident['repoze.who.userid'] == creator or silo in silos_admin or silo in silos_manager: c.editor = True version_uri = "%s?version=%s"%(item.uri.rstrip('/'), c.version) c.version_doi = item.list_rdf_objects(URIRef(version_uri), u"http://purl.org/ontology/bibo/doi") if not c.version_doi or not c.version_doi[0]: c.version_doi = None else: c.version_doi = c.version_doi[0] doi_conf = OxDataciteDoi() doi_api = HTTPRequest(endpointhost=doi_conf.endpoint_host, secure=True) doi_api.setRequestUserPass(endpointuser=doi_conf.account, endpointpass=doi_conf.password) # conneg: accept_list = None if 'HTTP_ACCEPT' in request.environ: try: accept_list = conneg_parse(request.environ['HTTP_ACCEPT']) except: accept_list= [MT("text", "html")] if not accept_list: accept_list= [MT("text", "html")] c.message = None c.resp_status = None c.resp_reason = None c.metadata = None if http_method == "GET": #Get a list of all dois registered for this data package c.dois = {} for v in item.manifest['versions']: doi_ans = None doi_ans = item.list_rdf_objects(URIRef("%s/version%s"%(item.uri.rstrip('/'), v)), u"http://purl.org/ontology/bibo/doi") if doi_ans and doi_ans[0]: c.dois[v] = doi_ans[0] c.heading = "Doi metadata information from Datacite" if not c.version_doi: mimetype = accept_list.pop(0) while(mimetype): if str(mimetype).lower() in ["text/html", "text/xhtml"]: #Doint this to avoid displaying the erro page!!! response.status_int = 200 response.status = "200 OK" c.metadata = None return render('/doiview.html') try: mimetype = accept_list.pop(0) except IndexError: mimetype = None c.message = 'DOI not registered for version %s of data package %s'%(c.version, c.silo_name) return render('/doiview.html') resource = "%s?doi=%s"%(doi_conf.endpoint_path_metadata, c.version_doi) (resp, respdata) = doi_api.doHTTP_GET(resource=resource, expect_type='application/xml') c.resp_reason = resp.reason c.resp_status = resp.status if resp.status < 200 or resp.status >= 300: response.status_int = 400 response.status = "400 Bad Request" response_msg = '' c.metadata = '' if resp.status == 403: #TODO: Confirm 403 is not due to authorization msg = "403 Forbidden - login error with Datacite or data package belongs to another party at Datacite." elif resp.status == 404: msg = "404 Not Found - DOI does not exist in DatCite's database" elif resp.status == 410: msg = "410 Gone - the requested data package was marked inactive (using DELETE method) at Datacite" elif resp.status == 500: msg = "500 Internal Server Error - Error retreiving the metadata from Datacite." else: msg = "Error retreiving the metadata from Datacite. %s"%str(resp.status) c.message = msg else: response.status_int = 200 response.status = "200 OK" c.metadata = respdata response_msg = respdata # conneg: mimetype = accept_list.pop(0) while(mimetype): if str(mimetype).lower() in ["text/html", "text/xhtml"]: #Setting headers to 200 to avoid displaying the error page!!! response.status_int = 200 response.status = "200 OK" return render('/doiview.html') elif str(mimetype).lower() in ["text/plain", "application/json"]: response.content_type = 'text/plain; charset="UTF-8"' return str(respdata.decode('utf-8')) elif str(mimetype).lower() in ["application/rdf+xml", "text/xml"]: response.status_int = 200 response.status = "200 OK" response.content_type = 'text/xml; charset="UTF-8"' return response_msg try: mimetype = accept_list.pop(0) except IndexError: mimetype = None #Whoops - nothing staisfies - default to text/html #Setting headers to 200 to avoid displaying the error page!!! response.status_int = 200 response.status = "200 OK" return render('/doiview.html') if http_method == "POST": item.set_version_cursor(c.version) #1a. If doi doen not exist for this version, generate doi register_doi = False if not c.version_doi: cnt = doi_count() if not cnt: abort(400, "Error generating DOI") register_doi = True tiny_pid = short_pid.encode_url(cnt) c.version_doi = "%s/bodleian%s.%s"%(doi_conf.prefix, tiny_pid, c.version) #1b. Construct XML metadata if c.version_doi: xml_metadata = get_doi_metadata(c.version_doi, item) c.metadata = xml_metadata #FOR TEST PURPOSES ONLY #xml_metadata = False # Have commented out the sections below as we will only register a DOI if there is metadata """ if not xml_metadata and not register_doi: #2a. If the doi already exists and there is no xml metadata to update, return bad request c.message = "Coud not update metadata" response.status_int = 400 response.status = "Bad request" respdata = c.message c.metadata = '' elif not xml_metadata and register_doi: #2b. If the doi is not registered, but there is no xml metadata to update, register just the doi with datacite c.heading = "Registering new DOI with Datacite" resource = "%s"%doi_conf.endpoint_path_doi body = "%s\n%s"%(c.version_doi, version_uri) #body_unicode = unicode(body, "utf-8") body_unicode = unicode(body) (resp, respdata) = doi_api.doHTTP_POST(body_unicode, resource=resource, data_type='text/plain;charset=UTF-8') c.resp_reason = resp.reason c.resp_status = resp.status if resp.status < 200 or resp.status >= 300: response.status_int = 400 response.status = "400 Bad Request" response_msg = "DOI not registered" c.metadata = '' if resp.status == 400: msg = "400 Bad Request - Request body must be exactly two lines: DOI and URL" elif resp.status == 403: #TODO: Confirm 403 is not due to authorization msg = "403 Forbidden - From Datacite: login problem, quota excceded, wrong domain, wrong prefix" elif resp.status == 500: msg = "500 Internal Server Error - Error registering the DOI." else: msg = "Error retreiving the metadata from Datacite. %s"%str(resp.status) c.message = msg else: #3. Add the DOI to the rdf metadata item.add_namespace('bibo', "http://purl.org/ontology/bibo/") item.add_triple(URIRef(version_uri), u"bibo:doi", Literal(c.version_doi)) item.del_triple(item.uri, u"dcterms:modified") item.add_triple(item.uri, u"dcterms:modified", datetime.now()) item.sync() response.status_int = 200 response.status = "200 OK" response_msg = "DOI Registered. %s"%respdata c.metadata = '' c.message = "201 Created - DOI registered. %s"%respdata """ if not xml_metadata: #2a. If the doi already exists and there is no xml metadata to update, return bad request c.message = "Could not generate metadata" c.metadata = '' abort(400, "Error generating metadata") elif not register_doi: c.message = "Could not generate DOI" abort(400, "Error generating DOI") else: #register the DOI with Datacite resource = "%s"%doi_conf.endpoint_path_doi body = "doi=%s\nurl=%s"%(c.version_doi, version_uri) body_unicode = unicode(body) (resp, respdata) = doi_api.doHTTP_POST(body_unicode, resource=resource, data_type='text/plain;charset=UTF-8') c.resp_reason1 = resp.reason c.resp_status1 = resp.status #Add the metadata within Datacite c.heading = "Registering new DOI along with its metadata with Datacite" #body_unicode = unicode(xml_metadata, "utf-8") #body_unicode = unicode(xml_metadata) body_unicode = xml_metadata resource = "%s?doi=%s&url=%s"%(doi_conf.endpoint_path_metadata, c.version_doi, version_uri) (resp, respdata) = doi_api.doHTTP_POST(body_unicode, resource=resource, data_type='application/xml;charset=UTF-8') c.resp_reason = resp.reason c.resp_status = resp.status if (c.resp_status1>= 200 and c.resp_status1 < 300) or (resp.status >= 200 and resp.status < 300): #3. Add the DOI to the rdf metadata item.add_namespace('bibo', "http://purl.org/ontology/bibo/") item.add_triple(URIRef(version_uri), u"bibo:doi", Literal(c.version_doi)) item.del_triple(item.uri, u"dcterms:modified") item.add_triple(item.uri, u"dcterms:modified", datetime.now()) item.sync() #4. Broadcast changes to redis try: ag.b.change(silo, id, ident=ident['repoze.who.userid']) except: pass if resp.status < 200 or resp.status >= 300: response.status_int = 400 response.status = "400 Bad Request" response_msg = "DOI and metadata not registered" c.metadata = body_unicode if resp.status == 400: msg = "400 Bad Request - Invalid XML metadata" elif resp.status == 403: #TODO: Confirm 403 is not due to authorization msg = "403 Forbidden - From Datacite: login problem, quota excceded, wrong domain, wrong prefix" elif resp.status == 500: msg = "500 Internal Server Error - Error registering the DOI." else: msg = "Error retreiving the metadata from Datacite. %s"%str(resp.status) c.message = msg else: response.status_int = 200 response.status = "200 OK" response_msg = body_unicode c.metadata = body_unicode c.message = "201 Created - DOI registered. %s"%respdata # conneg: mimetype = accept_list.pop(0) while(mimetype): if str(mimetype).lower() in ["text/html", "text/xhtml"]: #Setting headers to 200 to avoid displaying the error page!!! response.status_int = 200 response.status = "200 OK" return render('/doiview.html') elif str(mimetype).lower() in ["text/plain", "application/json"]: response.content_type = 'text/plain' return str(respdata.decode('utf-8')) elif str(mimetype).lower() in ["application/rdf+xml", "text/xml"]: response.status_int = 200 response.status = "200 OK" response.content_type = 'text/xml; charset="UTF-8"' return response_msg try: mimetype = accept_list.pop(0) except IndexError: mimetype = None #Whoops - nothing staisfies - default to text/html #Setting headers to 200 to avoid displaying the error page!!! response.status_int = 200 response.status = "200 OK" return render('/doiview.html')