diff --git a/seahub/templates/snippets/file_content_html.html b/seahub/templates/snippets/file_content_html.html
index ebc12dd431..1c9ed8ed0e 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/view_file_opendocument.html b/seahub/templates/view_file_opendocument.html
index 0803fad05d..672cc773c9 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/urls.py b/seahub/urls.py
index 794c1c4b04..4ad272c97a 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'),
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: