diff --git a/media/js/base.js b/media/js/base.js index ee42ba60a8..c9468c57e4 100644 --- a/media/js/base.js +++ b/media/js/base.js @@ -70,10 +70,18 @@ $(function() { // set a notice to be read when in it is clicked $('.unread a', notice_list).click(function() { var notice_id = $(this).parents('.unread').data('id'); + var link_href = $(this).attr('href'); $.ajax({ url: notice_list.data('url') + '?notice_id=' + e(notice_id), - dataType:'json' + dataType:'json', + success: function(data) { + location.href = link_href; + }, + error: function() { + location.href = link_href; + } }); + return false; }); $('.detail', notice_list).click(function() { diff --git a/seahub/notifications/management/commands/send_notices.py b/seahub/notifications/management/commands/send_notices.py index e22e7d069b..0730a7792b 100644 --- a/seahub/notifications/management/commands/send_notices.py +++ b/seahub/notifications/management/commands/send_notices.py @@ -44,7 +44,15 @@ class Command(BaseCommand): repl = r'src="%s\1"' % get_site_scheme_and_netloc() return re.sub(pattern, repl, img_tag) - def get_file_upload_avatar_url(self, default_size=32): + def get_avatar_src(self, username, default_size=32): + avatar_img = self.get_avatar(username, default_size) + m = re.search('""" % \ (get_default_avatar_url(), default_size, default_size) @@ -52,6 +60,14 @@ class Command(BaseCommand): repl = r'src="%s\1"' % get_site_scheme_and_netloc() return re.sub(pattern, repl, img_tag) + def get_default_avatar_src(self, default_size=32): + avatar_img = self.get_default_avatar(default_size) + m = re.search(' -table { width:100%; margin:12px 0 20px; table-layout:fixed; border-spacing: 0; border-collapse: collapse;} -td, th { font-size: 13px; padding: 5px 3px; word-wrap: break-word; border-bottom: 1px solid #eee; } -th { text-align: left; font-weight: normal; color: #9c9c9c; } -td { color: #333; } -p { line-height: 1.5; margin:.2em 0; } -.hi { color:#121214;font-size:14px;margin-bottom:12px; } -.amount { font-size:14px;color:#434144; } -.avatar-cell { text-align:center; vertical-align:top; padding-top:8px; } -.avatar {border-radius: 1000px;} -.topic { padding: 4px 13px; border-left: 3px solid #e0e0e0; margin-left: 7px; } -.brief, .detail { margin-right:10px; } - - -

{% blocktrans with name=to_user|email2nickname %}Hi, {{ name }}{% endblocktrans %}

-

+

{% blocktrans with name=to_user|email2nickname %}Hi, {{ name }}{% endblocktrans %}

+

{% blocktrans count num=notice_count %} You've got 1 new notice on {{ site_name }}: {% plural %} @@ -27,53 +13,53 @@ You've got {{num}} new notices on {{ site_name }}: {% endblocktrans %}

- +
- - - + + + {% for notice in notices %} - - + - + {% endfor %}
{% trans "Message" %}{% trans "Time" %}{% trans "Message" %}{% trans "Time" %}
{{notice.avatar|safe}} + {% if notice.is_group_msg %} -

{% blocktrans with user=notice.notice_from grp_url=notice.group_url grp_name=notice.group_name%}{{user}} posted a new discussion in {{grp_name}}{% endblocktrans %}

+

{% blocktrans with user=notice.notice_from grp_url=notice.group_url grp_name=notice.group_name%}{{user}} posted a new discussion in {{grp_name}}{% endblocktrans %}

{% if notice.grp_msg %} -

{{notice.grp_msg}}

+

{{notice.grp_msg}}

{% endif %} {% elif notice.is_grpmsg_reply %} -

{% blocktrans with user=notice.notice_from reply_url=notice.group_msg_reply_url%}{{user}} replied your group discussion{% endblocktrans %}

+

{% blocktrans with user=notice.notice_from reply_url=notice.group_msg_reply_url%}{{user}} replied your group discussion{% endblocktrans %}

{% if notice.grp_reply_msg %} -
+
{% if notice.grpmsg_topic %} -

{{notice.grpmsg_topic}}

+

{{notice.grpmsg_topic|truncatechars:45}}

{% endif %} -

{{notice.grp_reply_msg}}

+

{{notice.grp_reply_msg}}

{% endif %} {% elif notice.is_repo_share_msg %} -

{% blocktrans with user=notice.notice_from lib_url=notice.repo_url lib_name=notice.repo_name%}{{user}} has shared a library named {{lib_name}} to you.{% endblocktrans %}

+

{% blocktrans with user=notice.notice_from lib_url=notice.repo_url lib_name=notice.repo_name%}{{user}} has shared a library named {{lib_name}} to you.{% endblocktrans %}

{% elif notice.is_priv_file_share_msg %} -

{% blocktrans with user=notice.notice_from file_url=notice.priv_shared_file_url file_name=notice.priv_shared_file_name %}{{user}} has shared a file named {{file_name}} to you.{% endblocktrans %}

+

{% blocktrans with user=notice.notice_from file_url=notice.priv_shared_file_url file_name=notice.priv_shared_file_name %}{{user}} has shared a file named {{file_name}} to you.{% endblocktrans %}

{% elif notice.is_user_message %} -

{% blocktrans with msg_url=notice.user_msg_url user=notice.notice_from %}You have received a new message from {{user}}.{% endblocktrans %}

+

{% blocktrans with msg_url=notice.user_msg_url user=notice.notice_from %}You have received a new message from {{user}}.{% endblocktrans %}

{% if notice.user_msg %} -

{{notice.user_msg}}

+

{{notice.user_msg}}

{% endif %} {% elif notice.is_file_uploaded_msg %} -

{% blocktrans with file_url=notice.file_link file_name=notice.file_name folder_url=notice.folder_link folder_name=notice.folder_name %}A file named {{file_name}} is uploaded to your folder {{folder_name}}.{% endblocktrans %}

+

{% blocktrans with file_url=notice.file_link file_name=notice.file_name folder_url=notice.folder_link folder_name=notice.folder_name %}A file named {{file_name}} is uploaded to your folder {{folder_name}}.{% endblocktrans %}

{% elif notice.is_group_join_request %} -

{% blocktrans with user_url=notice.grpjoin_user_profile_url user=notice.notice_from grp_url=notice.grpjoin_group_url grp_name=notice.grpjoin_group_name msg=notice.grpjoin_request_msg %}User {{user}} has asked to join group {{grp_name}}, verification message: {{msg}}{% endblocktrans %}

+

{% blocktrans with user_url=notice.grpjoin_user_profile_url user=notice.notice_from grp_url=notice.grpjoin_group_url grp_name=notice.grpjoin_group_name msg=notice.grpjoin_request_msg %}User {{user}} has asked to join group {{grp_name}}, verification message: {{msg}}{% endblocktrans %}

{% endif %}
{{ notice.timestamp|date:"Y-m-d G:i:s"}}{{ notice.timestamp|date:"Y-m-d G:i:s"}}
diff --git a/seahub/notifications/templates/notifications/user_notification_tr.html b/seahub/notifications/templates/notifications/user_notification_tr.html index 57544a8203..f20e35e949 100644 --- a/seahub/notifications/templates/notifications/user_notification_tr.html +++ b/seahub/notifications/templates/notifications/user_notification_tr.html @@ -10,7 +10,7 @@ {% if notice.msg_from %}
{% avatar notice.msg_from 32 %} {% else %} - + {% endif %} @@ -25,7 +25,7 @@ {% if notice.format_grpmsg_reply_detail %}
{% if notice.format_grpmsg_reply_topic %} -

{{ notice.format_grpmsg_reply_topic|truncatechars:45 }}

+

{{ notice.format_grpmsg_reply_topic|truncatechars:60 }}

{% endif %}

{{ notice.format_grpmsg_reply_detail }}

diff --git a/seahub/templates/myhome.html b/seahub/templates/myhome.html index e15fcfff0a..4009d83d61 100644 --- a/seahub/templates/myhome.html +++ b/seahub/templates/myhome.html @@ -73,6 +73,11 @@ $(function() {$('#guide-for-new').modal({appendTo: '#main', focus:false});}); var cur_tab = $('.ui-tabs-selected .a'); var lib_create_btn = $('#repo-create'), sublib_create_btn = $('#sub-lib-create'); +// for 'long language' such as german +if (sublib_create_btn.text().length > 15) { // 'new Sub-library'.length is 15 + $('span', sublib_create_btn).text(trimFilename(sublib_create_btn.text(),14));; +} + // for initial state if (cur_tab.attr('id') == 'mylib-tab') { lib_create_btn.removeClass('hide'); diff --git a/seahub/templates/repo.html b/seahub/templates/repo.html index 8c901d7255..c8488b38df 100644 --- a/seahub/templates/repo.html +++ b/seahub/templates/repo.html @@ -936,14 +936,13 @@ $('#upload-file').click(function () { }); {% else %} $('#upload-file').click(function () { - var upload_success = false; var uploaded_files = []; $('#upload-file-dialog').modal({ focus:false, containerCss: {width:600, height:$(window).height()/1.5}, onClose: function() { $.modal.close(); - if (upload_success) { + if (uploaded_files.length > 0) { if ($('.file-item').length == 0) { // there is no file before this upload reqDirData('{% url 'repo_dir_data' repo.id %}?p=' + e(cur_path)); } else { @@ -985,39 +984,39 @@ $('#upload-file').click(function () { parent_dir.val(cur_path); - $.ajax({ - url: '{% url 'get_file_op_url' repo.id %}?op_type=' + e('upload'), - cache: false, - dataType: 'json', - success: function(data) { - form.attr('action', data['url']); - - try { - // Initialize the jQuery File Upload widget, which needs to use form action - form.fileupload({ - //singleFileUploads: false // using 1 request to upload all files of a selection - sequentialUploads: true - }) - .bind('fileuploaddone', function(e, data) { - if (data.textStatus == 'success') { - upload_success = true; - uploaded_files.push(data.result[0]); + try { + // Initialize the jQuery File Upload widget, which needs to use form action + form.fileupload({ + //singleFileUploads: false // using 1 request to upload all files of a selection + sequentialUploads: true + }) + .bind('fileuploadadd', function(e, data) { + // get url(token) for every file + $.ajax({ + url: '{% url 'get_file_op_url' repo.id %}?op_type=upload', + cache: false, + dataType: 'json', + success: function(ret) { + data.url = ret['url']; } }); - - // Enable iframe cross-domain access via redirect option: - form.fileupload( - 'option', - 'redirect', - window.location.href.replace(/\/repo\/[-a-z0-9]{36}\/.*/, '/media/cors/result.html?%s') - ); - } catch(e) { // in case the fileupload js file has not been loaded - form.append('

' + "{% trans "Error. Please try later." %}" + '

'); - setTimeout(function() { $.modal.close(); }, 1600); + }) + .bind('fileuploaddone', function(e, data) { + if (data.textStatus == 'success') { + uploaded_files.push(data.result[0]); } - }, - error: ajaxErrorHandler - }); + }); + + // Enable iframe cross-domain access via redirect option: + form.fileupload( + 'option', + 'redirect', + window.location.href.replace(/\/repo\/[-a-z0-9]{36}\/.*/, '/media/cors/result.html?%s') + ); + } catch(e) { // in case the fileupload js file has not been loaded + form.append('

' + "{% trans "Error. Please try later." %}" + '

'); + setTimeout(function() { $.modal.close(); }, 1600); + } }); {% endif %} diff --git a/seahub/templates/snippets/file_content_html.html b/seahub/templates/snippets/file_content_html.html index ebc12dd431..454b4c9df3 100644 --- a/seahub/templates/snippets/file_content_html.html +++ b/seahub/templates/snippets/file_content_html.html @@ -49,7 +49,7 @@ For details please refer to 'snippets/file_content_js.html'. {% endif %} {% if filetype == 'OpenDocument' %} - + {% endif %} {% else %}
diff --git a/seahub/templates/snippets/my_owned_repos.html b/seahub/templates/snippets/my_owned_repos.html index 0fe499ae43..3cb9f55e4e 100644 --- a/seahub/templates/snippets/my_owned_repos.html +++ b/seahub/templates/snippets/my_owned_repos.html @@ -1,7 +1,7 @@ {% load seahub_tags i18n %}
-
+
    {% if user.permissions.can_add_repo %}
  • {% trans "Mine" %}
  • @@ -15,7 +15,7 @@
    {% if ENABLE_SUB_LIBRARY and sub_lib_enabled %} - + {% endif %}
@@ -25,9 +25,9 @@ {% trans "Name" %} - {% trans "Description" %} - {% trans "Last Update" %} - {% trans "Operations" %} + {% trans "Description" %} + {% trans "Last Update" %} + {% trans "Operations" %} {% for repo in owned_repos %} {% if not ENABLE_SUB_LIBRARY or not repo.is_virtual %} @@ -72,9 +72,9 @@ {% trans "Name" %} - {% trans "Origin" %} - {% trans "Last Update" %} - {% trans "Operations" %} + {% trans "Origin" %} + {% trans "Last Update" %} + {% trans "Operations" %} {% for repo in sub_repos %} diff --git a/seahub/templates/snippets/notice_html.html b/seahub/templates/snippets/notice_html.html index 20ab1deab1..05097a6182 100644 --- a/seahub/templates/snippets/notice_html.html +++ b/seahub/templates/snippets/notice_html.html @@ -23,7 +23,7 @@ {% if notice.format_grpmsg_reply_detail %}
{% if notice.format_grpmsg_reply_topic %} -

{{ notice.format_grpmsg_reply_topic|truncatechars:25 }}

+

{{ notice.format_grpmsg_reply_topic|truncatechars:35 }}

{% endif %}

{{ notice.format_grpmsg_reply_detail }}

diff --git a/seahub/templates/view_file_base.html b/seahub/templates/view_file_base.html index e19d494d01..c66acfa426 100644 --- a/seahub/templates/view_file_base.html +++ b/seahub/templates/view_file_base.html @@ -239,20 +239,17 @@ function setToolbarPos() { $('#to-group').css({'top': parseInt(toolbar.css('top')) + 59}); } $(window).load(function() { - // if page needs scroll, show 'back-to-top' icon - if ($(document).height() > $(window).height()) { - var to_top = $('
  • {% trans
'); - to_top.click(function() { - $(window).scrollTop(0); - }).appendTo($('#fileview-toolbar')); - $(window).scroll(function() { - if ($(window).scrollTop() > 0) { - to_top.show(); - } else { - to_top.hide(); - } - }); - } + var to_top = $('
  • {% trans
'); + to_top.click(function() { + $(window).scrollTop(0); + }).appendTo($('#fileview-toolbar')); + $(window).scroll(function() { + if ($(window).scrollTop() > 0) { + to_top.show(); + } else { + to_top.hide(); + } + }); setToolbarPos(); }).resize(setToolbarPos); diff --git a/seahub/templates/view_file_opendocument.html b/seahub/templates/view_file_opendocument.html index 0803fad05d..4fb1b6a337 100644 --- a/seahub/templates/view_file_opendocument.html +++ b/seahub/templates/view_file_opendocument.html @@ -4,7 +4,7 @@ {% block file_view %} {% if not err %} - + {% endif %} {% endblock %} diff --git a/seahub/templates/view_shared_upload_link.html b/seahub/templates/view_shared_upload_link.html index 3bf2c1d9fe..6b3ee81b46 100644 --- a/seahub/templates/view_shared_upload_link.html +++ b/seahub/templates/view_shared_upload_link.html @@ -23,7 +23,7 @@ {% if no_quota %}

{% trans "The owner of this library has run out of space." %}

{% else %} -
{% csrf_token %} + {% csrf_token %}
@@ -90,6 +90,17 @@ form.fileupload({ //singleFileUploads: false // using 1 request to upload all files of a selection sequentialUploads: true }) +.bind('fileuploadadd', function(e, data) { + // get url(token) for every file + $.ajax({ + url: '{% url 'get_file_upload_url_ul' uploadlink.token %}?&r={{uploadlink.repo_id }}', + cache: false, + dataType: 'json', + success: function(ret) { + data.url = ret['url']; + } + }); +}) .bind('fileuploaddone', function(e, data) { if (data.textStatus == 'success') { var filename = ""; diff --git a/seahub/urls.py b/seahub/urls.py index 794c1c4b04..13e8c2c029 100644 --- a/seahub/urls.py +++ b/seahub/urls.py @@ -6,7 +6,7 @@ from django.views.generic import TemplateView from seahub.views import * from seahub.views.file import view_file, view_history_file, view_trash_file,\ view_snapshot_file, file_edit, view_shared_file, view_file_via_shared_dir,\ - text_diff, view_priv_shared_file + text_diff, view_priv_shared_file, view_raw_file, view_raw_shared_file from seahub.views.repo import repo, repo_history_view from notifications.views import notification_list from group.views import group_list @@ -72,6 +72,7 @@ urlpatterns = patterns('', url(r'^repo/recycle/(?P[-0-9a-f]{36})/$', repo_recycle_view, name='repo_recycle_view'), url(r'^repo/snapshot/view/(?P[-0-9a-f]{36})/$', repo_view_snapshot, name='repo_view_snapshot'), url(r'^repo/(?P[-0-9a-f]{36})/files/$', view_file, name="repo_view_file"), + url(r'^repo/(?P[-0-9a-f]{36})/raw/(?P.*)$', view_raw_file, name="view_raw_file"), url(r'^repo/(?P[-0-9a-f]{36})/history/files/$', view_history_file, name="view_history_file"), url(r'^repo/(?P[-0-9a-f]{36})/trash/files/$', view_trash_file, name="view_trash_file"), url(r'^repo/(?P[-0-9a-f]{36})/snapshot/files/$', view_snapshot_file, name="view_snapshot_file"), @@ -88,6 +89,7 @@ urlpatterns = patterns('', url(r'^s/f/(?P[a-f0-9]{10})/rm/$', rm_private_file_share, name="rm_private_file_share"), url(r'^s/f/(?P[a-f0-9]{10})/save/$', save_private_file_share, name='save_private_file_share'), url(r'^f/(?P[a-f0-9]{10})/$', view_shared_file, name='view_shared_file'), + url(r'^f/(?P[a-f0-9]{10})/raw/(?P[0-9a-f]{40})/(?P.*)', view_raw_shared_file, name='view_raw_shared_file'), url(r'^d/(?P[a-f0-9]{10})/$', view_shared_dir, name='view_shared_dir'), url(r'^d/(?P[a-f0-9]{10})/files/$', view_file_via_shared_dir, name='view_file_via_shared_dir'), url(r'^u/d/(?P[a-f0-9]{10})/$', view_shared_upload_link, name='view_shared_upload_link'), @@ -136,6 +138,7 @@ urlpatterns = patterns('', url(r'^ajax/repo/(?P[-0-9a-f]{36})/history/changes/$', repo_history_changes, name='repo_history_changes'), url(r'^ajax/repo/(?P[-0-9a-f]{36})/encrypted_file/(?P[0-9a-f]{40})/download/$', download_enc_file, name='download_enc_file'), url(r'^ajax/repo/(?P[-0-9a-f]{36})/file_op_url/$', get_file_op_url, name='get_file_op_url'), + url(r'^ajax/u/d/(?P[-0-9a-f]{10})/upload/$', get_file_upload_url_ul, name='get_file_upload_url_ul'), url(r'^ajax/group/(?P\d+)/repos/$', get_unenc_group_repos, name='get_group_repos'), url(r'^ajax/my-unenc-repos/$', get_my_unenc_repos, name='get_my_unenc_repos'), url(r'^ajax/unenc-rw-repos/$', unenc_rw_repos, name='unenc_rw_repos'), diff --git a/seahub/views/__init__.py b/seahub/views/__init__.py index ed7e12710f..d19b76d044 100644 --- a/seahub/views/__init__.py +++ b/seahub/views/__init__.py @@ -1475,6 +1475,7 @@ def view_shared_upload_link(request, token): return render_to_response('view_shared_upload_link.html', { 'repo': repo, 'token': token, + 'uploadlink': uploadlink, 'path': path, 'username': username, 'dir_name': dir_name, diff --git a/seahub/views/ajax.py b/seahub/views/ajax.py index 3d5b4caaf6..432dfbd9ae 100644 --- a/seahub/views/ajax.py +++ b/seahub/views/ajax.py @@ -26,6 +26,7 @@ from seahub.options.models import UserOptions, CryptoOptionNotSetError from seahub.notifications.models import UserNotification from seahub.notifications.views import add_notice_from_info from seahub.message.models import UserMessage +from seahub.share.models import UploadLinkShare from seahub.signals import upload_file_successful, repo_created, repo_deleted from seahub.views import get_repo_dirents, validate_owner, \ check_repo_access_permission, get_unencry_rw_repos_by_user, \ @@ -1561,6 +1562,35 @@ def get_file_op_url(request, repo_id): return HttpResponse(json.dumps({"url": url}), content_type=content_type) +def get_file_upload_url_ul(request, token): + """Get file upload url in dir upload link. + + Arguments: + - `request`: + - `token`: + """ + if not request.is_ajax(): + raise Http404 + + content_type = 'application/json; charset=utf-8' + + uls = UploadLinkShare.objects.get_valid_upload_link_by_token(token) + if uls is None: + return HttpResponse(json.dumps({"error": _("Bad upload link token.")}), + status=400, content_type=content_type) + + repo_id = uls.repo_id + r = request.GET.get('r', '') + if repo_id != r: # perm check + return HttpResponse(json.dumps({"error": _("Bad repo id in upload link.")}), + status=403, content_type=content_type) + + acc_token = seafile_api.get_fileserver_access_token(repo_id, 'dummy', + 'upload', + request.user.username) + url = gen_file_upload_url(acc_token, 'upload-aj') + return HttpResponse(json.dumps({"url": url}), content_type=content_type) + @login_required_ajax def repo_history_changes(request, repo_id): changes = {} diff --git a/seahub/views/file.py b/seahub/views/file.py index 4963627ff7..6849a42659 100644 --- a/seahub/views/file.py +++ b/seahub/views/file.py @@ -700,6 +700,43 @@ def view_shared_file(request, token): 'traffic_over_limit': traffic_over_limit, }, context_instance=RequestContext(request)) +def view_raw_shared_file(request, token, obj_id, file_name): + """Returns raw content of a shared file. + + Arguments: + - `request`: + - `token`: + - `obj_id`: + - `file_name`: + """ + fileshare = FileShare.objects.get_valid_file_link_by_token(token) + if fileshare is None: + raise Http404 + + repo_id = fileshare.repo_id + repo = get_repo(repo_id) + if not repo: + raise Http404 + + # Normalize file path based on file or dir share link + if fileshare.is_file_share_link(): + file_path = fileshare.path.rstrip('/') + else: + file_path = fileshare.path.rstrip('/') + '/' + file_name + + real_obj_id = seafile_api.get_file_id_by_path(repo_id, file_path) + if not real_obj_id: + raise Http404 + + if real_obj_id != obj_id: # perm check + raise Http404 + + filename = os.path.basename(file_path) + username = request.user.username + token = web_get_access_token(repo_id, real_obj_id, 'view', username) + outer_url = gen_file_get_url(token, filename) + return HttpResponseRedirect(outer_url) + def view_file_via_shared_dir(request, token): assert token is not None # Checked by URLconf @@ -969,6 +1006,33 @@ def file_edit(request, repo_id): 'cancel_url': cancel_url, }, context_instance=RequestContext(request)) +@login_required +def view_raw_file(request, repo_id, file_path): + """Returns raw content of a file. + + Arguments: + - `request`: + - `repo_id`: + """ + repo = get_repo(repo_id) + if not repo: + raise Http404 + + file_path = file_path.rstrip('/') + if file_path[0] != '/': + file_path = '/' + file_path + + obj_id = get_file_id_by_path(repo_id, file_path) + if not obj_id: + raise Http404 + + raw_path, inner_path, user_perm = get_file_view_path_and_perm( + request, repo.id, obj_id, file_path) + if user_perm is None: + raise Http404 + + return HttpResponseRedirect(raw_path) + ########## text diff def get_file_content_by_commit_and_path(request, repo_id, commit_id, path, file_enc): try: