Exemple #1
0
    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
Exemple #2
0
	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)
Exemple #3
0
    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 ''
Exemple #4
0
	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)
Exemple #5
0
	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
Exemple #6
0
    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()
Exemple #7
0
    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)
Exemple #8
0
    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]
Exemple #9
0
 def __init__(self, slug):
     self.slug = slug
     self._album = Album.objects(user=current_user.id, slug=self.slug)
Exemple #10
0
	def get():
		albums = Album.objects(user=current_user.id).order_by('-created')
		return albums
Exemple #11
0
 def __init__(self, album_id: str):
     self.album = Album.objects(id=album_id, user=current_user.id).first()