diff --git a/seahub/api2/views.py b/seahub/api2/views.py
index 8075c367d6..ca42a5a432 100644
--- a/seahub/api2/views.py
+++ b/seahub/api2/views.py
@@ -52,7 +52,7 @@ from seahub.group.views import group_check, remove_group_common, \
rename_group_with_new_name
from seahub.group.utils import BadGroupNameError, ConflictGroupNameError, \
validate_group_name
-from seahub.thumbnail.utils import allow_generate_thumbnail, generate_thumbnail
+from seahub.thumbnail.utils import generate_thumbnail
from seahub.message.models import UserMessage
from seahub.notifications.models import UserNotification
from seahub.options.models import UserOptions
@@ -90,7 +90,7 @@ if HAS_OFFICE_CONVERTER:
from seahub.utils import query_office_convert_status, prepare_converted_html
import seahub.settings as settings
from seahub.settings import THUMBNAIL_EXTENSION, THUMBNAIL_ROOT, \
- ENABLE_GLOBAL_ADDRESSBOOK, FILE_LOCK_EXPIRATION_DAYS
+ ENABLE_GLOBAL_ADDRESSBOOK, FILE_LOCK_EXPIRATION_DAYS, ENABLE_THUMBNAIL
try:
from seahub.settings import CLOUD_MODE
except ImportError:
@@ -4361,7 +4361,6 @@ class ThumbnailView(APIView):
return api_error(status.HTTP_404_NOT_FOUND, 'Library not found.')
size = request.GET.get('size', None)
- path = request.GET.get('p', None)
if size is None:
return api_error(status.HTTP_400_BAD_REQUEST, 'Size is missing.')
@@ -4371,27 +4370,32 @@ class ThumbnailView(APIView):
logger.error(e)
return api_error(status.HTTP_400_BAD_REQUEST, 'Invalid size.')
+ path = request.GET.get('p', None)
obj_id = get_file_id_by_path(repo_id, path)
if path is None or obj_id is None:
return api_error(status.HTTP_400_BAD_REQUEST, 'Wrong path.')
- if check_folder_permission(request, repo_id, path) is None:
+ if repo.encrypted or not ENABLE_THUMBNAIL or \
+ check_folder_permission(request, repo_id, path) is None:
return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')
- if not allow_generate_thumbnail(request, repo_id, path):
- return api_error(status.HTTP_403_FORBIDDEN, 'Not allowed to generate thumbnail.')
+ success, status_code = generate_thumbnail(request, repo_id, size, path)
+ if success:
+ thumbnail_dir = os.path.join(THUMBNAIL_ROOT, str(size))
+ thumbnail_file = os.path.join(thumbnail_dir, obj_id)
+ try:
+ with open(thumbnail_file, 'rb') as f:
+ thumbnail = f.read()
+ return HttpResponse(thumbnail, 'image/' + THUMBNAIL_EXTENSION)
+ except IOError as e:
+ logger.error(e)
+ return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Failed to get thumbnail.')
else:
- if generate_thumbnail(request, repo_id, size, path):
- thumbnail_dir = os.path.join(THUMBNAIL_ROOT, str(size))
- thumbnail_file = os.path.join(thumbnail_dir, obj_id)
- try:
- with open(thumbnail_file, 'rb') as f:
- thumbnail = f.read()
- return HttpResponse(thumbnail, 'image/' + THUMBNAIL_EXTENSION)
- except IOError as e:
- logger.error(e)
- return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Failed to get thumbnail.')
- else:
+ if status_code == 400:
+ return api_error(status.HTTP_400_BAD_REQUEST, "Invalid argument")
+ if status_code == 403:
+ return api_error(status.HTTP_403_FORBIDDEN, 'Forbidden')
+ if status_code == 500:
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Failed to generate thumbnail.')
_REPO_ID_PATTERN = re.compile(r'[-0-9a-f]{36}')
diff --git a/seahub/settings.py b/seahub/settings.py
index c13879d67c..fc310e6667 100644
--- a/seahub/settings.py
+++ b/seahub/settings.py
@@ -463,7 +463,7 @@ THUMBNAIL_EXTENSION = 'png'
THUMBNAIL_DEFAULT_SIZE = 48
# size(MB) limit for generate thumbnail
-THUMBNAIL_IMAGE_COMPRESSED_SIZE_LIMIT = 1
+THUMBNAIL_IMAGE_SIZE_LIMIT = 20
THUMBNAIL_IMAGE_ORIGINAL_SIZE_LIMIT = 256
#####################
diff --git a/seahub/templates/view_shared_dir.html b/seahub/templates/view_shared_dir.html
index e7d07b9f60..ca5f597e10 100644
--- a/seahub/templates/view_shared_dir.html
+++ b/seahub/templates/view_shared_dir.html
@@ -56,7 +56,7 @@
{% for dirent in file_list %}
- {% if dirent.allow_generate_thumbnail %}
+ {% if dirent.is_img %}
{% if dirent.encoded_thumbnail_src %}
 |
{% else %}
diff --git a/seahub/thumbnail/utils.py b/seahub/thumbnail/utils.py
index e46bebca69..35e3d1fc01 100644
--- a/seahub/thumbnail/utils.py
+++ b/seahub/thumbnail/utils.py
@@ -8,12 +8,10 @@ from PIL import Image
from seaserv import get_file_id_by_path, get_repo, get_file_size, \
seafile_api
-from seahub.utils import get_file_type_and_ext, gen_inner_file_get_url
-from seahub.utils.file_types import IMAGE
+from seahub.utils import gen_inner_file_get_url
-from seahub.settings import ENABLE_THUMBNAIL, THUMBNAIL_EXTENSION, \
- THUMBNAIL_IMAGE_COMPRESSED_SIZE_LIMIT, THUMBNAIL_ROOT, \
- THUMBNAIL_IMAGE_ORIGINAL_SIZE_LIMIT
+from seahub.settings import THUMBNAIL_IMAGE_SIZE_LIMIT, \
+ THUMBNAIL_EXTENSION, THUMBNAIL_ROOT, THUMBNAIL_IMAGE_ORIGINAL_SIZE_LIMIT
# Get an instance of a logger
logger = logging.getLogger(__name__)
@@ -24,60 +22,20 @@ def get_thumbnail_src(repo_id, size, path):
def get_share_link_thumbnail_src(token, size, path):
return posixpath.join("thumbnail", token, str(size), path.lstrip('/'))
-def allow_generate_thumbnail(request, repo_id, path):
- """check if thumbnail is allowed
- """
-
- # get file type
- obj_name = os.path.basename(path)
- file_type, file_ext = get_file_type_and_ext(obj_name)
-
- # get file size
- file_id = get_file_id_by_path(repo_id, path)
- if not file_id:
- return False
-
- repo = get_repo(repo_id)
- file_size = get_file_size(repo.store_id, repo.version, file_id)
-
- if repo.encrypted or file_type != IMAGE or not ENABLE_THUMBNAIL:
- return False
-
- # check image compressed size limit
- if file_size < THUMBNAIL_IMAGE_COMPRESSED_SIZE_LIMIT * 1024**2:
- return True
-
- # get image memory cost
- token = seafile_api.get_fileserver_access_token(repo_id, file_id, 'view',
- '', use_onetime = True)
-
- inner_path = gen_inner_file_get_url(token, obj_name)
- try:
- image_file = urllib2.urlopen(inner_path)
- f = StringIO(image_file.read())
- image = Image.open(f)
- width, height = image.size
-
- # check image memory cost size limit
- # use RGBA as default mode(4x8-bit pixels, true colour with transparency mask)
- # every pixel will cost 4 byte in RGBA mode
- image_memory_cost = width * height * 4 / 1024 / 1024
- if image_memory_cost < THUMBNAIL_IMAGE_ORIGINAL_SIZE_LIMIT:
- return True
-
- except Exception as e:
- logger.error(e)
- return False
-
def generate_thumbnail(request, repo_id, size, path):
""" generate and save thumbnail if not exist
+
+ before generate thumbnail, you should check:
+ 1. if repo exist: should exist;
+ 2. if repo is encrypted: not encrypted;
+ 3. if ENABLE_THUMBNAIL: enabled;
"""
try:
size = int(size)
except ValueError as e:
logger.error(e)
- return False
+ return (False, 400)
thumbnail_dir = os.path.join(THUMBNAIL_ROOT, str(size))
if not os.path.exists(thumbnail_dir):
@@ -85,12 +43,16 @@ def generate_thumbnail(request, repo_id, size, path):
file_id = get_file_id_by_path(repo_id, path)
if not file_id:
- return False
+ return (False, 400)
thumbnail_file = os.path.join(thumbnail_dir, file_id)
-
if os.path.exists(thumbnail_file):
- return True
+ return (True, 200)
+
+ repo = get_repo(repo_id)
+ file_size = get_file_size(repo.store_id, repo.version, file_id)
+ if file_size > THUMBNAIL_IMAGE_SIZE_LIMIT * 1024**2:
+ return (False, 403)
token = seafile_api.get_fileserver_access_token(repo_id, file_id, 'view',
'', use_onetime = True)
@@ -100,11 +62,20 @@ def generate_thumbnail(request, repo_id, size, path):
image_file = urllib2.urlopen(inner_path)
f = StringIO(image_file.read())
image = Image.open(f)
+
+ # check image memory cost size limit
+ # use RGBA as default mode(4x8-bit pixels, true colour with transparency mask)
+ # every pixel will cost 4 byte in RGBA mode
+ width, height = image.size
+ image_memory_cost = width * height * 4 / 1024 / 1024
+ if image_memory_cost > THUMBNAIL_IMAGE_ORIGINAL_SIZE_LIMIT:
+ return (False, 403)
+
if image.mode not in ["1", "L", "P", "RGB", "RGBA"]:
image = image.convert("RGB")
image.thumbnail((size, size), Image.ANTIALIAS)
image.save(thumbnail_file, THUMBNAIL_EXTENSION)
- return True
+ return (True, 200)
except Exception as e:
logger.error(e)
- return False
+ return (False, 500)
diff --git a/seahub/thumbnail/views.py b/seahub/thumbnail/views.py
index 034c10bfc6..d861e0b4d1 100644
--- a/seahub/thumbnail/views.py
+++ b/seahub/thumbnail/views.py
@@ -9,14 +9,14 @@ from django.utils.http import urlquote
from django.http import HttpResponse
from django.views.decorators.http import condition
-from seaserv import get_repo, get_file_id_by_path, seafile_api
+from seaserv import get_repo, get_file_id_by_path
from seahub.auth.decorators import login_required_ajax, login_required
from seahub.views import check_folder_permission
from seahub.settings import THUMBNAIL_DEFAULT_SIZE, THUMBNAIL_EXTENSION, \
- THUMBNAIL_ROOT
-from seahub.thumbnail.utils import allow_generate_thumbnail, \
- generate_thumbnail, get_thumbnail_src, get_share_link_thumbnail_src
+ THUMBNAIL_ROOT, ENABLE_THUMBNAIL
+from seahub.thumbnail.utils import generate_thumbnail, \
+ get_thumbnail_src, get_share_link_thumbnail_src
from seahub.share.models import FileShare
# Get an instance of a logger
@@ -33,37 +33,33 @@ def thumbnail_create(request, repo_id):
result = {}
repo = get_repo(repo_id)
- path = request.GET.get('path', None)
-
if not repo:
err_msg = _(u"Library does not exist.")
- return HttpResponse(json.dumps({"error": err_msg}), status=403,
+ return HttpResponse(json.dumps({"error": err_msg}), status=400,
content_type=content_type)
+ path = request.GET.get('path', None)
if not path:
err_msg = _(u"Invalid arguments.")
- return HttpResponse(json.dumps({"error": err_msg}), status=403,
+ return HttpResponse(json.dumps({"error": err_msg}), status=400,
content_type=content_type)
- if check_folder_permission(request, repo_id, path) is None:
+ if repo.encrypted or not ENABLE_THUMBNAIL or \
+ check_folder_permission(request, repo_id, path) is None:
err_msg = _(u"Permission denied.")
return HttpResponse(json.dumps({"error": err_msg}), status=403,
content_type=content_type)
- if not allow_generate_thumbnail(request, repo_id, path):
- err_msg = _(u"Not allowed to generate thumbnail.")
- return HttpResponse(json.dumps({"error": err_msg}), status=403,
- content_type=content_type)
-
size = request.GET.get('size', THUMBNAIL_DEFAULT_SIZE)
- if generate_thumbnail(request, repo_id, size, path):
+ success, status_code = generate_thumbnail(request, repo_id, size, path)
+ if success:
src = get_thumbnail_src(repo_id, size, path)
result['encoded_thumbnail_src'] = urlquote(src)
return HttpResponse(json.dumps(result), content_type=content_type)
else:
err_msg = _('Failed to create thumbnail.')
- return HttpResponse(json.dumps({'err_msg': err_msg}), status=500,
- content_type=content_type)
+ return HttpResponse(json.dumps({'err_msg': err_msg}),
+ status=status_code, content_type=content_type)
def latest_entry(request, repo_id, size, path):
obj_id = get_file_id_by_path(repo_id, path)
@@ -88,28 +84,38 @@ def thumbnail_get(request, repo_id, size, path):
return thumbnail file to web
"""
+ repo = get_repo(repo_id)
+ obj_id = get_file_id_by_path(repo_id, path)
+
+ # check if file exist
+ if not repo or not obj_id:
+ return HttpResponse()
+
+ # check if is allowed
+ if repo.encrypted or not ENABLE_THUMBNAIL or \
+ check_folder_permission(request, repo_id, path) is None:
+ return HttpResponse()
+
try:
size = int(size)
except ValueError as e:
logger.error(e)
return HttpResponse()
- obj_id = get_file_id_by_path(repo_id, path)
- if check_folder_permission(request, repo_id, path) is None \
- or obj_id is None:
- return HttpResponse()
-
+ success = True
thumbnail_file = os.path.join(THUMBNAIL_ROOT, str(size), obj_id)
+ if not os.path.exists(thumbnail_file):
+ success, status_code = generate_thumbnail(request, repo_id, size, path)
- if not os.path.exists(thumbnail_file) and \
- allow_generate_thumbnail(request, repo_id, path):
- generate_thumbnail(request, repo_id, size, path)
- try:
- with open(thumbnail_file, 'rb') as f:
- thumbnail = f.read()
- return HttpResponse(content=thumbnail, mimetype='image/'+THUMBNAIL_EXTENSION)
- except IOError as e:
- logger.error(e)
+ if success:
+ try:
+ with open(thumbnail_file, 'rb') as f:
+ thumbnail = f.read()
+ return HttpResponse(content=thumbnail, mimetype='image/'+THUMBNAIL_EXTENSION)
+ except IOError as e:
+ logger.error(e)
+ return HttpResponse()
+ else:
return HttpResponse()
def share_link_thumbnail_create(request, token):
@@ -124,20 +130,25 @@ def share_link_thumbnail_create(request, token):
fileshare = FileShare.objects.get_valid_file_link_by_token(token)
if not fileshare:
err_msg = _(u"Invalid token.")
- return HttpResponse(json.dumps({"error": err_msg}), status=403,
+ return HttpResponse(json.dumps({"error": err_msg}), status=400,
content_type=content_type)
repo_id = fileshare.repo_id
repo = get_repo(repo_id)
if not repo:
err_msg = _(u"Library does not exist.")
+ return HttpResponse(json.dumps({"error": err_msg}), status=400,
+ content_type=content_type)
+
+ if repo.encrypted or not ENABLE_THUMBNAIL:
+ err_msg = _(u"Permission denied.")
return HttpResponse(json.dumps({"error": err_msg}), status=403,
content_type=content_type)
req_path = request.GET.get('path', None)
if not req_path or '../' in req_path:
err_msg = _(u"Invalid arguments.")
- return HttpResponse(json.dumps({"error": err_msg}), status=403,
+ return HttpResponse(json.dumps({"error": err_msg}), status=400,
content_type=content_type)
if fileshare.path == '/':
@@ -145,20 +156,16 @@ def share_link_thumbnail_create(request, token):
else:
real_path = posixpath.join(fileshare.path, req_path.lstrip('/'))
- if not allow_generate_thumbnail(request, repo_id, real_path):
- err_msg = _(u"Not allowed to generate thumbnail.")
- return HttpResponse(json.dumps({"error": err_msg}), status=403,
- content_type=content_type)
-
size = request.GET.get('size', THUMBNAIL_DEFAULT_SIZE)
- if generate_thumbnail(request, repo_id, size, real_path):
+ success, status_code = generate_thumbnail(request, repo_id, size, real_path)
+ if success:
src = get_share_link_thumbnail_src(token, size, req_path)
result['encoded_thumbnail_src'] = urlquote(src)
return HttpResponse(json.dumps(result), content_type=content_type)
else:
err_msg = _('Failed to create thumbnail.')
- return HttpResponse(json.dumps({'err_msg': err_msg}), status=500,
- content_type=content_type)
+ return HttpResponse(json.dumps({'err_msg': err_msg}),
+ status=status_code, content_type=content_type)
def share_link_latest_entry(request, token, size, path):
fileshare = FileShare.objects.get_valid_file_link_by_token(token)
@@ -209,18 +216,27 @@ def share_link_thumbnail_get(request, token, size, path):
repo_id = fileshare.repo_id
repo = get_repo(repo_id)
obj_id = get_file_id_by_path(repo_id, image_path)
+
+ # check if file exist
if not repo or not obj_id:
return HttpResponse()
- thumbnail_file = os.path.join(THUMBNAIL_ROOT, str(size), obj_id)
-
- if not os.path.exists(thumbnail_file) and \
- allow_generate_thumbnail(request, repo_id, image_path):
- generate_thumbnail(request, repo_id, size, image_path)
- try:
- with open(thumbnail_file, 'rb') as f:
- thumbnail = f.read()
- return HttpResponse(content=thumbnail, mimetype='image/'+THUMBNAIL_EXTENSION)
- except IOError as e:
- logger.error(e)
+ # check if is allowed
+ if repo.encrypted or not ENABLE_THUMBNAIL:
+ return HttpResponse()
+
+ success = True
+ thumbnail_file = os.path.join(THUMBNAIL_ROOT, str(size), obj_id)
+ if not os.path.exists(thumbnail_file):
+ success, status_code = generate_thumbnail(request, repo_id, size, image_path)
+
+ if success:
+ try:
+ with open(thumbnail_file, 'rb') as f:
+ thumbnail = f.read()
+ return HttpResponse(content=thumbnail, mimetype='image/'+THUMBNAIL_EXTENSION)
+ except IOError as e:
+ logger.error(e)
+ return HttpResponse()
+ else:
return HttpResponse()
diff --git a/seahub/views/ajax.py b/seahub/views/ajax.py
index 3353ccf87a..a636f69188 100644
--- a/seahub/views/ajax.py
+++ b/seahub/views/ajax.py
@@ -60,7 +60,7 @@ from seahub.utils import check_filename_with_rename, EMPTY_SHA1, \
from seahub.utils.repo import get_sub_repo_abbrev_origin_path
from seahub.utils.star import star_file, unstar_file
from seahub.base.accounts import User
-from seahub.thumbnail.utils import get_thumbnail_src, allow_generate_thumbnail
+from seahub.thumbnail.utils import get_thumbnail_src
from seahub.utils.file_types import IMAGE
from seahub.base.templatetags.seahub_tags import translate_seahub_time, \
file_icon_filter, email2nickname, tsstr_sec
@@ -481,7 +481,6 @@ def list_lib_dir(request, repo_id):
file_type, file_ext = get_file_type_and_ext(f.obj_name)
if file_type == IMAGE:
f_['is_img'] = True
-
if not repo.encrypted and ENABLE_THUMBNAIL and \
os.path.exists(os.path.join(THUMBNAIL_ROOT, str(size), f.obj_id)):
file_path = posixpath.join(path, f.obj_name)
diff --git a/seahub/views/repo.py b/seahub/views/repo.py
index 932a498bec..a4a2a9f1c5 100644
--- a/seahub/views/repo.py
+++ b/seahub/views/repo.py
@@ -38,8 +38,7 @@ from seahub.settings import ENABLE_SUB_LIBRARY, FORCE_SERVER_CRYPTO, \
ENABLE_UPLOAD_FOLDER, ENABLE_RESUMABLE_FILEUPLOAD, ENABLE_THUMBNAIL, THUMBNAIL_ROOT, THUMBNAIL_DEFAULT_SIZE
from seahub.utils import gen_file_get_url
from seahub.utils.file_types import IMAGE
-from seahub.thumbnail.utils import get_thumbnail_src, \
- allow_generate_thumbnail, get_share_link_thumbnail_src
+from seahub.thumbnail.utils import get_thumbnail_src, get_share_link_thumbnail_src
# Get an instance of a logger
logger = logging.getLogger(__name__)
@@ -244,9 +243,10 @@ def render_repo(request, repo):
dir_shared_upload_link = get_dir_shared_upload_link(uploadlink)
for f in file_list:
- file_path = posixpath.join(path, f.obj_name)
- if allow_generate_thumbnail(request, repo.id, file_path):
- f.allow_generate_thumbnail = True
+ file_type, file_ext = get_file_type_and_ext(f.obj_name)
+ if file_type == IMAGE:
+ f.is_img = True
+ file_path = posixpath.join(path, f.obj_name)
if os.path.exists(os.path.join(THUMBNAIL_ROOT, str(THUMBNAIL_DEFAULT_SIZE), f.obj_id)):
src = get_thumbnail_src(repo.id, THUMBNAIL_DEFAULT_SIZE, file_path)
f.encoded_thumbnail_src = urlquote(src)
@@ -480,19 +480,15 @@ def view_shared_dir(request, token):
traffic_over_limit = user_traffic_over_limit(fileshare.username)
- for f in file_list:
-
- file_type, file_ext = get_file_type_and_ext(f.obj_name)
- if file_type == IMAGE:
- f.is_img = True
-
- real_image_path = posixpath.join(real_path, f.obj_name)
- if allow_generate_thumbnail(request, repo_id, real_image_path):
- f.allow_generate_thumbnail = True
- if os.path.exists(os.path.join(THUMBNAIL_ROOT, str(THUMBNAIL_DEFAULT_SIZE), f.obj_id)):
- req_image_path = posixpath.join(req_path, f.obj_name)
- src = get_share_link_thumbnail_src(token, THUMBNAIL_DEFAULT_SIZE, req_image_path)
- f.encoded_thumbnail_src = urlquote(src)
+ if not repo.encrypted and ENABLE_THUMBNAIL:
+ for f in file_list:
+ file_type, file_ext = get_file_type_and_ext(f.obj_name)
+ if file_type == IMAGE:
+ f.is_img = True
+ if os.path.exists(os.path.join(THUMBNAIL_ROOT, str(THUMBNAIL_DEFAULT_SIZE), f.obj_id)):
+ req_image_path = posixpath.join(req_path, f.obj_name)
+ src = get_share_link_thumbnail_src(token, THUMBNAIL_DEFAULT_SIZE, req_image_path)
+ f.encoded_thumbnail_src = urlquote(src)
return render_to_response('view_shared_dir.html', {
'repo': repo,