コード例 #1
0
    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')
コード例 #2
0
    def datasetview(self, silo, id):
        if not ag.granary.issilo(silo):
            abort(404)
        
        ident = request.environ.get('repoze.who.identity')

        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')

        rdfsilo = ag.granary.get_rdf_silo(silo)       
        if not rdfsilo.exists(id):
            abort(404)

        item = rdfsilo.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']
        #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. You should be the creator or manager or administrator to view this information")

        options = request.GET
        if 'version' in options and options['version']:
            if not options['version'] in item.manifest['versions']:
                abort(404)
            currentversion = str(item.currentversion)
            vnum = str(options['version'])
            if vnum and not vnum == currentversion:
                item.set_version_cursor(vnum) 

        parts = item.list_parts(detailed=True)

        dataset = {}
        dataset['parts'] = {}
        for part in parts:
            dataset['parts'][part] = serialisable_stat(parts[part])
            if item.manifest:
                dataset['state'] = item.manifest.state

        # Always return application/json
        response.content_type = 'application/json; charset="UTF-8"'
        response.status_int = 200
        response.status = "200 OK"
        return simplejson.dumps(dataset)
コード例 #3
0
 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)
コード例 #4
0
    def service_document(self, path=None):
        """
        Construct the Service Document.  This takes the set of collections that are in the store, and places them in
        an Atom Service document as the individual entries
        """
        service = ServiceDocument(version=self.config.sword_version,
                                  max_upload_size=self.config.max_upload_size)

        # get the authorised list of silos
        silos = ag.authz(self.auth_credentials.identity)

        # now for each collection create an sdcollection
        collections = []
        for col_name in silos:
            href = self.um.silo_url(col_name)
            title = col_name
            mediation = self.config.mediation

            # content types accepted
            accept = []
            multipart_accept = []
            if not self.config.accept_nothing:
                if self.config.app_accept is not None:
                    for acc in self.config.app_accept:
                        accept.append(acc)

                if self.config.multipart_accept is not None:
                    for acc in self.config.multipart_accept:
                        multipart_accept.append(acc)

            # SWORD packaging formats accepted
            accept_package = []
            for format in self.config.sword_accept_package:
                accept_package.append(format)

            col = SDCollection(href=href,
                               title=title,
                               accept=accept,
                               multipart_accept=multipart_accept,
                               accept_package=accept_package,
                               mediation=mediation)

            collections.append(col)

        service.add_workspace("Silos", collections)

        # serialise and return
        return service.serialise()
コード例 #5
0
ファイル: items.py プロジェクト: benosteen/RDFDatabank
    def subitemview(self, silo, id, path, subpath):
        # Function to retreive a file from the zipfile
        # TODO
        #    I check to see the path is avlid and it is a zip file.
        #    I do not deal with subpath. if it is a file - serve it. If it is a dir, show the contents of it.

        # tmpl_context variables needed: c.silo_name, c.zipfile_contents c.ident, c.id, c.path
        if not ag.granary.issilo(silo):
            abort(404)

        if not (path or subpath):
            abort(400, "You must supply a filename to unpack")

        rdfsilo = ag.granary.get_rdf_silo(silo)
        if not rdfsilo.exists(id):
            abort(404)

        c.silo_name = silo
        c.id = id
        c.path = path
        c.subpath = subpath

        ident = request.environ.get("repoze.who.identity")
        c.ident = ident
        dataset = rdfsilo.get_item(id)

        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")

        item_real_filepath = dataset.to_dirpath()
        target_filepath = "%s/%s" % (item_real_filepath, path)
        # c.parts = dataset.list_parts(detailed=False)
        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")

        # TODO : if subpath is a file - serve it. If subpath is a dir, show the contents of the dir

        return render("/zipfilesubitemview.html")
コード例 #6
0
    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')
コード例 #7
0
    def service_document(self, path=None):
        """
        Construct the Service Document.  This takes the set of collections that are in the store, and places them in
        an Atom Service document as the individual entries
        """
        service = ServiceDocument(version=self.config.sword_version,
                                    max_upload_size=self.config.max_upload_size)
        
        # get the authorised list of silos
        silos = ag.authz(self.auth_credentials.identity)
        
        # now for each collection create an sdcollection
        collections = []
        for col_name in silos:        
            href = self.um.silo_url(col_name)
            title = col_name
            mediation = self.config.mediation
            
            # content types accepted
            accept = []
            multipart_accept = []
            if not self.config.accept_nothing:
                if self.config.app_accept is not None:
                    for acc in self.config.app_accept:
                        accept.append(acc)
                
                if self.config.multipart_accept is not None:
                    for acc in self.config.multipart_accept:
                        multipart_accept.append(acc)
                        
            # SWORD packaging formats accepted
            accept_package = []
            for format in self.config.sword_accept_package:
                accept_package.append(format)
            
            col = SDCollection(href=href, title=title, accept=accept, multipart_accept=multipart_accept,
                                accept_package=accept_package, mediation=mediation)
                                
            collections.append(col)
        
        service.add_workspace("Silos", collections)

        # serialise and return
        return service.serialise()
