Ejemplo n.º 1
0
 def get_store(self) -> Store:
     """
     Returns the :class:`sqlalchemy_media.stores.Store` instance, which this file is stored on.
     
     """
     store_manager = StoreManager.get_current_store_manager()
     return store_manager.get(self.store_id)
Ejemplo n.º 2
0
    def __setitem__(self, index, value):
        old_value = self[index]
        store_manager = StoreManager.get_current_store_manager()
        if old_value:
            store_manager.orphaned(old_value)

        store_manager.adopted(value)
        super().__setitem__(index, value)
Ejemplo n.º 3
0
    def __setitem__(self, index, value):
        store_manager = StoreManager.get_current_store_manager()
        if isinstance(index, slice):
            for old_value in self[index]:
                if old_value:
                    store_manager.orphaned(old_value)

            for new_item in value:
                store_manager.adopted(new_item)
            super().__setitem__(index, [self.observe_item(i) for i in value])
        else:
            old_value = self[index]
            if old_value:
                store_manager.orphaned(old_value)

            value = self.observe_item(value)
            store_manager.adopted(value)
            super().__setitem__(index, value)
Ejemplo n.º 4
0
 def clear(self):
     StoreManager.get_current_store_manager().orphaned(*self.values())
     super().clear()
Ejemplo n.º 5
0
 def popitem(self):
     k, v = super().popitem()
     StoreManager.get_current_store_manager().orphaned(v)
     return k, v
Ejemplo n.º 6
0
 def pop(self, *args):
     i = super().pop(*args)
     StoreManager.get_current_store_manager().orphaned(i)
     return i
Ejemplo n.º 7
0
 def update(self, *a, **kw):
     StoreManager.get_current_store_manager().adopted(kw.values())
     super().update(*a, **kw)
Ejemplo n.º 8
0
 def setdefault(self, key, value):
     StoreManager.get_current_store_manager().adopted(value)
     return super().setdefault(key, value)
Ejemplo n.º 9
0
 def extend(self, x):
     StoreManager.get_current_store_manager().adopted(*x)
     super().extend([self.observe_item(i) for i in x])
Ejemplo n.º 10
0
 def insert(self, i, x):
     StoreManager.get_current_store_manager().adopted(x)
     super().insert(i, x)
Ejemplo n.º 11
0
 def extend(self, x):
     StoreManager.get_current_store_manager().adopted(*x)
     super().extend(x)
Ejemplo n.º 12
0
 def remove(self, i):
     super().remove(i)
     StoreManager.get_current_store_manager().orphaned(i)
Ejemplo n.º 13
0
 def append(self, x):
     super().append(x)
     StoreManager.get_current_store_manager().adopted(x)
