diff --git a/seahub/base/accounts.py b/seahub/base/accounts.py index 3b4db56a6d..a9737c590f 100644 --- a/seahub/base/accounts.py +++ b/seahub/base/accounts.py @@ -156,7 +156,10 @@ class UserPermissions(object): """ if CLOUD_MODE: - return False + if MULTI_TENANCY: + return True + else: + return False elif self.user.is_staff: return True elif get_enabled_role_permissions_by_role(self.user.role)['can_add_public_repo']: diff --git a/seahub/thumbnail/utils.py b/seahub/thumbnail/utils.py index 6d316a2333..0c9ed33cdd 100644 --- a/seahub/thumbnail/utils.py +++ b/seahub/thumbnail/utils.py @@ -150,6 +150,13 @@ def generate_thumbnail(request, repo_id, size, path): return (False, 500) def create_psd_thumbnails(repo, file_id, path, size, thumbnail_file, file_size): + try: + from psd_tools import PSDImage + except ImportError: + logger.error("Could not find psd_tools installed. " + "Please install by 'pip install psd_tools'") + return (False, 500) + token = seafile_api.get_fileserver_access_token( repo.id, file_id, 'view', '', use_onetime=False) if not token: @@ -158,8 +165,6 @@ def create_psd_thumbnails(repo, file_id, path, size, thumbnail_file, file_size): tmp_img_path = str(os.path.join(tempfile.gettempdir(), '%s.png' % file_id)) t1 = timeit.default_timer() - from psd_tools import PSDImage - inner_path = gen_inner_file_get_url(token, os.path.basename(path)) tmp_file = os.path.join(tempfile.gettempdir(), file_id) urlretrieve(inner_path, tmp_file) diff --git a/seahub/utils/__init__.py b/seahub/utils/__init__.py index 91c3325cb3..2ac4465f86 100644 --- a/seahub/utils/__init__.py +++ b/seahub/utils/__init__.py @@ -698,13 +698,20 @@ if EVENTS_CONFIG_FILE: return events if events else None def generate_file_audit_event_type(e): - return { + + event_type_dict = { 'file-download-web': ('web', ''), 'file-download-share-link': ('share-link',''), 'file-download-api': ('API', e.device), 'repo-download-sync': ('download-sync', e.device), 'repo-upload-sync': ('upload-sync', e.device), - }[e.etype] + 'seadrive-download-file': ('seadrive-download', e.device), + } + + if not event_type_dict.has_key(e.etype): + event_type_dict[e.etype] = (e.etype, e.device if e.device else '') + + return event_type_dict[e.etype] def get_file_audit_events_by_path(email, org_id, repo_id, file_path, start, limit): """Return file audit events list by file path. (If no file audit, return 'None') diff --git a/static/scripts/app/router.js b/static/scripts/app/router.js index b0b342098a..2baf222570 100644 --- a/static/scripts/app/router.js +++ b/static/scripts/app/router.js @@ -130,10 +130,19 @@ define([ this.currentView = newView; } else { if (this.currentView != newView) { + if (this.currentView == this.dirView) { + if ($('#upload-file-dialog').is(':visible') && + $('#upload-file-dialog .status').text() == window.fileuploading) { + if (!window.confirm('A file is being uploaded. Are you sure you want to leave this page?')) { + return false; + } + } + } this.currentView.hide(); this.currentView = newView; } } + return true; }, showRepos: function() { @@ -145,19 +154,25 @@ define([ }, showMyRepos: function() { - this.switchCurrentView(this.myReposView); + if (!this.switchCurrentView(this.myReposView)) { + return false; + }; this.myReposView.show(); this.sideNavView.setCurTab('mine'); }, showMyDeletedRepos: function() { - this.switchCurrentView(this.myDeletedReposView); + if (!this.switchCurrentView(this.myDeletedReposView)) { + return false; + }; this.myDeletedReposView.show(); this.sideNavView.setCurTab('mine'); }, showSharedRepos: function() { - this.switchCurrentView(this.sharedReposView); + if (!this.switchCurrentView(this.sharedReposView)) { + return false; + } this.sharedReposView.show(); this.sideNavView.setCurTab('shared'); }, @@ -196,7 +211,9 @@ define([ }, showGroups: function () { - this.switchCurrentView(this.groupsView); + if (!this.switchCurrentView(this.groupsView)) { + return false; + } this.groupsView.show(); this.sideNavView.setCurTab('group', { 'cur_group_tab': 'groups', @@ -205,7 +222,9 @@ define([ }, showGroup: function(group_id, options) { - this.switchCurrentView(this.groupView); + if (!this.switchCurrentView(this.groupView)) { + return false; + } this.groupView.show(group_id, options); this.sideNavView.setCurTab('group', { 'cur_group_tab': '', @@ -247,7 +266,9 @@ define([ }, showOrgRepos: function() { - this.switchCurrentView(this.orgView); + if (!this.switchCurrentView(this.orgView)) { + return false; + } this.orgView.show(); this.sideNavView.setCurTab('org'); }, @@ -264,49 +285,65 @@ define([ }, showStarredFile: function() { - this.switchCurrentView(this.starredFileView); + if (!this.switchCurrentView(this.starredFileView)) { + return false; + } this.starredFileView.show(); this.sideNavView.setCurTab('starred'); }, showActivities: function() { - this.switchCurrentView(this.activitiesView); + if (!this.switchCurrentView(this.activitiesView)) { + return false; + } this.activitiesView.show(); this.sideNavView.setCurTab('activities'); }, showDevices: function() { - this.switchCurrentView(this.devicesView); + if (!this.switchCurrentView(this.devicesView)) { + return false; + } this.devicesView.show(); this.sideNavView.setCurTab('devices'); }, showInvitations: function() { - this.switchCurrentView(this.invitationsView); + if (!this.switchCurrentView(this.invitationsView)) { + return false; + } this.invitationsView.show(); this.sideNavView.setCurTab('invitations'); }, showShareAdminRepos: function() { - this.switchCurrentView(this.shareAdminReposView); + if (!this.switchCurrentView(this.shareAdminReposView)) { + return false; + } this.shareAdminReposView.show(); this.sideNavView.setCurTab('share-admin-repos', {'show_share_admin': true}); }, showShareAdminFolders: function() { - this.switchCurrentView(this.shareAdminFoldersView); + if (!this.switchCurrentView(this.shareAdminFoldersView)) { + return false; + } this.shareAdminFoldersView.show(); this.sideNavView.setCurTab('share-admin-folders', {'show_share_admin': true}); }, showShareAdminShareLinks: function() { - this.switchCurrentView(this.shareAdminShareLinksView); + if (!this.switchCurrentView(this.shareAdminShareLinksView)) { + return false; + } this.shareAdminShareLinksView.show(); this.sideNavView.setCurTab('share-admin-links', {'show_share_admin': true}); }, showShareAdminUploadLinks: function() { - this.switchCurrentView(this.shareAdminUploadLinksView); + if (!this.switchCurrentView(this.shareAdminUploadLinksView)) { + return false; + } this.shareAdminUploadLinksView.show(); this.sideNavView.setCurTab('share-admin-links', {'show_share_admin': true}); } diff --git a/static/scripts/app/views/dir.js b/static/scripts/app/views/dir.js index 90bbcdcabc..ab1336742f 100644 --- a/static/scripts/app/views/dir.js +++ b/static/scripts/app/views/dir.js @@ -106,6 +106,14 @@ define([ } }); + // confirm leaving the page when file is uploading + window.onbeforeunload = function(e) { + if ($('#upload-file-dialog').is(':visible') && + $('#upload-file-dialog .status').text() == window.fileuploading) { + return ''; + } + }; + }, renderMainCon: function() { diff --git a/static/scripts/app/views/fileupload.js b/static/scripts/app/views/fileupload.js index 725ed7c3d5..9d55429ee6 100644 --- a/static/scripts/app/views/fileupload.js +++ b/static/scripts/app/views/fileupload.js @@ -49,6 +49,8 @@ define([ 'canceled': gettext("File Upload canceled"), 'failed': gettext("File Upload failed") }; + // for the leaving page confirm popup + window.fileuploading = fu_status.uploading; var uploaded_files = []; var updated_files = []; diff --git a/tests/seahub/utils/test_generate_file_audit_event_type.py b/tests/seahub/utils/test_generate_file_audit_event_type.py new file mode 100644 index 0000000000..77a20f2ba2 --- /dev/null +++ b/tests/seahub/utils/test_generate_file_audit_event_type.py @@ -0,0 +1,44 @@ +from seahub.test_utils import BaseTestCase +from seahub.utils import generate_file_audit_event_type + +try: + from seahub.settings import LOCAL_PRO_DEV_ENV +except ImportError: + LOCAL_PRO_DEV_ENV = False + +class Events(): + + def __init__(self, etype, device): + self.etype = etype + self.device = device + + +class GenerateFileAuditEventTypeTest(BaseTestCase): + + def test_generate_file_audit_event_type(self): + + if not LOCAL_PRO_DEV_ENV: + return + + event_type_device = { + 'file-download-web': '', + 'file-download-share-link': '', + 'file-download-api': 'file-download-api-device', + 'repo-download-sync': 'repo-download-sync-device', + 'repo-upload-sync': 'repo-upload-sync-device', + 'seadrive-download-file': 'seadrive-download-file-device', + 'unknow-type-has-device': 'has-device', + 'unknow-type-no-device': '', + } + + for key,value in event_type_device.items(): + + e = Events(key, value) + + assert generate_file_audit_event_type(e)[1] == value + + if e.etype == 'unknow-type-has-device': + assert generate_file_audit_event_type(e)[1] == 'has-device' + + if e.etype == 'unknow-type-no-device': + assert generate_file_audit_event_type(e)[1] == ''