Exemple #1
0
    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
Exemple #2
0
    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 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 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 deposit_new(self, silo, deposit):
        """
        Take the supplied deposit and treat it as a new container with content to be created in the specified collection
        Args:
        -collection:    the ID of the collection to be deposited into
        -deposit:       the DepositRequest object to be processed
        Returns a DepositResponse object which will contain the Deposit Receipt or a SWORD Error
        """
        # check against the authorised list of silos
        rdf_silo = self._get_authorised_rdf_silo(silo)

        # ensure that we have a slug
        if deposit.slug is None:
            deposit.slug = str(uuid.uuid4())
            
        # weed out unacceptable deposits
        if rdf_silo.exists(deposit.slug):
            raise SwordError(error_uri=DataBankErrors.dataset_conflict, msg="A Dataset with the name " + deposit.slug + " already exists")
        if not allowable_id2(deposit.slug):
            raise SwordError(error_uri=Errors.bad_request, msg="Dataset name can contain only the following characters - " + 
                                                                ag.naming_rule_humanized + " and has to be more than 1 character")
        
        # NOTE: we pass in an empty dictionary of metadata on create, and then run
        # _ingest_metadata to augment the item from the deposit
        item = create_new(rdf_silo, deposit.slug, self.auth_credentials.username, {})
        add_dataset(silo, deposit.slug)
        self._ingest_metadata(item, deposit)
        
        # NOTE: left in for reference for the time being, but deposit_new 
        # only support entry only deposits in databank.  This will need to be
        # re-introduced for full sword support
        # store the content file if one exists, and do some processing on it
        #deposit_uri = None
        #derived_resource_uris = []
        #if deposit.content is not None:
        
       #     if deposit.filename is None:
       #         deposit.filename = "unnamed.file"
       #     fn = self.dao.store_content(collection, id, deposit.content, deposit.filename)

            # now that we have stored the atom and the content, we can invoke a package ingester over the top to extract
            # all the metadata and any files we want
            
            # FIXME: because the deposit interpreter doesn't deal with multipart properly
            # we don't get the correct packaging format here if the package is anything
            # other than Binary
       #     ssslog.info("attempting to load ingest packager for format " + str(deposit.packaging))
       #     packager = self.configuration.get_package_ingester(deposit.packaging)(self.dao)
       #     derived_resources = packager.ingest(collection, id, fn, deposit.metadata_relevant)

            # An identifier which will resolve to the package just deposited
       #     deposit_uri = self.um.part_uri(collection, id, fn)
            
            # a list of identifiers which will resolve to the derived resources
       #     derived_resource_uris = self.get_derived_resource_uris(collection, id, derived_resources)

        # the aggregation uri
        agg_uri = self.um.agg_uri(silo, deposit.slug)

        # the Edit-URI
        edit_uri = self.um.edit_uri(silo, deposit.slug)

        # create the initial statement
        s = Statement(aggregation_uri=agg_uri, rem_uri=edit_uri, states=[DataBankStates.initial_state])
        
        # FIXME: need to sort out authentication before we can do this ...
        # FIXME: also, it's not relevant unless we take a binary-only deposit, which
        # we currently don't
        # User already authorized to deposit in this silo (_get_authorised_rdf_silo). 
        # This is to augment metadata with details like who created, on behalf of, when
        #
        #by = deposit.auth.username if deposit.auth is not None else None
        #obo = deposit.auth.on_behalf_of if deposit.auth is not None else None
        #if deposit_uri is not None:
        #    s.original_deposit(deposit_uri, datetime.now(), deposit.packaging, by, obo)
        #s.aggregates = derived_resource_uris

        # In creating the statement we use the existing manifest.rdf file in the
        # item:
        manifest = item.get_rdf_manifest()
        f = open(manifest.filepath, "r")
        rdf_string = f.read()

        # create the new manifest and store it
        #Serialize rdf adds the sword statement - state, depositedOn, by, onBehalfOf, stateDesc
        new_manifest = s.serialise_rdf(rdf_string)
        item.put_stream("manifest.rdf", new_manifest)

        # FIXME: here is where we have to put the correct treatment in
        # now generate a receipt for the deposit
        # TODO: Add audit log from item.manifest in place of  "created new item"
        receipt = self.deposit_receipt(silo, deposit.slug, item, "created new item")

        # FIXME: while we don't have full text deposit, we don't need to augment
        # the deposit receipt
        
        # now augment the receipt with the details of this particular deposit
        # this handles None arguments, and converts the xml receipt into a string
        # receipt = self.augmented_receipt(receipt, deposit_uri, derived_resource_uris)
        
        # finally, assemble the deposit response and return
        dr = DepositResponse()
        dr.receipt = receipt.serialise()
        dr.location = receipt.edit_uri
        
        # Broadcast change as message
        ag.b.creation(silo, deposit.slug, ident=self.auth_credentials.username)
        
        return dr
