def stream(page) -> dict: pipeline = [{ '$unwind': { 'path': '$photos' } }, { '$sort': { 'photos.created': -1 } }, { '$skip': (page - 1) * Config.IMG_PER_PAGE }, { '$limit': Config.IMG_PER_PAGE }] photos = Album.objects(user=current_user.id).aggregate(*pipeline) # подсчет кол-ва страниц для пагинации pipeline = [{'$unwind': {'path': '$photos'}}, {'$count': 'total'}] photos_total = Album.objects(user=current_user.id).aggregate(*pipeline) pages_total = ceil( int(list(photos_total)[0].get('total', 1)) / Config.IMG_PER_PAGE) result = { 'photos': list(photos), 'pages_total': pages_total, 'current_page': page, } return result
def get(self): album = Album.objects(id=self.album_id, user=current_user.id).first() case = { 'min': Config.MIN_PHOTOS_DIR, 'max': Config.UPLOADS_DEFAULT_DEST, 'full': Config.UPLOADS_DEFAULT_DEST } if album: file = os.path.join(case.get(self.filetype), str(current_user.id), album.slug, self.filename) # ресайз картинки if self.filetype == 'max': img = PilImage.open(file, mode='r') ratio = (Config.MAX_WIDTH / float(img.size[0])) height = int((float(img.size[1]) * float(ratio))) img = img.resize((Config.MAX_WIDTH, height), PIL.Image.ANTIALIAS) rgb_im = img.convert('RGB') img_response = io.BytesIO() rgb_im.save(img_response, 'JPEG') img_response.seek(0) else: img_response = file else: img_response = os.path.join(Config.BASE_DIR, 'static/images/forbidden.jpg') if self.filetype != 'full': as_attachment = False else: as_attachment = True return send_file(img_response, mimetype='image/jpeg', as_attachment=as_attachment)
def delete(self) -> str: album = Album.objects(id=self.album_id, user=current_user.id) if album.first(): album.update_one( __raw__={'$pull': { 'photos': { 'file': self.file } }}) album = album.first() path_max = os.path.join(Config.UPLOADS_DEFAULT_DEST, str(current_user.id), album.slug, self.file) path_min = os.path.join(Config.DEFAULT_MIN_DIR, str(current_user.id), album.slug, self.file) try: os.remove(path_max) os.remove(path_min) except FileNotFoundError: pass return album.slug else: return ''
def upload(): path = os.path.join(Config.UPLOADS_DEFAULT_DEST, str(current_user.id), request.form.get('slug')) path_min = os.path.join(Config.DEFAULT_MIN_DIR, str(current_user.id), request.form.get('slug')) # создаем директорию для фоток, если ее нет if not os.path.isdir(path): os.makedirs(path) # создаем директорию для миниатюр, если ее нет if not os.path.isdir(path_min): os.makedirs(path_min) album = Album.objects(slug=request.form.get('slug', ''), user=current_user.id).get() photos_list = album.photos for img in request.files.getlist("images"): if img.filename: file_path = photos.save(img, folder=path) filename = file_path.split('/')[-1] image = PilImage.open(file_path) exif_data = image.getexif() device = None created = None for tag_id in exif_data: tag = TAGS.get(tag_id, tag_id) data = exif_data.get(tag_id) try: if isinstance(data, bytes): data = data.decode() if f"{tag:25}".find('Model') == 0: device = data if f"{tag:25}".find('DateTimeOriginal') == 0: created = data except: pass ratio = (Config.WIDTH / float(image.size[0])) height = int((float(image.size[1]) * float(ratio))) image = image.resize((Config.WIDTH, height), PIL.Image.ANTIALIAS) file_min_path = image.save(os.path.join(path_min, filename)) photo = Photo() photo.file = filename photo.device = device if created: photo.created = datetime.strptime(created, '%Y:%m:%d %H:%M:%S') photos_list.append(photo) # сортируем фотографии по дате создания в обратном порядке try: photos_list = sorted(photos_list, key=itemgetter('created'), reverse=True) except TypeError: photos_list = sorted(photos_list, key=itemgetter('file')) album.update(photos=photos_list)
def filter(self) -> list: photos = [] album = Album.objects(slug=self.album_slug, user=current_user.id) if album.first(): pipelines = [ {'$unwind': {'path': '$photos', 'includeArrayIndex': 'counter'}}, {'$match': {'photos.device': self.camera}} ] photos = list(album.aggregate(*pipelines)) return photos
def delete(self) -> None: album = Album.objects(id=self.album_id, user=current_user.id).first() if album: path = os.path.join(Config.UPLOADS_DEFAULT_DEST, str(current_user.id), album.slug) try: shutil.rmtree(path) except FileNotFoundError: pass album.delete()
def cover(self): album = Album.objects(id=self.album_id, user=current_user.id).first() try: photo = album.photos[0] photo_path = os.path.join(Config.UPLOADS_DEFAULT_DEST, str(current_user.id), album.slug, photo.file) img = PilImage.open(photo_path, mode='r') ratio = (Config.ALBUM_COVER / float(img.size[0])) ratio_h = (Config.ALBUM_COVER / float(img.size[1])) height = int((float(img.size[1]) * float(ratio))) width = int((float(img.size[0]) * float(ratio_h))) if img.size[0] >= img.size[1]: img = img.resize((Config.ALBUM_COVER, height), PIL.Image.ANTIALIAS) else: img = img.resize((width, Config.ALBUM_COVER), PIL.Image.ANTIALIAS) width, height = img.size left = (width - Config.ALBUM_COVER) // 2 top = (height - Config.ALBUM_COVER) // 2 right = (width + Config.ALBUM_COVER) // 2 bottom = (height + Config.ALBUM_COVER) // 2 img = img.crop((left, top, right, bottom)) rgb_im = img.convert('RGB') img_response = io.BytesIO() rgb_im.save(img_response, 'JPEG') img_response.seek(0) return send_file(img_response, attachment_filename='cover.jpg', mimetype='image/jpg', cache_timeout=-1) except IndexError: default = os.path.join(Config.BASE_DIR, 'static', 'images', 'cover.jpg') return send_file(default, attachment_filename='cover.jpg', mimetype='image/jpg', cache_timeout=-1)
def show(self) -> list: album = Album.objects(id=self.album_id, user=current_user.id, photos__file=self.file) if album.first(): pipeline = [{ '$unwind': { 'path': '$photos', 'includeArrayIndex': 'counter' } }] # выбираем конкретно запрашиваемую фотографию photo = album.aggregate(*pipeline, {'$match': { 'photos.file': self.file }}) photo = list(photo)[0] # предыдущая и следующая фотографии в альбоме photo_prev = album.aggregate( *pipeline, {'$match': { 'counter': photo.get('counter') - 1 }}) photo_next = album.aggregate( *pipeline, {'$match': { 'counter': photo.get('counter') + 1 }}) else: photo = [] photo_prev = [] photo_next = [] try: photo_prev = list(photo_prev)[0] except IndexError: photo_prev = [] photo_prev.append({'photos': []}) photo_prev = photo_prev[0] try: photo_next = list(photo_next)[0] except IndexError: photo_next = [] photo_next.append({'photos': []}) photo_next = photo_next[0] return [photo, photo_prev, photo_next]
def __init__(self, slug): self.slug = slug self._album = Album.objects(user=current_user.id, slug=self.slug)
def get(): albums = Album.objects(user=current_user.id).order_by('-created') return albums
def __init__(self, album_id: str): self.album = Album.objects(id=album_id, user=current_user.id).first()