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'^thirdparty-editor/', include('seahub.thirdparty_editor.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'^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')
|
||||
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:
|
||||
return_dict['err'] = "File preview unsupported"
|
||||
return render(request, template, return_dict)
|
||||
|
Reference in New Issue
Block a user