mirror of
https://github.com/haiwen/seahub.git
synced 2025-08-31 14:42:10 +00:00
1
media/js/GStarSDK.js
Executable file
1
media/js/GStarSDK.js
Executable file
File diff suppressed because one or more lines are too long
0
seahub/cad/__init__.py
Normal file
0
seahub/cad/__init__.py
Normal file
14
seahub/cad/settings.py
Normal file
14
seahub/cad/settings.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
|
||||||
|
ENABLE_CAD = getattr(settings, 'ENABLE_CAD', False)
|
||||||
|
CAD_MOBILE_SIZE_LIMIT = getattr(settings, 'CAD_MOBILE_SIZE_LIMIT', 5242880)
|
||||||
|
CAD_PC_SIZE_LIMIT = getattr(settings, 'CAD_PC_SIZE_LIMIT', 12582912)
|
||||||
|
CAD_HOST = getattr(settings, 'CAD_HOST', 'http://127.0.0.1:8000')
|
||||||
|
|
||||||
|
WEBCAD_ROOT_FOLDER = getattr(settings, 'WEBCAD_ROOT_FOLDER', '')
|
||||||
|
WEBCAD_DWG_PATH = getattr(settings, 'WEBCAD_DWG_PATH', 'file/dwg')
|
||||||
|
WEBCAD_OCF_PATH = getattr(settings, 'WEBCAD_OCF_PATH', 'file/ocf')
|
||||||
|
|
||||||
|
WEBCAD_HOST = getattr(settings, 'WEBCAD_HOST', '127.0.0.1')
|
||||||
|
WEBCAD_PORT = getattr(settings, 'WEBCAD_PORT', 3181)
|
9
seahub/cad/urls.py
Normal file
9
seahub/cad/urls.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Copyright (c) 2012-2016 Seafile Ltd.
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from .views import CadApiFileContentView
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
# RESTful API
|
||||||
|
url(r'^api/file-content/$', CadApiFileContentView.as_view(), name='CadApiFileContentView'),
|
||||||
|
]
|
22
seahub/cad/utils.py
Normal file
22
seahub/cad/utils.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import logging
|
||||||
|
from requests.models import PreparedRequest
|
||||||
|
from django.urls import reverse
|
||||||
|
from seahub.cad.settings import CAD_MOBILE_SIZE_LIMIT, CAD_PC_SIZE_LIMIT, \
|
||||||
|
CAD_HOST
|
||||||
|
|
||||||
|
# Get an instance of a logger
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def get_cad_dict(request, username, repo_id, file_path):
|
||||||
|
|
||||||
|
return_dict = {}
|
||||||
|
return_dict['cad_mobile_size_limit'] = CAD_MOBILE_SIZE_LIMIT
|
||||||
|
return_dict['cad_pc_size_limit'] = CAD_PC_SIZE_LIMIT
|
||||||
|
|
||||||
|
req = PreparedRequest()
|
||||||
|
param_dict = {'repo_id': repo_id, 'file_path': file_path}
|
||||||
|
req.prepare_url(CAD_HOST + reverse('CadApiFileContentView'), param_dict)
|
||||||
|
return_dict['doc_url'] = req.url
|
||||||
|
|
||||||
|
return return_dict
|
178
seahub/cad/views.py
Normal file
178
seahub/cad/views.py
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
# Copyright (c) 2012-2016 Seafile Ltd.
|
||||||
|
# encoding: utf-8
|
||||||
|
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
import socket
|
||||||
|
import logging
|
||||||
|
import posixpath
|
||||||
|
import urllib.parse
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
|
from rest_framework import status
|
||||||
|
from rest_framework.views import APIView
|
||||||
|
from rest_framework.permissions import IsAuthenticated
|
||||||
|
from rest_framework.authentication import SessionAuthentication
|
||||||
|
|
||||||
|
from django.http import HttpResponse
|
||||||
|
|
||||||
|
from seaserv import seafile_api
|
||||||
|
|
||||||
|
from seahub.api2.utils import api_error
|
||||||
|
from seahub.api2.throttling import UserRateThrottle
|
||||||
|
from seahub.api2.authentication import TokenAuthentication
|
||||||
|
|
||||||
|
from seahub.utils import gen_inner_file_get_url
|
||||||
|
from seahub.views import check_folder_permission
|
||||||
|
from seahub.cad.settings import WEBCAD_ROOT_FOLDER, \
|
||||||
|
WEBCAD_DWG_PATH, WEBCAD_OCF_PATH, WEBCAD_HOST, WEBCAD_PORT
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def dwg_to_ocf(dwg_filename, ocf_filename):
|
||||||
|
|
||||||
|
try:
|
||||||
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
except socket.error as m:
|
||||||
|
logger.error(m)
|
||||||
|
return False
|
||||||
|
|
||||||
|
s.connect((WEBCAD_HOST, WEBCAD_PORT))
|
||||||
|
|
||||||
|
# send data to webcad
|
||||||
|
input_dict = {
|
||||||
|
"path": '',
|
||||||
|
"name": dwg_filename,
|
||||||
|
"ocf": ocf_filename,
|
||||||
|
"layout": "",
|
||||||
|
"utoken": "",
|
||||||
|
"taskClass": "MakeOcf",
|
||||||
|
"id": 1
|
||||||
|
}
|
||||||
|
|
||||||
|
message = {
|
||||||
|
"status": 0,
|
||||||
|
"host": "webcad",
|
||||||
|
"input": json.dumps(input_dict),
|
||||||
|
"output": ""
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
s.sendall(bytes(json.dumps(message), encoding='utf-8'))
|
||||||
|
s.sendall(bytes(0))
|
||||||
|
except socket.error as m:
|
||||||
|
logger.error(m)
|
||||||
|
return False
|
||||||
|
|
||||||
|
# receive data
|
||||||
|
buffer = []
|
||||||
|
while True:
|
||||||
|
d = s.recv(1024)
|
||||||
|
if d:
|
||||||
|
buffer.append(d)
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
rec_data = b''.join(buffer)
|
||||||
|
rec_str = rec_data.decode(encoding='utf-8')
|
||||||
|
s.close()
|
||||||
|
|
||||||
|
rec_json = json.loads(rec_str.strip('\x00'))
|
||||||
|
output_str = rec_json.get('output', '')
|
||||||
|
output_json = json.loads(output_str)
|
||||||
|
|
||||||
|
return output_json.get('msg', '') == 'OK'
|
||||||
|
|
||||||
|
|
||||||
|
class CadApiFileContentView(APIView):
|
||||||
|
|
||||||
|
authentication_classes = (TokenAuthentication, SessionAuthentication)
|
||||||
|
permission_classes = (IsAuthenticated,)
|
||||||
|
throttle_classes = (UserRateThrottle,)
|
||||||
|
|
||||||
|
def get(self, request, format=None):
|
||||||
|
""" get file content
|
||||||
|
"""
|
||||||
|
|
||||||
|
# parameter check
|
||||||
|
repo_id = request.GET.get('repo_id', None)
|
||||||
|
file_path = request.GET.get('file_path', None)
|
||||||
|
|
||||||
|
if not repo_id:
|
||||||
|
error_msg = 'repo_id invalid.'
|
||||||
|
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||||
|
|
||||||
|
if not file_path:
|
||||||
|
error_msg = 'file_path invalid.'
|
||||||
|
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||||
|
|
||||||
|
# resource check
|
||||||
|
if not seafile_api.get_repo(repo_id):
|
||||||
|
error_msg = 'Library %s not found.' % repo_id
|
||||||
|
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||||
|
|
||||||
|
obj_id = seafile_api.get_file_id_by_path(repo_id, file_path)
|
||||||
|
if not obj_id:
|
||||||
|
error_msg = 'file %s not found.' % file_path
|
||||||
|
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||||
|
|
||||||
|
# permission check
|
||||||
|
if not check_folder_permission(request, repo_id, '/'):
|
||||||
|
error_msg = 'Permission denied.'
|
||||||
|
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||||
|
|
||||||
|
# process dwg and ocf file
|
||||||
|
base_filename = "{}_{}_{}".format(repo_id, file_path, obj_id)
|
||||||
|
base_filename = urllib.parse.quote(base_filename, safe='')
|
||||||
|
|
||||||
|
dwg_filename = "{}.dwg".format(base_filename)
|
||||||
|
dwg_filepath = posixpath.join(WEBCAD_ROOT_FOLDER,
|
||||||
|
WEBCAD_DWG_PATH,
|
||||||
|
dwg_filename)
|
||||||
|
|
||||||
|
if not os.path.exists(dwg_filepath):
|
||||||
|
|
||||||
|
try:
|
||||||
|
fileserver_token = seafile_api.get_fileserver_access_token(repo_id,
|
||||||
|
obj_id,
|
||||||
|
'download',
|
||||||
|
request.user.username,
|
||||||
|
use_onetime=False)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(e)
|
||||||
|
error_msg = 'Internal Server Error'
|
||||||
|
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
||||||
|
|
||||||
|
if not fileserver_token:
|
||||||
|
logger.error('No fileserver token')
|
||||||
|
error_msg = 'Internal Server Error'
|
||||||
|
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
||||||
|
|
||||||
|
file_name = os.path.basename(file_path)
|
||||||
|
inner_path = gen_inner_file_get_url(fileserver_token, file_name)
|
||||||
|
|
||||||
|
try:
|
||||||
|
file_content = urllib.request.urlopen(inner_path).read()
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(e)
|
||||||
|
error_msg = 'Internal Server Error'
|
||||||
|
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
||||||
|
|
||||||
|
with open(dwg_filepath, 'wb') as f:
|
||||||
|
f.write(file_content)
|
||||||
|
|
||||||
|
ocf_filename = "{}.ocf".format(base_filename)
|
||||||
|
ocf_filepath = posixpath.join(WEBCAD_ROOT_FOLDER,
|
||||||
|
WEBCAD_OCF_PATH,
|
||||||
|
ocf_filename)
|
||||||
|
|
||||||
|
if not os.path.exists(ocf_filepath):
|
||||||
|
success = dwg_to_ocf(dwg_filename, ocf_filename)
|
||||||
|
if not success:
|
||||||
|
error_msg = 'Internal Server Error'
|
||||||
|
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
||||||
|
|
||||||
|
with open(ocf_filepath, 'rb') as f:
|
||||||
|
ocf_file_content = f.read()
|
||||||
|
|
||||||
|
return HttpResponse(ocf_file_content, content_type="application/octet-stream")
|
173
seahub/templates/view_file_cad.html
Executable file
173
seahub/templates/view_file_cad.html
Executable file
@@ -0,0 +1,173 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
{% load static %}
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>{{filename}}</title>
|
||||||
|
<style>
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#webcad {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
如果不需要布局功能,可以取消这个注释,布局按钮就隐藏了。
|
||||||
|
电脑网页布局按钮隐藏
|
||||||
|
#GStarSDK-pc-toolsbar-floatbar-layout {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*手机网页布局按钮隐藏
|
||||||
|
.GStarSDK #GStarSDK-panel-list li:nth-child(3) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="webcad"></div>
|
||||||
|
<script type="text/javascript" src="{{ MEDIA_URL }}js/GStarSDK.js"></script>
|
||||||
|
<script>
|
||||||
|
//先判断是否是IE浏览器,IE10及以下的IE浏览器不支持,直接弹出提示告知
|
||||||
|
window.onload = function () {
|
||||||
|
var browser = getBrowerInfo()
|
||||||
|
var ieversion = getIeVersion();
|
||||||
|
if (browser == 'IE') {
|
||||||
|
if (ieversion != '11.0') {
|
||||||
|
alert('不支持IE10及以下的浏览器,请使用其他浏览器打开重试!')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化SDK
|
||||||
|
var gstarSDK = new GStarSDK({
|
||||||
|
wrapId: 'webcad', //容器ID
|
||||||
|
switchLayoutCB: switchLayout, // 点击布局功能会触发此回调
|
||||||
|
apiHost: window.location.host, //API域名,转换PDF、另存功能需要向该域名发送请求,如果没有用的转PDF、版本转换功能,则无须关注这个参数。
|
||||||
|
|
||||||
|
tipsTime: 3000, //错误提示信息存在时间(毫秒),默认3000(3秒)
|
||||||
|
mobileSizeLimit: {{cad_mobile_size_limit}}, //移动端可打开ocf文件的最大限制(字节数),默认5242880(5M)
|
||||||
|
pcSizeLimit: {{cad_pc_size_limit}}, //PC端可打开ocf文件最大限制(字节数),默认12582912(12M)
|
||||||
|
sizeLimitCB: sizeLimit, //当ocf文件超过设置的最大值后,执行该回调函数
|
||||||
|
language: 'zh', //语言设置,可选'zh'(简中)/'en'(英语)/'ko'(韩语),默认'zh'
|
||||||
|
measureAccuracy: 3, //测量数值的精度位数
|
||||||
|
mode: 'default', //填充显示模式,"default":默认值,粗文字不填充,其他填充图案正常填充;"line":所有元素都不填充;"fill":所有需要填充元素都填充
|
||||||
|
})
|
||||||
|
|
||||||
|
gstarSDK.enableZoom(5) // 开启鼠标缩放功能,数字是缩放的速度
|
||||||
|
gstarSDK.enablePan(1) // 开启鼠标平移功能
|
||||||
|
|
||||||
|
var fileId = "{{file_id}}"; //自定义,当前图纸的唯一标识
|
||||||
|
|
||||||
|
// 当ocf文件超过设置的最大值后,执行这个函数,里面逻辑可以自己定义
|
||||||
|
function sizeLimit(ocfSize, limitSize) {
|
||||||
|
alert('图纸太大,超过了系统设置的最大值')
|
||||||
|
//alert('图纸太大,当前图纸大小:' + parseInt(ocfSize / 1048576) + 'M,大于系统限制的:' + parseInt(limitSize / 1048576)+'M')
|
||||||
|
}
|
||||||
|
|
||||||
|
//测试用的ocf样例文件
|
||||||
|
var demoocfurl = {
|
||||||
|
'*MODEL_SPACE': 'https://resource-cn.gstarcad.com/sampledraw/0000012863.ocf',
|
||||||
|
'*PAPER_SPACE': 'https://resource-cn.gstarcad.com/sampledraw/0000012863.257.ocf',
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化渲染默认ocf文件
|
||||||
|
//var defaultocfurl = 'http://127.0.0.1/file/ocf/1001/test.ocf' //默认显示的ocf文件url地址
|
||||||
|
//var defaultocfurl = demoocfurl['*MODEL_SPACE']
|
||||||
|
var defaultocfurl = "{{doc_url|safe}}";
|
||||||
|
getDrawSheet(defaultocfurl, function (arraybuffer) {
|
||||||
|
gstarSDK.render('ocf', arraybuffer, fileId, true)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 切换布局回调方法
|
||||||
|
function switchLayout(obj) {
|
||||||
|
alert(obj.globalName) //布局名称
|
||||||
|
//var makeocfurl = 'http://127.0.0.1/transform.do?fileId=' + fileId + '&layout=' + obj.globalName //根据布局globalName获取相应布局名称,由于布局图形必须有对应的布局名称,后台才能转换生成,需要将布局名传给后台,然后后台返回转换后的ocf地址
|
||||||
|
//var layoutocfurl = getLayoutOcfUrl(makeocfurl)
|
||||||
|
|
||||||
|
var layoutocfurl = demoocfurl[String(obj.globalName)] //样例布局ocf文件
|
||||||
|
getDrawSheet(layoutocfurl, function (arraybuffer) {
|
||||||
|
gstarSDK.render('ocf', arraybuffer, fileId, true)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下载图纸数据
|
||||||
|
function getDrawSheet(url, cb) {
|
||||||
|
var req
|
||||||
|
if (window.XMLHttpRequest) {
|
||||||
|
req = new XMLHttpRequest()
|
||||||
|
} else {
|
||||||
|
req = new ActiveXObject('Microsoft.XMLHTTP')
|
||||||
|
}
|
||||||
|
gstarSDK.Tips.showProgress(0, '下载中...')
|
||||||
|
req.onload = function () {
|
||||||
|
if ((req.status >= 200 && req.status < 300) || req.status === 304) {
|
||||||
|
cb(req.response)
|
||||||
|
}
|
||||||
|
if (req.status === 404) {
|
||||||
|
gstarSDK.Tips.showProgress(0, url+' 此ocf文件下载失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
req.open('GET', url, true)
|
||||||
|
req.responseType = 'arraybuffer'
|
||||||
|
req.send(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取布局图纸转换请求链接返回的ocf地址
|
||||||
|
function getLayoutOcfUrl(url) {
|
||||||
|
var req
|
||||||
|
if (window.XMLHttpRequest) {
|
||||||
|
req = new XMLHttpRequest()
|
||||||
|
} else {
|
||||||
|
req = new ActiveXObject('Microsoft.XMLHTTP')
|
||||||
|
}
|
||||||
|
req.open('GET', url, false)
|
||||||
|
req.send(null)
|
||||||
|
|
||||||
|
req.onreadystatechange = function () {
|
||||||
|
if (req.status == 200 && req.readyState == 4) {
|
||||||
|
alert(req.responseText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return req.responseText
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取浏览器信息
|
||||||
|
function getBrowerInfo() {
|
||||||
|
var userAgent = window.navigator.userAgent.toLowerCase()
|
||||||
|
var browserType = ''
|
||||||
|
// 浏览器类型IE
|
||||||
|
if (userAgent.match(/msie/) != null || userAgent.match(/trident/) != null) {
|
||||||
|
browserType = 'IE'
|
||||||
|
}
|
||||||
|
return browserType
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取IE浏览器版本
|
||||||
|
function getIeVersion() {
|
||||||
|
var IEMode = document.documentMode
|
||||||
|
var rMsie = /(msie\s|trident.*rv:)([\w.]+)/;
|
||||||
|
var ma = window.navigator.userAgent.toLowerCase()
|
||||||
|
var match = rMsie.exec(ma);
|
||||||
|
try {
|
||||||
|
return match[2];
|
||||||
|
} catch (e) {
|
||||||
|
return IEMode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@@ -199,6 +199,7 @@ urlpatterns = [
|
|||||||
url(r'^oauth/', include('seahub.oauth.urls')),
|
url(r'^oauth/', include('seahub.oauth.urls')),
|
||||||
url(r'^thirdparty-editor/', include('seahub.thirdparty_editor.urls')),
|
url(r'^thirdparty-editor/', include('seahub.thirdparty_editor.urls')),
|
||||||
url(r'^ocm-via-webdav/', include('seahub.ocm_via_webdav.urls')),
|
url(r'^ocm-via-webdav/', include('seahub.ocm_via_webdav.urls')),
|
||||||
|
url(r'^cad/', include('seahub.cad.urls')),
|
||||||
|
|
||||||
url(r'^$', react_fake_view, name='libraries'),
|
url(r'^$', react_fake_view, name='libraries'),
|
||||||
url(r'^robots\.txt$', TemplateView.as_view(template_name='robots.txt', content_type='text/plain')),
|
url(r'^robots\.txt$', TemplateView.as_view(template_name='robots.txt', content_type='text/plain')),
|
||||||
|
@@ -880,6 +880,14 @@ def view_lib_file(request, repo_id, path):
|
|||||||
|
|
||||||
send_file_access_msg(request, repo, path, 'web')
|
send_file_access_msg(request, repo, path, 'web')
|
||||||
return render(request, template, return_dict)
|
return render(request, template, return_dict)
|
||||||
|
elif getattr(settings, 'ENABLE_CAD', False) and path.endswith('.dwg'):
|
||||||
|
|
||||||
|
from seahub.cad.utils import get_cad_dict
|
||||||
|
cad_dict = get_cad_dict(request, username, repo_id, path)
|
||||||
|
|
||||||
|
return_dict.update(cad_dict)
|
||||||
|
|
||||||
|
return render(request, 'view_file_cad.html', return_dict)
|
||||||
else:
|
else:
|
||||||
return_dict['err'] = "File preview unsupported"
|
return_dict['err'] = "File preview unsupported"
|
||||||
return render(request, template, return_dict)
|
return render(request, template, return_dict)
|
||||||
|
Reference in New Issue
Block a user