Skip to content

Commit

Permalink
Warming up to migrate to PIL, pylover#112
Browse files Browse the repository at this point in the history
  • Loading branch information
pylover committed Aug 3, 2018
1 parent 37f1a81 commit 1ecded4
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 47 deletions.
4 changes: 2 additions & 2 deletions requirements-optional.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
python-magic >= 0.4.12
wand >= 0.4.3
pillow
requests
Werkzeug
requests-aws4auth >= 0.9
requests-aliyun >= 0.2.5
paramiko
paramiko
48 changes: 26 additions & 22 deletions sqlalchemy_media/attachments.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from .descriptors import AttachableDescriptor
from .exceptions import ThumbnailIsNotAvailableError
from .helpers import validate_width_height_ratio
from .imaginglibs import get_image_factory
from .stores import StoreManager, Store
from .typing_ import Attachable, Dimension

Expand Down Expand Up @@ -226,8 +225,8 @@ def content_type(self) -> str:
@property
def original_filename(self) -> str:
"""
Original file name, it may be provided by user within :attr:`cgi.FieldStorage.filename`,
url or Physical filename.
Original file name, it may be provided by user within
:attr:`cgi.FieldStorage.filename`, url or Physical filename.
:type: str
"""
Expand Down Expand Up @@ -273,7 +272,8 @@ def copy(self) -> 'Attachment':

def get_store(self) -> Store:
"""
Returns the :class:`sqlalchemy_media.stores.Store` instance, which this file is stored on.
Returns the :class:`sqlalchemy_media.stores.Store` instance, which
this file is stored on.
"""
store_manager = StoreManager.get_current_store_manager()
Expand All @@ -283,9 +283,10 @@ def delete(self) -> None:
"""
Deletes the file.
.. warning:: This operation can not be roll-backed.So if you want to delete a file,
just set it to :const:`None` or set it by new :class:`.Attachment` instance,
while passed ``delete_orphan=True`` in :class:`.StoreManager`.
.. warning:: This operation can not be roll-backed.So if you want to
delete a file, just set it to :const:`None` or set it by
new :class:`.Attachment` instance, while passed
``delete_orphan=True`` in :class:`.StoreManager`.
"""
self.get_store().delete(self.path)
Expand All @@ -302,8 +303,8 @@ def attach(
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.
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::
Expand Down Expand Up @@ -510,17 +511,20 @@ class Person(BaseModel):

def observe_item(self, item):
"""
A simple monkeypatch to instruct the children to notify the parent if contents are changed:
A simple monkeypatch to instruct the children to notify the parent if
contents are changed:
From `sqlalchemy mutable documentation:
<http://docs.sqlalchemy.org/en/latest/orm/extensions/mutable.html#sqlalchemy.ext.mutable.MutableList>`_
From `sqlalchemy mutable documentation: <http://docs.sqlalchemy.org/en
/latest/orm/extensions/mutable.html#sqlalchemy.ext.mutable.MutableLis
t>`_
Note that MutableList does not apply mutable tracking to the values themselves inside
the list. Therefore it is not a sufficient solution for the use case of tracking deep
changes to a recursive mutable structure, such as a JSON structure. To support this
use case, build a subclass of MutableList that provides appropriate coercion to the
values placed in the dictionary so that they too are “mutable”, and emit events up to
their parent structure.
Note that MutableList does not apply mutable tracking to the values
themselves inside the list. Therefore it is not a sufficient
solution for the use case of tracking deep changes to a recursive
mutable structure, such as a JSON structure. To support this
use case, build a subclass of MutableList that provides appropriate
coercion to the values placed in the dictionary so that they too
are “mutable”, and emit events up to their parent structure.
:param item: The item to observe
:return:
Expand Down Expand Up @@ -660,8 +664,8 @@ def __setitem__(self, key, value):

class File(Attachment):
"""
Representing an attached file. Normally if you want to store any file, this class is
the best choice.
Representing an attached file. Normally if you want to store any file,
this class is the best choice.
"""

Expand Down Expand Up @@ -703,8 +707,8 @@ class BaseImage(File):

def attach(self, *args, dimension: Dimension = None, **kwargs):
"""
A new overload for :meth:`.Attachment.attach`, which accepts one additional
argument: ``dimension``.
A new overload for :meth:`.Attachment.attach`, which accepts one
additional argument: ``dimension``.
:param args: The same as the: :meth:`.Attachment.attach`.
:param dimension: Image (width, height).
Expand Down
15 changes: 0 additions & 15 deletions sqlalchemy_media/imaginglibs.py

This file was deleted.

12 changes: 4 additions & 8 deletions sqlalchemy_media/processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from .exceptions import ContentTypeValidationError, DimensionValidationError, \
AspectRatioValidationError, AnalyzeError
from .helpers import validate_width_height_ratio, deprecated
from .imaginglibs import get_image_factory
from .mimetypes_ import guess_extension
from .optionals import magic_mime_from_buffer, ensure_wand
from .typing_ import Dimension
Expand Down Expand Up @@ -428,12 +427,10 @@ def __init__(self, fmt: str = None, width: int = None, height: int = None, crop=

def process(self, descriptor: StreamDescriptor, context: dict):

from .imaginglibs import get_image_factory

Image = get_image_factory()
from PIL import Image as PilImage
# Copy the original info
# generating thumbnail and storing in buffer
img = Image(file=descriptor)
img = PilImage(file=descriptor)

is_invalid_format = self.format is None or img.format == self.format
is_invalid_size = (
Expand Down Expand Up @@ -517,12 +514,11 @@ class ImageAnalyzer(Analyzer):

def process(self, descriptor: StreamDescriptor, context: dict):

Image = get_image_factory()

from PIL import Image as PilImage
# This processor requires seekable stream.
descriptor.prepare_to_read(backend='memory')

with Image(file=descriptor)as img:
with PilImage.open(descriptor)as img:
context.update(
width=img.width,
height=img.height,
Expand Down

0 comments on commit 1ecded4

Please sign in to comment.