diff --git a/seahub/api2/urls.py b/seahub/api2/urls.py index 877656cffe..904f7191b2 100644 --- a/seahub/api2/urls.py +++ b/seahub/api2/urls.py @@ -36,7 +36,7 @@ urlpatterns = patterns('', url(r'^repos/(?P[-0-9-a-f]{36})/dir/sub_repo/$', DirSubRepoView.as_view()), url(r'^repos/(?P[-0-9-a-f]{36})/dir/share/$', DirShareView.as_view()), url(r'^repos/(?P[-0-9-a-f]{36})/dir/download/$', DirDownloadView.as_view()), - url(r'^repos/(?P[-0-9-a-f]{36})/thumbnail/(?P.+)$', ThumbnailView.as_view(), name='api2-thumbnail'), + url(r'^repos/(?P[-0-9-a-f]{36})/thumbnail/$', ThumbnailView.as_view(), name='api2-thumbnail'), url(r'^starredfiles/', StarredFileView.as_view(), name='starredfiles'), url(r'^shared-repos/$', SharedRepos.as_view(), name='sharedrepos'), url(r'^shared-repos/(?P[-0-9-a-f]{36})/$', SharedRepo.as_view(), name='sharedrepo'), diff --git a/seahub/api2/views.py b/seahub/api2/views.py index 6eab80054d..5f4e4ba113 100644 --- a/seahub/api2/views.py +++ b/seahub/api2/views.py @@ -1159,7 +1159,7 @@ class OpCopyView(APIView): if check_folder_permission(repo_id, parent_dir, username) != 'rw': return api_error(status.HTTP_403_FORBIDDEN, 'Forbid to access this folder.') - parent_dir = request.GET.get('p', None) + parent_dir = request.POST.get('p', '/') dst_repo = request.POST.get('dst_repo', None) dst_dir = request.POST.get('dst_dir', None) file_names = request.POST.get("file_names", None) @@ -1168,6 +1168,13 @@ class OpCopyView(APIView): return api_error(status.HTTP_400_BAD_REQUEST, 'Missing argument.') + if not get_repo(dst_repo): + return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.') + + if seafile_api.get_dir_id_by_path(repo_id, parent_dir) is None or \ + seafile_api.get_dir_id_by_path(dst_repo, dst_dir) is None: + return api_error(status.HTTP_400_BAD_REQUEST, 'Path does not exist.') + parent_dir_utf8 = parent_dir.encode('utf-8') for file_name in file_names.split(':'): file_name = unquote(file_name.encode('utf-8')) @@ -3508,7 +3515,7 @@ class ThumbnailView(APIView): permission_classes = (IsAuthenticated,) throttle_classes = (UserRateThrottle, ) - def get(self, request, repo_id, path): + def get(self, request, repo_id): repo = get_repo(repo_id) if not repo: @@ -3523,10 +3530,14 @@ class ThumbnailView(APIView): return api_error(status.HTTP_403_FORBIDDEN, 'Thumbnail function is not enabled.') - size = request.GET.get('s', None) + 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.') + if path is None: + return api_error(status.HTTP_400_BAD_REQUEST, 'Path is missing.') + obj_id = get_file_id_by_path(repo_id, path) if obj_id is None: diff --git a/seahub/templates/registration/login.html b/seahub/templates/registration/login.html index dcbbe964f6..55ee0d9aed 100644 --- a/seahub/templates/registration/login.html +++ b/seahub/templates/registration/login.html @@ -130,11 +130,13 @@ $(function() { }); })(); +{% if enable_shib_login %} $(function() { $('#shib-login').click(function() { window.location = "{% url 'shib_login' %}"; return false; }); }); +{% endif %} {% endblock %} diff --git a/seahub/templates/repo.html b/seahub/templates/repo.html index 29a67e5122..a51c47b6ee 100644 --- a/seahub/templates/repo.html +++ b/seahub/templates/repo.html @@ -325,6 +325,7 @@ $(function() { var file = data.files[0]; if (file.name == '.') { data.files.shift(); + return; } if (file.webkitRelativePath) { // for 'upload folder' file.relative_path = file.webkitRelativePath; @@ -338,7 +339,9 @@ $(function() { fu_status.html(fu_status_.uploading); }) .bind('fileuploadsubmit', function(e, data) { - var _this = $(this); + if (data.files.length == 0) { + return false; + } var file = data.files[0]; // get url(token) for every file if (!file.error) { @@ -363,7 +366,7 @@ $(function() { {% endif %} data.url = ret['url']; - data.jqXHR = _this.fileupload('send', data); + data.jqXHR = popup.fileupload('send', data); }, error: function() { file.error = "{% trans "Failed to get upload url" %}"; @@ -2087,7 +2090,7 @@ $('#add-new-file-form, #add-new-dir-form, #rename-form, #mv-form').submit(functi paddingTop: 50 }, focus:false}); var det_text = op == 'mv' ? "{% trans "Moving %(name)s" %}": "{% trans "Copying %(name)s" %}"; - details.html(det_text.replace('%(name)s', trimFilename(obj_name, 20))); + details.html(det_text.replace('%(name)s', trimFilename(obj_name, 20))).removeClass('vh'); $('#mv-progress').progressbar(); req_progress(); }, 100); @@ -2386,7 +2389,7 @@ function updateCmt() { {% endif %} {% if not repo.encrypted and ENABLE_THUMBNAIL %} -var timer, +var timer, ajaxRequest = $.ajax(), default_size = {{PREVIEW_DEFAULT_SIZE}}, preview_wrap = $('
') .appendTo("body") @@ -2401,50 +2404,59 @@ $("#repo-file-list").on({ file_item = thumbnail.closest('.file-item'); timer = setTimeout(function () { - $.ajax({ - url: '{% url 'thumbnail_create' repo.id %}?path=' + e(cur_path+file_item.attr('data-name')) + '&size=' + default_size, - cache: false, - dataType: 'json', - success: function(data) { - image_preview.attr("src", data.thumbnail_src); + ajaxRequest = $.ajax({ + url: '{% url 'thumbnail_create' repo.id %}?path=' + e(cur_path+file_item.attr('data-name')) + '&size=' + default_size, + cache: false, + dataType: 'json', + success: function(data) { + image_preview.attr("src", data.thumbnail_src); - var file_item_offset = file_item.offset(), - thumbnail_offset = thumbnail.offset(), + var file_item_offset = file_item.offset(), + thumbnail_offset = thumbnail.offset(), - wrap_width = preview_wrap.outerWidth(), - wrap_padding = parseInt(preview_wrap.css('padding-top')), + wrap_width = preview_wrap.outerWidth(), + wrap_padding = parseInt(preview_wrap.css('padding-top')), - caret_width = parseInt(caret.css('border-top-width')), - caret_pos_x = (default_size)/2 + wrap_padding - caret_width, - caret_pos_y = default_size + 2 * wrap_padding, + caret_width = parseInt(caret.css('border-top-width')), + caret_pos_x = (default_size)/2 + wrap_padding - caret_width, + caret_pos_y = default_size + 2 * wrap_padding, - wrap_left = file_item_offset.left - wrap_width - caret_width; + wrap_left = file_item_offset.left - wrap_width - caret_width; - if (wrap_left >= 0) { - caret.removeClass('bottom-outer-caret') - .addClass('right-outer-caret') - .css({'top':caret_pos_x + 'px', 'left':caret_pos_y + 'px'}); + if (wrap_left >= 0) { + caret.removeClass('bottom-outer-caret') + .addClass('right-outer-caret') + .css({'top':caret_pos_x + 'px', 'left':caret_pos_y + 'px'}); - preview_wrap.css({ - 'top' : (thumbnail_offset.top + (thumbnail.height() - wrap_width)/2) + 'px', - 'left' : wrap_left + 'px' - }).fadeIn(); - } else { - caret.removeClass("right-outer-caret") - .addClass("bottom-outer-caret") - .css({'top':caret_pos_y + 'px', 'left':caret_pos_x + 'px'}); + preview_wrap.css({ + 'top' : (thumbnail_offset.top + (thumbnail.height() - wrap_width)/2) + 'px', + 'left' : wrap_left + 'px' + }).fadeIn(); + } else { + caret.removeClass("right-outer-caret") + .addClass("bottom-outer-caret") + .css({'top':caret_pos_y + 'px', 'left':caret_pos_x + 'px'}); - preview_wrap.css({ - 'top' : (file_item_offset.top - wrap_width) - caret_width + 'px', - 'left' : (thumbnail_offset.left + (thumbnail.width() - wrap_width)/2) + 'px' - }).fadeIn(); + preview_wrap.css({ + 'top' : (file_item_offset.top - wrap_width) - caret_width + 'px', + 'left' : (thumbnail_offset.left + (thumbnail.width() - wrap_width)/2) + 'px' + }).fadeIn(); + } + }, + error: function(xhr, textStatus, errorThrown) { + if (textStatus != "abort") { + if (xhr.responseText) { + feedback($.parseJSON(xhr.responseText).error, 'error'); + } else { + feedback("{% trans "Failed. Please check the network." %}", 'error'); + }; + }; } - }, - error: ajaxErrorHandler }); }, 200); }, mouseleave: function() { + ajaxRequest.abort(); clearTimeout(timer); preview_wrap.hide(); image_preview.attr('src', ''); // for ff. In ff, when hover, the last preview image would be shown first, then the right one. diff --git a/seahub/templates/view_shared_upload_link.html b/seahub/templates/view_shared_upload_link.html index 14e8dde4e3..93b076eba4 100644 --- a/seahub/templates/view_shared_upload_link.html +++ b/seahub/templates/view_shared_upload_link.html @@ -117,6 +117,7 @@ form.fileupload({ var file = data.files[0]; if (file.name == '.') { data.files.shift(); + return; } if (file.webkitRelativePath) { // for 'upload folder' file.relative_path = file.webkitRelativePath; @@ -127,7 +128,9 @@ form.fileupload({ {% endif %} }) .bind('fileuploadsubmit', function(e, data) { - var _this = $(this); + if (data.files.length == 0) { + return false; + } var file = data.files[0]; // get url(token) for every file if (!file.error) { @@ -148,7 +151,7 @@ form.fileupload({ {% endif %} data.url = ret['url']; - data.jqXHR = _this.fileupload('send', data); + data.jqXHR = form.fileupload('send', data); }, error: function() { file.error = "{% trans "Failed to get upload url" %}"; diff --git a/seahub/utils/devices.py b/seahub/utils/devices.py index c6357738fd..3f4ceb424f 100644 --- a/seahub/utils/devices.py +++ b/seahub/utils/devices.py @@ -1,4 +1,5 @@ import logging +import datetime from seaserv import seafile_api from seahub.api2.models import TokenV2, DESKTOP_PLATFORMS @@ -10,6 +11,10 @@ __all__ = [ 'do_unlink_device', ] +def _last_sync_time(repos): + latest_sync_time = max([r['sync_time'] for r in repos]) + return datetime.datetime.fromtimestamp(latest_sync_time) + def get_user_devices(username): devices = TokenV2.objects.get_user_devices(username) @@ -18,7 +23,11 @@ def get_user_devices(username): for device in devices: if device['platform'] in DESKTOP_PLATFORMS: peer_id = device['device_id'] - device['synced_repos'] = peer_repos_map.get(peer_id, []) + repos = peer_repos_map.get(peer_id, []) + device['synced_repos'] = repos + if repos: + device['last_accessed'] = max(device['last_accessed'], + _last_sync_time(repos)) return devices @@ -61,7 +70,7 @@ def get_user_synced_repo_infos(username): def do_unlink_device(username, platform, device_id): if platform in DESKTOP_PLATFORMS: # For desktop client, we also remove the sync tokens - msg = 'failed to delete_repo_tokens_by_peer_id' + msg = 'failed to delete_repo_tokens_by_peer_id' try: if seafile_api.delete_repo_tokens_by_peer_id(username, device_id) < 0: logger.warning(msg) diff --git a/thirdpart/shibboleth/backends.py b/thirdpart/shibboleth/backends.py index bfd51ffbe3..edbbc26d28 100644 --- a/thirdpart/shibboleth/backends.py +++ b/thirdpart/shibboleth/backends.py @@ -41,11 +41,12 @@ class ShibbolethRemoteUserBackend(RemoteUserBackend): # Note that this could be accomplished in one try-except clause, but # instead we use get_or_create when creating unknown users since it has # built-in safeguards for multiple threads. - if self.create_unknown_user: - user = User.objects.create_user(email=username, is_active=True) - else: - try: - user = User.objects.get(email=username) - except User.DoesNotExist: + try: + user = User.objects.get(email=username) + except User.DoesNotExist: + if self.create_unknown_user: + user = User.objects.create_user(email=username, is_active=True) + else: pass + return user