コード例 #8
0
    def container_exists(self, path):
        # extract information from the path
        silo, dataset_id, accept_parameters = self.um.interpret_path(path)
        
        # is this a silo?
        if not ag.granary.issilo(silo):
            return False

        # is this an authorised silo?
        silos = ag.authz(self.auth_credentials.identity)
        if silo not in silos:
            return False
        
        # get a full silo object
        rdf_silo = ag.granary.get_rdf_silo(silo)
        
        # is the dataset in the authorised silo?
        if not rdf_silo.exists(dataset_id):
            return False
        
        # if we get here without failing, then the container exists (from the
        # perspective of the user)
        return True
コード例 #9
0
    def container_exists(self, path):
        # extract information from the path
        silo, dataset_id, accept_parameters = self.um.interpret_path(path)

        # is this a silo?
        if not ag.granary.issilo(silo):
            return False

        # is this an authorised silo?
        silos = ag.authz(self.auth_credentials.identity)
        if silo not in silos:
            return False

        # get a full silo object
        rdf_silo = ag.granary.get_rdf_silo(silo)

        # is the dataset in the authorised silo?
        if not rdf_silo.exists(dataset_id):
            return False

        # if we get here without failing, then the container exists (from the
        # perspective of the user)
        return True
コード例 #10
0
 def _get_authorised_rdf_silo(self, silo):
 
     if not ag.granary.issilo(silo):
         return SwordError(status=404, empty=True)
 
     # get the authorised list of silos
     #granary_list = ag.granary.silos
     granary_list = list_silos()
     silos = ag.authz(self.auth_credentials.identity)
     
     # does the collection/silo exist?  If not, we can't do a deposit
     if silo not in silos:
         # if it's not in the silos it is either non-existant or it is
         # forbidden...
         if silo in granary_list:
             # forbidden
             raise SwordError(status=403, empty=True)
         else:
             # not found
             raise SwordError(status=404, empty=True)
     
     # get a full silo object
     rdf_silo = ag.granary.get_rdf_silo(silo)
     return rdf_silo
コード例 #11
0
    def _get_authorised_rdf_silo(self, silo):

        if not ag.granary.issilo(silo):
            return SwordError(status=404, empty=True)

        # get the authorised list of silos
        #granary_list = ag.granary.silos
        granary_list = list_silos()
        silos = ag.authz(self.auth_credentials.identity)

        # does the collection/silo exist?  If not, we can't do a deposit
        if silo not in silos:
            # if it's not in the silos it is either non-existant or it is
            # forbidden...
            if silo in granary_list:
                # forbidden
                raise SwordError(status=403, empty=True)
            else:
                # not found
                raise SwordError(status=404, empty=True)

        # get a full silo object
        rdf_silo = ag.granary.get_rdf_silo(silo)
        return rdf_silo
コード例 #12
0
ファイル: items.py プロジェクト: benosteen/RDFDatabank
    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
コード例 #13
0
ファイル: items.py プロジェクト: benosteen/RDFDatabank
    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
コード例 #14
0
    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')
コード例 #15
0
    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."
コード例 #16
0
    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'}"
コード例 #17
0
ファイル: doi.py プロジェクト: anusharanganathan/RDFDatabank
    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')
コード例 #18
0
    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'}"
コード例 #19
0
    def siloview(self, silo):
        """
        Returns the state information of a silo. 
        Only authorized users with role 'admin' or 'manager' can view this information

        The state information for a silo contains the following:
            Name of the silo (machine name, used in uris) - ans["silo"]
            Base URI for the silo - ans["uri_base"]
            Users who can access the silo (silo owners) - ans["owners"]
            Silo description - ans["description"]
            Title of the silo (human readable) - ans["title"]
            Disk allocation for the silo (in kB) - ans["disk_allocation"]
            List of datasets in the silo (ans["datasets"]) 
               with embargo information for each of the datasets 
               (ans["datasets"]["dataset_name"]["embargo_info"])
        """
    
        # Only authorized users can view state information.
        # Should this be restricted to admins and managers only, or shoud users too be able to see this information?
        # Going with restricting this information to admins and managers 
        if not ag.granary.issilo(silo):
            abort(404)

        ident = request.environ.get('repoze.who.identity')
        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.get('role') in ["admin", "manager"]:
        if not (silo in silos_admin or silo in silos_manager):
            abort(403, "Forbidden. You should be an administrator or manager to view this information")

        options = request.GET
        start = 0
        if 'start' in options and options['start']:
            try:
                start = int(options['start'])
            except:
                start = 0
        rows = 1000
        if 'rows' in options and options['rows']:
            try:
                rows = int(options['rows'])
            except:
                rows = 1000

        rdfsilo = ag.granary.get_rdf_silo(silo)
        state_info = ag.granary.describe_silo(silo)
        state_info['silo'] = silo
        state_info['uri_base'] = ''
        if rdfsilo.state and rdfsilo.state['uri_base']:
            state_info['uri_base'] = rdfsilo.state['uri_base']
        state_info['number of data packages'] = get_datasets_count(silo)
        state_info['params'] = {'start':start, 'rows':rows}
        items = {}
        #for item in rdfsilo.list_items():
        for item in get_datasets(silo, start=start, rows=rows):
            items[item] = {}
            try:
                items[item]['embargo_info'] = is_embargoed(rdfsilo, item)
            except:
                pass
        state_info['datasets'] = items

        # conneg return
        # Always return application/json
        response.content_type = 'application/json; charset="UTF-8"'
        response.status_int = 200
        response.status = "200 OK"
        return simplejson.dumps(state_info)