Ejemplo n.º 14
0
    def attach(self,
               attachable: Attachable,
               content_type: str = None,
               original_filename: str = None,
               extension: str = None,
               store_id: str = None,
               overwrite: bool = False,
               suppress_pre_process: bool = False,
               suppress_validation: bool = False,
               **kwargs) -> 'Attachment':
        """
        Attach a file. if the session is rolled-back, all operations will be rolled-back.
        The old file will be deleted after commit, if any.

        Workflow::


                             +--------+
                             | Start  |
                             +---+----+
                                 |
                      +----------v-----------+
                      | Wrap with Descriptor <----+
                      +----------+-----------+    |
                                 |                |
                      +----------v-----------+    |
                      | Nothing or Analyze   |    |
                      +----------+-----------+    |
                                 |                |
                      +----------v-----------+    |
                      | Nothing or Validate  |    |
                      +----------+-----------+    |
                                 |                |
                      +----------v-----------+    |
                      |Nothing or Pre Process+----+
                      +------+---------------+
                             |
                  +----------+-----------+
                  |                      |
           +------v---------+  +---------v------+
           |  Store in DB   |  |Store In Storage|
           +------+---------+  +---------+------+
                  |                      |
                  +----------+-----------+
                             |
                             |
                         +---v----+
                         | Finish |
                         +--------+


        :param attachable: file-like object, filename or URL to attach.
        :param content_type: If given, the content-detection is suppressed.
        :param original_filename: Original name of the file, if available, to append to the end of the the filename, 
                                  useful for SEO, and readability.
        :param extension: The file's extension, is available.else, tries to guess it by content_type
        :param store_id: The store id to store this file on. Stores must be registered with appropriate id via
                         :meth:`sqlalchemy_media.stores.StoreManager.register`.
        :param overwrite: Overwrites the file without changing it's unique-key and name, useful to prevent broken links.
                          Currently, when using this option, Rollback function is not available, because the old file
                          will be overwritten by the given new one.
        :param suppress_pre_process: When is :data:`.True`, ignores the pre-processing phase, during attachment.
        :param suppress_validation: When is :data:`.True`, ignores the validation phase, during attachment.
        :param kwargs: Additional metadata to be stored in backend.

        .. note:: :exc:`.MaximumLengthIsReachedError` and or :exc:`.MinimumLengthIsNotReachedError` may be raised.

        .. warning:: This operation can not be rolled-back, if ``overwrite=True`` given.

        .. versionchanged:: 0.1

            - This method will return the self. it's useful to chain method calls on the object within a single line.
            - Additional ``kwargs`` are accepted to be stored in database alongside the file's metadata.

        .. versionchanged:: 0.5

            - ``suppress_pre_process`` argument.
            - ``suppress_validation`` argument.
            - pre-processing phase.

        """

        # Wrap in AttachableDescriptor
        descriptor = self.__descriptor__(attachable,
                                         content_type=content_type,
                                         original_filename=original_filename,
                                         extension=extension,
                                         max_length=self.__max_length__,
                                         min_length=self.__min_length__,
                                         reproducible=self.__reproducible__)

        try:

            # Backup the old key and filename if exists
            if overwrite:
                old_attachment = None
            else:
                old_attachment = None if self.empty else self.copy()
                self.key = str(uuid.uuid4())

            # Store information from descriptor
            attachment_info = kwargs.copy()
            attachment_info.update(
                original_filename=descriptor.original_filename,
                extension=descriptor.extension,
                content_type=descriptor.content_type,
                length=descriptor.content_length,
                store_id=store_id,
                reproducible=descriptor.reproducible)

            # Pre-processing
            if self.__pre_processors__:
                processors = self.__pre_processors__ if isinstance(self.__pre_processors__, Iterable) \
                    else [self.__pre_processors__]

                # noinspection PyTypeChecker
                for processor in processors:
                    processor.process(descriptor, attachment_info)

            # Updating the mutable dictionary
            self.update([(k, v) for k, v in attachment_info.items()
                         if v is not None])

            # Putting the file on the store.
            self['length'] = self.get_store().put(self.path, descriptor)

            self.timestamp = time.time()

            store_manager = StoreManager.get_current_store_manager()
            store_manager.register_to_delete_after_rollback(self)

            if old_attachment:
                store_manager.register_to_delete_after_commit(old_attachment)

        except:
            descriptor.close(check_length=False)
            raise

        else:
            descriptor.close()

        return self
Ejemplo n.º 15
0
 def __delitem__(self, key):
     StoreManager.get_current_store_manager().orphaned(self[key])
     super().__delitem__(key)
Ejemplo n.º 16
0
 def __delitem__(self, index):
     StoreManager.get_current_store_manager().orphaned(self[index])
     super().__delitem__(index)
Ejemplo n.º 17
0
 def __setitem__(self, key, value):
     StoreManager.get_current_store_manager().adopted(value)
     super().__setitem__(key, value)
Ejemplo n.º 18
0
 def append(self, x):
     super().append(self.observe_item(x))
     StoreManager.get_current_store_manager().adopted(x)