diff --git a/media/css/seahub.css b/media/css/seahub.css
index 2df5768d74..66e373ff3a 100644
--- a/media/css/seahub.css
+++ b/media/css/seahub.css
@@ -582,3 +582,15 @@ table img {
#upload-cancel {
margin-top:8px;
}
+
+/* file preview */
+#file-content {
+ border: 1px solid #999;
+ padding: 5px;
+ min-height: 200px;
+ white-space: pre-wrap; /* css-3 */
+ white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
+ white-space: -pre-wrap; /* Opera 4-6 */
+ white-space: -o-pre-wrap; /* Opera 7 */
+ word-wrap: break-word; /* Internet Explorer 5.5+ */
+}
diff --git a/settings.py b/settings.py
index 34e3222aa9..10f65a1ba0 100644
--- a/settings.py
+++ b/settings.py
@@ -170,6 +170,13 @@ USE_SUBDOMAIN = False
# account type is `personal` or `business`
ACCOUNT_TYPE = 'personal'
+FILE_PREVIEW_MAX_SIZE = 10 * 1024 * 1024
+
+PREVIEW_FILEEXT = {
+ 'Document': ('ac', 'am', 'as', 'as3', 'asm', 'bat', 'c', 'cc', 'cmake', 'cpp', 'cs', 'css', 'csv', 'cxx', 'diff', 'erb', 'groovy', 'gsheet', 'h', 'haml', 'hh', 'htm', 'html', 'java', 'js', 'less', 'm', 'make', 'ml', 'mm', 'ods', 'odt', 'php', 'pl', 'properties', 'py', 'rb', 'rtf', 'sass', 'scala', 'scm', 'script', 'sh', 'sml', 'sql', 'txt', 'vi', 'vim', 'wpd', 'xls', 'xlsm', 'xlsx', 'xml', 'xsd', 'xsl', 'xslt', 'yaml'),
+ 'Image': ('ai', 'bmp', 'eps', 'gif', 'ind', 'jpeg', 'jpg', 'png', 'ps', 'psd', 'tif', 'tiff'),
+}
+
try:
import local_settings
except ImportError:
diff --git a/templates/repo.html b/templates/repo.html
index 0f512c3dc1..fecd5af62a 100644
--- a/templates/repo.html
+++ b/templates/repo.html
@@ -104,7 +104,7 @@
{% for dirent in file_list %}
 |
