def handle(self, *args, **options): full = 'full' in args for gallery in Gallery.objects.all(): ImageStorage(gallery).clear_cache(full=full) ImageStorage(gallery, archive_cache=True).clear_cache(full=full) self.stdout.write('Clear cache for {0} galleries'.format( Gallery.objects.count()))
def images_view(request, gallery_id, album_id): gallery = Gallery.objects.safe_get(id=gallery_id, user=request.user) if not gallery: raise Http404() controller = AlbumController(gallery, request.user, uid=album_id) if not controller.exists(): return message_view(request, message='No such album') images = controller.get_images() storage = ImageStorage(gallery) path = request.GET.get('p', '') try: image_paths = storage.list(path, saved_images=images) folder = ImageFolder(path, image_paths) except FileError as e: logger.exception(e) return message_view(request, message=smart_text(e)) return render( request, 'profile/images.html', { 'gallery': gallery, 'album': controller.get_object(), 'folder': folder, 'title': 'Select images', })
def clean(self): """ Check path exists """ storage = ImageStorage(self.album.gallery) if not storage.exists(self.path): raise ValidationError( smart_text('No {0} path exists').format(self.path))
def check_album(self, gallery, album, report): counter = 0 images = Image.objects.filter(album=album).iterator() storage = ImageStorage(gallery) for image in images: image_path = storage.get_path(image.path) if not image_path.exists: counter += 1 report[album.title].append(image.path) return counter
def __init__(self, image_paths, gallery, name=None): """ :type image_paths: list of str :type gallery: bviewer.core.models.Gallery :type name: str """ self.gallery = gallery self.storage = ImageStorage(gallery, archive_cache=True) self.image_paths = [self.storage.get_path(i) for i in image_paths] self.name = name or self.uid options = ImageOptions(name=self.name) self.archive = self.storage.get_archive(options)
def test_method_for_cache(self): """ Test that method(path) and method(path, for_cache) retrun right values """ def assert_method_for_cache(patch_module, func, side_effect): with patch(patch_module) as mock: mock.configure_mock(side_effect=side_effect) image_path = os.path.normpath('path/img.jpg') for_root = os.path.normcase('root/home/path/img.jpg') self.assertEqual(func(image_path, for_cache=False), for_root) for_cache = os.path.normcase('cache/images/url/path/img.jpg') self.assertEqual(func(image_path, for_cache=True), for_cache) gallery = Mock(home='home', url='url', cache_size=0) # Storage pre create cache dir, fix it with patch('os.makedirs'): storage = ImageStorage(gallery, root_path='root', cache_path='cache') assert_method_for_cache('os.path.getctime', storage.ctime, side_effect=str) assert_method_for_cache('os.path.exists', storage.exists, side_effect=str) open_module = 'builtins.open' if six.PY3 else '__builtin__.open' assert_method_for_cache(open_module, storage.open, side_effect=lambda path, mode: str(path))
def setUp(self): self.gallery = Mock(home='gallery_home', url='gallery_url', cache_size=0) self.storage = ImageStorage(self.gallery) self.remove_storage_folders() self.create_storage_folders()
def update_time_from_exif(sender, instance, created, **kwargs): """ :type instance: Image """ if created: storage = ImageStorage(instance.album.gallery) set_time_from_exif(storage, instance, save=True)
def download_image(request, gallery_id): if request.GET.get('p', None): path = request.GET['p'] gallery = Gallery.objects.safe_get(id=gallery_id, user=request.user) storage = ImageStorage(gallery) options = ImageOptions.from_settings('tiny') image_path = storage.get_path(path, options) try: if image_path.exists: if not image_path.cache_exists: image = CacheImage(image_path) as_job(image.process) return download_response(image_path) err_msg = smart_text('Path not exists "{0}"').format(path) logger.info(err_msg) raise Http404(err_msg) except FileError as e: logger.info(e) raise Http404(e) raise Http404('No Image')
def cache_info(self, user): storage = ImageStorage(user) images_size = storage.cache_size() / 2**20 storage = ImageStorage(user, archive_cache=True) archive_size = storage.cache_size() / 2**20 return 'Images size: {0:.1f} MB, archives size: {1:.1f} MB'.format( images_size, archive_size)
class ZipArchiveController(object): STATUS_KEY_TIMOUT = 4 * 60 def __init__(self, image_paths, gallery, name=None): """ :type image_paths: list of str :type gallery: bviewer.core.models.Gallery :type name: str """ self.gallery = gallery self.storage = ImageStorage(gallery, archive_cache=True) self.image_paths = [self.storage.get_path(i) for i in image_paths] self.name = name or self.uid options = ImageOptions(name=self.name) self.archive = self.storage.get_archive(options) @property def status(self): """ Return status DONE, PROCESSING, NONE :rtype: str """ if self.archive.cache_exists: return 'DONE' if 0 <= self.progress <= 100: return 'PROCESSING' return 'NONE' @property @cache_method def uid(self): pack = [ self.gallery.home, ] for path in self.image_paths: if path.exists: pack.append(path.cache_name) return self.storage.hash_for(tuple(pack)) @property def _redis_uid(self): return 'bviewer.archive.status:{0}'.format(self.uid) @property def progress(self): """ Get progress from redis. Range 0..100, if None return -1. :rtype: int """ redis = get_redis_connection() value = redis.get(self._redis_uid) return int(value) if value is not None else -1 def process(self): """ Process if `self.status` == NONE Update redis progress each file. """ # local otherwise not pickle redis = get_redis_connection() if self.status == 'NONE': with self.archive.open(mode='w') as z: for i, image_path in enumerate(self.image_paths, start=1): # if file not exists - ignore if image_path.exists: with image_path.open(mode='rb') as f: z.writestr(image_path.name, f.read()) percent = int(float(i) / len(self.image_paths) * 100) redis.setex(self._redis_uid, value=percent, time=self.STATUS_KEY_TIMOUT) self.archive.rename_temp_cache() def add_job(self): """ Send task to RQ `low` queue """ as_job(self.process, queue='low', waite=False)
def update_time_from_exif(model_admin, request, queryset): for image in queryset: storage = ImageStorage(image.album.gallery) set_time_from_exif(storage, image, save=True)
def size_for_gallery(self, gallery, stat): albums = Album.objects.filter(gallery=gallery).iterator() storage = ImageStorage(gallery) for album in albums: self.size_for_album(storage, album, stat)