Exemple #6
0
    def deposit_new(self, silo, deposit):
        """
        Take the supplied deposit and treat it as a new container with content to be created in the specified collection
        Args:
        -collection:    the ID of the collection to be deposited into
        -deposit:       the DepositRequest object to be processed
        Returns a DepositResponse object which will contain the Deposit Receipt or a SWORD Error
        """
        # check against the authorised list of silos
        rdf_silo = self._get_authorised_rdf_silo(silo)

        # ensure that we have a slug
        if deposit.slug is None:
            deposit.slug = str(uuid.uuid4())

        # weed out unacceptable deposits
        if rdf_silo.exists(deposit.slug):
            raise SwordError(error_uri=DataBankErrors.dataset_conflict,
                             msg="A Dataset with the name " + deposit.slug +
                             " already exists")
        if not allowable_id2(deposit.slug):
            raise SwordError(
                error_uri=Errors.bad_request,
                msg="Dataset name can contain only the following characters - "
                + ag.naming_rule_humanized +
                " and has to be more than 1 character")

        # NOTE: we pass in an empty dictionary of metadata on create, and then run
        # _ingest_metadata to augment the item from the deposit
        item = create_new(rdf_silo, deposit.slug,
                          self.auth_credentials.username, {})
        add_dataset(silo, deposit.slug)
        self._ingest_metadata(item, deposit)

        # NOTE: left in for reference for the time being, but deposit_new
        # only support entry only deposits in databank.  This will need to be
        # re-introduced for full sword support
        # store the content file if one exists, and do some processing on it
        #deposit_uri = None
        #derived_resource_uris = []
        #if deposit.content is not None:

        #     if deposit.filename is None:
        #         deposit.filename = "unnamed.file"
        #     fn = self.dao.store_content(collection, id, deposit.content, deposit.filename)

        # now that we have stored the atom and the content, we can invoke a package ingester over the top to extract
        # all the metadata and any files we want

        # FIXME: because the deposit interpreter doesn't deal with multipart properly
        # we don't get the correct packaging format here if the package is anything
        # other than Binary
        #     ssslog.info("attempting to load ingest packager for format " + str(deposit.packaging))
        #     packager = self.configuration.get_package_ingester(deposit.packaging)(self.dao)
        #     derived_resources = packager.ingest(collection, id, fn, deposit.metadata_relevant)

        # An identifier which will resolve to the package just deposited
        #     deposit_uri = self.um.part_uri(collection, id, fn)

        # a list of identifiers which will resolve to the derived resources
        #     derived_resource_uris = self.get_derived_resource_uris(collection, id, derived_resources)

        # the aggregation uri
        agg_uri = self.um.agg_uri(silo, deposit.slug)

        # the Edit-URI
        edit_uri = self.um.edit_uri(silo, deposit.slug)

        # create the initial statement
        s = Statement(aggregation_uri=agg_uri,
                      rem_uri=edit_uri,
                      states=[DataBankStates.initial_state])

        # FIXME: need to sort out authentication before we can do this ...
        # FIXME: also, it's not relevant unless we take a binary-only deposit, which
        # we currently don't
        # User already authorized to deposit in this silo (_get_authorised_rdf_silo).
        # This is to augment metadata with details like who created, on behalf of, when
        #
        #by = deposit.auth.username if deposit.auth is not None else None
        #obo = deposit.auth.on_behalf_of if deposit.auth is not None else None
        #if deposit_uri is not None:
        #    s.original_deposit(deposit_uri, datetime.now(), deposit.packaging, by, obo)
        #s.aggregates = derived_resource_uris

        # In creating the statement we use the existing manifest.rdf file in the
        # item:
        manifest = item.get_rdf_manifest()
        f = open(manifest.filepath, "r")
        rdf_string = f.read()

        # create the new manifest and store it
        #Serialize rdf adds the sword statement - state, depositedOn, by, onBehalfOf, stateDesc
        new_manifest = s.serialise_rdf(rdf_string)
        item.put_stream("manifest.rdf", new_manifest)

        # FIXME: here is where we have to put the correct treatment in
        # now generate a receipt for the deposit
        # TODO: Add audit log from item.manifest in place of  "created new item"
        receipt = self.deposit_receipt(silo, deposit.slug, item,
                                       "created new item")

        # FIXME: while we don't have full text deposit, we don't need to augment
        # the deposit receipt

        # now augment the receipt with the details of this particular deposit
        # this handles None arguments, and converts the xml receipt into a string
        # receipt = self.augmented_receipt(receipt, deposit_uri, derived_resource_uris)

        # finally, assemble the deposit response and return
        dr = DepositResponse()
        dr.receipt = receipt.serialise()
        dr.location = receipt.edit_uri

        # Broadcast change as message
        ag.b.creation(silo, deposit.slug, ident=self.auth_credentials.username)

        return dr