diff --git a/base/models.py b/base/models.py
index 71a8362390..c82197f8cf 100644
--- a/base/models.py
+++ b/base/models.py
@@ -1,3 +1,11 @@
from django.db import models
-# Create your models here.
+
+class UuidOjbidMap(models.Model):
+ """
+ Model used for store crocdoc uuid and file object id mapping.
+ """
+ uuid = models.CharField(max_length=40)
+ obj_id = models.CharField(max_length=40, unique=True)
+
+
diff --git a/settings.py b/settings.py
index 461686e9bc..84bdd88307 100644
--- a/settings.py
+++ b/settings.py
@@ -205,6 +205,9 @@ SEAHUB_TITLE = 'SeaHub'
USE_SUBDOMAIN = False
ACCOUNT_TYPE = 'personal'
+# Replace this with your Crocodoc.com api token
+CROCODOC_API_TOKEN = ''
+
try:
import local_settings
except ImportError:
diff --git a/templates/repo_file_get.html b/templates/repo_file_get.html
index 0beeead7ff..9fe9b4437c 100644
--- a/templates/repo_file_get.html
+++ b/templates/repo_file_get.html
@@ -1,4 +1,4 @@
- if (filetype == 'Document') {
+ if (filetype == 'Text') {
$.ajax({
url: url,
dataType: 'json',
@@ -18,6 +18,82 @@
$('#file-view').html('
').css({'text-align':'center', 'padding':'30px 0'});
} else if (filetype == 'SVG') {
$('#file-view').html('');
- } else {
+ } else if (filetype == 'Document' ) {
+ var tid= 0;
+ var uuid = '';
+ var obj_id = '';
+ function create_session() {
+ $.ajax({
+ url: '{{ SITE_ROOT }}crocodoc/session/?uuid=' + uuid,
+ dataType: 'json',
+ cache: false,
+ contentType: 'application/json; charset=utf-8',
+ success: function(data) {
+ if (data.length > 0) {
+ var doc_src = data[0]['doc_src'];
+ var iframe_src = ''
+ $('#file-view').html(iframe_src);
+ }
+ },
+ error: function(xhr, ajaxOptions, thrownError) {
+ var jsonVal = jQuery.parseJSON(xhr.responseText);
+ $('#file-view').html('
' + jsonVal[0]['error'] + '
');
+ }
+ });
+ }
+ function abortTimer () {
+ clearTimeout(tid);
+ }
+ function check_status () {
+ $.ajax({
+ url: '{{ SITE_ROOT }}crocodoc/status/?uuids='+ uuid + '&obj_id=' + obj_id,
+ dataType: 'json',
+ cache: false,
+ contentType: 'application/json; charset=utf-8',
+ success: function(data) {
+ if (data.length > 0) {
+ var status = data[0]['status']
+ if (status == 'QUEUED') {
+ $('#file-view').html('' + '文档转换任务正在排队,请稍后...' + '
');
+ tid = setTimeout(check_status, 1000); } else if (status == 'PROCESSING') {
+ $('#file-view').html('' + '文档正在转换,请稍候...' + '
');
+ tid = setTimeout(check_status, 1000); } else if (status == 'DONE') {
+ $('#file-view').html('' + '文档转换成功。正在打开...' + '
');
+ abortTimer();
+ create_session();
+ } else {
+ abortTimer();
+ }
+ }
+ },
+ error: function(xhr, ajaxOptions, thrownError) {
+ var jsonVal = jQuery.parseJSON(xhr.responseText);
+ $('#file-view').html('' + jsonVal[0]['error'] + '
');
+ abortTimer();
+ return false;
+ }
+ });
+ }
+ $.ajax({
+ url: '{{ SITE_ROOT }}crocodoc/upload/?raw_path={{ raw_path|urlencode }}',
+ dataType: 'json',
+ cache: false,
+ contentType: 'application/json; charset=utf-8',
+ success: function(data) {
+ if (data.length > 0) {
+ uuid = data[0]['uuid'];
+ obj_id = data[0]['obj_id'];
+ $('#file-view').html('文档内容读取成功,开始转换...
');
+
+ tid = setTimeout(check_status, 1000);
+ }
+ },
+ error: function(xhr, ajaxOptions, thrownError) {
+ var jsonVal = jQuery.parseJSON(xhr.responseText);
+ $('#file-view').html('' + jsonVal[0]['error'] + '
');
+ }
+ });
+ }
+ else {
$('#file-view').html('该类型文件无法在线查看。下载
');
}
\ No newline at end of file
diff --git a/urls.py b/urls.py
index fad5896dce..c83725dc14 100644
--- a/urls.py
+++ b/urls.py
@@ -13,7 +13,8 @@ from seahub.views import root, peers, myhome, \
repo_upload_file, file_upload_progress, file_upload_progress_page, \
get_subdir, file_move, repo_new_dir, repo_rename_file, validate_filename, \
repo_create, repo_update_file, file_revisions, \
- get_shared_link, view_shared_file, remove_shared_link, send_shared_link
+ get_shared_link, view_shared_file, remove_shared_link, send_shared_link, \
+ crocodoc_upload, crocodoc_status, crocodoc_session
from seahub.notifications.views import notification_list
from seahub.share.views import share_admin
from seahub.group.views import group_list
@@ -68,7 +69,7 @@ urlpatterns = patterns('',
url(r'^repo/(?P[^/]+)/files/$', repo_view_file, name="repo_view_file"),
(r'^repo/(?P[^/]+)/file/get/$', repo_file_get),
url(r'^repo/(?P[^/]+)/(?P[^/]+)/$', repo_access_file, name='repo_access_file'),
-
+
(r'^download/repo/$', repo_download),
(r'^file/move/get_subdir/$', get_subdir),
(r'^file/move/$', file_move),
@@ -81,6 +82,11 @@ urlpatterns = patterns('',
(r'^useradmin/remove/(?P[^/]+)/$', user_remove),
(r'^useradmin/info/(?P[^/]+)/$', user_info),
(r'^useradmin/activate/(?P[^/]+)/$', activate_user),
+
+ ### Document previewd ###
+ (r'^crocodoc/upload/$', crocodoc_upload),
+ (r'^crocodoc/status/$', crocodoc_status),
+ (r'^crocodoc/session/$', crocodoc_session),
### Apps ###
(r'^avatar/', include('avatar.urls')),
diff --git a/utils.py b/utils.py
index 0234ac1d8e..2a09b1df6e 100644
--- a/utils.py
+++ b/utils.py
@@ -19,9 +19,10 @@ import settings
EMPTY_SHA1 = '0000000000000000000000000000000000000000'
PREVIEW_FILEEXT = {
- 'Document': ('ac', 'am', 'bat', 'c', 'cc', 'cmake', 'cpp', 'css', 'diff', 'h', 'html', 'java', 'js', 'json', 'less', 'make', 'markdown', 'org', 'php', 'properties', 'py', 'rb', 'scala', 'script', 'sh', 'sql', 'txt','text', 'vi', 'vim'),
+ 'Text': ('ac', 'am', 'bat', 'c', 'cc', 'cmake', 'cpp', 'css', 'diff', 'h', 'html', 'java', 'js', 'json', 'less', 'make', 'markdown', 'org', 'php', 'properties', 'py', 'rb', 'scala', 'script', 'sh', 'sql', 'txt','text', 'vi', 'vim'),
'Image': ('gif', 'jpeg', 'jpg', 'png'),
'SVG': ('svg',),
+ 'Document': ('doc', 'docx', 'ppt', 'pptx'),
}
def go_permission_error(request, msg=None):
diff --git a/views.py b/views.py
index 8087dcf19b..a5b9df0d6c 100644
--- a/views.py
+++ b/views.py
@@ -5,6 +5,7 @@ import stat
import simplejson as json
import re
import sys
+import urllib
import urllib2
from urllib import quote
from django.core.urlresolvers import reverse
@@ -33,6 +34,7 @@ from seaserv import ccnet_rpc, ccnet_threaded_rpc, get_groups, get_users, get_re
from pysearpc import SearpcError
from seahub.base.accounts import CcnetUser
+from seahub.base.models import UuidOjbidMap
from seahub.contacts.models import Contact
from seahub.notifications.models import UserNotification
from forms import AddUserForm, FileLinkShareForm
@@ -40,9 +42,10 @@ from utils import go_permission_error, go_error, list_to_string, \
get_httpserver_root, get_ccnetapplet_root, gen_token, \
calculate_repo_last_modify, valid_previewed_file, \
check_filename_with_rename, get_accessible_repos, EMPTY_SHA1, \
- get_file_revision_id_size, get_ccnet_server_addr_port, gen_file_get_url
+ get_file_revision_id_size, get_ccnet_server_addr_port, \
+ gen_file_get_url
from seahub.profile.models import Profile
-from settings import FILE_PREVIEW_MAX_SIZE
+from seahub.settings import FILE_PREVIEW_MAX_SIZE, CROCODOC_API_TOKEN
@login_required
def root(request):
@@ -846,7 +849,7 @@ def repo_view_file(request, repo_id):
# determin whether file can preview on web
filetype = valid_previewed_file(filename)
-
+
# raw path
raw_path = gen_file_get_url(token, filename)
@@ -881,6 +884,7 @@ def repo_view_file(request, repo_id):
'protocol': http_or_https,
'domain': domain,
'file_shared_link': file_shared_link,
+ # 'doc_src': doc_src,
}, context_instance=RequestContext(request))
def repo_file_get(request, repo_id):
@@ -1985,3 +1989,126 @@ def send_shared_link(request):
msg = '发送成功。'
data = json.dumps([{'msg': msg}])
return HttpResponse(data, status=200, content_type=content_type)
+
+def crocodoc_upload(request):
+ """
+ Handle ajax request to upload document to crocodoc.com.
+ """
+ if not request.is_ajax():
+ raise Http404
+
+ content_type = 'application/json; charset=utf-8'
+ raw_path = request.GET.get('raw_path', '')
+
+ # Fetch obj_id according token, if this obj_id already has uuid,
+ # send uuid; else, upload file.
+ obj_id = seafserv_rpc.web_query_access_token(raw_path.split('/files/')[1][:5]).obj_id
+ if not obj_id:
+ # Should nerver reach here.
+ data = json.dumps([{'error': '缺少obj_id'}])
+ return HttpResponse(data, status=500, content_type=content_type)
+ try:
+ uo = UuidOjbidMap.objects.get(obj_id=obj_id)
+ except UuidOjbidMap.DoesNotExist:
+ uo = None
+ if uo:
+ data = json.dumps([{'uuid': uo.uuid, 'obj_id': obj_id}])
+ return HttpResponse(data, status=200, content_type=content_type)
+
+ curl = "https://crocodoc.com/api/v2/document/upload"
+ data = {'token': CROCODOC_API_TOKEN,
+ 'url': raw_path}
+ try:
+ f = urllib2.urlopen(url=curl, data=urllib.urlencode(data))
+ except urllib2.URLError, e:
+ data = json.dumps([{'error': e.msg}])
+ return HttpResponse(data, status=500, content_type=content_type)
+ else:
+ ret = f.read()
+ ret_dict = json.loads(ret)
+ if ret_dict.has_key('error'):
+ data = json.dumps([{'error': ret_dict['error']}])
+ return HttpResponse(data, status=500, content_type=content_type)
+ else:
+ data = json.dumps([{'uuid': ret_dict['uuid'], 'obj_id': obj_id}])
+ return HttpResponse(data, status=200, content_type=content_type)
+
+def crocodoc_status(request):
+ """
+ Handle ajax request to get status of the document from crocodoc.com.
+ """
+ if not request.is_ajax():
+ raise Http404
+
+ content_type = 'application/json; charset=utf-8'
+ uuids = request.GET.get('uuids', '')
+ obj_id = request.GET.get('obj_id', '')
+
+ curl = 'https://crocodoc.com/api/v2/document/status?token=%s&uuids=%s' % (
+ CROCODOC_API_TOKEN, uuids
+ )
+
+ f = urllib2.urlopen(url=curl)
+ ret = f.read()
+ ret_list = json.loads(ret)
+ ret_dict = ret_list[0]
+ if ret_dict.has_key('error'):
+ # Delete obj_id-uuid in db
+ UuidOjbidMap.objects.filter(obj_id=obj_id).delete()
+
+ data = json.dumps([{'error': '文档转换出错:' + ret_dict['error']}])
+ return HttpResponse(data, status=500, content_type=content_type)
+
+ viewable = ret_dict['viewable'] # TODO: this may used in large file preview
+ status = ret_dict['status']
+ if status == 'QUEUED':
+ data = json.dumps([{'status': status}])
+ return HttpResponse(data, status=200, content_type=content_type)
+ elif status == 'PROCESSING':
+ data = json.dumps([{'status': status}])
+ return HttpResponse(data, status=200, content_type=content_type)
+ elif status == 'DONE':
+ # Cache obj_id and uuid in db
+ uo = UuidOjbidMap(uuid=uuids, obj_id=obj_id)
+ try:
+ uo.save()
+ except IntegrityError, e:
+ pass
+
+ data = json.dumps([{'status': status}])
+ return HttpResponse(data, status=200, content_type=content_type)
+ elif status == 'ERROR':
+ # Delete obj_id-uuid in db
+ UuidOjbidMap.objects.filter(obj_id=obj_id).delete()
+
+ err_msg = '文档转换出错:' + ret_dict['error'] if ret_dict.has_key('error') \
+ else '文档转换出错'
+ data = json.dumps([{'error': err_msg}])
+ return HttpResponse(data, status=500, content_type=content_type)
+
+def crocodoc_session(request):
+ """
+ Handle ajax reqeust to create session.
+ Session expires 60 minutes after it's generated.
+ """
+ if not request.is_ajax():
+ raise Http404
+
+ content_type = 'application/json; charset=utf-8'
+ uuid = request.GET.get('uuid', '')
+
+ curl = 'https://crocodoc.com/api/v2/session/create'
+ data = {'token': CROCODOC_API_TOKEN,
+ 'uuid': uuid,
+ 'editable': 'true',
+ 'user': '1337,Peter', # TODO: Fake user, should be changed
+ 'downloadable': 'true',
+ }
+ f = urllib2.urlopen(url=curl, data=urllib.urlencode(data))
+ ret = f.read()
+ ret_dict = json.loads(ret)
+ session = ret_dict['session']
+ doc_src = 'https://crocodoc.com/view/%s' % session
+
+ data = json.dumps([{'doc_src': doc_src}])
+ return HttpResponse(data, status=200, content_type=content_type)