def test_public_base_url_strip(self): public_base_url = 'http://test.sqlalchemy.media/' StoreManager.register( 's3', lambda: _get_s3_store(public_base_url=public_base_url), default=True) class Person(self.Base): __tablename__ = 'person' id = Column(Integer, primary_key=True) file = Column(File.as_mutable(Json)) session = self.create_all_and_get_session() person1 = Person() self.assertIsNone(person1.file) sample_content = b'Simple text.' with StoreManager(session): person1 = Person() person1.file = File.create_from(io.BytesIO(sample_content), content_type='text/plain', extension='.txt') self.assertIsInstance(person1.file, File) self.assertEqual( person1.file.locate(), '%s/%s?_ts=%s' % (public_base_url.rstrip('/'), person1.file.path, person1.file.timestamp))
def test_cdn_url_with_prefix(self): prefix = 'media' cdn_url = 'http//test.sqlalchemy-media.com' with mockup_s3_server(TEST_BUCKET) as (server, uri): StoreManager.register( 's3', functools.partial( create_s3_store, prefix=prefix, base_url=uri, cdn_url=cdn_url ), default=True ) class Person(self.Base): __tablename__ = 'person' id = Column(Integer, primary_key=True) file = Column(File.as_mutable(Json)) session = self.create_all_and_get_session() person1 = Person() self.assertIsNone(person1.file) sample_content = b'Simple text.' with StoreManager(session): person1 = Person() person1.file = File.create_from(io.BytesIO(sample_content), content_type='text/plain', extension='.txt') self.assertIsInstance(person1.file, File) self.assertEqual(person1.file.locate(), '%s/%s/%s?_ts=%s' % ( cdn_url, prefix, person1.file.path, person1.file.timestamp) )
def test_rrs_put(self): with mockup_s3_server(TEST_BUCKET) as (server, uri): StoreManager.register( 's3', functools.partial(create_s3_store, base_url=uri), default=True ) class Thumbnail(BaseThumbnail): __reproducible__ = True class Image(BaseImage): __thumbnail_type__ = Thumbnail class Person(self.Base): __tablename__ = 'person' id = Column(Integer, primary_key=True) image = Column(Image.as_mutable(Json)) session = self.create_all_and_get_session() person1 = Person() self.assertIsNone(person1.image) with StoreManager(session): person1 = Person() person1.image = Image.create_from(self.dog_jpeg) self.assertIsInstance(person1.image, Image) thumbnail = person1.image.get_thumbnail( width=100, auto_generate=True ) self.assertIsInstance(thumbnail, Thumbnail) self.assertTrue(thumbnail.reproducible, True)
def test_image_thumbnail_pre_generate(self): """ Issue #72 :return: """ class Person(self.Base): __tablename__ = 'person' id = Column(Integer, primary_key=True) image = Column(Image.as_mutable(Json), nullable=True) session = self.create_all_and_get_session() # person1 = Person(name='person1') person1 = Person() self.assertIsNone(person1.image) with StoreManager(session): person1.image = Image.create_from(self.dog_jpeg) person1.image.generate_thumbnail(width=100) session.add(person1) session.commit() session = self.create_all_and_get_session() person1 = session.query(Person).filter(Person.id == person1.id).one() with StoreManager(session): self.assertTrue(person1.image.locate().startswith( 'http://static1.example.orm/images/image-')) thumbnail = person1.image.get_thumbnail(width=100) self.assertTrue(thumbnail.locate().startswith( 'http://static1.example.orm/thumbnails/thumbnail-'))
def test_prefix(self): prefix = 'test' StoreManager.register('s3', lambda: _get_s3_store(prefix=prefix), default=True) class Person(self.Base): __tablename__ = 'person' id = Column(Integer, primary_key=True) file = Column(File.as_mutable(Json)) session = self.create_all_and_get_session() person1 = Person() self.assertIsNone(person1.file) sample_content = b'Simple text.' with StoreManager(session): person1 = Person() person1.file = File.create_from(io.BytesIO(sample_content), content_type='text/plain', extension='.txt') self.assertIsInstance(person1.file, File) self.assertEqual( person1.file.locate(), '%s/%s/%s?_ts=%s' % (TEST_SERVER_URL, prefix, person1.file.path, person1.file.timestamp))
def test_public_base_url_strip(self): with mockup_s3_server(TEST_BUCKET) as (server, uri): base_url = '%s/' % uri StoreManager.register( 's3', functools.partial(create_s3_store, base_url=base_url), default=True ) class Person(self.Base): __tablename__ = 'person' id = Column(Integer, primary_key=True) file = Column(File.as_mutable(Json)) session = self.create_all_and_get_session() person1 = Person() self.assertIsNone(person1.file) sample_content = b'Simple text.' with StoreManager(session): person1 = Person() person1.file = File.create_from(io.BytesIO(sample_content), content_type='text/plain', extension='.txt') self.assertIsInstance(person1.file, File) self.assertEqual(person1.file.locate(), '%s%s?_ts=%s' % ( base_url, person1.file.path, person1.file.timestamp))
def test_context_stack(self): self.assertRaises(ContextError, StoreManager.get_current_store_manager) with StoreManager(Session) as manager1: store1 = manager1.get() self.assertIs(store1, manager1.default_store) with StoreManager(Session) as manager2: store2 = manager2.get() self.assertIs(store2, manager2.default_store) self.assertIsNot(manager1, manager2) self.assertIsNot(store1, store2)
def run(self): with StoreManager(Session) as manager1: store1 = manager1.get() self.test_case.assertIs(store1, manager1.default_store) self.stat.store1 = store1 with StoreManager(Session) as manager2: store2 = manager2.get() self.test_case.assertIs(store2, manager2.default_store) self.stat.store2 = store2 self.stat.ready = True while self.stat.wait: time.sleep(.7)
def test_default_store(self): with StoreManager(Session) as manager1: # Hacking StoreManager to raise error StoreManager._default = None self.assertRaises(DefaultStoreError, manager1.get) # making it default again StoreManager.make_default('dummy') self.assertIsNotNone(manager1.get()) # unregister StoreManager.unregister('dummy')
def test_delete_orphan(self): class Person(self.Base): __tablename__ = 'person' id = Column(Integer, primary_key=True) cv = Column(File.as_mutable(Json), nullable=True) session = self.create_all_and_get_session() person1 = Person() self.assertIsNone(person1.cv) with StoreManager(session, delete_orphan=True): # First file before commit person1.cv = File.create_from(BytesIO(b'Simple text.'), content_type='text/plain', extension='.txt') self.assertIsInstance(person1.cv, File) first_filename = join(self.temp_path, person1.cv.path) self.assertTrue(exists(first_filename)) person1.cv = File.create_from(BytesIO(b'Second simple text.')) second_filename = join(self.temp_path, person1.cv.path) self.assertTrue(exists(first_filename)) self.assertTrue(exists(second_filename)) session.add(person1) session.commit() self.assertFalse(exists(first_filename)) self.assertTrue(exists(second_filename))
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)
def test_delete_orphan_list(self): class Person(self.Base): __tablename__ = 'person' id = Column(Integer, primary_key=True) files = Column(FileList.as_mutable(Json)) session = self.create_all_and_get_session() with StoreManager(session, delete_orphan=True): person1 = Person() person1.files = FileList([ File.create_from(BytesIO(b'simple text %d' % i)) for i in range(2) ]) # Removing the first file first_filename = join(self.temp_path, person1.files[0].path) second_filename = join(self.temp_path, person1.files[1].path) person1.files = FileList([ File.create_from(BytesIO(b'New test file: %d' % i)) for i in range(2) ]) session.add(person1) session.commit() self.assertFalse(exists(first_filename)) self.assertFalse(exists(second_filename)) first_filename = join(self.temp_path, person1.files[0].path) second_filename = join(self.temp_path, person1.files[1].path) self.assertTrue(exists(first_filename)) self.assertTrue(exists(second_filename))
def test_delete_orphan_dict_item(self): class Person(self.Base): __tablename__ = 'person' id = Column(Integer, primary_key=True) files = Column(FileDict.as_mutable(Json)) session = self.create_all_and_get_session() with StoreManager(session, delete_orphan=True): person1 = Person() person1.files = FileDict({ str(i): File.create_from(BytesIO(b'simple text %d' % i)) for i in range(2) }) # Removing the first file first_filename = join(self.temp_path, person1.files['0'].path) del person1.files['0'] session.add(person1) session.commit() self.assertFalse(exists(first_filename)) # noinspection PyTypeChecker self.assertEqual(len(person1.files), 1) # Loading from db person1 = session.query(Person).one() # Preserving the first file's path first_filename = join(self.temp_path, person1.files['1'].path) # Clearing person1.files.clear() session.commit() self.assertFalse(exists(first_filename)) self.assertEqual(len(person1.files), 0)
def test_thumbnail_delete(self): class Person(self.Base): __tablename__ = 'person' id = Column(Integer, primary_key=True) image = Column(Image.as_mutable(Json), nullable=True) session = self.create_all_and_get_session() # person1 = Person(name='person1') person1 = Person() self.assertIsNone(person1.image) with StoreManager(session, delete_orphan=True): person1.image = Image.create_from(self.dog_jpeg) session.add(person1) session.commit() thumbnail = person1.image.get_thumbnail(width=100, auto_generate=True) self.assertIsInstance(thumbnail, Thumbnail) image_filename = join(self.temp_path, person1.image.path) self.assertTrue(exists(image_filename)) first_thumbnail_filename = join(self.temp_path, thumbnail.path) self.assertTrue(exists(first_thumbnail_filename)) session.delete(person1) session.commit() self.assertFalse(exists(image_filename)) self.assertFalse(exists(first_thumbnail_filename))
def test_file_assignment(self): class Person(self.Base): __tablename__ = 'person' id = Column(Integer, primary_key=True) cv = Column(AutoCoerceFile.as_mutable(Json)) session = self.create_all_and_get_session() person1 = Person() resume = io.BytesIO(b'This is my resume') with StoreManager(session): person1.cv = resume self.assertIsNone(person1.cv.content_type) self.assertIsNone(person1.cv.extension) self.assertTrue(exists(join(self.temp_path, person1.cv.path))) person1.cv = resume, 'text/plain' self.assertEqual(person1.cv.content_type, 'text/plain') self.assertEqual(person1.cv.extension, '.txt') self.assertTrue(exists(join(self.temp_path, person1.cv.path))) person1.cv = resume, 'text/plain', 'myfile.note' self.assertEqual(person1.cv.content_type, 'text/plain') self.assertEqual(person1.cv.extension, '.note') self.assertTrue(exists(join(self.temp_path, person1.cv.path)))
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)
def test_delete_orphan_list_item(self): class Person(self.Base): __tablename__ = 'person' id = Column(Integer, primary_key=True) files = Column(FileList.as_mutable(Json)) session = self.create_all_and_get_session() with StoreManager(session, delete_orphan=True): person1 = Person() person1.files = FileList() person1.files.append(File.create_from(BytesIO(b'simple text 1'))) person1.files.append(File.create_from(BytesIO(b'simple text 2'))) person1.files.append(File.create_from(BytesIO(b'simple text 3'))) # Removing the first file first_filename = join(self.temp_path, person1.files[0].path) person1.files.remove(person1.files[0]) session.add(person1) session.commit() self.assertFalse(exists(first_filename)) # noinspection PyTypeChecker self.assertEqual(len(person1.files), 2) # Loading from db person1 = session.query(Person).one() # Preserving the first file's path first_filename = join(self.temp_path, person1.files[0].path) # remove from orphan list f = person1.files[1] person1.files.remove(f) person1.files.insert(1, f) self.assertEqual(len(person1.files), 2) # Removing the first file del person1.files[0] session.commit() self.assertFalse(exists(first_filename)) self.assertEqual(len(person1.files), 1) old_attachment_filename = join(self.temp_path, person1.files[0].path) attachment = person1.files[0].attach( BytesIO(b'Changed inside nested mutable!')) attachment_filename = join(self.temp_path, attachment.path) self.assertTrue(exists(old_attachment_filename)) self.assertTrue(exists(attachment_filename)) session.commit() self.assertFalse(exists(old_attachment_filename)) self.assertTrue(exists(attachment_filename))
def test_image_list(self): class Person(self.Base): __tablename__ = 'person' id = Column(Integer, primary_key=True) images = Column(ImageList.as_mutable(Json)) session = self.create_all_and_get_session() with StoreManager(session, delete_orphan=True): person1 = Person() person1.images = ImageList() person1.images.append(Image.create_from(self.dog_jpeg)) person1.images.append(Image.create_from(self.cat_jpeg)) session.add(person1) session.commit() person1 = session.query(Person).one() self.assertEqual(len(person1.images), 2) for f in person1.images: self.assertIsInstance(f, Image) filename = join(self.temp_path, f.path) self.assertTrue(exists(filename)) self.assertEqual( f.locate(), '%s/%s?_ts=%s' % (self.base_url, f.path, f.timestamp)) # Overwriting the first image first_filename = join(self.temp_path, person1.images[0].path) person1.images[0].attach(self.dog_png) first_new_filename = join(self.temp_path, person1.images[0].path) session.commit() self.assertFalse(exists(first_filename)) self.assertTrue(exists(first_new_filename)) person1 = session.query(Person).one() # Generating a thumbnail for the first image thumbnail = person1.images[0].get_thumbnail(width=10, auto_generate=True) session.commit() thumbnail_filename = join(self.temp_path, thumbnail.path) self.assertTrue(exists(thumbnail_filename)) # Removing the image should force to orphanage the thumbnails. del person1.images[0] session.commit() self.assertFalse(exists(thumbnail_filename))
def test_pre_process(self): class Banner(Image): __pre_processors__ = ImageProcessor(fmt='jpeg', width=300) class Person(self.Base): __tablename__ = 'person' id = Column(Integer, primary_key=True) image = Column(Banner.as_mutable(Json), nullable=True) session = self.create_all_and_get_session() # person1 = Person(name='person1') person1 = Person() self.assertIsNone(person1.image) with StoreManager(session): person1.image = Banner.create_from(self.cat_png) self.assertEqual(person1.image.content_type, 'image/jpeg')
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)
def test_image(self): class Person(self.Base): __tablename__ = 'person' id = Column(Integer, primary_key=True) image = Column(Image.as_mutable(Json), nullable=True) session = self.create_all_and_get_session() # person1 = Person(name='person1') person1 = Person() self.assertIsNone(person1.image) with StoreManager(session): person1.image = Image.create_from(self.dog_jpeg) self.assertEqual(person1.image.content_type, 'image/jpeg') self.assertEqual(person1.image.extension, '.jpg') self.assertTrue(exists(join(self.temp_path, person1.image.path))) person1.image = Image.create_from(self.dog_png) self.assertEqual(person1.image.content_type, 'image/png') self.assertTrue(exists(join(self.temp_path, person1.image.path)))
def test_delete_orphan_image(self): """ https://github.com/pylover/sqlalchemy-media/issues/81 """ class Person(self.Base): __tablename__ = 'person' id = Column(Integer, primary_key=True) pic = Column(Image.as_mutable(Json), nullable=True) session = self.create_all_and_get_session() with StoreManager(session, delete_orphan=True): person1 = Person() person1.pic = Image.create_from(self.cat_jpeg) first_filename = join(self.temp_path, person1.pic.path) session.commit() self.assertTrue(exists(first_filename)) person1.pic = Image.create_from(self.dog_jpeg) session.commit() self.assertFalse(exists(first_filename))
def _listen_on_attribute(cls, attribute, coerce, parent_cls): StoreManager.observe_attribute(attribute) super()._listen_on_attribute(attribute, coerce, parent_cls)
def popitem(self): k, v = super().popitem() StoreManager.get_current_store_manager().orphaned(v) return k, v
def pop(self, *args): i = super().pop(*args) StoreManager.get_current_store_manager().orphaned(i) return i
def clear(self): StoreManager.get_current_store_manager().orphaned(*self.values()) super().clear()
def __delitem__(self, key): StoreManager.get_current_store_manager().orphaned(self[key]) super().__delitem__(key)
def __setitem__(self, key, value): StoreManager.get_current_store_manager().adopted(value) super().__setitem__(key, value)
def test_thumbnail(self): class Person(self.Base): __tablename__ = 'person' id = Column(Integer, primary_key=True) image = Column(Image.as_mutable(Json), nullable=True) session = self.create_all_and_get_session() # person1 = Person(name='person1') person1 = Person() self.assertIsNone(person1.image) with StoreManager(session): person1.image = Image.create_from(self.dog_jpeg) session.add(person1) # Getting an unavailable thumbnail. self.assertRaises(ThumbnailIsNotAvailableError, person1.image.get_thumbnail, width=100) # Auto generate thumbnail = person1.image.get_thumbnail(width=100, auto_generate=True) self.assertIsInstance(thumbnail, Thumbnail) self.assertEqual(thumbnail.content_type, 'image/jpeg') self.assertEqual(thumbnail.extension, '.jpg') self.assertEqual(thumbnail.width, 100) self.assertEqual(thumbnail.height, 75) first_thumbnail_filename = join(self.temp_path, thumbnail.path) self.assertTrue(exists(first_thumbnail_filename)) self.assertIsNotNone(person1.image.get_thumbnail(width=100)) self.assertIsNotNone(person1.image.get_thumbnail(height=75)) # Generate thumbnail with height thumbnail = person1.image.generate_thumbnail(height=20) self.assertEqual(thumbnail.width, 26) second_thumbnail_filename = join(self.temp_path, thumbnail.path) self.assertTrue(exists(second_thumbnail_filename)) self.assertIsNotNone(person1.image.get_thumbnail(width=26)) self.assertIsNotNone(person1.image.get_thumbnail(height=20)) # Generate thumbnail with ratio thumbnail = person1.image.generate_thumbnail(ratio=1 / 3) self.assertEqual(thumbnail.width, 213) self.assertEqual(thumbnail.height, 160) third_thumbnail_filename = join(self.temp_path, thumbnail.path) self.assertTrue(exists(third_thumbnail_filename)) self.assertIsNotNone(person1.image.get_thumbnail(ratio=1 / 3)) self.assertIsNotNone(person1.image.get_thumbnail(width=213)) self.assertIsNotNone(person1.image.get_thumbnail(height=160)) # Exceptions self.assertRaises(ValueError, person1.image.generate_thumbnail) self.assertRaises(ValueError, person1.image.generate_thumbnail, width=10, height=10) self.assertRaises(ValueError, person1.image.generate_thumbnail, width=10, ratio=.1) self.assertRaises(ValueError, person1.image.generate_thumbnail, height=10, ratio=.1) self.assertRaises(ValueError, person1.image.generate_thumbnail, ratio=1.1) self.assertRaises(ValueError, person1.image.generate_thumbnail, width=0) self.assertRaises(ValueError, person1.image.generate_thumbnail, height=0) self.assertRaises(TypeError, person1.image.generate_thumbnail, width='a') self.assertRaises(TypeError, person1.image.generate_thumbnail, height='a') self.assertRaises(TypeError, person1.image.generate_thumbnail, ratio='a') session.commit() # Issue 94, Cannot reproduce same_person = session.query(Person) \ .filter(Person.id == person1.id) \ .one() self.assertEqual(3, len(same_person.image['thumbnails'])) # Attaching new image must deletes all thumbnails: issue: #54 with StoreManager(session): person1.image.attach(self.cat_png) session.commit() self.assertFalse(exists(first_thumbnail_filename)) self.assertFalse(exists(second_thumbnail_filename)) self.assertFalse(exists(third_thumbnail_filename)) self.assertFalse(person1.image.thumbnails)
def setUp(self): StoreManager.register('dummy', DummyStore, default=True)