Files
pillar-python-sdk/pillarsdk/files.py
Sybren A. Stüvel a9920fa76a Files: Get thumbnails from variations, rather than from 'link' property
The 'link' property might not exist, for example when a user is not a
Cloud subscriber.
2016-05-10 12:45:27 +02:00

144 lines
5.0 KiB
Python
Executable File

import os.path
from .resource import List
from .resource import Find
from .resource import Create
from .resource import Post
from .resource import Update
from .resource import Delete
from .resource import Replace
from . import utils
THUMBNAIL_SIZES = 'sbtmlh'
class File(List, Find, Create, Post, Update, Delete, Replace):
"""Node class wrapping the REST nodes endpoint
"""
path = "files"
file_server_path = "file_storage/file"
build_previews_server_path = "file_storage/build_previews"
ensure_query_projections = {'backend': 1, 'file_path': 1, 'project': 1, 'content_type': 1,
'link': 1, 'link_expires': 1}
def post_file(self, file_path, name=None, api=None):
"""Stores a file on the database or static folder.
:param file: A file object
"""
api = api or self.api
url = utils.join_url(self.file_server_path)
file_ = open(file_path, 'rb')
files = {'data': file_}
api.post(url, {"name": name}, {}, files)
file_.close()
# self.error = None
# self.merge(new_attributes)
return self.success()
def build_previews(self, path, api=None):
"""Stores a file on the database or static folder.
:param path: A file path
"""
api = api or self.api
url = utils.join_url(self.build_previews_server_path, path)
api.get(url)
return self.success()
# def children(self, api=None):
# """Collect children (variations) of the current file. Used to connect
# different resolutions of the same picture, or multiple versions of the
# same video in different formats/containers.
# TODO: add params to support pagination.
# """
# api = api or self.api
# files = self.all({'where': '{"parent": "%s"}' % self._id}, api=api)
# if not files._items:
# return None
# return files
def thumbnail(self, size, api=None):
"""Utility to replace a component of an image link so that it points to
a thumbnail, without querying the database.
"""
if size not in THUMBNAIL_SIZES:
raise ValueError("Size should be in ({}), not {}"
.format(', '.join(THUMBNAIL_SIZES), size))
if self.variations:
thumbnail = next((item for item in self['variations']
if item['size'] == size), None)
if thumbnail:
return thumbnail['link']
if self.backend == 'gcs':
thumbnail_link = self.thumbnail_file(size, api=api)
return thumbnail_link
if self.link:
root, ext = os.path.splitext(self.link)
return "{0}-{1}.jpg".format(root, size)
return None
def thumbnail_file(self, size, api=None):
"""Delivers a single thumbnail (child) file for an image. Before returning
we check that the parent is actually an image.
:param path: the size (s, b, t, m, l, h)
@returns: a link to the thumbnail, or None if there is no thumbnail
@rtype: str
"""
api = api or self.api
if size not in THUMBNAIL_SIZES:
raise ValueError("Size should be in ({}), not {}"
.format(', '.join(THUMBNAIL_SIZES), size))
# We check from the content_type if the file is an image
if self.content_type.split('/')[0] != 'image':
# File is not an image, so no thumbnail available
return None
if self.variations:
thumbnail = next((item for item in self['variations']
if item['size'] == size), None)
if thumbnail:
return thumbnail['link']
else:
thumbnail = self.find_first(
{'where': {"parent": self._id, "size": size}},
api=api)
return thumbnail.link
def stream_thumb_to_file(self, directory, desired_size, api=None):
"""Streams a thumbnail to a file.
@param directory: the directory to save the file to.
@param desired_size: thumbnail size
@return: the absolute path of the downloaded file.
"""
api = api or self.api
thumb_link = self.thumbnail_file(desired_size, api=api)
if thumb_link is None:
raise ValueError("File {} has no thumbnail of size {}"
.format(self._id, desired_size))
root, ext = os.path.splitext(self.file_path)
thumb_fname = "{0}-{1}.jpg".format(root, desired_size)
# thumb is now a dict like:
# {'content_type': 'image/jpeg', 'height': 160, 'length': 5846,
# 'link': 'https://storage.googleapis.com/asdlajsdhaukihuwefiuh',
# 'width': 160, 'size': 'b', 'file_path': '65b526639295c0dd9dc99cf54a0a606cd4924f1d-b.jpg',
# 'md5': '--', 'format': 'jpg'},
thumb_path = os.path.abspath(os.path.join(directory, thumb_fname))
utils.download_to_file(thumb_link, thumb_path)
return thumb_path