mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-02 07:27:04 +00:00
update onlyoffice convert
This commit is contained in:
@@ -39,6 +39,7 @@ const propTypes = {
|
|||||||
onItemsDelete: PropTypes.func.isRequired,
|
onItemsDelete: PropTypes.func.isRequired,
|
||||||
onFileTagChanged: PropTypes.func,
|
onFileTagChanged: PropTypes.func,
|
||||||
showDirentDetail: PropTypes.func.isRequired,
|
showDirentDetail: PropTypes.func.isRequired,
|
||||||
|
loadDirentList: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
class DirListView extends React.Component {
|
class DirListView extends React.Component {
|
||||||
@@ -99,6 +100,7 @@ class DirListView extends React.Component {
|
|||||||
onAddFolder={this.props.onAddFolder}
|
onAddFolder={this.props.onAddFolder}
|
||||||
onFileTagChanged={this.props.onFileTagChanged}
|
onFileTagChanged={this.props.onFileTagChanged}
|
||||||
showDirentDetail={this.props.showDirentDetail}
|
showDirentDetail={this.props.showDirentDetail}
|
||||||
|
loadDirentList={this.props.loadDirentList}
|
||||||
/>
|
/>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
|
@@ -369,28 +369,16 @@ class DirentListItem extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onConvertWithONLYOFFICE = ()=> {
|
onConvertWithONLYOFFICE = ()=> {
|
||||||
|
|
||||||
let repoID = this.props.repoID;
|
let repoID = this.props.repoID;
|
||||||
let user = username;
|
let filePath = this.getDirentPath(this.props.dirent)
|
||||||
let fileUri = this.getDirentPath(this.props.dirent)
|
|
||||||
fetch(siteRoot+'onlyoffice/convert', {
|
seafileAPI.onlyofficeConvert(repoID, filePath).then(res => {
|
||||||
method: 'POST',
|
this.props.loadDirentList(res.data.parent_dir)
|
||||||
body: JSON.stringify({
|
}).catch(error => {
|
||||||
username: user,
|
let errMessage = Utils.getErrorMsg(error);
|
||||||
fileUri: fileUri,
|
toaster.danger(errMessage);
|
||||||
repo_id: repoID,
|
});
|
||||||
}),
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
}
|
|
||||||
}).then(res => {
|
|
||||||
if(res.status >= 400) throw new Error()
|
|
||||||
//Replace with changes in the state
|
|
||||||
//like this one => this.addNodeToTree(name, parentPath, 'file');
|
|
||||||
window.location.reload();
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
toaster.danger('Could not convert the file');
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onItemDownload = (e) => {
|
onItemDownload = (e) => {
|
||||||
|
@@ -49,6 +49,7 @@ const propTypes = {
|
|||||||
isGroupOwnedRepo: PropTypes.bool.isRequired,
|
isGroupOwnedRepo: PropTypes.bool.isRequired,
|
||||||
userPerm: PropTypes.string,
|
userPerm: PropTypes.string,
|
||||||
showDirentDetail: PropTypes.func.isRequired,
|
showDirentDetail: PropTypes.func.isRequired,
|
||||||
|
loadDirentList: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
class DirentListView extends React.Component {
|
class DirentListView extends React.Component {
|
||||||
@@ -645,6 +646,7 @@ class DirentListView extends React.Component {
|
|||||||
showDirentDetail={this.props.showDirentDetail}
|
showDirentDetail={this.props.showDirentDetail}
|
||||||
onItemsMove={this.props.onItemsMove}
|
onItemsMove={this.props.onItemsMove}
|
||||||
onShowDirentsDraggablePreview={this.onShowDirentsDraggablePreview}
|
onShowDirentsDraggablePreview={this.onShowDirentsDraggablePreview}
|
||||||
|
loadDirentList={this.props.loadDirentList}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
@@ -86,6 +86,7 @@ const propTypes = {
|
|||||||
onListContainerScroll: PropTypes.func.isRequired,
|
onListContainerScroll: PropTypes.func.isRequired,
|
||||||
onDirentClick: PropTypes.func.isRequired,
|
onDirentClick: PropTypes.func.isRequired,
|
||||||
direntDetailPanelTab: PropTypes.string,
|
direntDetailPanelTab: PropTypes.string,
|
||||||
|
loadDirentList: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
class LibContentContainer extends React.Component {
|
class LibContentContainer extends React.Component {
|
||||||
@@ -237,6 +238,7 @@ class LibContentContainer extends React.Component {
|
|||||||
onItemsDelete={this.props.onItemsDelete}
|
onItemsDelete={this.props.onItemsDelete}
|
||||||
onFileTagChanged={this.props.onFileTagChanged}
|
onFileTagChanged={this.props.onFileTagChanged}
|
||||||
showDirentDetail={this.props.showDirentDetail}
|
showDirentDetail={this.props.showDirentDetail}
|
||||||
|
loadDirentList={this.props.loadDirentList}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{this.props.currentMode === 'grid' && (
|
{this.props.currentMode === 'grid' && (
|
||||||
|
@@ -1928,6 +1928,7 @@ class LibContentView extends React.Component {
|
|||||||
onToolbarFileTagChanged={this.onToolbarFileTagChanged}
|
onToolbarFileTagChanged={this.onToolbarFileTagChanged}
|
||||||
updateDetail={this.state.updateDetail}
|
updateDetail={this.state.updateDetail}
|
||||||
onListContainerScroll={this.onListContainerScroll}
|
onListContainerScroll={this.onListContainerScroll}
|
||||||
|
loadDirentList={this.loadDirentList}
|
||||||
/>
|
/>
|
||||||
{canUpload && this.state.pathExist && !this.state.isViewFile && (
|
{canUpload && this.state.pathExist && !this.state.isViewFile && (
|
||||||
<FileUploader
|
<FileUploader
|
||||||
|
@@ -21,7 +21,6 @@ def get_converter_uri(doc_uri, from_ext, to_ext, doc_key, is_async, file_passwor
|
|||||||
'filetype': from_ext.replace('.', ''),
|
'filetype': from_ext.replace('.', ''),
|
||||||
'title': title,
|
'title': title,
|
||||||
'key': doc_key,
|
'key': doc_key,
|
||||||
'password': file_password
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if file_password:
|
if file_password:
|
||||||
|
@@ -2,30 +2,25 @@ from seahub.onlyoffice.settings import EXT_DOCUMENT, \
|
|||||||
EXT_SPREADSHEET, EXT_PRESENTATION
|
EXT_SPREADSHEET, EXT_PRESENTATION
|
||||||
|
|
||||||
|
|
||||||
def get_file_name(file_uri):
|
def get_file_name(file_path):
|
||||||
ind = file_uri.rfind('/')
|
ind = file_path.rfind('/')
|
||||||
return file_uri[ind+1:]
|
return file_path[ind+1:]
|
||||||
|
|
||||||
|
|
||||||
def get_file_path_without_mame(file_uri):
|
def get_file_name_without_ext(file_path):
|
||||||
ind = file_uri.rfind('/')
|
fn = get_file_name(file_path)
|
||||||
return file_uri[:ind]
|
|
||||||
|
|
||||||
|
|
||||||
def get_file_name_without_ext(file_uri):
|
|
||||||
fn = get_file_name(file_uri)
|
|
||||||
ind = fn.rfind('.')
|
ind = fn.rfind('.')
|
||||||
return fn[:ind]
|
return fn[:ind]
|
||||||
|
|
||||||
|
|
||||||
def get_file_ext(file_uri):
|
def get_file_ext(file_path):
|
||||||
fn = get_file_name(file_uri)
|
fn = get_file_name(file_path)
|
||||||
ind = fn.rfind('.')
|
ind = fn.rfind('.')
|
||||||
return fn[ind:].lower()
|
return fn[ind:].lower()
|
||||||
|
|
||||||
|
|
||||||
def get_file_type(file_uri):
|
def get_file_type(file_path):
|
||||||
ext = get_file_ext(file_uri)
|
ext = get_file_ext(file_path)
|
||||||
if ext in EXT_DOCUMENT:
|
if ext in EXT_DOCUMENT:
|
||||||
return 'word'
|
return 'word'
|
||||||
if ext in EXT_SPREADSHEET:
|
if ext in EXT_SPREADSHEET:
|
||||||
|
@@ -1,22 +1,33 @@
|
|||||||
# Copyright (c) 2012-2017 Seafile Ltd.
|
# Copyright (c) 2012-2017 Seafile Ltd.
|
||||||
|
import os
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
import requests
|
import requests
|
||||||
|
import posixpath
|
||||||
import email.utils
|
import email.utils
|
||||||
|
|
||||||
|
from rest_framework.authentication import SessionAuthentication
|
||||||
|
from rest_framework.permissions import IsAuthenticated
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from rest_framework.views import APIView
|
||||||
|
|
||||||
|
from seahub.api2.utils import api_error
|
||||||
|
from seahub.api2.throttling import UserRateThrottle
|
||||||
|
from seahub.api2.authentication import TokenAuthentication
|
||||||
|
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
from django.shortcuts import render
|
|
||||||
|
|
||||||
from seaserv import seafile_api
|
from seaserv import seafile_api
|
||||||
|
|
||||||
from seahub.onlyoffice.settings import VERIFY_ONLYOFFICE_CERTIFICATE
|
from seahub.onlyoffice.settings import VERIFY_ONLYOFFICE_CERTIFICATE
|
||||||
from seahub.onlyoffice.utils import generate_onlyoffice_cache_key, get_onlyoffice_dict
|
from seahub.onlyoffice.utils import generate_onlyoffice_cache_key, get_onlyoffice_dict
|
||||||
from seahub.onlyoffice.converter_utils import get_file_name_without_ext, \
|
from seahub.onlyoffice.converter_utils import get_file_name_without_ext, \
|
||||||
get_file_ext, get_file_type, get_internal_extension, get_file_path_without_mame
|
get_file_ext, get_file_type, get_internal_extension
|
||||||
from seahub.onlyoffice.converter import get_converter_uri
|
from seahub.onlyoffice.converter import get_converter_uri
|
||||||
from seahub.utils import gen_inner_file_upload_url, is_pro_version
|
from seahub.utils import gen_inner_file_upload_url, is_pro_version, \
|
||||||
|
normalize_file_path, check_filename_with_rename
|
||||||
from seahub.utils.file_op import if_locked_by_online_office
|
from seahub.utils.file_op import if_locked_by_online_office
|
||||||
|
|
||||||
|
|
||||||
@@ -168,83 +179,97 @@ def onlyoffice_editor_callback(request):
|
|||||||
return HttpResponse('{"error": 0}')
|
return HttpResponse('{"error": 0}')
|
||||||
|
|
||||||
|
|
||||||
@csrf_exempt
|
class OnlyofficeConvert(APIView):
|
||||||
def onlyoffice_convert(request):
|
|
||||||
|
|
||||||
if request.method != 'POST':
|
authentication_classes = (TokenAuthentication, SessionAuthentication)
|
||||||
logger.error('Request method if not POST.')
|
permission_classes = (IsAuthenticated,)
|
||||||
return render(request, '404.html')
|
throttle_classes = (UserRateThrottle,)
|
||||||
|
|
||||||
body = json.loads(request.body)
|
def post(self, request):
|
||||||
|
|
||||||
username = body.get('username')
|
repo_id = request.data.get('repo_id')
|
||||||
file_uri = body.get('fileUri')
|
if not repo_id:
|
||||||
file_pass = body.get('filePass') or None
|
error_msg = 'repo_id invalid.'
|
||||||
repo_id = body.get('repo_id')
|
return api_error(400, error_msg)
|
||||||
folder_name = get_file_path_without_mame(file_uri) + '/'
|
|
||||||
file_ext = get_file_ext(file_uri)
|
|
||||||
file_type = get_file_type(file_uri)
|
|
||||||
new_ext = get_internal_extension(file_type)
|
|
||||||
|
|
||||||
if not new_ext:
|
file_path = request.data.get('file_path')
|
||||||
logger.error('[OnlyOffice] Could not generate internal extension.')
|
if not file_path:
|
||||||
return HttpResponse(status=500)
|
error_msg = 'file_path invalid.'
|
||||||
|
return api_error(400, error_msg)
|
||||||
|
|
||||||
doc_dic = get_onlyoffice_dict(request, username, repo_id, file_uri)
|
file_path = normalize_file_path(file_path)
|
||||||
|
parent_dir = os.path.dirname(file_path)
|
||||||
|
|
||||||
download_uri = doc_dic["doc_url"]
|
file_ext = get_file_ext(file_path)
|
||||||
key = doc_dic["doc_key"]
|
file_type = get_file_type(file_path)
|
||||||
|
new_ext = get_internal_extension(file_type)
|
||||||
|
|
||||||
new_uri = get_converter_uri(download_uri, file_ext, new_ext,
|
if not new_ext:
|
||||||
key, False, file_pass)
|
logger.error('[OnlyOffice] Could not generate internal extension.')
|
||||||
|
error_msg = 'Internal Server Error'
|
||||||
|
return api_error(500, error_msg)
|
||||||
|
|
||||||
if not new_uri:
|
username = request.user.username
|
||||||
logger.error('[OnlyOffice] No response from file converter.')
|
doc_dic = get_onlyoffice_dict(request, username, repo_id, file_path)
|
||||||
return HttpResponse(status=500)
|
new_uri = get_converter_uri(doc_dic["doc_url"], file_ext, new_ext,
|
||||||
|
doc_dic["doc_key"], False,
|
||||||
|
request.data.get('file_password'))
|
||||||
|
|
||||||
onlyoffice_resp = requests.get(new_uri, verify=VERIFY_ONLYOFFICE_CERTIFICATE)
|
if not new_uri:
|
||||||
|
logger.error('[OnlyOffice] No response from file converter.')
|
||||||
|
error_msg = 'Internal Server Error'
|
||||||
|
return api_error(500, error_msg)
|
||||||
|
|
||||||
if not onlyoffice_resp:
|
onlyoffice_resp = requests.get(new_uri, verify=VERIFY_ONLYOFFICE_CERTIFICATE)
|
||||||
logger.error('[OnlyOffice] No response from file content url.')
|
if not onlyoffice_resp:
|
||||||
return HttpResponse(status=500)
|
logger.error('[OnlyOffice] No response from file content url.')
|
||||||
|
error_msg = 'Internal Server Error'
|
||||||
|
return api_error(500, error_msg)
|
||||||
|
|
||||||
fake_obj_id = {'parent_dir': folder_name}
|
fake_obj_id = {'parent_dir': parent_dir}
|
||||||
|
upload_token = seafile_api.get_fileserver_access_token(repo_id,
|
||||||
|
json.dumps(fake_obj_id),
|
||||||
|
'upload-link',
|
||||||
|
username)
|
||||||
|
|
||||||
upload_token = seafile_api.get_fileserver_access_token(repo_id,
|
if not upload_token:
|
||||||
json.dumps(fake_obj_id),
|
logger.error('[OnlyOffice] No fileserver access token.')
|
||||||
'upload-link',
|
error_msg = 'Internal Server Error'
|
||||||
username)
|
return api_error(500, error_msg)
|
||||||
|
|
||||||
if not upload_token:
|
file_name = get_file_name_without_ext(file_path) + new_ext
|
||||||
logger.error('[OnlyOffice] No fileserver access token.')
|
file_name = check_filename_with_rename(repo_id, parent_dir, file_name)
|
||||||
return HttpResponse(status=500)
|
|
||||||
|
|
||||||
file_name = get_file_name_without_ext(file_uri) + new_ext
|
files = {
|
||||||
|
'file': (file_name, onlyoffice_resp.content),
|
||||||
|
'parent_dir': parent_dir,
|
||||||
|
}
|
||||||
|
upload_url = gen_inner_file_upload_url('upload-api', upload_token)
|
||||||
|
|
||||||
files = {
|
try:
|
||||||
'file': (file_name, onlyoffice_resp.content),
|
file_name.encode('ascii')
|
||||||
'parent_dir': folder_name,
|
except UnicodeEncodeError:
|
||||||
}
|
|
||||||
|
|
||||||
upload_url = gen_inner_file_upload_url('upload-api', upload_token)
|
def rewrite_request(prepared_request):
|
||||||
|
|
||||||
def rewrite_request(prepared_request):
|
old_content = 'filename*=' + email.utils.encode_rfc2231(file_name, 'utf-8')
|
||||||
|
old_content = old_content.encode()
|
||||||
|
|
||||||
old_content = 'filename*=' + email.utils.encode_rfc2231(file_name, 'utf-8')
|
# new_content = 'filename="{}"\r\n\r\n'.format(file_name)
|
||||||
old_content = old_content.encode()
|
new_content = 'filename="{}"'.format(file_name)
|
||||||
|
new_content = new_content.encode()
|
||||||
|
|
||||||
new_content = 'filename="{}"\r\n\r\n'.format(file_name)
|
prepared_request.body = prepared_request.body.replace(old_content, new_content)
|
||||||
new_content = new_content.encode()
|
|
||||||
|
|
||||||
prepared_request.body = prepared_request.body.replace(old_content, new_content)
|
return prepared_request
|
||||||
|
|
||||||
return prepared_request
|
requests.post(upload_url, files=files, auth=rewrite_request)
|
||||||
|
else:
|
||||||
|
requests.post(upload_url, files=files)
|
||||||
|
|
||||||
try:
|
result = {}
|
||||||
file_name.encode('ascii')
|
result['parent_dir'] = parent_dir
|
||||||
except UnicodeEncodeError:
|
result['file_name'] = file_name
|
||||||
requests.post(upload_url, files=files, auth=rewrite_request)
|
result['file_path'] = posixpath.join(parent_dir, file_name)
|
||||||
else:
|
|
||||||
requests.post(upload_url, files=files)
|
|
||||||
|
|
||||||
return HttpResponse(status=200)
|
return Response(result)
|
||||||
|
@@ -866,10 +866,10 @@ if getattr(settings, 'ENABLE_ADFS_LOGIN', False):
|
|||||||
|
|
||||||
if getattr(settings, 'ENABLE_ONLYOFFICE', False):
|
if getattr(settings, 'ENABLE_ONLYOFFICE', False):
|
||||||
from seahub.onlyoffice.views import onlyoffice_editor_callback
|
from seahub.onlyoffice.views import onlyoffice_editor_callback
|
||||||
from seahub.onlyoffice.views import onlyoffice_convert
|
from seahub.onlyoffice.views import OnlyofficeConvert
|
||||||
urlpatterns += [
|
urlpatterns += [
|
||||||
url(r'^onlyoffice/editor-callback/$', onlyoffice_editor_callback, name='onlyoffice_editor_callback'),
|
url(r'^onlyoffice/editor-callback/$', onlyoffice_editor_callback, name='onlyoffice_editor_callback'),
|
||||||
url(r'^onlyoffice/convert', onlyoffice_convert, name='onlyoffice_convert')
|
url(r'^onlyoffice-api/convert/$', OnlyofficeConvert.as_view(), name='onlyoffice_api_convert'),
|
||||||
]
|
]
|
||||||
|
|
||||||
if getattr(settings, 'ENABLE_BISHENG_OFFICE', False):
|
if getattr(settings, 'ENABLE_BISHENG_OFFICE', False):
|
||||||
|
Reference in New Issue
Block a user