Exemple #1
0
def view_collection(request, path):
    if not path:
        path = '/'
    collection = Collection.find(path)

    if not collection:
        raise Http404()

    if not collection.user_can(request.user, "read") and not collection.is_root:
        # If the user can't read, then return 404 rather than 403 so that
        # we don't leak information.
        raise Http404()

    paths = []
    full = ""
    for p in collection.path.split('/'):
        if not p:
            continue
        full = u"{}/{}".format(full, p)
        paths.append((p, full))

    children_c, children_r = collection.get_child()
    children_c.sort(key=lambda x: x.lower())
    children_r.sort(key=lambda x: x.lower())
    ctx = {
        'collection': collection.to_dict(request.user),
        'children_c': [Collection.find(merge(path,c)).to_dict(request.user) for c in children_c],
        'children_r': [Resource.find(merge(path,c)).simple_dict(request.user) for c in children_r],
        'collection_paths': paths,
        'empty': len(children_c) + len(children_r) == 0,
    }

    return render(request, 'archive/index.html', ctx)
Exemple #2
0
 def delete_all(cls, path, username=None):
     """Delete recursively all sub-collections and all resources contained
     in a collection at 'path'"""
     from indigo.models import Resource
     parent = Collection.find(path)
     if not parent:
         return
     collections, resources = parent.get_child()
     collections = [Collection.find(merge(path, c)) for c in collections]
     resources = [Resource.find(merge(path, c)) for c in resources]
     for resource in resources:
         resource.delete(username)
     for collection in collections:
         Collection.delete_all(collection.path, username)
     parent.delete(username)
Exemple #3
0
 def path(self):
     """Get the full path of the specific entry"""
     return merge(self.container, self.name)
Exemple #4
0
    def create(cls,
               container,
               name,
               uuid=None,
               metadata=None,
               url=None,
               mimetype=None,
               username=None,
               size=None):
        """Create a new resource in the tree_entry table"""
        from indigo.models import Collection
        from indigo.models import Notification
        # Check if parent collection exists
        parent = Collection.find(container)
        if parent is None:
            raise NoSuchCollectionError(container)
        if uuid is None:
            uuid = default_cdmi_id()
        create_ts = datetime.now()
        modified_ts = create_ts
        path = merge(container, name)
        if metadata:
            metadata_cass = meta_cdmi_to_cassandra(metadata)
        # Check the container exists
        collection = Collection.find(container)
        if not collection:
            raise NoSuchCollectionError(container)
        # Make sure parent/name are not in use.
        existing = cls.find(path)
        if existing:
            raise ResourceConflictError(path)
        kwargs = {
            "container": container,
            "name": name,
            "url": url,
            "uuid": uuid,
        }
        if is_reference(url):
            kwargs["create_ts"] = create_ts
            kwargs["modified_ts"] = modified_ts
            kwargs["mimetype"] = mimetype
            if metadata:
                kwargs["metadata"] = metadata_cass
        else:
            obj_id = url.replace("cassandra://", "")
            data_obj = DataObject.find(obj_id)
            if metadata:
                data_obj.update(mimetype=mimetype, metadata=metadata_cass)
            else:
                if mimetype:
                    data_obj.update(mimetype=mimetype)
                if size:
                    data_obj.update(size=size)

        data_entry = TreeEntry.create(**kwargs)
        new = Resource(data_entry)

        session = get_graph_session()

        add_user_edge = ""
        if username:
            user = User.find(username)
            if user:
                add_user_edge = """v_user = {}.next();
                                   v_user.addEdge('owns', v_new);
                                   """.format(gq_get_vertex_user(user))
        else:
            add_user_edge = ""

        session.execute_graph("""v_parent = {}.next();
                                 v_new = {};
                                 v_parent.addEdge('son', v_new);
                                 {}
                                 """.format(gq_get_vertex_collection(parent),
                                            gq_add_vertex_resource(new),
                                            add_user_edge))
        if metadata:
            new.update_graph(metadata)

        state = new.mqtt_get_state()
        payload = new.mqtt_payload({}, state)
        Notification.create_resource(username, path, payload)
        # Index the resource
        new.index()
        return new