- {{ dirent.props.obj_name }} |
+ {{ dirent.props.obj_name }} |
{{ dirent.file_size|filesizeformat }} |
diff --git a/templates/repo_view_file.html b/templates/repo_view_file.html
new file mode 100644
index 0000000000..f9640015d1
--- /dev/null
+++ b/templates/repo_view_file.html
@@ -0,0 +1,71 @@
+{% extends "myhome_base.html" %}
+{% load seahub_tags %}
+
+{% block info_bar_message %}
+{% if request.user.is_authenticated %}
+ {{ block.super }}
+{% else %}
+
+{% endif %}
+{% endblock %}
+
+{% block main_panel %}
+
+ {{repo.props.name}}
+
+
+
+
+
+
+ 当前路径:
+ {% for name, link in zipped %}
+ {% if not forloop.last %}
+ {{ name }} /
+ {% else %}
+ {{ name }}
+ {% endif %}
+ {% endfor %}
+
+ 正在读取文件内容...
+
+{% endblock %}
+
+{% block extra_script %}
+
+{% endblock %}
diff --git a/urls.py b/urls.py
index 168db59d8d..bce26d81b6 100644
--- a/urls.py
+++ b/urls.py
@@ -8,11 +8,10 @@ from seahub.views import root, peers, myhome, \
activate_user, user_add, user_remove, sys_group_admin, sys_org_admin, \
ownerhome, repo_history_dir, repo_history_revert, \
user_info, repo_set_access_property, repo_access_file, \
- repo_remove_share, repo_download, org_info, \
+ repo_remove_share, repo_download, org_info, repo_view_file, \
seafile_access_check, back_local, repo_history_changes, \
repo_upload_file, file_upload_progress, file_upload_progress_page, get_subdir, file_move, \
repo_new_dir, repo_rename_file, validate_filename
-
from seahub.notifications.views import notification_list
from seahub.share.views import share_admin
from seahub.group.views import group_list
@@ -59,6 +58,8 @@ urlpatterns = patterns('',
# (r'^repo/removefetched/(?P[^/]+)/(?P[^/]+)/$', remove_fetched_repo),
# (r'^repo/setap/(?P[^/]+)/$', repo_set_access_property),
(r'^repo/(?P[^/]+)/(?P[^/]+)/$', repo_access_file),
+ (r'^repo/(?P[^/]+)/view/(?P[^/]+)/$', repo_view_file),
+
(r'^download/repo/$', repo_download),
(r'^file/move/get_subdir/$', get_subdir),
(r'^file/move/$', file_move),
diff --git a/utils.py b/utils.py
index a761a1c2a7..924f75cc2d 100644
--- a/utils.py
+++ b/utils.py
@@ -1,6 +1,7 @@
#!/usr/bin/env python
# encoding: utf-8
import settings
+import os
import re
import time
import os
@@ -17,6 +18,9 @@ from seaserv import seafserv_rpc, ccnet_threaded_rpc, seafserv_threaded_rpc, \
EMPTY_SHA1 = '0000000000000000000000000000000000000000'
+import settings
+from settings import PREVIEW_FILEEXT
+
def go_permission_error(request, msg=None):
"""
Return permisson error page.
@@ -225,3 +229,14 @@ def get_accessible_repos(request, repo):
repo.props.has_subdir = check_has_subdir(repo)
return accessible_repos
+
+def valid_previewed_file(filename):
+ """
+ Check whether file can preview on web
+
+ """
+ fileExt = os.path.splitext(filename)[1][1:]
+ for filetype in PREVIEW_FILEEXT.keys():
+ if fileExt in PREVIEW_FILEEXT.get(filetype):
+ return (True, filetype)
+ return (False, '')
diff --git a/views.py b/views.py
index 83460d0edf..92f732faaa 100644
--- a/views.py
+++ b/views.py
@@ -3,7 +3,9 @@ import settings
import os
import stat
import simplejson as json
+import re
import sys
+import urllib2
from urllib import quote
from django.core.urlresolvers import reverse
from django.core.mail import send_mail
@@ -34,9 +36,10 @@ from seahub.notifications.models import UserNotification
from forms import AddUserForm
from utils import go_permission_error, go_error, list_to_string, \
get_httpserver_root, get_ccnetapplet_root, gen_token, \
- calculate_repo_last_modify, \
+ calculate_repo_last_modify, valid_previewed_file, \
check_filename_with_rename, get_accessible_repos, EMPTY_SHA1
from seahub.profile.models import Profile
+from settings import FILE_PREVIEW_MAX_SIZE
@login_required
def root(request):
@@ -751,6 +754,104 @@ def repo_del_file(request, repo_id):
url = reverse('repo', args=[repo_id]) + ('?p=%s' % parent_dir)
return HttpResponseRedirect(url)
+@login_required
+def repo_view_file(request, repo_id, obj_id):
+ http_server_root = get_httpserver_root()
+ filename = urllib2.quote(request.GET.get('file_name', '').encode('utf-8'))
+
+ if request.is_ajax():
+ content_type = 'application/json; charset=utf-8'
+ token = request.GET.get('t')
+ tmp_str = '%s/access?repo_id=%s&id=%s&filename=%s&op=%s&t=%s&u=%s'
+ redirect_url = tmp_str % (http_server_root,
+ repo_id, obj_id,
+ filename, 'view',
+ token,
+ request.user.username)
+ try:
+ proxied_request = urllib2.urlopen(redirect_url)
+ if long(proxied_request.headers['Content-Length']) > FILE_PREVIEW_MAX_SIZE:
+ data = json.dumps([{'error': '文件超过10M,无法在线查看。'}])
+ return HttpResponse(data, status=400, content_type=content_type)
+ else:
+ content = proxied_request.read()
+ except urllib2.HTTPError, e:
+ err = 'HTTPError: 无法在线打开该文件'
+ data = json.dumps([{'error': err}])
+ return HttpResponse(data, status=400, content_type=content_type)
+ except urllib2.URLError as e:
+ err = 'URLError: 无法在线打开该文件'
+ data = json.dumps([{'error': err}])
+ return HttpResponse(data, status=400, content_type=content_type)
+ else:
+ l, d = [], {}
+ try:
+ # XXX: file in windows is encoded in gbk
+ u_content = content.decode('gbk')
+ except:
+ u_content = content.decode('utf-8')
+ from django.utils.html import escape
+ d['content'] = re.sub("\r\n|\n", " ", escape(u_content))
+ l.append(d)
+ data = json.dumps(l)
+ return HttpResponse(data, status=200, content_type=content_type)
+
+ repo = get_repo(repo_id)
+ if not repo:
+ raise Http404
+
+ # if a repo doesn't have access property in db, then assume it's 'own'
+ repo_ap = seafserv_threaded_rpc.repo_query_access_property(repo_id)
+ if not repo_ap:
+ repo_ap = 'own'
+
+ # if a repo is shared to me, then I can view and download file no mater whether
+ # repo's access property is 'own' or 'public'
+ if check_shared_repo(request, repo_id):
+ share_to_me = True
+ else:
+ share_to_me = False
+
+ token = ''
+ if repo_ap == 'own':
+ # people who is owner or this repo is shared to him, can visit the repo;
+ # others, just go to 404 page
+ if validate_owner(request, repo_id) or share_to_me:
+ # owner should get a token to visit repo
+ token = gen_token()
+ # put token into memory in seaf-server
+ seafserv_rpc.web_save_access_token(token, obj_id)
+ else:
+ raise Http404
+
+ # generate path and link
+ path = request.GET.get('p', '/')
+ if path[-1] != '/':
+ path = path + '/'
+ zipped = gen_path_link(path, repo.name)
+
+ # filename
+ can_preview, filetype = valid_previewed_file(filename)
+
+ # raw path
+ tmp_str = '%s/access?repo_id=%s&id=%s&filename=%s&op=%s&t=%s&u=%s'
+ raw_path = tmp_str % (http_server_root,
+ repo_id, obj_id,
+ filename, 'view',
+ token,
+ request.user.username)
+
+ return render_to_response('repo_view_file.html', {
+ 'repo': repo,
+ 'obj_id': obj_id,
+ 'file_name': filename,
+ 'zipped': zipped,
+ 'token': token,
+ 'can_preview': can_preview,
+ 'filetype': filetype,
+ 'raw_path': raw_path,
+ }, context_instance=RequestContext(request))
+
def repo_access_file(request, repo_id, obj_id):
if repo_id:
repo = get_repo(repo_id)
@@ -807,7 +908,7 @@ def repo_access_file(request, repo_id, obj_id):
token,
request.user.username)
return HttpResponseRedirect(redirect_url)
-
+
@login_required
def repo_download(request):
repo_id = request.GET.get('repo_id', '')
|