Exemple #5
0
    def create(cls, name, container='/', metadata=None, username=None):
        """Create a new collection"""
        from indigo.models import Notification
        from indigo.models import Resource
        path = merge(container, name)
        # Check if parent collection exists
        parent = Collection.find(container)
        if parent is None:
            raise NoSuchCollectionError(container)
        resource = Resource.find(merge(container, name))
        if resource is not None:
            raise ResourceConflictError(container)
        collection = Collection.find(path)
        if collection is not None:
            raise CollectionConflictError(container)
        now = datetime.now()
        # If we try to create a tree entry with no metadata, cassandra-driver
        # will fail as it tries to delete a static column
        if metadata:
            metadata_cass = meta_cdmi_to_cassandra(metadata)
            coll_entry = TreeEntry.create(container=path,
                                          name='.',
                                          container_create_ts=now,
                                          container_modified_ts=now,
                                          container_metadata=metadata_cass)
        else:
            coll_entry = TreeEntry.create(container=path,
                                          name='.',
                                          container_create_ts=now,
                                          container_modified_ts=now)
        coll_entry.update(uuid=coll_entry.container_uuid)
        child_entry = TreeEntry.create(container=container,
                                       name=name + '/',
                                       uuid=coll_entry.container_uuid)

        new = Collection.find(path)

        add_user_edge = ""
        if username:
            user = User.find(username)
            if user:
                add_user_edge = """v_user = {}.next();
                                   v_user.addEdge('owns', v_new);
                                   """.format(gq_get_vertex_user(user))
        else:
            add_user_edge = ""
        session = get_graph_session()
        session.execute_graph("""v_parent = {}.next();
                                 v_new = {};
                                 v_parent.addEdge('son', v_new);
                                 {}
                                 """.format(gq_get_vertex_collection(parent),
                                            gq_add_vertex_collection(new),
                                            add_user_edge))
        if metadata:
            new.update_graph(metadata)

        state = new.mqtt_get_state()
        payload = new.mqtt_payload({}, state)
        Notification.create_collection(username, path, payload)
        # Index the collection
        new.index()
        return new
Exemple #6
0
    def process_create_entry_work(self, resc_dict, context, is_reference):
        # MOSTLY the resource will not exist... so start by calculating the URL and trying to insert the entire record..
        if is_reference:
            url = "file://{}{}/{}".format(context['local_ip'], context['path'],
                                          context['entry'])
        else:
            with open(context['fullpath'], 'r') as f:
                seq_number = 0
                data_uuid = None

                for chk in read_in_chunks(f):
                    if seq_number == 0:
                        data_object = DataObject.create(
                            chk, resc_dict['compress'])
                        data_uuid = data_object.uuid
                    else:
                        DataObject.append_chunk(data_uuid, chk, seq_number,
                                                resc_dict['compress'])
                    seq_number += 1
                if data_uuid:
                    url = "cassandra://{}".format(data_uuid)
                else:
                    return None

        try:
            # OK -- try to insert ( create ) the record...
            t1 = time.time()

            resource = Resource.create(container=resc_dict['container'],
                                       name=resc_dict['name'],
                                       url=url,
                                       mimetype=resc_dict['mimetype'],
                                       username=context['user'],
                                       size=resc_dict['size'])
            resource.create_acl_list(resc_dict['read_access'],
                                     resc_dict['write_access'])

            msg = 'Resource {} created --> {}'.format(resource.get_name(),
                                                      time.time() - t1)
            logger.info(msg)
        except ResourceConflictError:
            # If the create fails, the record already exists... so retrieve it...
            t1 = time.time()
            resource = Resource.find(
                merge(resc_dict['container'], resc_dict['name']))
            msg = "{} ::: Fetch Object -> {}".format(resource.get_name(),
                                                     time.time() - t1)
            logger.info(msg)

        # if the url is not correct then update
        # TODO: if the url is a block set that is stored internally then reduce its count so that it can be GC'd.
        # t3 = None
        if resource.url != url:
            t2 = time.time()
            # if url.startswith('cassandra://') : tidy up the stored block count...
            resource.update(url=url)
            t3 = time.time()
            msg = "{} ::: update -> {}".format(resource.get_name(), t3 - t2)
            logger.info(msg)

        # t1 = time.time()
        SearchIndex.reset(resource.uuid)
        SearchIndex.index(resource, ['name', 'metadata'])