Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b983a115c2 | ||
|
|
9d11fbe7ea |
@@ -27,7 +27,7 @@ docker container prune
|
||||
# 构建新版本 (最后的.不能少)
|
||||
docker build -t eyeblue/tank:x.x.x .
|
||||
# 本地测试
|
||||
docker run --name dockermysql -p 13306:3306 -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=tank -e MYSQL_USER=tank -e MYSQL_PASSWORD=tank123 -v ~/data/dockermysql:/var/lib/mysql -e TZ=Asia/Shanghai -d mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
|
||||
docker run --name dockermysql -p 13306:3306 -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=tank -e MYSQL_USER=tank -e MYSQL_PASSWORD=tank123 -v ~/data/dockermysql:/var/lib/mysql -d mysql:5.7
|
||||
docker run --name tank -p 6010:6010 --link dockermysql:mysql -v ~/data/dockermatter:/data/build/matter -d eyeblue/tank:x.x.x
|
||||
# 没问题后,推送到远程
|
||||
docker push eyeblue/tank:x.x.x
|
||||
@@ -47,36 +47,8 @@ c. 在github上发布新版本。
|
||||
|
||||
3.更新tank-doc 下载内容
|
||||
|
||||
## useful commands
|
||||
go get xxx/xxx
|
||||
go mod tidy
|
||||
|
||||
|
||||
tank-3.1.5 2022-03-21
|
||||
1. Support Sqlite.
|
||||
2. Upgrade webpack.
|
||||
|
||||
1. 支持Sqlite
|
||||
2. 升级了前端的webpack
|
||||
|
||||
|
||||
tank-3.1.4 2022-03-20
|
||||
1. Support Sqlite.
|
||||
2. Upgrade webpack.
|
||||
|
||||
1. 支持Sqlite
|
||||
2. 升级了前端的webpack
|
||||
|
||||
|
||||
|
||||
tank-3.1.3 2022-03-10
|
||||
1. Add kkfileview 3.x support
|
||||
2. Fix search bug https://github.com/eyebluecn/tank/issues/148
|
||||
3. Fix bug of totalSize in dashboard
|
||||
|
||||
1. 添加了kkfileview 3.x的预览支持
|
||||
2. 修复了一个搜索的bug https://github.com/eyebluecn/tank/issues/148
|
||||
3. 修复了文件大小统计的bug
|
||||
tank-3.1.3 2021-08-27
|
||||
1.tank.json中新增5个字段。
|
||||
|
||||
|
||||
tank-3.1.2 2021-01-02
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# use golang 1.17
|
||||
FROM golang:1.17
|
||||
# use golang 1.12
|
||||
FROM golang:1.12
|
||||
|
||||
# maintainer. Author's name and email.
|
||||
MAINTAINER eyeblue "eyebluecn@126.com"
|
||||
@@ -14,14 +14,10 @@ COPY . /data
|
||||
VOLUME /data/build/matter
|
||||
|
||||
# proxy
|
||||
ENV GOPROXY=https://goproxy.cn
|
||||
|
||||
# Handle time-zone
|
||||
ENV TZ=Asia/Shanghai
|
||||
RUN apt-get install -y tzdata
|
||||
ENV GOPROXY=https://goproxy.io
|
||||
|
||||
# prepare the config file
|
||||
RUN go build \
|
||||
RUN go build -mod=readonly \
|
||||
&& cp -r /data/tank /data/build
|
||||
|
||||
# use 6010 as default.
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
[English Version](https://tank-doc.eyeblue.cn/en)
|
||||
|
||||
# 蓝眼云盘(4.0.0.beta1)
|
||||
[在线Demo](https://tanker.eyeblue.cn) (体验账号: demo 密码:123456)
|
||||
# 蓝眼云盘(3.1.2)
|
||||
[在线Demo](https://tank.eyeblue.cn) (体验账号: demo 密码:123456)
|
||||
|
||||
蓝眼云盘是蓝眼开源系列代表作品之一,致力于打造精致,优雅,简约的云盘。核心功能如下:
|
||||
1. 文件列表
|
||||
@@ -15,8 +15,6 @@
|
||||
7. [WebDav](https://tank-doc.eyeblue.cn/advance/webdav.html)
|
||||
8. [扫描磁盘任务](https://tank-doc.eyeblue.cn/advance/scan.html)
|
||||
9. [在线预览及自定义配置预览引擎](https://tank-doc.eyeblue.cn/advance/preview.html)
|
||||
10. 支持Sqlite和Mysql数据库用以存储文件元信息,Sqlite可以做到开箱即用。
|
||||
|
||||
|
||||
[更多内容请移步至文档](https://tank-doc.eyeblue.cn/)
|
||||
|
||||
@@ -37,34 +35,17 @@
|
||||
|
||||
## [安装文档](https://tank-doc.eyeblue.cn/basic/install.html)
|
||||
|
||||
### 快速运行
|
||||
安装依赖
|
||||
```shell
|
||||
go mod tidy
|
||||
```
|
||||
运行main文件即可:
|
||||
```shell
|
||||
./main.go
|
||||
```
|
||||
|
||||
### Contribution
|
||||
|
||||
感谢所有蓝眼云盘的贡献者 [@zicla](https://github.com/zicla),[@seaheart](https://github.com/seaheart),[@yemuhe](https://github.com/yemuhe),[@hxsherry](https://github.com/hxsherry)
|
||||
|
||||
如果您也想参与进来,请尽情的fork, star, post issue, pull requests
|
||||
|
||||
当然你可以加入钉钉群(一群已满员)一起直接交流,在钉钉群中可以获取最新beta版本。
|
||||
当然你可以加入钉钉群一起直接交流,在钉钉群中可以获取最新beta版本。
|
||||
|
||||

|
||||
|
||||
群号:44754005
|
||||
|
||||
|
||||
### Support
|
||||
IDE for this project is supported by [Jetbrains](https://jb.gg/OpenSourceSupport).
|
||||
|
||||
[](https://jb.gg/OpenSourceSupport)
|
||||

|
||||
|
||||
群号:23156361
|
||||
|
||||
### License
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| master | :white_check_mark: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
We strongly encourage you to report security vulnerabilities to
|
||||
our private security mailing list: security@cilium.io - first, before
|
||||
disclosing them in any public forums.
|
||||
|
||||
This is a private mailing list where only members of the Cilium internal
|
||||
security team are subscribed to, and is treated as top priority.
|
||||
|
Before Width: | Height: | Size: 188 KiB After Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 58 KiB |
@@ -1,28 +1,38 @@
|
||||
{
|
||||
"files": {
|
||||
"main.css": "/static/css/main.d3300c6a.css",
|
||||
"main.js": "/static/js/main.e6a355f9.js",
|
||||
"static/media/logo.png": "/static/media/logo.847e54ef7fb4b744fad4.png",
|
||||
"static/media/empty.svg": "/static/media/empty.1ac6f6fb3e1d8c985f32df632ded4fe1.svg",
|
||||
"static/media/psd.svg": "/static/media/psd.f2767f53369b5e75d7708a857d8381f4.svg",
|
||||
"static/media/xls.svg": "/static/media/xls.9f55e13113424a3cc3316acbf072f072.svg",
|
||||
"static/media/ppt.svg": "/static/media/ppt.8696321d8f3893a15681473769c8283c.svg",
|
||||
"static/media/doc.svg": "/static/media/doc.017d14ee10ef3d2427494d1b0e52b03e.svg",
|
||||
"static/media/pdf.svg": "/static/media/pdf.67d0061b2cef7912ed36b895cb8a328a.svg",
|
||||
"static/media/video.svg": "/static/media/video.09bf3324c0e699b3611bf6bb0fc1b50e.svg",
|
||||
"static/media/file.svg": "/static/media/file.b6be968e09dc04a45ec49a0dbcef53da.svg",
|
||||
"static/media/default-skin.svg": "/static/media/default-skin.f64c3af3d0d25b9e4e00.svg",
|
||||
"static/media/text.svg": "/static/media/text.fa66aadee4b7dd9d51f4d1c863e5f75e.svg",
|
||||
"static/media/audio.svg": "/static/media/audio.59dab6a9512494e5a34c8a424ab68f39.svg",
|
||||
"static/media/image.svg": "/static/media/image.ee35022875b37a7962afa08bce8bc1fd.svg",
|
||||
"static/media/folder.svg": "/static/media/folder.b4ce8a2960e8da846081c692d3065dff.svg",
|
||||
"static/media/archive.svg": "/static/media/archive.f58837716d1fc6f2e61dc1618dad27a6.svg",
|
||||
"main.css": "/static/css/main.8aa2b3c6.chunk.css",
|
||||
"main.js": "/static/js/main.692308e3.chunk.js",
|
||||
"main.js.map": "/static/js/main.692308e3.chunk.js.map",
|
||||
"runtime-main.js": "/static/js/runtime-main.9bf84af1.js",
|
||||
"runtime-main.js.map": "/static/js/runtime-main.9bf84af1.js.map",
|
||||
"static/css/2.e86c2f44.chunk.css": "/static/css/2.e86c2f44.chunk.css",
|
||||
"static/js/2.789172e0.chunk.js": "/static/js/2.789172e0.chunk.js",
|
||||
"static/js/2.789172e0.chunk.js.map": "/static/js/2.789172e0.chunk.js.map",
|
||||
"index.html": "/index.html",
|
||||
"main.d3300c6a.css.map": "/static/css/main.d3300c6a.css.map",
|
||||
"main.e6a355f9.js.map": "/static/js/main.e6a355f9.js.map"
|
||||
"static/css/2.e86c2f44.chunk.css.map": "/static/css/2.e86c2f44.chunk.css.map",
|
||||
"static/css/main.8aa2b3c6.chunk.css.map": "/static/css/main.8aa2b3c6.chunk.css.map",
|
||||
"static/js/2.789172e0.chunk.js.LICENSE.txt": "/static/js/2.789172e0.chunk.js.LICENSE.txt",
|
||||
"static/media/archive.svg": "/static/media/archive.77d78eb7.svg",
|
||||
"static/media/audio.svg": "/static/media/audio.30a1ea02.svg",
|
||||
"static/media/default-skin.css": "/static/media/default-skin.b257fa9c.svg",
|
||||
"static/media/doc.svg": "/static/media/doc.1e70a87c.svg",
|
||||
"static/media/empty.svg": "/static/media/empty.babf4d08.svg",
|
||||
"static/media/file.svg": "/static/media/file.fd3e15f8.svg",
|
||||
"static/media/folder.svg": "/static/media/folder.f8d1b500.svg",
|
||||
"static/media/image.svg": "/static/media/image.06f036ce.svg",
|
||||
"static/media/logo.png": "/static/media/logo.21458adb.png",
|
||||
"static/media/pdf.svg": "/static/media/pdf.c256fdcb.svg",
|
||||
"static/media/ppt.svg": "/static/media/ppt.9ec3e018.svg",
|
||||
"static/media/psd.svg": "/static/media/psd.be6691be.svg",
|
||||
"static/media/text.svg": "/static/media/text.49dc13ae.svg",
|
||||
"static/media/video.svg": "/static/media/video.4387235d.svg",
|
||||
"static/media/xls.svg": "/static/media/xls.ef5ba31b.svg"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/css/main.d3300c6a.css",
|
||||
"static/js/main.e6a355f9.js"
|
||||
"static/js/runtime-main.9bf84af1.js",
|
||||
"static/css/2.e86c2f44.chunk.css",
|
||||
"static/js/2.789172e0.chunk.js",
|
||||
"static/css/main.8aa2b3c6.chunk.css",
|
||||
"static/js/main.692308e3.chunk.js"
|
||||
]
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="eyeblue tank"/><title>EyeblueTank</title><script defer="defer" src="/static/js/main.e6a355f9.js"></script><link href="/static/css/main.d3300c6a.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run EyeblueTank.</noscript><div id="root"></div></body></html>
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="eyeblue tank"/><title>EyeblueTank</title><link href="/static/css/2.e86c2f44.chunk.css" rel="stylesheet"><link href="/static/css/main.8aa2b3c6.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run EyeblueTank.</noscript><div id="root"></div><script>!function(e){function t(t){for(var n,f,l=t[0],a=t[1],i=t[2],c=0,s=[];c<l.length;c++)f=l[c],Object.prototype.hasOwnProperty.call(o,f)&&o[f]&&s.push(o[f][0]),o[f]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(p&&p(t);s.length;)s.shift()();return u.push.apply(u,i||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,l=1;l<r.length;l++){var a=r[l];0!==o[a]&&(n=!1)}n&&(u.splice(t--,1),e=f(f.s=r[0]))}return e}var n={},o={1:0},u=[];function f(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,f),r.l=!0,r.exports}f.m=e,f.c=n,f.d=function(e,t,r){f.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},f.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(e,t){if(1&t&&(e=f(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(f.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)f.d(r,n,function(t){return e[t]}.bind(null,n));return r},f.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(t,"a",t),t},f.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},f.p="/";var l=this["webpackJsonptank-front"]=this["webpackJsonptank-front"]||[],a=l.push.bind(l);l.push=t,l=l.slice();for(var i=0;i<l.length;i++)t(l[i]);var p=a;r()}([])</script><script src="/static/js/2.789172e0.chunk.js"></script><script src="/static/js/main.692308e3.chunk.js"></script></body></html>
|
||||
@@ -5,7 +5,7 @@ object-assign
|
||||
*/
|
||||
|
||||
/*!
|
||||
Copyright (c) 2018 Jed Watson.
|
||||
Copyright (c) 2017 Jed Watson.
|
||||
Licensed under the MIT License (MIT), see
|
||||
http://jedwatson.github.io/classnames
|
||||
*/
|
||||
@@ -22,7 +22,7 @@ object-assign
|
||||
|
||||
/*! VelocityJS.org jQuery Shim (1.0.1). (C) 2014 The jQuery Foundation. MIT @license: en.wikipedia.org/wiki/MIT_License. */
|
||||
|
||||
/** @license React v0.20.2
|
||||
/** @license React v0.19.1
|
||||
* scheduler.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
@@ -31,6 +31,15 @@ object-assign
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v16.13.1
|
||||
* react-dom.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v16.13.1
|
||||
* react-is.production.min.js
|
||||
*
|
||||
@@ -40,25 +49,7 @@ object-assign
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v17.0.2
|
||||
* react-dom.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v17.0.2
|
||||
* react-jsx-runtime.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v17.0.2
|
||||
/** @license React v16.13.1
|
||||
* react.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
@@ -66,5 +57,3 @@ object-assign
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
//! moment.js
|
||||
@@ -0,0 +1,2 @@
|
||||
!function(e){function webpackJsonpCallback(r){for(var n,o,u=r[0],c=r[1],p=r[2],i=0,l=[];i<u.length;i++)o=u[i],Object.prototype.hasOwnProperty.call(_,o)&&_[o]&&l.push(_[o][0]),_[o]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(a&&a(r);l.length;)l.shift()();return t.push.apply(t,p||[]),checkDeferredModules()}function checkDeferredModules(){for(var e,r=0;r<t.length;r++){for(var n=t[r],o=!0,u=1;u<n.length;u++){var a=n[u];0!==_[a]&&(o=!1)}o&&(t.splice(r--,1),e=__webpack_require__(__webpack_require__.s=n[0]))}return e}var r={},_={1:0},t=[];function __webpack_require__(_){if(r[_])return r[_].exports;var t=r[_]={i:_,l:!1,exports:{}};return e[_].call(t.exports,t,t.exports,__webpack_require__),t.l=!0,t.exports}__webpack_require__.m=e,__webpack_require__.c=r,__webpack_require__.d=function(e,r,_){__webpack_require__.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:_})},__webpack_require__.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},__webpack_require__.t=function(e,r){if(1&r&&(e=__webpack_require__(e)),8&r)return e;if(4&r&&"object"===typeof e&&e&&e.__esModule)return e;var _=Object.create(null);if(__webpack_require__.r(_),Object.defineProperty(_,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var t in e)__webpack_require__.d(_,t,function(r){return e[r]}.bind(null,t));return _},__webpack_require__.n=function(e){var r=e&&e.__esModule?function getDefault(){return e.default}:function getModuleExports(){return e};return __webpack_require__.d(r,"a",r),r},__webpack_require__.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},__webpack_require__.p="/";var n=this["webpackJsonptank-front"]=this["webpackJsonptank-front"]||[],o=n.push.bind(n);n.push=webpackJsonpCallback,n=n.slice();for(var u=0;u<n.length;u++)webpackJsonpCallback(n[u]);var a=o;checkDeferredModules()}([]);
|
||||
//# sourceMappingURL=runtime-main.9bf84af1.js.map
|
||||
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1514189353878" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1197" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M9.367 0h992.97v341.333H9.366z" fill="#55C7F7" p-id="1198"></path><path d="M9.367 341.333h992.97v341.334H9.366z" fill="#F95F5D" p-id="1199"></path><path d="M9.367 682.667h992.97V1024H9.366z" fill="#7ECF3B" p-id="1200"></path><path d="M350.7 0h310.303v1024H350.7z" fill="#FDAF42" p-id="1201"></path><path d="M304.154 386.638V646.05h403.394V386.638H304.154z m356.849 215.97H350.7V429.46h310.303v173.15z" fill="#FFFFFF" p-id="1202"></path></svg>
|
||||
|
After Width: | Height: | Size: 828 B |
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1514189353878" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="1197" width="200" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M9.367 0h992.97v341.333H9.366z" fill="#55C7F7" p-id="1198"></path>
|
||||
<path d="M9.367 341.333h992.97v341.334H9.366z" fill="#F95F5D" p-id="1199"></path>
|
||||
<path d="M9.367 682.667h992.97V1024H9.366z" fill="#7ECF3B" p-id="1200"></path>
|
||||
<path d="M350.7 0h310.303v1024H350.7z" fill="#FDAF42" p-id="1201"></path>
|
||||
<path d="M304.154 386.638V646.05h403.394V386.638H304.154z m356.849 215.97H350.7V429.46h310.303v173.15z"
|
||||
fill="#FFFFFF" p-id="1202"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 855 B |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1543321997742" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3887" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M160 32c-12 0-24.8 4.8-33.6 14.4S112 68 112 80v864c0 12 4.8 24.8 14.4 33.6C136 987.2 148 992 160 992h704c12 0 24.8-4.8 33.6-14.4C907.2 968 912 956 912 944V304L640 32H160z" fill="#FF5562" p-id="3888"></path><path d="M912 304H688c-12 0-24.8-4.8-33.6-14.4-9.6-8.8-14.4-21.6-14.4-33.6V32l272 272z" fill="#FFBBC0" p-id="3889"></path><path d="M669.6 491.2c0-1.6 0.8-4 0-6.4V369.6c0-4.8-2.4-8.8-5.6-12-4-3.2-8-4-12.8-3.2l-250.4 70.4c-7.2 1.6-12 7.2-12 14.4v275.2c-9.6-4-20.8-6.4-32.8-6.4-8.8 0-17.6 0.8-26.4 3.2-40.8 11.2-66.4 43.2-58.4 72.8 6.4 23.2 30.4 37.6 60.8 37.6 8.8 0 17.6-1.6 26.4-3.2 36.8-10.4 60.8-36.8 60-63.2 0.8-1.6 0.8-3.2 0.8-5.6V570.4l220-61.6v136c-9.6-4-20.8-6.4-32.8-6.4-8.8 0-17.6 0.8-26.4 3.2-40.8 11.2-66.4 43.2-58.4 72.8C528 737.6 552 752 582.4 752c8.8 0 17.6-0.8 26.4-3.2 36-9.6 60-36 60-62.4 0.8-1.6 0.8-3.2 0.8-5.6V491.2z m-250.4 48v-53.6l220-61.6v53.6l-220 61.6z" fill="#FFFFFF" p-id="3890"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1543321997742" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="3887" width="200" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M160 32c-12 0-24.8 4.8-33.6 14.4S112 68 112 80v864c0 12 4.8 24.8 14.4 33.6C136 987.2 148 992 160 992h704c12 0 24.8-4.8 33.6-14.4C907.2 968 912 956 912 944V304L640 32H160z"
|
||||
fill="#FF5562" p-id="3888"></path>
|
||||
<path d="M912 304H688c-12 0-24.8-4.8-33.6-14.4-9.6-8.8-14.4-21.6-14.4-33.6V32l272 272z" fill="#FFBBC0"
|
||||
p-id="3889"></path>
|
||||
<path d="M669.6 491.2c0-1.6 0.8-4 0-6.4V369.6c0-4.8-2.4-8.8-5.6-12-4-3.2-8-4-12.8-3.2l-250.4 70.4c-7.2 1.6-12 7.2-12 14.4v275.2c-9.6-4-20.8-6.4-32.8-6.4-8.8 0-17.6 0.8-26.4 3.2-40.8 11.2-66.4 43.2-58.4 72.8 6.4 23.2 30.4 37.6 60.8 37.6 8.8 0 17.6-1.6 26.4-3.2 36.8-10.4 60.8-36.8 60-63.2 0.8-1.6 0.8-3.2 0.8-5.6V570.4l220-61.6v136c-9.6-4-20.8-6.4-32.8-6.4-8.8 0-17.6 0.8-26.4 3.2-40.8 11.2-66.4 43.2-58.4 72.8C528 737.6 552 752 582.4 752c8.8 0 17.6-0.8 26.4-3.2 36-9.6 60-36 60-62.4 0.8-1.6 0.8-3.2 0.8-5.6V491.2z m-250.4 48v-53.6l220-61.6v53.6l-220 61.6z"
|
||||
fill="#FFFFFF" p-id="3890"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1543300132402" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="2107" width="200" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M533.947184 38.36489h65.880106v88.119185c117.859409 0.660894 235.60867-1.211639 353.35793 0.660894 25.102953-2.533427 44.81962 16.962943 42.506492 42.07691 1.872533 216.993492-0.440596 434.097133 1.112505 651.090626-1.112505 22.250094 2.191965 46.923466-10.695466 66.640133-16.081751 11.455494-36.899909 10.023557-55.625236 10.904749-110.25913-0.550745-220.408111-0.330447-330.656225-0.330447v88.119185h-68.843113c-167.657764-30.621417-335.745108-58.709407-503.722304-88.119185-0.110149-256.977572 0-513.955144 0-770.822567 168.858388-29.519927 337.826924-58.268811 506.685311-88.339483z"
|
||||
fill="#2A5699" p-id="2108"></path>
|
||||
<path d="M599.816275 159.528769h363.491637v704.953477h-363.491637v-88.119185h286.38735v-44.059592h-286.38735v-55.07449h286.38735v-44.059593h-286.38735v-55.07449h286.38735v-44.059592h-286.38735v-55.074491h286.38735v-44.059592h-286.38735v-55.074491h286.38735v-44.059592h-286.38735v-55.07449h286.38735v-44.059593h-286.38735v-77.104286zM254.829667 354.162018c20.928306-1.211639 41.856613-2.092831 62.784919-3.19432 14.649814 74.350562 29.619061 148.590975 45.491529 222.61109 12.446835-76.443393 26.215457-152.666487 39.543484-228.999731 22.029796-0.771043 44.059592-1.982682 65.97924-3.30447-24.89367 106.734362-46.703168 214.349917-73.909966 320.423385-18.39488 9.582961-45.932125-0.440596-67.741623 1.10149-14.649814-72.90761-31.722906-145.38564-44.819621-218.645727-12.898446 71.156242-29.641091 141.651589-44.390039 212.367235a4187.754101 4187.754101 0 0 1-63.666111-3.866229c-18.284731-96.931103-39.763782-193.190297-56.836874-290.341698 18.835476-0.881192 37.792115-1.652235 56.627591-2.313129 11.33433 70.164901 24.221761 139.999355 34.146184 210.274404 15.508976-72.037433 31.37043-144.074867 46.791287-216.1123z"
|
||||
fill="#FFFFFF" p-id="2109"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1543300132402" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2107" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M533.947184 38.36489h65.880106v88.119185c117.859409 0.660894 235.60867-1.211639 353.35793 0.660894 25.102953-2.533427 44.81962 16.962943 42.506492 42.07691 1.872533 216.993492-0.440596 434.097133 1.112505 651.090626-1.112505 22.250094 2.191965 46.923466-10.695466 66.640133-16.081751 11.455494-36.899909 10.023557-55.625236 10.904749-110.25913-0.550745-220.408111-0.330447-330.656225-0.330447v88.119185h-68.843113c-167.657764-30.621417-335.745108-58.709407-503.722304-88.119185-0.110149-256.977572 0-513.955144 0-770.822567 168.858388-29.519927 337.826924-58.268811 506.685311-88.339483z" fill="#2A5699" p-id="2108"></path><path d="M599.816275 159.528769h363.491637v704.953477h-363.491637v-88.119185h286.38735v-44.059592h-286.38735v-55.07449h286.38735v-44.059593h-286.38735v-55.07449h286.38735v-44.059592h-286.38735v-55.074491h286.38735v-44.059592h-286.38735v-55.074491h286.38735v-44.059592h-286.38735v-55.07449h286.38735v-44.059593h-286.38735v-77.104286zM254.829667 354.162018c20.928306-1.211639 41.856613-2.092831 62.784919-3.19432 14.649814 74.350562 29.619061 148.590975 45.491529 222.61109 12.446835-76.443393 26.215457-152.666487 39.543484-228.999731 22.029796-0.771043 44.059592-1.982682 65.97924-3.30447-24.89367 106.734362-46.703168 214.349917-73.909966 320.423385-18.39488 9.582961-45.932125-0.440596-67.741623 1.10149-14.649814-72.90761-31.722906-145.38564-44.819621-218.645727-12.898446 71.156242-29.641091 141.651589-44.390039 212.367235a4187.754101 4187.754101 0 0 1-63.666111-3.866229c-18.284731-96.931103-39.763782-193.190297-56.836874-290.341698 18.835476-0.881192 37.792115-1.652235 56.627591-2.313129 11.33433 70.164901 24.221761 139.999355 34.146184 210.274404 15.508976-72.037433 31.37043-144.074867 46.791287-216.1123z" fill="#FFFFFF" p-id="2109"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1582644951614" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3842"
|
||||
width="200" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M692.906667 385.024c-11.605333-2.730667-23.210667-6.144-34.816-11.605333l-63.488 25.258666-5.461334 2.048h-5.461333c-8.874667 0-17.749333-4.096-23.210667-11.605333-5.461333-7.509333-6.826667-17.066667-4.778666-25.258667l8.874666-30.72-97.621333-19.797333v400.725333L901.12 402.090667l-105.130667-21.162667c-18.432 5.461333-38.229333 8.874667-59.392 8.874667-13.653333 0-28.672-1.365333-43.690666-4.778667z"
|
||||
fill="#A6DAFC" p-id="3843"></path>
|
||||
<path d="M512 502.442667v467.626666l389.802667-100.352V402.090667zM111.274667 413.696l356.352-100.352V580.266667z"
|
||||
fill="#568EC8" p-id="3844"></path>
|
||||
<path d="M111.274667 413.696v456.021333L512 970.069333V502.442667z" fill="#A6DAFC" p-id="3845"></path>
|
||||
<path d="M512 502.442667l389.802667-100.352L1024 546.816 645.802667 658.090667z" fill="#78C5FD" p-id="3846"></path>
|
||||
<path d="M111.274667 413.696l400.725333 88.746667-122.197333 167.253333L0 569.344z" fill="#CFF0FF"
|
||||
p-id="3847"></path>
|
||||
<path d="M886.784 160.426667c-2.730667-6.826667-6.144-13.653333-9.557333-20.48-1.365333-2.048-2.730667-4.096-4.096-6.826667-4.096-6.144-8.192-12.970667-13.653334-18.432s-10.24-11.605333-16.384-16.384c-2.048-2.048-4.096-3.413333-6.144-4.778667-8.192-6.826667-17.066667-12.288-25.941333-17.749333-2.048-1.365333-4.778667-2.730667-6.826667-3.413333-4.778667-2.048-9.557333-4.778667-15.018666-6.144-7.509333-2.730667-15.701333-5.461333-23.893334-6.826667-2.730667-0.682667-6.144-1.365333-8.874666-2.048-0.682667 0-2.048 0-2.730667-0.682667-2.048 0-4.096-0.682667-6.144-0.682666-1.365333 0-2.048 0-3.413333-0.682667-2.048 0-3.413333 0-5.461334-0.682667H727.04c-4.096 0-8.192 0-11.605333 0.682667h-2.048c-4.096 0.682667-8.192 0.682667-12.288 1.365333h-0.682667c-4.096 0.682667-7.509333 1.365333-11.605333 2.048-0.682667 0-1.365333 0-1.365334 0.682667-4.096 0.682667-7.509333 2.048-10.922666 3.413333-0.682667 0-1.365333 0.682667-2.048 0.682667-3.413333 1.365333-7.509333 2.730667-10.922667 4.096-0.682667 0-0.682667 0.682667-1.365333 0.682667-3.413333 1.365333-6.826667 3.413333-10.24 4.778666 0 0-0.682667 0-0.682667 0.682667-3.413333 2.048-6.826667 3.413333-10.24 5.461333-0.682667 0.682667-1.365333 0.682667-2.048 1.365334-3.413333 2.048-6.144 4.096-9.557333 6.144-0.682667 0.682667-1.365333 0.682667-1.365334 1.365333-3.413333 2.048-6.144 4.778667-8.874666 7.509333l-8.192 8.192-1.365334 1.365334c-2.730667 2.730667-4.778667 5.461333-7.509333 8.192-0.682667 0.682667-0.682667 1.365333-1.365333 1.365333-2.048 2.730667-4.778667 6.144-6.826667 8.874667 0 0.682667-0.682667 0.682667-0.682667 1.365333-2.048 3.413333-4.096 6.144-5.461333 9.557333 0 0.682667-0.682667 0.682667-0.682667 1.365334-2.048 3.413333-3.413333 6.826667-4.778666 10.24 0 0.682667-0.682667 1.365333-0.682667 2.048-1.365333 3.413333-2.730667 6.826667-4.096 10.922666 0 0.682667-0.682667 1.365333-0.682667 2.048-1.365333 4.096-2.048 7.509333-3.413333 11.605334-10.24 46.421333 2.730667 92.16 32.085333 127.658666L593.92 339.968l-9.557333 32.768v0.682667h0.682666l58.709334-23.210667 16.384-6.826667c6.144 3.413333 12.970667 6.144 19.797333 8.192s13.653333 4.778667 21.162667 6.144c2.730667 0.682667 6.144 1.365333 8.874666 2.048 0.682667 0 2.048 0 2.730667 0.682667 2.048 0 4.096 0.682667 6.144 0.682667 1.365333 0 2.048 0 3.413333 0.682666 2.048 0 3.413333 0 5.461334 0.682667H739.328c4.096 0 8.192 0 11.605333-0.682667h2.048c4.096-0.682667 8.192-0.682667 12.288-1.365333h0.682667c4.096-0.682667 7.509333-1.365333 11.605333-2.048 0.682667 0 1.365333 0 2.048-0.682667 4.096-0.682667 7.509333-2.048 10.922667-3.413333 0.682667 0 1.365333-0.682667 2.048-0.682667 3.413333-1.365333 7.509333-2.730667 10.922667-4.096 0.682667 0 0.682667-0.682667 1.365333-0.682666 3.413333-1.365333 6.826667-3.413333 10.24-4.778667 0 0 0.682667 0 0.682667-0.682667 3.413333-2.048 6.826667-3.413333 10.24-5.461333 0.682667-0.682667 1.365333-0.682667 2.048-1.365333 3.413333-2.048 6.144-4.096 9.557333-6.144 0.682667-0.682667 1.365333-0.682667 1.365333-1.365334 3.413333-2.048 6.144-4.778667 8.874667-7.509333l8.192-8.192 1.365333-1.365333c2.730667-2.730667 4.778667-5.461333 7.509334-8.192 0.682667-0.682667 0.682667-1.365333 1.365333-2.048 2.048-2.730667 4.778667-6.144 6.826667-8.874667 0-0.682667 0.682667-0.682667 0.682666-1.365333 2.048-3.413333 4.096-6.144 5.461334-9.557334 0-0.682667 0.682667-0.682667 0.682666-1.365333 2.048-3.413333 3.413333-6.826667 4.778667-10.24 0-0.682667 0.682667-1.365333 0.682667-2.048 1.365333-3.413333 2.730667-6.826667 4.096-10.922667 0-0.682667 0.682667-1.365333 0.682666-2.048 1.365333-4.096 2.048-7.509333 3.413334-11.605333 5.461333-28.672 2.730667-57.344-6.826667-83.285333z"
|
||||
fill="#F9DA3E" p-id="3848"></path>
|
||||
<path d="M739.328 167.936h48.469333v27.989333h-13.653333v-15.701333h-83.968v15.701333h-13.653333v-27.989333h48.469333c-1.365333-3.413333-3.413333-6.826667-4.778667-10.24l14.336-2.048c2.048 3.413333 3.413333 7.509333 4.778667 12.288z m37.546667 52.565333v12.288h-37.546667v25.258667h48.469333v12.970667H677.205333v-12.970667h48.469334v-25.258667h-37.546667v-12.288h88.746667z m-51.882667-24.576c-10.24 8.874667-22.528 16.384-37.546667 22.528l-5.461333-12.288c14.336-5.461333 25.941333-11.605333 34.816-19.797333l8.192 9.557333z m56.661333 10.922667l-7.509333 11.605333c-11.605333-9.557333-23.210667-17.066667-35.498667-22.528l6.826667-10.24c13.653333 6.144 25.258667 12.970667 36.181333 21.162667z"
|
||||
fill="#FFFFFF" p-id="3849"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1514189511483" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="6709" width="200" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M676.297143 0H145.609143C130.834286 0 118.857143 11.977143 118.857143 35.218286V1005.714286c0 6.308571 11.977143 18.285714 26.752 18.285714h732.781714c14.774857 0 26.752-11.977143 26.752-18.285714V237.312c0-12.726857-1.700571-16.822857-4.699428-19.84L687.670857 4.699429A16.164571 16.164571 0 0 0 676.297143 0z"
|
||||
fill="#E9E9E0" p-id="6710"></path>
|
||||
<path d="M685.714286 2.761143V219.428571h216.667428z" fill="#D9D7CA" p-id="6711"></path>
|
||||
<path d="M878.390857 1024H145.609143A26.752 26.752 0 0 1 118.857143 997.248V713.142857h786.285714v284.105143c0 14.774857-11.977143 26.752-26.752 26.752z"
|
||||
fill="#C8BDB8" p-id="6712"></path>
|
||||
<path d="M338.285714 859.428571m-54.857143 0a54.857143 54.857143 0 1 0 109.714286 0 54.857143 54.857143 0 1 0-109.714286 0Z"
|
||||
fill="#FFFFFF" p-id="6713"></path>
|
||||
<path d="M521.142857 859.428571m-54.857143 0a54.857143 54.857143 0 1 0 109.714286 0 54.857143 54.857143 0 1 0-109.714286 0Z"
|
||||
fill="#FFFFFF" p-id="6714"></path>
|
||||
<path d="M704 859.428571m-54.857143 0a54.857143 54.857143 0 1 0 109.714286 0 54.857143 54.857143 0 1 0-109.714286 0Z"
|
||||
fill="#FFFFFF" p-id="6715"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1514189511483" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6709" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M676.297143 0H145.609143C130.834286 0 118.857143 11.977143 118.857143 35.218286V1005.714286c0 6.308571 11.977143 18.285714 26.752 18.285714h732.781714c14.774857 0 26.752-11.977143 26.752-18.285714V237.312c0-12.726857-1.700571-16.822857-4.699428-19.84L687.670857 4.699429A16.164571 16.164571 0 0 0 676.297143 0z" fill="#E9E9E0" p-id="6710"></path><path d="M685.714286 2.761143V219.428571h216.667428z" fill="#D9D7CA" p-id="6711"></path><path d="M878.390857 1024H145.609143A26.752 26.752 0 0 1 118.857143 997.248V713.142857h786.285714v284.105143c0 14.774857-11.977143 26.752-26.752 26.752z" fill="#C8BDB8" p-id="6712"></path><path d="M338.285714 859.428571m-54.857143 0a54.857143 54.857143 0 1 0 109.714286 0 54.857143 54.857143 0 1 0-109.714286 0Z" fill="#FFFFFF" p-id="6713"></path><path d="M521.142857 859.428571m-54.857143 0a54.857143 54.857143 0 1 0 109.714286 0 54.857143 54.857143 0 1 0-109.714286 0Z" fill="#FFFFFF" p-id="6714"></path><path d="M704 859.428571m-54.857143 0a54.857143 54.857143 0 1 0 109.714286 0 54.857143 54.857143 0 1 0-109.714286 0Z" fill="#FFFFFF" p-id="6715"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1514189634329" class="icon" style="" viewBox="0 0 1219 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="10648" width="238.0859375" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M1197.787429 327.192381a19.504762 19.504762 0 0 1 19.553523 19.407238v614.156191c0 34.913524-28.574476 63.24419-63.878095 63.24419H63.878095C28.623238 1024 0 995.718095 0 960.75581V346.599619a19.504762 19.504762 0 0 1 19.602286-19.358476h1178.185143z m-66.80381-213.089524C1179.550476 114.102857 1219.047619 153.209905 1219.047619 201.386667v80.213333H1.657905V88.259048C1.657905 39.497143 41.593905 0 90.794667 0h290.864762c17.408 0 33.987048 7.655619 45.104761 20.967619l78.214096 93.135238h626.005333z"
|
||||
fill="#23B7E5" p-id="10649"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 949 B |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1514189634329" class="icon" style="" viewBox="0 0 1219 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10648" xmlns:xlink="http://www.w3.org/1999/xlink" width="238.0859375" height="200"><defs><style type="text/css"></style></defs><path d="M1197.787429 327.192381a19.504762 19.504762 0 0 1 19.553523 19.407238v614.156191c0 34.913524-28.574476 63.24419-63.878095 63.24419H63.878095C28.623238 1024 0 995.718095 0 960.75581V346.599619a19.504762 19.504762 0 0 1 19.602286-19.358476h1178.185143z m-66.80381-213.089524C1179.550476 114.102857 1219.047619 153.209905 1219.047619 201.386667v80.213333H1.657905V88.259048C1.657905 39.497143 41.593905 0 90.794667 0h290.864762c17.408 0 33.987048 7.655619 45.104761 20.967619l78.214096 93.135238h626.005333z" fill="#23B7E5" p-id="10649"></path></svg>
|
||||
|
After Width: | Height: | Size: 943 B |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1514190539077" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="14917" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M128 0h597.3l227.6 227.9v739.2c0 31.4-25.5 56.9-56.9 56.9H128c-31.4 0-56.9-25.5-56.9-56.9V56.9C71.1 25.5 96.6 0 128 0z" fill="#13BE93" p-id="14918"></path><path d="M630.5 1024H128c-25.7 0-47.4-17-54.4-40.4l218.1-218.1c22.2-22.2 58.2-22.2 80.5 0L630.5 1024z" fill="#6BD8BD" p-id="14919"></path><path d="M952.9 858v109.1c0 31.4-25.5 56.9-56.9 56.9H322.4l-4.7-4.7 358-358c22.2-22.2 58.2-22.2 80.5 0L952.9 858z" fill="#9CF9E2" p-id="14920"></path><path d="M725.3 0l227.6 227.6H782.2c-31.4 0-56.9-25.5-56.9-56.9V0z" fill="#69DCC0" p-id="14921"></path><path d="M327.1 483.6m-85.3 0a85.3 85.3 0 1 0 170.6 0 85.3 85.3 0 1 0-170.6 0Z" fill="#E9FFFA" p-id="14922"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1514190539077" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="14917" width="200" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M128 0h597.3l227.6 227.9v739.2c0 31.4-25.5 56.9-56.9 56.9H128c-31.4 0-56.9-25.5-56.9-56.9V56.9C71.1 25.5 96.6 0 128 0z"
|
||||
fill="#13BE93" p-id="14918"></path>
|
||||
<path d="M630.5 1024H128c-25.7 0-47.4-17-54.4-40.4l218.1-218.1c22.2-22.2 58.2-22.2 80.5 0L630.5 1024z"
|
||||
fill="#6BD8BD" p-id="14919"></path>
|
||||
<path d="M952.9 858v109.1c0 31.4-25.5 56.9-56.9 56.9H322.4l-4.7-4.7 358-358c22.2-22.2 58.2-22.2 80.5 0L952.9 858z"
|
||||
fill="#9CF9E2" p-id="14920"></path>
|
||||
<path d="M725.3 0l227.6 227.6H782.2c-31.4 0-56.9-25.5-56.9-56.9V0z" fill="#69DCC0" p-id="14921"></path>
|
||||
<path d="M327.1 483.6m-85.3 0a85.3 85.3 0 1 0 170.6 0 85.3 85.3 0 1 0-170.6 0Z" fill="#E9FFFA" p-id="14922"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
@@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1514284130163" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="1551" width="200" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M915.114667 1024H108.885333V0h587.776v218.112H914.773333V1024z m-785.066667-20.821333h763.904V238.933333H675.84V20.821333H129.706667v982.357334z"
|
||||
fill="#F90E09" p-id="1552"></path>
|
||||
<path d="M708.266667 10.581333L904.533333 206.848h-196.266666z" fill="#F90E09" p-id="1553"></path>
|
||||
<path d="M282.965333 792.576c33.450667-23.210667 55.637333-57.344 76.8-91.136-30.378667 25.941333-59.050667 54.954667-76.8 91.136z m396.629334-169.642667c31.402667 15.018667 65.877333 31.061333 101.376 21.504-24.576-29.696-67.584-21.504-101.376-21.504z m-246.101334 23.210667c45.397333-16.725333 91.818667-29.696 138.922667-39.594667-30.378667-26.965333-55.978667-58.368-76.458667-93.525333-16.725333 46.08-38.912 90.112-62.464 133.12z m67.925334-243.370667c14.677333-37.546667 19.114667-83.285333-5.802667-117.418666-7.168 38.912-4.096 79.189333 5.802667 117.418666z m-45.397334-105.130666c4.096-24.917333 35.84-29.696 55.637334-22.186667 12.288 7.850667 18.432 22.869333 18.773333 37.205333 1.365333 44.032-6.485333 87.381333-12.629333 130.730667-3.413333 20.138667 8.874667 38.229333 17.749333 55.296 21.845333 40.277333 52.224 76.458667 92.16 99.669333 48.128-5.802667 98.645333-12.970667 145.749333 2.389334 35.157333 11.946667 26.965333 77.141333-11.264 77.824-53.589333 2.730667-102.058667-23.893333-150.186666-43.349334-66.218667 4.778667-130.730667 24.917333-194.218667 44.032-28.672 46.762667-54.613333 98.986667-101.034667 130.730667-23.210667 18.090667-76.458667 3.072-64.512-32.085333 20.138667-49.152 70.314667-76.117333 114.346667-100.693334 12.629333-6.485333 19.797333-18.773333 26.282667-31.061333 30.037333-57.685333 60.074667-115.370667 84.309333-175.786667-12.629333-56.661333-31.061333-114.688-21.162667-172.714666z"
|
||||
fill="#F90E09" p-id="1554"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1514284130163" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1551" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M915.114667 1024H108.885333V0h587.776v218.112H914.773333V1024z m-785.066667-20.821333h763.904V238.933333H675.84V20.821333H129.706667v982.357334z" fill="#F90E09" p-id="1552"></path><path d="M708.266667 10.581333L904.533333 206.848h-196.266666z" fill="#F90E09" p-id="1553"></path><path d="M282.965333 792.576c33.450667-23.210667 55.637333-57.344 76.8-91.136-30.378667 25.941333-59.050667 54.954667-76.8 91.136z m396.629334-169.642667c31.402667 15.018667 65.877333 31.061333 101.376 21.504-24.576-29.696-67.584-21.504-101.376-21.504z m-246.101334 23.210667c45.397333-16.725333 91.818667-29.696 138.922667-39.594667-30.378667-26.965333-55.978667-58.368-76.458667-93.525333-16.725333 46.08-38.912 90.112-62.464 133.12z m67.925334-243.370667c14.677333-37.546667 19.114667-83.285333-5.802667-117.418666-7.168 38.912-4.096 79.189333 5.802667 117.418666z m-45.397334-105.130666c4.096-24.917333 35.84-29.696 55.637334-22.186667 12.288 7.850667 18.432 22.869333 18.773333 37.205333 1.365333 44.032-6.485333 87.381333-12.629333 130.730667-3.413333 20.138667 8.874667 38.229333 17.749333 55.296 21.845333 40.277333 52.224 76.458667 92.16 99.669333 48.128-5.802667 98.645333-12.970667 145.749333 2.389334 35.157333 11.946667 26.965333 77.141333-11.264 77.824-53.589333 2.730667-102.058667-23.893333-150.186666-43.349334-66.218667 4.778667-130.730667 24.917333-194.218667 44.032-28.672 46.762667-54.613333 98.986667-101.034667 130.730667-23.210667 18.090667-76.458667 3.072-64.512-32.085333 20.138667-49.152 70.314667-76.117333 114.346667-100.693334 12.629333-6.485333 19.797333-18.773333 26.282667-31.061333 30.037333-57.685333 60.074667-115.370667 84.309333-175.786667-12.629333-56.661333-31.061333-114.688-21.162667-172.714666z" fill="#F90E09" p-id="1554"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1543300178225" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="5733" width="200" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M537.372818 38.36489h62.454472v99.134083c117.738246 0.660894 235.60867-1.211639 353.236766 0.550745 25.334266-2.423278 45.172097 17.29339 42.627656 42.627655 1.872533 205.758296-0.440596 411.626741 1.10149 617.506201-1.10149 22.250094 2.20298 46.923466-10.574302 66.640134-16.081751 11.664777-36.999043 10.133706-55.834519 11.014898-110.148981-0.550745-220.297962-0.330447-330.557091-0.330447v110.148981h-68.523681c-167.856032-30.621417-336.06454-58.599258-504.041736-88.119185-0.110149-256.977572 0-513.955144 0-770.822567 169.970892-29.420793 339.93077-59.381316 510.110945-88.350498z"
|
||||
fill="#D24625" p-id="5734"></path>
|
||||
<path d="M599.82729 170.543667h363.491636v671.908783h-363.491636v-88.119185h264.357554v-44.059592h-264.357554v-55.074491h264.357554v-44.059592h-264.247405c-0.110149-21.5892-0.110149-43.1784-0.231313-64.767601 43.630011 13.53731 93.307202 13.217878 132.299941-13.008594 42.18706-25.003819 64.216856-72.698327 67.851772-120.271672-48.366417-0.330447-96.710805-0.220298-144.956059-0.220298-0.121164-47.914807 0.550745-95.829613-0.991341-143.634271-18.075448 3.524767-36.128866 7.269833-54.083149 11.125047v-109.818534z"
|
||||
fill="#FFFFFF" p-id="5735"></path>
|
||||
<path d="M677.041725 246.216017c76.553542 3.524767 140.880546 67.961921 144.956059 144.295165-48.366417 0.550745-96.710805 0.330447-145.066208 0.330447 0-48.245254-0.121164-96.490507 0.110149-144.625612z"
|
||||
fill="#D24625" p-id="5736"></path>
|
||||
<path d="M203.940838 329.378497c59.810897 2.863874 132.288926-23.682031 181.855967 21.148605 47.485226 57.607917 34.917227 163.571236-35.467972 198.047867-25.003819 12.777282-53.642554 11.014898-80.849351 10.133706-0.110149 43.068251-0.220298 86.136503-0.110149 129.19374-21.820513-1.872533-43.74016-3.745065-65.538644-5.507449-0.980326-117.628097-1.211639-235.377357 0.110149-353.016469z"
|
||||
fill="#FFFFFF" p-id="5737"></path>
|
||||
<path d="M269.380347 388.969096c21.699349-0.991341 48.575701-4.956704 63.214501 15.420857 12.567999 21.5892 11.89609 50.007637 1.442951 72.257732-12.567999 22.69069-40.986436 20.48771-62.895068 23.131286-2.313129-36.899909-2.092831-73.799817-1.762384-110.809875z"
|
||||
fill="#D24625" p-id="5738"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.5 KiB |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1543300178225" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5733" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M537.372818 38.36489h62.454472v99.134083c117.738246 0.660894 235.60867-1.211639 353.236766 0.550745 25.334266-2.423278 45.172097 17.29339 42.627656 42.627655 1.872533 205.758296-0.440596 411.626741 1.10149 617.506201-1.10149 22.250094 2.20298 46.923466-10.574302 66.640134-16.081751 11.664777-36.999043 10.133706-55.834519 11.014898-110.148981-0.550745-220.297962-0.330447-330.557091-0.330447v110.148981h-68.523681c-167.856032-30.621417-336.06454-58.599258-504.041736-88.119185-0.110149-256.977572 0-513.955144 0-770.822567 169.970892-29.420793 339.93077-59.381316 510.110945-88.350498z" fill="#D24625" p-id="5734"></path><path d="M599.82729 170.543667h363.491636v671.908783h-363.491636v-88.119185h264.357554v-44.059592h-264.357554v-55.074491h264.357554v-44.059592h-264.247405c-0.110149-21.5892-0.110149-43.1784-0.231313-64.767601 43.630011 13.53731 93.307202 13.217878 132.299941-13.008594 42.18706-25.003819 64.216856-72.698327 67.851772-120.271672-48.366417-0.330447-96.710805-0.220298-144.956059-0.220298-0.121164-47.914807 0.550745-95.829613-0.991341-143.634271-18.075448 3.524767-36.128866 7.269833-54.083149 11.125047v-109.818534z" fill="#FFFFFF" p-id="5735"></path><path d="M677.041725 246.216017c76.553542 3.524767 140.880546 67.961921 144.956059 144.295165-48.366417 0.550745-96.710805 0.330447-145.066208 0.330447 0-48.245254-0.121164-96.490507 0.110149-144.625612z" fill="#D24625" p-id="5736"></path><path d="M203.940838 329.378497c59.810897 2.863874 132.288926-23.682031 181.855967 21.148605 47.485226 57.607917 34.917227 163.571236-35.467972 198.047867-25.003819 12.777282-53.642554 11.014898-80.849351 10.133706-0.110149 43.068251-0.220298 86.136503-0.110149 129.19374-21.820513-1.872533-43.74016-3.745065-65.538644-5.507449-0.980326-117.628097-1.211639-235.377357 0.110149-353.016469z" fill="#FFFFFF" p-id="5737"></path><path d="M269.380347 388.969096c21.699349-0.991341 48.575701-4.956704 63.214501 15.420857 12.567999 21.5892 11.89609 50.007637 1.442951 72.257732-12.567999 22.69069-40.986436 20.48771-62.895068 23.131286-2.313129-36.899909-2.092831-73.799817-1.762384-110.809875z" fill="#D24625" p-id="5738"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1545064197737" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="14227" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M759.725253 0H134.464646v1024h817.131314V191.870707z" fill="#02007A" p-id="14228"></path><path d="M72.40404 708.525253h687.838384v258.585858H72.40404z" fill="#230091" p-id="14229"></path><path d="M82.747475 718.868687h667.151515v237.89899H82.747475zM755.070707 5.171717l191.353535 191.353536h-191.353535z" fill="#FFFFFF" p-id="14230"></path><path d="M506.828283 791.272727v93.090909h25.858586c28.444444 0 41.373737-12.929293 41.373737-45.511111s-12.929293-47.579798-41.373737-47.579798h-25.858586z m-25.858586-25.858586h51.717172c42.408081 0 67.232323 29.99596 67.232323 74.989899S575.612121 910.222222 532.686869 910.222222H480.969697v-144.808081z m-132.39596 104.468687c1.034343 26.375758 22.755556 42.408081 55.337374 42.408081 34.650505 0 55.854545-17.066667 55.854546-43.959596 0-21.20404-12.412121-33.09899-40.856566-39.822222l-16.549495-3.620202c-17.583838-4.137374-24.824242-9.826263-24.824242-19.135354 0-11.894949 10.860606-19.652525 26.892929-19.652525s27.410101 7.757576 28.444444 21.204041h24.307071c-0.517172-24.824242-21.20404-41.890909-52.751515-41.89091S351.676768 782.480808 351.676768 807.822222c0 20.169697 12.412121 33.09899 38.787878 38.787879l18.618182 4.137374c18.10101 4.137374 25.341414 10.343434 25.341414 20.169697 0 11.894949-11.894949 20.169697-28.961616 20.169697s-30.513131-8.791919-32.064646-21.721212l-24.824243 0.517171zM258.585859 788.686869v53.785858h20.686868c18.10101 0 31.030303-9.826263 31.030303-26.892929s-12.412121-26.892929-31.030303-26.892929h-20.686868z m-25.858586-23.272728h56.888889c28.444444 0 46.545455 20.686869 46.545454 49.131314s-17.583838 49.131313-46.545454 49.131313h-31.030303v46.545454h-25.858586v-144.808081z" fill="#230091" p-id="14231"></path><path d="M415.806061 443.216162h-31.030303v137.567676H321.163636V196.525253h93.090909c91.022222 0 140.670707 35.684848 140.670708 122.052525 0.517172 103.434343-92.573737 124.638384-139.119192 124.638384z m-5.688889-192.905051c-6.206061 0-14.99798 0.517172-26.89293 1.551515V387.878788h36.202021C461.834343 387.878788 491.313131 366.157576 491.313131 312.888889c0-40.856566-32.064646-62.577778-81.195959-62.577778z m258.068687 337.19596c70.852525 0 96.711111-50.165657 96.711111-84.816162 0-54.820202-35.684848-67.749495-66.19798-87.40202-25.858586-17.066667-49.648485-23.272727-49.648485-40.856566 0-22.755556 15.515152-27.410101 36.20202-27.410101 25.858586 0 54.820202 2.068687 67.232323 16.032323V306.682828c-12.929293-10.343434-37.236364-13.446465-68.783838-13.446464-67.749495 0-93.608081 44.993939-93.608081 84.29899 0 50.682828 33.616162 65.680808 66.19798 83.781818 21.20404 11.894949 46.545455 20.686869 46.545455 44.476767 0 13.963636-8.791919 27.927273-37.753536 27.927273-26.892929 0-59.991919-10.343434-74.989899-23.789899v59.991919c13.446465 10.343434 40.339394 17.583838 78.09293 17.583839z" fill="#7AB7FF" p-id="14232"></path></svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1545064197737" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="14227" width="200" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M759.725253 0H134.464646v1024h817.131314V191.870707z" fill="#02007A" p-id="14228"></path>
|
||||
<path d="M72.40404 708.525253h687.838384v258.585858H72.40404z" fill="#230091" p-id="14229"></path>
|
||||
<path d="M82.747475 718.868687h667.151515v237.89899H82.747475zM755.070707 5.171717l191.353535 191.353536h-191.353535z"
|
||||
fill="#FFFFFF" p-id="14230"></path>
|
||||
<path d="M506.828283 791.272727v93.090909h25.858586c28.444444 0 41.373737-12.929293 41.373737-45.511111s-12.929293-47.579798-41.373737-47.579798h-25.858586z m-25.858586-25.858586h51.717172c42.408081 0 67.232323 29.99596 67.232323 74.989899S575.612121 910.222222 532.686869 910.222222H480.969697v-144.808081z m-132.39596 104.468687c1.034343 26.375758 22.755556 42.408081 55.337374 42.408081 34.650505 0 55.854545-17.066667 55.854546-43.959596 0-21.20404-12.412121-33.09899-40.856566-39.822222l-16.549495-3.620202c-17.583838-4.137374-24.824242-9.826263-24.824242-19.135354 0-11.894949 10.860606-19.652525 26.892929-19.652525s27.410101 7.757576 28.444444 21.204041h24.307071c-0.517172-24.824242-21.20404-41.890909-52.751515-41.89091S351.676768 782.480808 351.676768 807.822222c0 20.169697 12.412121 33.09899 38.787878 38.787879l18.618182 4.137374c18.10101 4.137374 25.341414 10.343434 25.341414 20.169697 0 11.894949-11.894949 20.169697-28.961616 20.169697s-30.513131-8.791919-32.064646-21.721212l-24.824243 0.517171zM258.585859 788.686869v53.785858h20.686868c18.10101 0 31.030303-9.826263 31.030303-26.892929s-12.412121-26.892929-31.030303-26.892929h-20.686868z m-25.858586-23.272728h56.888889c28.444444 0 46.545455 20.686869 46.545454 49.131314s-17.583838 49.131313-46.545454 49.131313h-31.030303v46.545454h-25.858586v-144.808081z"
|
||||
fill="#230091" p-id="14231"></path>
|
||||
<path d="M415.806061 443.216162h-31.030303v137.567676H321.163636V196.525253h93.090909c91.022222 0 140.670707 35.684848 140.670708 122.052525 0.517172 103.434343-92.573737 124.638384-139.119192 124.638384z m-5.688889-192.905051c-6.206061 0-14.99798 0.517172-26.89293 1.551515V387.878788h36.202021C461.834343 387.878788 491.313131 366.157576 491.313131 312.888889c0-40.856566-32.064646-62.577778-81.195959-62.577778z m258.068687 337.19596c70.852525 0 96.711111-50.165657 96.711111-84.816162 0-54.820202-35.684848-67.749495-66.19798-87.40202-25.858586-17.066667-49.648485-23.272727-49.648485-40.856566 0-22.755556 15.515152-27.410101 36.20202-27.410101 25.858586 0 54.820202 2.068687 67.232323 16.032323V306.682828c-12.929293-10.343434-37.236364-13.446465-68.783838-13.446464-67.749495 0-93.608081 44.993939-93.608081 84.29899 0 50.682828 33.616162 65.680808 66.19798 83.781818 21.20404 11.894949 46.545455 20.686869 46.545455 44.476767 0 13.963636-8.791919 27.927273-37.753536 27.927273-26.892929 0-59.991919-10.343434-74.989899-23.789899v59.991919c13.446465 10.343434 40.339394 17.583838 78.09293 17.583839z"
|
||||
fill="#7AB7FF" p-id="14232"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.2 KiB |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1514189544355" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8186" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M176 1024l672 0c26.464 0 48-21.536 48-48l0-672c0-0.544-0.256-0.992-0.288-1.504-0.064-0.736-0.256-1.376-0.416-2.08-0.544-2.272-1.472-4.32-2.88-6.112-0.224-0.288-0.192-0.64-0.416-0.928l-256-288c-0.096-0.096-0.224-0.096-0.32-0.192-1.92-2.048-4.352-3.456-7.136-4.288-0.608-0.192-1.152-0.256-1.792-0.352-0.928-0.16-1.792-0.544-2.752-0.544l-448 0c-26.464 0-48 21.536-48 48l0 928c0 26.464 21.536 48 48 48zM640 58.08l204.384 229.92-188.384 0c-7.04 0-16-13.44-16-24l0-205.92zM160 48c0-8.832 7.2-16 16-16l432 0 0 232c0 25.888 20.96 56 48 56l208 0 0 656c0 8.832-7.2 16-16 16l-672 0c-8.96 0-16-7.04-16-16l0-928zM304 448l416 0c8.832 0 16-7.168 16-16s-7.168-16-16-16l-416 0c-8.832 0-16 7.168-16 16s7.168 16 16 16zM304 576l416 0c8.832 0 16-7.168 16-16s-7.168-16-16-16l-416 0c-8.832 0-16 7.168-16 16s7.168 16 16 16zM304 320l192 0c8.832 0 16-7.168 16-16s-7.168-16-16-16l-192 0c-8.832 0-16 7.168-16 16s7.168 16 16 16zM304 704l416 0c8.832 0 16-7.168 16-16s-7.168-16-16-16l-416 0c-8.832 0-16 7.168-16 16s7.168 16 16 16zM304 832l416 0c8.832 0 16-7.168 16-16s-7.168-16-16-16l-416 0c-8.832 0-16 7.168-16 16s7.168 16 16 16z" p-id="8187"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1514189544355" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="8186" width="200" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M176 1024l672 0c26.464 0 48-21.536 48-48l0-672c0-0.544-0.256-0.992-0.288-1.504-0.064-0.736-0.256-1.376-0.416-2.08-0.544-2.272-1.472-4.32-2.88-6.112-0.224-0.288-0.192-0.64-0.416-0.928l-256-288c-0.096-0.096-0.224-0.096-0.32-0.192-1.92-2.048-4.352-3.456-7.136-4.288-0.608-0.192-1.152-0.256-1.792-0.352-0.928-0.16-1.792-0.544-2.752-0.544l-448 0c-26.464 0-48 21.536-48 48l0 928c0 26.464 21.536 48 48 48zM640 58.08l204.384 229.92-188.384 0c-7.04 0-16-13.44-16-24l0-205.92zM160 48c0-8.832 7.2-16 16-16l432 0 0 232c0 25.888 20.96 56 48 56l208 0 0 656c0 8.832-7.2 16-16 16l-672 0c-8.96 0-16-7.04-16-16l0-928zM304 448l416 0c8.832 0 16-7.168 16-16s-7.168-16-16-16l-416 0c-8.832 0-16 7.168-16 16s7.168 16 16 16zM304 576l416 0c8.832 0 16-7.168 16-16s-7.168-16-16-16l-416 0c-8.832 0-16 7.168-16 16s7.168 16 16 16zM304 320l192 0c8.832 0 16-7.168 16-16s-7.168-16-16-16l-192 0c-8.832 0-16 7.168-16 16s7.168 16 16 16zM304 704l416 0c8.832 0 16-7.168 16-16s-7.168-16-16-16l-416 0c-8.832 0-16 7.168-16 16s7.168 16 16 16zM304 832l416 0c8.832 0 16-7.168 16-16s-7.168-16-16-16l-416 0c-8.832 0-16 7.168-16 16s7.168 16 16 16z"
|
||||
p-id="8187"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.5 KiB |
@@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1514189554639" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="8871" width="200" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M80 34.4h864v960H80z" fill="#8095FF" p-id="8872"></path>
|
||||
<path d="M176 112m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8873"></path>
|
||||
<path d="M176 272m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8874"></path>
|
||||
<path d="M176 432m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8875"></path>
|
||||
<path d="M176 592m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8876"></path>
|
||||
<path d="M176 752m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8877"></path>
|
||||
<path d="M176 912m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8878"></path>
|
||||
<path d="M864 112m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8879"></path>
|
||||
<path d="M864 272m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8880"></path>
|
||||
<path d="M864 432m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8881"></path>
|
||||
<path d="M864 592m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8882"></path>
|
||||
<path d="M864 752m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8883"></path>
|
||||
<path d="M864 912m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8884"></path>
|
||||
<path d="M648 508L436 362.4c-4.8-3.2-11.2-4-16.8-0.8-5.6 3.2-8.8 8.8-8.8 14.4v290.4c0 5.6 3.2 11.2 8.8 14.4 5.6 3.2 12 2.4 16.8-0.8L648 533.6c4.8-2.4 7.2-8 7.2-12.8 0-4.8-3.2-9.6-7.2-12.8z"
|
||||
fill="#FFFFFF" p-id="8885"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.8 KiB |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1514189554639" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8871" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M80 34.4h864v960H80z" fill="#8095FF" p-id="8872"></path><path d="M176 112m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8873"></path><path d="M176 272m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8874"></path><path d="M176 432m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8875"></path><path d="M176 592m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8876"></path><path d="M176 752m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8877"></path><path d="M176 912m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8878"></path><path d="M864 112m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8879"></path><path d="M864 272m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8880"></path><path d="M864 432m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8881"></path><path d="M864 592m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8882"></path><path d="M864 752m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8883"></path><path d="M864 912m-40 0a40 40 0 1 0 80 0 40 40 0 1 0-80 0Z" fill="#FFFFFF" p-id="8884"></path><path d="M648 508L436 362.4c-4.8-3.2-11.2-4-16.8-0.8-5.6 3.2-8.8 8.8-8.8 14.4v290.4c0 5.6 3.2 11.2 8.8 14.4 5.6 3.2 12 2.4 16.8-0.8L648 533.6c4.8-2.4 7.2-8 7.2-12.8 0-4.8-3.2-9.6-7.2-12.8z" fill="#FFFFFF" p-id="8885"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg t="1543300142282" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="2233" width="200" height="200">
|
||||
<defs>
|
||||
<style type="text/css"></style>
|
||||
</defs>
|
||||
<path d="M534.310676 38.36489h65.428495v88.119185c110.25913 0 220.507245 0.220298 330.766374-0.330447 18.615178 0.771043 39.113903-0.550745 55.305803 10.574302 11.345345 16.302049 10.023557 37.010058 10.783586 55.746399-0.550745 191.218631-0.319432 382.327112-0.220298 573.435594-0.550745 32.053353 2.974022 64.767601-3.745066 96.380358-4.405959 22.910988-31.943204 23.461733-50.338084 24.232776-114.114344 0.330447-228.338837-0.220298-342.56333 0v99.134083h-68.402517c-167.867047-30.511268-336.075555-58.709407-504.151885-88.119185v-770.932716c169.0897-29.420793 338.168386-58.389975 507.136922-88.240349z"
|
||||
fill="#207245" p-id="2234"></path>
|
||||
<path d="M599.739171 159.528769h363.491636v693.938579h-363.491636v-66.089389h88.119184v-77.104286h-88.119184v-44.059592h88.119184v-77.104287h-88.119184v-44.059592h88.119184v-77.104287h-88.119184v-44.059592h88.119184v-77.104287h-88.119184v-44.059592h88.119184v-77.104287h-88.119184v-66.089388z"
|
||||
fill="#FFFFFF" p-id="2235"></path>
|
||||
<path d="M731.917948 225.618157h154.208573v77.104287h-154.208573v-77.104287z" fill="#207245" p-id="2236"></path>
|
||||
<path d="M353.44605 328.827752c24.89367-1.762384 49.897488-3.304469 74.901307-4.516108-29.409778 60.251492-58.929705 120.502985-88.879213 180.53418 30.29097 61.683429 61.242833 122.926263 91.632937 184.609692-26.545904-1.553101-52.98166-3.19432-79.527564-5.066854-18.725327-45.932125-41.526166-90.322164-54.964342-138.358134-14.969246 44.731501-36.349164 86.918561-53.521389 130.74684-24.122627-0.330447-48.256268-1.321788-72.367881-2.313129 28.308288-55.404937 55.625235-111.250471 84.814716-166.324961-24.783521-56.726725-52.001334-112.35196-77.544883-168.748238 24.232776-1.431937 48.454537-2.863874 72.698327-4.185662 16.412198 43.068251 34.366482 85.585758 47.925822 129.7555 14.506621-46.802302 36.216985-90.861894 54.832163-136.133126z"
|
||||
fill="#FFFFFF" p-id="2237"></path>
|
||||
<path d="M731.917948 346.782036h154.208573v77.104287h-154.208573v-77.104287zM731.917948 467.945915h154.208573v77.104287h-154.208573v-77.104287zM731.917948 589.109794h154.208573v77.104287h-154.208573v-77.104287zM731.917948 710.273673h154.208573v77.104286h-154.208573v-77.104286z"
|
||||
fill="#207245" p-id="2238"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.6 KiB |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1543300142282" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2233" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M534.310676 38.36489h65.428495v88.119185c110.25913 0 220.507245 0.220298 330.766374-0.330447 18.615178 0.771043 39.113903-0.550745 55.305803 10.574302 11.345345 16.302049 10.023557 37.010058 10.783586 55.746399-0.550745 191.218631-0.319432 382.327112-0.220298 573.435594-0.550745 32.053353 2.974022 64.767601-3.745066 96.380358-4.405959 22.910988-31.943204 23.461733-50.338084 24.232776-114.114344 0.330447-228.338837-0.220298-342.56333 0v99.134083h-68.402517c-167.867047-30.511268-336.075555-58.709407-504.151885-88.119185v-770.932716c169.0897-29.420793 338.168386-58.389975 507.136922-88.240349z" fill="#207245" p-id="2234"></path><path d="M599.739171 159.528769h363.491636v693.938579h-363.491636v-66.089389h88.119184v-77.104286h-88.119184v-44.059592h88.119184v-77.104287h-88.119184v-44.059592h88.119184v-77.104287h-88.119184v-44.059592h88.119184v-77.104287h-88.119184v-44.059592h88.119184v-77.104287h-88.119184v-66.089388z" fill="#FFFFFF" p-id="2235"></path><path d="M731.917948 225.618157h154.208573v77.104287h-154.208573v-77.104287z" fill="#207245" p-id="2236"></path><path d="M353.44605 328.827752c24.89367-1.762384 49.897488-3.304469 74.901307-4.516108-29.409778 60.251492-58.929705 120.502985-88.879213 180.53418 30.29097 61.683429 61.242833 122.926263 91.632937 184.609692-26.545904-1.553101-52.98166-3.19432-79.527564-5.066854-18.725327-45.932125-41.526166-90.322164-54.964342-138.358134-14.969246 44.731501-36.349164 86.918561-53.521389 130.74684-24.122627-0.330447-48.256268-1.321788-72.367881-2.313129 28.308288-55.404937 55.625235-111.250471 84.814716-166.324961-24.783521-56.726725-52.001334-112.35196-77.544883-168.748238 24.232776-1.431937 48.454537-2.863874 72.698327-4.185662 16.412198 43.068251 34.366482 85.585758 47.925822 129.7555 14.506621-46.802302 36.216985-90.861894 54.832163-136.133126z" fill="#FFFFFF" p-id="2237"></path><path d="M731.917948 346.782036h154.208573v77.104287h-154.208573v-77.104287zM731.917948 467.945915h154.208573v77.104287h-154.208573v-77.104287zM731.917948 589.109794h154.208573v77.104287h-154.208573v-77.104287zM731.917948 710.273673h154.208573v77.104286h-154.208573v-77.104286z" fill="#207245" p-id="2238"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
@@ -11,10 +11,10 @@
|
||||
@REM prepare the variables.
|
||||
|
||||
@REM version name
|
||||
SET VERSION_NAME=tank-4.0.0.beta1
|
||||
SET VERSION_NAME=tank-3.1.2
|
||||
ECHO VERSION_NAME: %VERSION_NAME%
|
||||
@REM golang proxy
|
||||
SET GOPROXY=https://goproxy.cn
|
||||
SET GOPROXY=https://athens.azurefd.net
|
||||
ECHO GOPROXY: %GOPROXY%
|
||||
@REM assign variable like Linux GOARCH=$(go env GOARCH) eg. amd64
|
||||
FOR /f %%i IN ('go env GOARCH') DO SET GOARCH=%%i
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
@@ -10,10 +9,10 @@ set -e
|
||||
#prepare the variables.
|
||||
|
||||
# version name
|
||||
VERSION_NAME=tank-4.0.0.beta1
|
||||
VERSION_NAME=tank-3.1.2
|
||||
echo "VERSION_NAME: ${VERSION_NAME}"
|
||||
# golang proxy
|
||||
GOPROXY=https://goproxy.cn
|
||||
GOPROXY=https://athens.azurefd.net
|
||||
echo "GOPROXY: ${GOPROXY}"
|
||||
# eg. amd64
|
||||
GOARCH=$(go env GOARCH)
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package core
|
||||
|
||||
import "gorm.io/gorm/schema"
|
||||
|
||||
const (
|
||||
//authentication key of cookie
|
||||
COOKIE_AUTH_KEY = "_ak"
|
||||
@@ -11,25 +9,26 @@ const (
|
||||
|
||||
DEFAULT_SERVER_PORT = 6010
|
||||
|
||||
//db table's prefix. tank40_ means current version is tank:4.0.x
|
||||
TABLE_PREFIX = "tank40_"
|
||||
//db table's prefix. tank31_ means current version is tank:3.1.x
|
||||
TABLE_PREFIX = "tank31_"
|
||||
|
||||
VERSION = "4.0.0.beta1"
|
||||
VERSION = "3.1.2"
|
||||
)
|
||||
|
||||
type Config interface {
|
||||
Installed() bool
|
||||
ServerPort() int
|
||||
//get the db type
|
||||
DbType() string
|
||||
//get the mysql url. eg. tank:tank123@tcp(127.0.0.1:3306)/tank?charset=utf8&parseTime=True&loc=Local
|
||||
MysqlUrl() string
|
||||
//get the sqlite path
|
||||
SqliteFolder() string
|
||||
//files storage location.
|
||||
MatterPath() string
|
||||
//table name strategy
|
||||
NamingStrategy() schema.NamingStrategy
|
||||
|
||||
OssAccessKey() string
|
||||
OssSecretKey() string
|
||||
OssEndpoint() string
|
||||
OssCustomHost() string
|
||||
OssBucket() string
|
||||
|
||||
//when installed by user. Write configs to tank.json
|
||||
FinishInstall(dbType string, mysqlPort int, mysqlHost string, mysqlSchema string, mysqlUsername string, mysqlPassword string, mysqlCharset string)
|
||||
FinishInstall(mysqlPort int, mysqlHost string, mysqlSchema string, mysqlUsername string, mysqlPassword string, mysqlCharset string)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package core
|
||||
|
||||
import (
|
||||
"github.com/eyebluecn/tank/code/tool/cache"
|
||||
"gorm.io/gorm"
|
||||
"github.com/jinzhu/gorm"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
|
||||
@@ -12,16 +12,14 @@ import (
|
||||
|
||||
type AlienController struct {
|
||||
BaseController
|
||||
uploadTokenDao *UploadTokenDao
|
||||
downloadTokenDao *DownloadTokenDao
|
||||
matterDao *MatterDao
|
||||
spaceDao *SpaceDao
|
||||
matterService *MatterService
|
||||
imageCacheDao *ImageCacheDao
|
||||
imageCacheService *ImageCacheService
|
||||
alienService *AlienService
|
||||
shareService *ShareService
|
||||
spaceMemberService *SpaceMemberService
|
||||
uploadTokenDao *UploadTokenDao
|
||||
downloadTokenDao *DownloadTokenDao
|
||||
matterDao *MatterDao
|
||||
matterService *MatterService
|
||||
imageCacheDao *ImageCacheDao
|
||||
imageCacheService *ImageCacheService
|
||||
alienService *AlienService
|
||||
shareService *ShareService
|
||||
}
|
||||
|
||||
func (this *AlienController) Init() {
|
||||
@@ -42,11 +40,6 @@ func (this *AlienController) Init() {
|
||||
this.matterDao = c
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.spaceDao)
|
||||
if c, ok := b.(*SpaceDao); ok {
|
||||
this.spaceDao = c
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.matterService)
|
||||
if c, ok := b.(*MatterService); ok {
|
||||
this.matterService = c
|
||||
@@ -71,11 +64,6 @@ func (this *AlienController) Init() {
|
||||
if c, ok := b.(*ShareService); ok {
|
||||
this.shareService = c
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.spaceMemberService)
|
||||
if b, ok := b.(*SpaceMemberService); ok {
|
||||
this.spaceMemberService = b
|
||||
}
|
||||
}
|
||||
|
||||
func (this *AlienController) RegisterRoutes() map[string]func(writer http.ResponseWriter, request *http.Request) {
|
||||
@@ -92,7 +80,7 @@ func (this *AlienController) RegisterRoutes() map[string]func(writer http.Respon
|
||||
return routeMap
|
||||
}
|
||||
|
||||
// handle some special routes, eg. params in the url.
|
||||
//handle some special routes, eg. params in the url.
|
||||
func (this *AlienController) HandleRoutes(writer http.ResponseWriter, request *http.Request) (func(writer http.ResponseWriter, request *http.Request), bool) {
|
||||
|
||||
path := request.URL.Path
|
||||
@@ -120,7 +108,7 @@ func (this *AlienController) HandleRoutes(writer http.ResponseWriter, request *h
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// fetch a upload token for guest. Guest can upload file with this token.
|
||||
//fetch a upload token for guest. Guest can upload file with this token.
|
||||
func (this *AlienController) FetchUploadToken(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
filename := request.FormValue("filename")
|
||||
@@ -163,8 +151,7 @@ func (this *AlienController) FetchUploadToken(writer http.ResponseWriter, reques
|
||||
}
|
||||
|
||||
user := this.checkUser(request)
|
||||
space := this.spaceDao.CheckByUuid(user.SpaceUuid)
|
||||
dirMatter := this.matterService.CreateDirectories(request, user, space, dirPath)
|
||||
dirMatter := this.matterService.CreateDirectories(request, user, dirPath)
|
||||
|
||||
uploadToken := &UploadToken{
|
||||
UserUuid: user.Uuid,
|
||||
@@ -183,7 +170,7 @@ func (this *AlienController) FetchUploadToken(writer http.ResponseWriter, reques
|
||||
|
||||
}
|
||||
|
||||
// user confirm a file whether uploaded successfully.
|
||||
//user confirm a file whether uploaded successfully.
|
||||
func (this *AlienController) Confirm(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
matterUuid := request.FormValue("matterUuid")
|
||||
@@ -201,7 +188,7 @@ func (this *AlienController) Confirm(writer http.ResponseWriter, request *http.R
|
||||
return this.Success(matter)
|
||||
}
|
||||
|
||||
// a guest upload a file with a upload token.
|
||||
//a guest upload a file with a upload token.
|
||||
func (this *AlienController) Upload(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
//allow cors.
|
||||
this.allowCORS(writer)
|
||||
@@ -229,7 +216,6 @@ func (this *AlienController) Upload(writer http.ResponseWriter, request *http.Re
|
||||
}
|
||||
|
||||
user := this.userDao.CheckByUuid(uploadToken.UserUuid)
|
||||
space := this.spaceDao.CheckByUuid(user.SpaceUuid)
|
||||
|
||||
err = request.ParseMultipartForm(32 << 20)
|
||||
this.PanicError(err)
|
||||
@@ -242,9 +228,9 @@ func (this *AlienController) Upload(writer http.ResponseWriter, request *http.Re
|
||||
panic(result.BadRequest("file size doesn't the one in uploadToken"))
|
||||
}
|
||||
|
||||
dirMatter := this.matterDao.CheckWithRootByUuid(uploadToken.FolderUuid, space)
|
||||
dirMatter := this.matterDao.CheckWithRootByUuid(uploadToken.FolderUuid, user)
|
||||
|
||||
matter := this.matterService.Upload(request, file, handler, user, space, dirMatter, uploadToken.Filename, uploadToken.Privacy)
|
||||
matter := this.matterService.Upload(request, file, user, dirMatter, uploadToken.Filename, uploadToken.Privacy)
|
||||
|
||||
//expire the upload token.
|
||||
uploadToken.ExpireTime = time.Now()
|
||||
@@ -253,7 +239,7 @@ func (this *AlienController) Upload(writer http.ResponseWriter, request *http.Re
|
||||
return this.Success(matter)
|
||||
}
|
||||
|
||||
// crawl a url with uploadToken. guest can visit this method.
|
||||
//crawl a url with uploadToken. guest can visit this method.
|
||||
func (this *AlienController) CrawlToken(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
//allow cors.
|
||||
@@ -277,11 +263,10 @@ func (this *AlienController) CrawlToken(writer http.ResponseWriter, request *htt
|
||||
}
|
||||
|
||||
user := this.userDao.CheckByUuid(uploadToken.UserUuid)
|
||||
space := this.spaceDao.CheckByUuid(user.SpaceUuid)
|
||||
|
||||
dirMatter := this.matterDao.CheckWithRootByUuid(uploadToken.FolderUuid, space)
|
||||
dirMatter := this.matterDao.CheckWithRootByUuid(uploadToken.FolderUuid, user)
|
||||
|
||||
matter := this.matterService.AtomicCrawl(request, url, uploadToken.Filename, user, space, dirMatter, uploadToken.Privacy)
|
||||
matter := this.matterService.AtomicCrawl(request, url, uploadToken.Filename, user, dirMatter, uploadToken.Privacy)
|
||||
|
||||
//expire the upload token.
|
||||
uploadToken.ExpireTime = time.Now()
|
||||
@@ -290,7 +275,7 @@ func (this *AlienController) CrawlToken(writer http.ResponseWriter, request *htt
|
||||
return this.Success(matter)
|
||||
}
|
||||
|
||||
// crawl a url directly. only user can visit this method.
|
||||
//crawl a url directly. only user can visit this method.
|
||||
func (this *AlienController) CrawlDirect(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
filename := request.FormValue("filename")
|
||||
@@ -306,15 +291,14 @@ func (this *AlienController) CrawlDirect(writer http.ResponseWriter, request *ht
|
||||
}
|
||||
|
||||
user := this.checkUser(request)
|
||||
space := this.spaceDao.CheckByUuid(user.SpaceUuid)
|
||||
dirMatter := this.matterService.CreateDirectories(request, user, space, dirPath)
|
||||
dirMatter := this.matterService.CreateDirectories(request, user, dirPath)
|
||||
|
||||
matter := this.matterService.AtomicCrawl(request, url, filename, user, space, dirMatter, privacy)
|
||||
matter := this.matterService.AtomicCrawl(request, url, filename, user, dirMatter, privacy)
|
||||
|
||||
return this.Success(matter)
|
||||
}
|
||||
|
||||
// fetch a download token for guest. Guest can download file with this token.
|
||||
//fetch a download token for guest. Guest can download file with this token.
|
||||
func (this *AlienController) FetchDownloadToken(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
matterUuid := request.FormValue("matterUuid")
|
||||
@@ -327,9 +311,8 @@ func (this *AlienController) FetchDownloadToken(writer http.ResponseWriter, requ
|
||||
user := this.checkUser(request)
|
||||
|
||||
matter := this.matterDao.CheckByUuid(matterUuid)
|
||||
canRead := this.spaceMemberService.canRead(user, matter.SpaceUuid)
|
||||
if !canRead {
|
||||
panic(result.BadRequest("no auth to visit this file."))
|
||||
if matter.UserUuid != user.Uuid {
|
||||
panic(result.BadRequest("matter not belong to you"))
|
||||
}
|
||||
|
||||
var expireTime time.Time
|
||||
@@ -355,14 +338,14 @@ func (this *AlienController) FetchDownloadToken(writer http.ResponseWriter, requ
|
||||
|
||||
}
|
||||
|
||||
// preview a file.
|
||||
//preview a file.
|
||||
func (this *AlienController) Preview(writer http.ResponseWriter, request *http.Request, uuid string, filename string) {
|
||||
matter := this.alienService.ValidMatter(writer, request, uuid, filename)
|
||||
this.alienService.PreviewOrDownload(writer, request, matter, false)
|
||||
|
||||
this.alienService.PreviewOrDownload(writer, request, uuid, filename, false)
|
||||
}
|
||||
|
||||
// download a file.
|
||||
//download a file.
|
||||
func (this *AlienController) Download(writer http.ResponseWriter, request *http.Request, uuid string, filename string) {
|
||||
matter := this.alienService.ValidMatter(writer, request, uuid, filename)
|
||||
this.alienService.PreviewOrDownload(writer, request, matter, true)
|
||||
|
||||
this.alienService.PreviewOrDownload(writer, request, uuid, filename, true)
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// @Service
|
||||
//@Service
|
||||
type AlienService struct {
|
||||
BaseBean
|
||||
matterDao *MatterDao
|
||||
@@ -19,7 +19,6 @@ type AlienService struct {
|
||||
shareService *ShareService
|
||||
imageCacheDao *ImageCacheDao
|
||||
imageCacheService *ImageCacheService
|
||||
spaceService *SpaceService
|
||||
}
|
||||
|
||||
func (this *AlienService) Init() {
|
||||
@@ -64,18 +63,14 @@ func (this *AlienService) Init() {
|
||||
if c, ok := b.(*ImageCacheService); ok {
|
||||
this.imageCacheService = c
|
||||
}
|
||||
b = core.CONTEXT.GetBean(this.spaceService)
|
||||
if c, ok := b.(*SpaceService); ok {
|
||||
this.spaceService = c
|
||||
}
|
||||
}
|
||||
|
||||
// check whether the request params ok.
|
||||
func (this *AlienService) ValidMatter(
|
||||
func (this *AlienService) PreviewOrDownload(
|
||||
writer http.ResponseWriter,
|
||||
request *http.Request,
|
||||
uuid string,
|
||||
filename string) *Matter {
|
||||
filename string,
|
||||
withContentDisposition bool) {
|
||||
|
||||
matter := this.matterDao.CheckByUuid(uuid)
|
||||
|
||||
@@ -109,28 +104,18 @@ func (this *AlienService) ValidMatter(
|
||||
|
||||
} else {
|
||||
|
||||
//whether this is myself's matter.
|
||||
operator := this.findUser(request)
|
||||
if operator == nil {
|
||||
panic(result.BadRequest("no auth"))
|
||||
}
|
||||
|
||||
if matter.SpaceUuid != operator.SpaceUuid {
|
||||
//whether user has the space's read auth.
|
||||
this.spaceService.CheckReadableByUuid(request, operator, matter.SpaceUuid)
|
||||
}
|
||||
//use share code to auth.
|
||||
shareUuid := request.FormValue("shareUuid")
|
||||
shareCode := request.FormValue("shareCode")
|
||||
shareRootUuid := request.FormValue("shareRootUuid")
|
||||
|
||||
this.shareService.ValidateMatter(request, shareUuid, shareCode, operator, shareRootUuid, matter)
|
||||
|
||||
}
|
||||
}
|
||||
return matter
|
||||
}
|
||||
|
||||
func (this *AlienService) PreviewOrDownload(
|
||||
writer http.ResponseWriter,
|
||||
request *http.Request,
|
||||
matter *Matter,
|
||||
withContentDisposition bool,
|
||||
) {
|
||||
//download directory
|
||||
if matter.Dir {
|
||||
|
||||
@@ -150,7 +135,7 @@ func (this *AlienService) PreviewOrDownload(
|
||||
}
|
||||
|
||||
//download the cache image file.
|
||||
this.matterService.DownloadFile(writer, request, GetSpaceCacheRootDir(imageCache.Username)+imageCache.Path, imageCache.Name, withContentDisposition)
|
||||
this.matterService.DownloadFile(writer, request, GetUserCacheRootDir(imageCache.Username)+imageCache.Path, imageCache.Name, withContentDisposition)
|
||||
|
||||
} else {
|
||||
this.matterService.DownloadFile(writer, request, matter.AbsolutePath(), matter.Name, withContentDisposition)
|
||||
@@ -160,6 +145,7 @@ func (this *AlienService) PreviewOrDownload(
|
||||
|
||||
//async increase the download times.
|
||||
go core.RunWithRecovery(func() {
|
||||
this.matterDao.TimesIncrement(matter.Uuid)
|
||||
this.matterDao.TimesIncrement(uuid)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
@@ -13,10 +13,8 @@ import (
|
||||
|
||||
type BaseController struct {
|
||||
BaseBean
|
||||
userDao *UserDao
|
||||
spaceDao *SpaceDao
|
||||
spaceService *SpaceService
|
||||
sessionDao *SessionDao
|
||||
userDao *UserDao
|
||||
sessionDao *SessionDao
|
||||
}
|
||||
|
||||
func (this *BaseController) Init() {
|
||||
@@ -28,16 +26,6 @@ func (this *BaseController) Init() {
|
||||
this.userDao = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.spaceDao)
|
||||
if b, ok := b.(*SpaceDao); ok {
|
||||
this.spaceDao = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.spaceService)
|
||||
if b, ok := b.(*SpaceService); ok {
|
||||
this.spaceService = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.sessionDao)
|
||||
if b, ok := b.(*SessionDao); ok {
|
||||
this.sessionDao = b
|
||||
@@ -50,12 +38,12 @@ func (this *BaseController) RegisterRoutes() map[string]func(writer http.Respons
|
||||
return make(map[string]func(writer http.ResponseWriter, request *http.Request))
|
||||
}
|
||||
|
||||
// handle some special routes, eg. params in the url.
|
||||
//handle some special routes, eg. params in the url.
|
||||
func (this *BaseController) HandleRoutes(writer http.ResponseWriter, request *http.Request) (func(writer http.ResponseWriter, request *http.Request), bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// wrap the handle method.
|
||||
//wrap the handle method.
|
||||
func (this *BaseController) Wrap(f func(writer http.ResponseWriter, request *http.Request) *result.WebResult, qualifiedRole string) func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
return func(writer http.ResponseWriter, request *http.Request) {
|
||||
@@ -99,50 +87,7 @@ func (this *BaseController) Wrap(f func(writer http.ResponseWriter, request *htt
|
||||
}
|
||||
}
|
||||
|
||||
// wrap the handle method without result.
|
||||
func (this *BaseController) WrapPure(f func(writer http.ResponseWriter, request *http.Request), qualifiedRole string) func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
return func(writer http.ResponseWriter, request *http.Request) {
|
||||
|
||||
var webResult *result.WebResult = nil
|
||||
|
||||
//if the api not annotated with GUEST. login is required.
|
||||
if qualifiedRole != USER_ROLE_GUEST {
|
||||
user := this.checkUser(request)
|
||||
|
||||
if user.Status == USER_STATUS_DISABLED {
|
||||
//check user's status
|
||||
webResult = result.CustomWebResultI18n(request, result.USER_DISABLED, i18n.UserDisabled)
|
||||
} else {
|
||||
if qualifiedRole == USER_ROLE_ADMINISTRATOR && user.Role != USER_ROLE_ADMINISTRATOR {
|
||||
webResult = result.ConstWebResult(result.UNAUTHORIZED)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//if webResult not nil. response a json. if webResult is nil, return empty body or binary content.
|
||||
if webResult != nil {
|
||||
|
||||
writer.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
||||
|
||||
b, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(webResult)
|
||||
|
||||
this.PanicError(err)
|
||||
|
||||
writer.WriteHeader(result.FetchHttpStatus(webResult.Code))
|
||||
|
||||
_, err = fmt.Fprintf(writer, string(b))
|
||||
this.PanicError(err)
|
||||
}
|
||||
|
||||
//no error.
|
||||
f(writer, request)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// response a success result. 1.string 2. WebResult 3.nil pointer 4.any type
|
||||
//response a success result. 1.string 2. WebResult 3.nil pointer 4.any type
|
||||
func (this *BaseController) Success(data interface{}) *result.WebResult {
|
||||
var webResult *result.WebResult = nil
|
||||
if value, ok := data.(string); ok {
|
||||
@@ -161,7 +106,7 @@ func (this *BaseController) Success(data interface{}) *result.WebResult {
|
||||
return webResult
|
||||
}
|
||||
|
||||
// allow cors.
|
||||
//allow cors.
|
||||
func (this *BaseController) allowCORS(writer http.ResponseWriter) {
|
||||
util.AllowCORS(writer)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package rest
|
||||
|
||||
import (
|
||||
"math"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -15,6 +16,24 @@ const (
|
||||
EMPTY_JSON_ARRAY = "[]"
|
||||
)
|
||||
|
||||
type IBase interface {
|
||||
//name of db table
|
||||
TableName() string
|
||||
}
|
||||
|
||||
// Mysql 5.5 only support one CURRENT_TIMESTAMP
|
||||
// so we use 2018-01-01 00:00:00 as default, which is the first release date of EyeblueTank
|
||||
type Base struct {
|
||||
Uuid string `json:"uuid" gorm:"type:char(36);primary_key;unique"`
|
||||
Sort int64 `json:"sort" gorm:"type:bigint(20) not null"`
|
||||
UpdateTime time.Time `json:"updateTime" gorm:"type:timestamp not null;default:CURRENT_TIMESTAMP"`
|
||||
CreateTime time.Time `json:"createTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"`
|
||||
}
|
||||
|
||||
func (this *Base) TableName() string {
|
||||
panic("you should overwrite TableName()")
|
||||
}
|
||||
|
||||
//pager
|
||||
type Pager struct {
|
||||
Page int `json:"page"`
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"github.com/eyebluecn/tank/code/tool/builder"
|
||||
"github.com/eyebluecn/tank/code/tool/result"
|
||||
"github.com/eyebluecn/tank/code/tool/uuid"
|
||||
"gorm.io/gorm"
|
||||
"github.com/jinzhu/gorm"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -69,7 +69,7 @@ func (this *BridgeDao) PlainPage(page int, pageSize int, shareUuid string, sortA
|
||||
var conditionDB *gorm.DB
|
||||
conditionDB = core.CONTEXT.GetDB().Model(&Bridge{}).Where(wp.Query, wp.Args...)
|
||||
|
||||
var count int64 = 0
|
||||
count := 0
|
||||
db := conditionDB.Count(&count)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
@@ -77,7 +77,7 @@ func (this *BridgeDao) PlainPage(page int, pageSize int, shareUuid string, sortA
|
||||
db = conditionDB.Order(this.GetSortString(sortArray)).Offset(page * pageSize).Limit(pageSize).Find(&bridges)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
return int(count), bridges
|
||||
return count, bridges
|
||||
}
|
||||
|
||||
//get pager
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
package rest
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
)
|
||||
|
||||
/**
|
||||
* the link table for Share and Matter.
|
||||
*/
|
||||
type Bridge struct {
|
||||
Uuid string `json:"uuid" gorm:"type:char(36);primary_key;unique"`
|
||||
Sort int64 `json:"sort" gorm:"type:bigint(20) not null"`
|
||||
UpdateTime time.Time `json:"updateTime" gorm:"type:timestamp not null;default:CURRENT_TIMESTAMP"`
|
||||
CreateTime time.Time `json:"createTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"`
|
||||
ShareUuid string `json:"shareUuid" gorm:"type:char(36)"`
|
||||
MatterUuid string `json:"matterUuid" gorm:"type:char(36)"`
|
||||
Base
|
||||
ShareUuid string `json:"shareUuid" gorm:"type:char(36)"`
|
||||
MatterUuid string `json:"matterUuid" gorm:"type:char(36)"`
|
||||
}
|
||||
|
||||
func (this *Bridge) TableName() string {
|
||||
return core.TABLE_PREFIX + "bridge"
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
"github.com/eyebluecn/tank/code/tool/builder"
|
||||
"github.com/eyebluecn/tank/code/tool/uuid"
|
||||
"gorm.io/gorm"
|
||||
"github.com/jinzhu/gorm"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -61,14 +61,14 @@ func (this *DashboardDao) Page(page int, pageSize int, dt string, sortArray []bu
|
||||
var conditionDB *gorm.DB
|
||||
conditionDB = core.CONTEXT.GetDB().Model(&Dashboard{}).Where(wp.Query, wp.Args...)
|
||||
|
||||
var count int64 = 0
|
||||
count := 0
|
||||
db := conditionDB.Count(&count)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
var dashboards []*Dashboard
|
||||
db = conditionDB.Order(this.GetSortString(sortArray)).Offset(page * pageSize).Limit(pageSize).Find(&dashboards)
|
||||
this.PanicError(db.Error)
|
||||
pager := NewPager(page, pageSize, int(count), dashboards)
|
||||
pager := NewPager(page, pageSize, count, dashboards)
|
||||
|
||||
return pager
|
||||
}
|
||||
|
||||
@@ -1,25 +1,27 @@
|
||||
package rest
|
||||
|
||||
import "time"
|
||||
import "github.com/eyebluecn/tank/code/core"
|
||||
|
||||
/**
|
||||
* application's dashboard.
|
||||
*/
|
||||
type Dashboard struct {
|
||||
Uuid string `json:"uuid" gorm:"type:char(36);primary_key;unique"`
|
||||
Sort int64 `json:"sort" gorm:"type:bigint(20) not null"`
|
||||
UpdateTime time.Time `json:"updateTime" gorm:"type:timestamp not null;default:CURRENT_TIMESTAMP"`
|
||||
CreateTime time.Time `json:"createTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"`
|
||||
InvokeNum int64 `json:"invokeNum" gorm:"type:bigint(20) not null"` //api invoke num.
|
||||
TotalInvokeNum int64 `json:"totalInvokeNum" gorm:"type:bigint(20) not null;default:0"` //total invoke num up to now.
|
||||
Uv int64 `json:"uv" gorm:"type:bigint(20) not null;default:0"` //today's uv
|
||||
TotalUv int64 `json:"totalUv" gorm:"type:bigint(20) not null;default:0"` //total uv
|
||||
MatterNum int64 `json:"matterNum" gorm:"type:bigint(20) not null;default:0"` //file's num
|
||||
TotalMatterNum int64 `json:"totalMatterNum" gorm:"type:bigint(20) not null;default:0"` //file's total number
|
||||
FileSize int64 `json:"fileSize" gorm:"type:bigint(20) not null;default:0"` //today's file size
|
||||
TotalFileSize int64 `json:"totalFileSize" gorm:"type:bigint(20) not null;default:0"` //total file's size
|
||||
AvgCost int64 `json:"avgCost" gorm:"type:bigint(20) not null;default:0"` //api time cost in ms
|
||||
Dt string `json:"dt" gorm:"type:varchar(45) not null;index:idx_dt"` //date. index should unique globally.
|
||||
Base
|
||||
InvokeNum int64 `json:"invokeNum" gorm:"type:bigint(20) not null"` //api invoke num.
|
||||
TotalInvokeNum int64 `json:"totalInvokeNum" gorm:"type:bigint(20) not null;default:0"` //total invoke num up to now.
|
||||
Uv int64 `json:"uv" gorm:"type:bigint(20) not null;default:0"` //today's uv
|
||||
TotalUv int64 `json:"totalUv" gorm:"type:bigint(20) not null;default:0"` //total uv
|
||||
MatterNum int64 `json:"matterNum" gorm:"type:bigint(20) not null;default:0"` //file's num
|
||||
TotalMatterNum int64 `json:"totalMatterNum" gorm:"type:bigint(20) not null;default:0"` //file's total number
|
||||
FileSize int64 `json:"fileSize" gorm:"type:bigint(20) not null;default:0"` //today's file size
|
||||
TotalFileSize int64 `json:"totalFileSize" gorm:"type:bigint(20) not null;default:0"` //total file's size
|
||||
AvgCost int64 `json:"avgCost" gorm:"type:bigint(20) not null;default:0"` //api time cost in ms
|
||||
Dt string `json:"dt" gorm:"type:varchar(45) not null;index:idx_dt"` //date
|
||||
}
|
||||
|
||||
// set File's table name to be `profiles`
|
||||
func (this *Dashboard) TableName() string {
|
||||
return core.TABLE_PREFIX + "dashboard"
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,7 +25,6 @@ type DavController struct {
|
||||
BaseController
|
||||
uploadTokenDao *UploadTokenDao
|
||||
downloadTokenDao *DownloadTokenDao
|
||||
spaceDao *SpaceDao
|
||||
matterDao *MatterDao
|
||||
matterService *MatterService
|
||||
imageCacheDao *ImageCacheDao
|
||||
@@ -51,11 +50,6 @@ func (this *DavController) Init() {
|
||||
this.matterDao = c
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.spaceDao)
|
||||
if c, ok := b.(*SpaceDao); ok {
|
||||
this.spaceDao = c
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.matterService)
|
||||
if c, ok := b.(*MatterService); ok {
|
||||
this.matterService = c
|
||||
@@ -77,7 +71,7 @@ func (this *DavController) Init() {
|
||||
}
|
||||
}
|
||||
|
||||
// Auth user by BasicAuth
|
||||
//Auth user by BasicAuth
|
||||
func (this *DavController) CheckCurrentUser(writer http.ResponseWriter, request *http.Request) *User {
|
||||
|
||||
username, password, ok := request.BasicAuth()
|
||||
@@ -106,7 +100,7 @@ func (this *DavController) RegisterRoutes() map[string]func(writer http.Response
|
||||
return routeMap
|
||||
}
|
||||
|
||||
// handle some special routes, eg. params in the url.
|
||||
//handle some special routes, eg. params in the url.
|
||||
func (this *DavController) HandleRoutes(writer http.ResponseWriter, request *http.Request) (func(writer http.ResponseWriter, request *http.Request), bool) {
|
||||
|
||||
path := request.URL.Path
|
||||
@@ -117,16 +111,10 @@ func (this *DavController) HandleRoutes(writer http.ResponseWriter, request *htt
|
||||
strs := reg.FindStringSubmatch(path)
|
||||
if len(strs) == 2 {
|
||||
var f = func(writer http.ResponseWriter, request *http.Request) {
|
||||
|
||||
if err := recover(); err != nil {
|
||||
this.logger.Error("occur error in webdav: %v", err)
|
||||
}
|
||||
|
||||
subPath := strs[1]
|
||||
//guarantee subPath not end with /
|
||||
subPath = strings.TrimSuffix(subPath, "/")
|
||||
this.Index(writer, request, subPath)
|
||||
|
||||
}
|
||||
return f, true
|
||||
}
|
||||
@@ -178,8 +166,7 @@ func (this *DavController) Index(writer http.ResponseWriter, request *http.Reque
|
||||
//this.debug(writer, request, subPath)
|
||||
|
||||
user := this.CheckCurrentUser(writer, request)
|
||||
space := this.spaceDao.CheckByUuid(user.SpaceUuid)
|
||||
|
||||
this.davService.HandleDav(writer, request, user, space, subPath)
|
||||
this.davService.HandleDav(writer, request, user, subPath)
|
||||
|
||||
}
|
||||
|
||||
@@ -9,19 +9,19 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// webdav url prefix.
|
||||
//webdav url prefix.
|
||||
var WEBDAV_PREFIX = "/api/dav"
|
||||
|
||||
// live prop.
|
||||
//live prop.
|
||||
type LiveProp struct {
|
||||
findFn func(space *Space, matter *Matter) string
|
||||
findFn func(user *User, matter *Matter) string
|
||||
dir bool
|
||||
}
|
||||
|
||||
// all live prop map.
|
||||
//all live prop map.
|
||||
var LivePropMap = map[xml.Name]LiveProp{
|
||||
{Space: "DAV:", Local: "resourcetype"}: {
|
||||
findFn: func(space *Space, matter *Matter) string {
|
||||
findFn: func(user *User, matter *Matter) string {
|
||||
if matter.Dir {
|
||||
return `<D:collection xmlns:D="DAV:"/>`
|
||||
} else {
|
||||
@@ -31,7 +31,7 @@ var LivePropMap = map[xml.Name]LiveProp{
|
||||
dir: true,
|
||||
},
|
||||
{Space: "DAV:", Local: "displayname"}: {
|
||||
findFn: func(space *Space, matter *Matter) string {
|
||||
findFn: func(user *User, matter *Matter) string {
|
||||
if path.Clean("/"+matter.Name) == "/" {
|
||||
return ""
|
||||
} else {
|
||||
@@ -41,13 +41,13 @@ var LivePropMap = map[xml.Name]LiveProp{
|
||||
dir: true,
|
||||
},
|
||||
{Space: "DAV:", Local: "getcontentlength"}: {
|
||||
findFn: func(space *Space, matter *Matter) string {
|
||||
findFn: func(user *User, matter *Matter) string {
|
||||
return strconv.FormatInt(matter.Size, 10)
|
||||
},
|
||||
dir: false,
|
||||
},
|
||||
{Space: "DAV:", Local: "getlastmodified"}: {
|
||||
findFn: func(space *Space, matter *Matter) string {
|
||||
findFn: func(user *User, matter *Matter) string {
|
||||
return matter.UpdateTime.UTC().Format(http.TimeFormat)
|
||||
},
|
||||
// http://webdav.org/specs/rfc4918.html#PROPERTY_getlastmodified
|
||||
@@ -68,7 +68,7 @@ var LivePropMap = map[xml.Name]LiveProp{
|
||||
dir: false,
|
||||
},
|
||||
{Space: "DAV:", Local: "getcontenttype"}: {
|
||||
findFn: func(space *Space, matter *Matter) string {
|
||||
findFn: func(user *User, matter *Matter) string {
|
||||
if matter.Dir {
|
||||
return ""
|
||||
} else {
|
||||
@@ -78,7 +78,7 @@ var LivePropMap = map[xml.Name]LiveProp{
|
||||
dir: false,
|
||||
},
|
||||
{Space: "DAV:", Local: "getetag"}: {
|
||||
findFn: func(space *Space, matter *Matter) string {
|
||||
findFn: func(user *User, matter *Matter) string {
|
||||
return fmt.Sprintf(`"%x%x"`, matter.UpdateTime.UnixNano(), matter.Size)
|
||||
},
|
||||
// findETag implements ETag as the concatenated hex values of a file's
|
||||
@@ -91,7 +91,7 @@ var LivePropMap = map[xml.Name]LiveProp{
|
||||
// active locks on a resource.
|
||||
{Space: "DAV:", Local: "lockdiscovery"}: {},
|
||||
{Space: "DAV:", Local: "supportedlock"}: {
|
||||
findFn: func(space *Space, matter *Matter) string {
|
||||
findFn: func(user *User, matter *Matter) string {
|
||||
return `` +
|
||||
`<D:lockentry xmlns:D="DAV:">` +
|
||||
`<D:lockscope><D:exclusive/></D:lockscope>` +
|
||||
@@ -101,11 +101,11 @@ var LivePropMap = map[xml.Name]LiveProp{
|
||||
dir: true,
|
||||
},
|
||||
{Space: "DAV:", Local: "quota-available-bytes"}: {
|
||||
findFn: func(space *Space, matter *Matter) string {
|
||||
findFn: func(user *User, matter *Matter) string {
|
||||
var size int64 = 0
|
||||
if space.TotalSizeLimit >= 0 {
|
||||
if space.TotalSizeLimit-space.TotalSize > 0 {
|
||||
size = space.TotalSizeLimit - space.TotalSize
|
||||
if user.TotalSizeLimit >= 0 {
|
||||
if user.TotalSizeLimit-user.TotalSize > 0 {
|
||||
size = user.TotalSizeLimit - user.TotalSize
|
||||
} else {
|
||||
size = 0
|
||||
}
|
||||
@@ -118,8 +118,8 @@ var LivePropMap = map[xml.Name]LiveProp{
|
||||
dir: true,
|
||||
},
|
||||
{Space: "DAV:", Local: "quota-used-bytes"}: {
|
||||
findFn: func(space *Space, matter *Matter) string {
|
||||
return fmt.Sprintf(`%d`, space.TotalSize)
|
||||
findFn: func(user *User, matter *Matter) string {
|
||||
return fmt.Sprintf(`%d`, user.TotalSize)
|
||||
},
|
||||
dir: true,
|
||||
},
|
||||
|
||||
@@ -49,7 +49,7 @@ func (this *DavService) Init() {
|
||||
this.lockSystem = webdav.NewMemLS()
|
||||
}
|
||||
|
||||
// get the depth in header. Not support infinity yet.
|
||||
//get the depth in header. Not support infinity yet.
|
||||
func (this *DavService) ParseDepth(request *http.Request) int {
|
||||
|
||||
depth := 1
|
||||
@@ -88,8 +88,8 @@ func (this *DavService) makePropstatResponse(href string, pstats []dav.Propstat)
|
||||
return &resp
|
||||
}
|
||||
|
||||
// fetch a matter's []dav.Propstat
|
||||
func (this *DavService) PropstatsFromXmlNames(user *User, space *Space, matter *Matter, xmlNames []xml.Name) []dav.Propstat {
|
||||
//fetch a matter's []dav.Propstat
|
||||
func (this *DavService) PropstatsFromXmlNames(user *User, matter *Matter, xmlNames []xml.Name) []dav.Propstat {
|
||||
|
||||
propstats := make([]dav.Propstat, 0)
|
||||
|
||||
@@ -101,7 +101,7 @@ func (this *DavService) PropstatsFromXmlNames(user *User, space *Space, matter *
|
||||
|
||||
// Otherwise, it must either be a live property or we don't know it.
|
||||
if liveProp := LivePropMap[xmlName]; liveProp.findFn != nil && (liveProp.dir || !matter.Dir) {
|
||||
innerXML := liveProp.findFn(space, matter)
|
||||
innerXML := liveProp.findFn(user, matter)
|
||||
|
||||
okProperties = append(okProperties, dav.Property{
|
||||
XMLName: xmlName,
|
||||
@@ -162,7 +162,7 @@ func (this *DavService) AllPropXmlNames(matter *Matter) []xml.Name {
|
||||
return pnames
|
||||
}
|
||||
|
||||
func (this *DavService) Propstats(user *User, space *Space, matter *Matter, propfind *dav.Propfind) []dav.Propstat {
|
||||
func (this *DavService) Propstats(user *User, matter *Matter, propfind *dav.Propfind) []dav.Propstat {
|
||||
|
||||
propstats := make([]dav.Propstat, 0)
|
||||
if propfind.Propname != nil {
|
||||
@@ -172,18 +172,18 @@ func (this *DavService) Propstats(user *User, space *Space, matter *Matter, prop
|
||||
//TODO: if include other things. add to it.
|
||||
xmlNames := this.AllPropXmlNames(matter)
|
||||
|
||||
propstats = this.PropstatsFromXmlNames(user, space, matter, xmlNames)
|
||||
propstats = this.PropstatsFromXmlNames(user, matter, xmlNames)
|
||||
|
||||
} else {
|
||||
propstats = this.PropstatsFromXmlNames(user, space, matter, propfind.Prop)
|
||||
propstats = this.PropstatsFromXmlNames(user, matter, propfind.Prop)
|
||||
}
|
||||
|
||||
return propstats
|
||||
|
||||
}
|
||||
|
||||
// list the directory.
|
||||
func (this *DavService) HandlePropfind(writer http.ResponseWriter, request *http.Request, user *User, space *Space, subPath string) {
|
||||
//list the directory.
|
||||
func (this *DavService) HandlePropfind(writer http.ResponseWriter, request *http.Request, user *User, subPath string) {
|
||||
|
||||
fmt.Printf("PROPFIND %s\n", subPath)
|
||||
|
||||
@@ -193,7 +193,7 @@ func (this *DavService) HandlePropfind(writer http.ResponseWriter, request *http
|
||||
propfind := dav.ReadPropfind(request.Body)
|
||||
|
||||
//find the matter, if subPath is null, means the root directory.
|
||||
matter := this.matterDao.CheckWithRootByPath(subPath, user, space)
|
||||
matter := this.matterDao.CheckWithRootByPath(subPath, user)
|
||||
|
||||
var matters []*Matter
|
||||
if depth == 0 {
|
||||
@@ -213,7 +213,7 @@ func (this *DavService) HandlePropfind(writer http.ResponseWriter, request *http
|
||||
|
||||
fmt.Printf("handle Matter %s\n", matter.Path)
|
||||
|
||||
propstats := this.Propstats(user, space, matter, propfind)
|
||||
propstats := this.Propstats(user, matter, propfind)
|
||||
visitPath := fmt.Sprintf("%s%s", WEBDAV_PREFIX, matter.Path)
|
||||
response := this.makePropstatResponse(visitPath, propstats)
|
||||
|
||||
@@ -228,7 +228,7 @@ func (this *DavService) HandlePropfind(writer http.ResponseWriter, request *http
|
||||
|
||||
}
|
||||
|
||||
// change the file's property
|
||||
//change the file's property
|
||||
func (this *DavService) HandleProppatch(writer http.ResponseWriter, request *http.Request, user *User, subPath string) {
|
||||
|
||||
fmt.Printf("PROPPATCH %s\n", subPath)
|
||||
@@ -251,7 +251,7 @@ func (this *DavService) HandleProppatch(writer http.ResponseWriter, request *htt
|
||||
patches, status, err := webdav.ReadProppatch(request.Body)
|
||||
this.PanicError(err)
|
||||
|
||||
fmt.Printf("status:%v\n", status)
|
||||
fmt.Println("status:%v", status)
|
||||
|
||||
//prepare a multiStatusWriter.
|
||||
multiStatusWriter := &dav.MultiStatusWriter{Writer: writer}
|
||||
@@ -296,16 +296,16 @@ func (this *DavService) HandleProppatch(writer http.ResponseWriter, request *htt
|
||||
|
||||
}
|
||||
|
||||
// handle download
|
||||
func (this *DavService) HandleGetHeadPost(writer http.ResponseWriter, request *http.Request, user *User, space *Space, subPath string) {
|
||||
//handle download
|
||||
func (this *DavService) HandleGetHeadPost(writer http.ResponseWriter, request *http.Request, user *User, subPath string) {
|
||||
|
||||
fmt.Printf("GET %s\n", subPath)
|
||||
|
||||
matter := this.matterDao.CheckWithRootByPath(subPath, user, space)
|
||||
matter := this.matterDao.CheckWithRootByPath(subPath, user)
|
||||
|
||||
//if this is a Directory, it means Propfind
|
||||
if matter.Dir {
|
||||
this.HandlePropfind(writer, request, user, space, subPath)
|
||||
this.HandlePropfind(writer, request, user, subPath)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -314,8 +314,8 @@ func (this *DavService) HandleGetHeadPost(writer http.ResponseWriter, request *h
|
||||
|
||||
}
|
||||
|
||||
// upload a file
|
||||
func (this *DavService) HandlePut(writer http.ResponseWriter, request *http.Request, user *User, space *Space, subPath string) {
|
||||
//upload a file
|
||||
func (this *DavService) HandlePut(writer http.ResponseWriter, request *http.Request, user *User, subPath string) {
|
||||
|
||||
fmt.Printf("PUT %s\n", subPath)
|
||||
|
||||
@@ -339,23 +339,23 @@ func (this *DavService) HandlePut(writer http.ResponseWriter, request *http.Requ
|
||||
filename := util.GetFilenameOfPath(subPath)
|
||||
dirPath := util.GetDirOfPath(subPath)
|
||||
|
||||
dirMatter := this.matterDao.CheckWithRootByPath(dirPath, user, space)
|
||||
dirMatter := this.matterDao.CheckWithRootByPath(dirPath, user)
|
||||
|
||||
//if exist delete it.
|
||||
srcMatter := this.matterDao.findByUserUuidAndPath(user.Uuid, subPath)
|
||||
if srcMatter != nil {
|
||||
this.matterService.AtomicDelete(request, srcMatter, user, space)
|
||||
this.matterService.AtomicDelete(request, srcMatter, user)
|
||||
}
|
||||
|
||||
this.matterService.Upload(request, request.Body, nil, user, space, dirMatter, filename, true)
|
||||
this.matterService.Upload(request, request.Body, user, dirMatter, filename, true)
|
||||
|
||||
//set the status code 201
|
||||
writer.WriteHeader(http.StatusCreated)
|
||||
|
||||
}
|
||||
|
||||
// delete file
|
||||
func (this *DavService) HandleDelete(w http.ResponseWriter, r *http.Request, user *User, space *Space, subPath string) {
|
||||
//delete file
|
||||
func (this *DavService) HandleDelete(w http.ResponseWriter, r *http.Request, user *User, subPath string) {
|
||||
|
||||
fmt.Printf("DELETE %s\n", subPath)
|
||||
|
||||
@@ -371,13 +371,13 @@ func (this *DavService) HandleDelete(w http.ResponseWriter, r *http.Request, use
|
||||
defer release()
|
||||
}
|
||||
|
||||
matter := this.matterDao.CheckWithRootByPath(subPath, user, space)
|
||||
matter := this.matterDao.CheckWithRootByPath(subPath, user)
|
||||
|
||||
this.matterService.AtomicDelete(r, matter, user, space)
|
||||
this.matterService.AtomicDelete(r, matter, user)
|
||||
}
|
||||
|
||||
// crate a directory
|
||||
func (this *DavService) HandleMkcol(writer http.ResponseWriter, request *http.Request, user *User, space *Space, subPath string) {
|
||||
//crate a directory
|
||||
func (this *DavService) HandleMkcol(writer http.ResponseWriter, request *http.Request, user *User, subPath string) {
|
||||
|
||||
fmt.Printf("MKCOL %s\n", subPath)
|
||||
|
||||
@@ -395,34 +395,34 @@ func (this *DavService) HandleMkcol(writer http.ResponseWriter, request *http.Re
|
||||
thisDirName := util.GetFilenameOfPath(subPath)
|
||||
dirPath := util.GetDirOfPath(subPath)
|
||||
|
||||
dirMatter := this.matterDao.FindWithRootByPath(dirPath, user, space)
|
||||
dirMatter := this.matterDao.FindWithRootByPath(dirPath, user)
|
||||
if dirMatter == nil {
|
||||
//throw conflict error
|
||||
panic(result.CustomWebResult(result.CONFLICT, fmt.Sprintf("%s not exist", dirPath)))
|
||||
}
|
||||
|
||||
//check whether col exists. (RFC2518:8.3.1)
|
||||
dbMatter := this.matterDao.FindBySpaceNameAndPuuidAndDirAndName(space.Name, dirMatter.Uuid, TRUE, thisDirName)
|
||||
dbMatter := this.matterDao.FindByUserUuidAndPuuidAndDirAndName(user.Uuid, dirMatter.Uuid, TRUE, thisDirName)
|
||||
if dbMatter != nil {
|
||||
panic(result.CustomWebResult(result.METHOD_NOT_ALLOWED, fmt.Sprintf("%s already exists", dirPath)))
|
||||
}
|
||||
|
||||
//check whether file exists. (RFC2518:8.3.1)
|
||||
fileMatter := this.matterDao.FindBySpaceNameAndPuuidAndDirAndName(space.Name, dirMatter.Uuid, FALSE, thisDirName)
|
||||
fileMatter := this.matterDao.FindByUserUuidAndPuuidAndDirAndName(user.Uuid, dirMatter.Uuid, FALSE, thisDirName)
|
||||
if fileMatter != nil {
|
||||
panic(result.CustomWebResult(result.METHOD_NOT_ALLOWED, fmt.Sprintf("%s file already exists", dirPath)))
|
||||
}
|
||||
|
||||
this.matterService.AtomicCreateDirectory(request, dirMatter, thisDirName, user, space)
|
||||
this.matterService.AtomicCreateDirectory(request, dirMatter, thisDirName, user)
|
||||
|
||||
}
|
||||
|
||||
// cors options
|
||||
func (this *DavService) HandleOptions(w http.ResponseWriter, r *http.Request, user *User, space *Space, subPath string) {
|
||||
//cors options
|
||||
func (this *DavService) HandleOptions(w http.ResponseWriter, r *http.Request, user *User, subPath string) {
|
||||
|
||||
fmt.Printf("OPTIONS %s\n", subPath)
|
||||
|
||||
matter := this.matterDao.CheckWithRootByPath(subPath, user, space)
|
||||
matter := this.matterDao.CheckWithRootByPath(subPath, user)
|
||||
|
||||
allow := "OPTIONS, LOCK, PUT, MKCOL"
|
||||
if matter.Dir {
|
||||
@@ -439,11 +439,11 @@ func (this *DavService) HandleOptions(w http.ResponseWriter, r *http.Request, us
|
||||
|
||||
}
|
||||
|
||||
// prepare for moving or copying
|
||||
//prepare for moving or copying
|
||||
func (this *DavService) prepareMoveCopy(
|
||||
writer http.ResponseWriter,
|
||||
request *http.Request,
|
||||
user *User, space *Space, subPath string) (
|
||||
user *User, subPath string) (
|
||||
srcMatter *Matter,
|
||||
destDirMatter *Matter,
|
||||
srcDirPath string,
|
||||
@@ -506,14 +506,14 @@ func (this *DavService) prepareMoveCopy(
|
||||
}
|
||||
|
||||
//source matter
|
||||
srcMatter = this.matterDao.CheckWithRootByPath(subPath, user, space)
|
||||
srcMatter = this.matterDao.CheckWithRootByPath(subPath, user)
|
||||
|
||||
//if source matter is root.
|
||||
if srcMatter.Uuid == MATTER_ROOT {
|
||||
panic(result.BadRequest("you cannot move the root directory"))
|
||||
}
|
||||
|
||||
destDirMatter = this.matterDao.FindWithRootByPath(destinationDirPath, user, space)
|
||||
destDirMatter = this.matterDao.FindWithRootByPath(destinationDirPath, user)
|
||||
if destDirMatter == nil {
|
||||
//throw conflict error
|
||||
panic(result.CustomWebResult(result.CONFLICT, fmt.Sprintf("%s not exist", destinationDirPath)))
|
||||
@@ -523,8 +523,8 @@ func (this *DavService) prepareMoveCopy(
|
||||
|
||||
}
|
||||
|
||||
// move or rename.
|
||||
func (this *DavService) HandleMove(writer http.ResponseWriter, request *http.Request, user *User, space *Space, subPath string) {
|
||||
//move or rename.
|
||||
func (this *DavService) HandleMove(writer http.ResponseWriter, request *http.Request, user *User, subPath string) {
|
||||
|
||||
fmt.Printf("MOVE %s\n", subPath)
|
||||
|
||||
@@ -541,14 +541,14 @@ func (this *DavService) HandleMove(writer http.ResponseWriter, request *http.Req
|
||||
defer release()
|
||||
}
|
||||
|
||||
srcMatter, destDirMatter, srcDirPath, destinationDirPath, destinationName, overwrite := this.prepareMoveCopy(writer, request, user, space, subPath)
|
||||
srcMatter, destDirMatter, srcDirPath, destinationDirPath, destinationName, overwrite := this.prepareMoveCopy(writer, request, user, subPath)
|
||||
|
||||
//move to the new directory
|
||||
if destinationDirPath == srcDirPath {
|
||||
//if destination path not change. it means rename.
|
||||
this.matterService.AtomicRename(request, srcMatter, destinationName, overwrite, user, space)
|
||||
this.matterService.AtomicRename(request, srcMatter, destinationName, overwrite, user)
|
||||
} else {
|
||||
this.matterService.AtomicMove(request, srcMatter, destDirMatter, overwrite, user, space)
|
||||
this.matterService.AtomicMove(request, srcMatter, destDirMatter, overwrite, user)
|
||||
}
|
||||
|
||||
this.logger.Info("finish moving %s => %s", subPath, destDirMatter.Path)
|
||||
@@ -562,12 +562,12 @@ func (this *DavService) HandleMove(writer http.ResponseWriter, request *http.Req
|
||||
}
|
||||
}
|
||||
|
||||
// copy file/directory
|
||||
func (this *DavService) HandleCopy(writer http.ResponseWriter, request *http.Request, user *User, space *Space, subPath string) {
|
||||
//copy file/directory
|
||||
func (this *DavService) HandleCopy(writer http.ResponseWriter, request *http.Request, user *User, subPath string) {
|
||||
|
||||
fmt.Printf("COPY %s\n", subPath)
|
||||
|
||||
srcMatter, destDirMatter, _, _, destinationName, overwrite := this.prepareMoveCopy(writer, request, user, space, subPath)
|
||||
srcMatter, destDirMatter, _, _, destinationName, overwrite := this.prepareMoveCopy(writer, request, user, subPath)
|
||||
|
||||
// handle the lock feature.
|
||||
release, status, err := this.confirmLocks(request, destDirMatter.Path+"/"+destinationName, "")
|
||||
@@ -579,7 +579,7 @@ func (this *DavService) HandleCopy(writer http.ResponseWriter, request *http.Req
|
||||
}
|
||||
|
||||
//copy to the new directory
|
||||
this.matterService.AtomicCopy(request, srcMatter, destDirMatter, destinationName, overwrite, user, space)
|
||||
this.matterService.AtomicCopy(request, srcMatter, destDirMatter, destinationName, overwrite, user)
|
||||
|
||||
this.logger.Info("finish copying %s => %s", subPath, destDirMatter.Path)
|
||||
|
||||
@@ -688,7 +688,7 @@ func (h *DavService) confirmLocks(r *http.Request, src, dst string) (release fun
|
||||
return nil, http.StatusLocked, webdav.ErrLocked
|
||||
}
|
||||
|
||||
// lock.
|
||||
//lock.
|
||||
func (this *DavService) HandleLock(w http.ResponseWriter, r *http.Request, user *User, subPath string) {
|
||||
|
||||
duration, err := webdav.ParseTimeout(r.Header.Get("Timeout"))
|
||||
@@ -785,7 +785,7 @@ func (this *DavService) HandleLock(w http.ResponseWriter, r *http.Request, user
|
||||
|
||||
}
|
||||
|
||||
// unlock
|
||||
//unlock
|
||||
func (this *DavService) HandleUnlock(w http.ResponseWriter, r *http.Request, user *User, subPath string) {
|
||||
|
||||
// http://www.webdav.org/specs/rfc4918.html#HEADER_Lock-Token says that the
|
||||
@@ -810,44 +810,44 @@ func (this *DavService) HandleUnlock(w http.ResponseWriter, r *http.Request, use
|
||||
}
|
||||
}
|
||||
|
||||
// hanle all the request.
|
||||
func (this *DavService) HandleDav(writer http.ResponseWriter, request *http.Request, user *User, space *Space, subPath string) {
|
||||
//hanle all the request.
|
||||
func (this *DavService) HandleDav(writer http.ResponseWriter, request *http.Request, user *User, subPath string) {
|
||||
|
||||
method := request.Method
|
||||
if method == "OPTIONS" {
|
||||
|
||||
//cors option
|
||||
this.HandleOptions(writer, request, user, space, subPath)
|
||||
this.HandleOptions(writer, request, user, subPath)
|
||||
|
||||
} else if method == "GET" || method == "HEAD" || method == "POST" {
|
||||
|
||||
//get the detail of file. download
|
||||
this.HandleGetHeadPost(writer, request, user, space, subPath)
|
||||
this.HandleGetHeadPost(writer, request, user, subPath)
|
||||
|
||||
} else if method == "DELETE" {
|
||||
|
||||
//delete file
|
||||
this.HandleDelete(writer, request, user, space, subPath)
|
||||
this.HandleDelete(writer, request, user, subPath)
|
||||
|
||||
} else if method == "PUT" {
|
||||
|
||||
//upload file
|
||||
this.HandlePut(writer, request, user, space, subPath)
|
||||
this.HandlePut(writer, request, user, subPath)
|
||||
|
||||
} else if method == "MKCOL" {
|
||||
|
||||
//crate directory
|
||||
this.HandleMkcol(writer, request, user, space, subPath)
|
||||
this.HandleMkcol(writer, request, user, subPath)
|
||||
|
||||
} else if method == "COPY" {
|
||||
|
||||
//copy file/directory
|
||||
this.HandleCopy(writer, request, user, space, subPath)
|
||||
this.HandleCopy(writer, request, user, subPath)
|
||||
|
||||
} else if method == "MOVE" {
|
||||
|
||||
//move/rename a file or directory
|
||||
this.HandleMove(writer, request, user, space, subPath)
|
||||
this.HandleMove(writer, request, user, subPath)
|
||||
|
||||
} else if method == "LOCK" {
|
||||
|
||||
@@ -862,7 +862,7 @@ func (this *DavService) HandleDav(writer http.ResponseWriter, request *http.Requ
|
||||
} else if method == "PROPFIND" {
|
||||
|
||||
//list a directory
|
||||
this.HandlePropfind(writer, request, user, space, subPath)
|
||||
this.HandlePropfind(writer, request, user, subPath)
|
||||
|
||||
} else if method == "PROPPATCH" {
|
||||
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
"time"
|
||||
)
|
||||
|
||||
type DownloadToken struct {
|
||||
Uuid string `json:"uuid" gorm:"type:char(36);primary_key;unique"`
|
||||
Sort int64 `json:"sort" gorm:"type:bigint(20) not null"`
|
||||
UpdateTime time.Time `json:"updateTime" gorm:"type:timestamp not null;default:CURRENT_TIMESTAMP"`
|
||||
CreateTime time.Time `json:"createTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"`
|
||||
Base
|
||||
UserUuid string `json:"userUuid" gorm:"type:char(36) not null"`
|
||||
MatterUuid string `json:"matterUuid" gorm:"type:char(36) not null;index:idx_mu"` //index should unique globally.
|
||||
MatterUuid string `json:"matterUuid" gorm:"type:char(36) not null;index:idx_mu"`
|
||||
ExpireTime time.Time `json:"expireTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"`
|
||||
Ip string `json:"ip" gorm:"type:varchar(128) not null"`
|
||||
}
|
||||
|
||||
func (this *DownloadToken) TableName() string {
|
||||
return core.TABLE_PREFIX + "download_token"
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
"github.com/eyebluecn/tank/code/tool/builder"
|
||||
"github.com/eyebluecn/tank/code/tool/result"
|
||||
"gorm.io/gorm"
|
||||
"github.com/jinzhu/gorm"
|
||||
|
||||
"github.com/eyebluecn/tank/code/tool/uuid"
|
||||
"time"
|
||||
@@ -48,14 +48,14 @@ func (this *FootprintDao) Page(page int, pageSize int, userUuid string, sortArra
|
||||
var conditionDB *gorm.DB
|
||||
conditionDB = core.CONTEXT.GetDB().Model(&Footprint{}).Where(wp.Query, wp.Args...)
|
||||
|
||||
var count int64 = 0
|
||||
count := 0
|
||||
db := conditionDB.Count(&count)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
var footprints []*Footprint
|
||||
db = conditionDB.Order(this.GetSortString(sortArray)).Offset(page * pageSize).Limit(pageSize).Find(&footprints)
|
||||
this.PanicError(db.Error)
|
||||
pager := NewPager(page, pageSize, int(count), footprints)
|
||||
pager := NewPager(page, pageSize, count, footprints)
|
||||
|
||||
return pager
|
||||
}
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
package rest
|
||||
|
||||
import "time"
|
||||
import "github.com/eyebluecn/tank/code/core"
|
||||
|
||||
// Footprint /**
|
||||
// Mysql 5.5 only support one CURRENT_TIMESTAMP
|
||||
// so we use 2018-01-01 00:00:00 as default, which is the first release date of EyeblueTank
|
||||
/**
|
||||
* visit record.
|
||||
*/
|
||||
type Footprint struct {
|
||||
Uuid string `json:"uuid" gorm:"type:char(36);primary_key;unique"`
|
||||
Sort int64 `json:"sort" gorm:"type:bigint(20) not null"`
|
||||
UpdateTime time.Time `json:"updateTime" gorm:"type:timestamp not null;default:CURRENT_TIMESTAMP"`
|
||||
CreateTime time.Time `json:"createTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"`
|
||||
UserUuid string `json:"userUuid" gorm:"type:char(36)"`
|
||||
Ip string `json:"ip" gorm:"type:varchar(128) not null"`
|
||||
Host string `json:"host" gorm:"type:varchar(45) not null"`
|
||||
Uri string `json:"uri" gorm:"type:varchar(255) not null"`
|
||||
Params string `json:"params" gorm:"type:text"`
|
||||
Cost int64 `json:"cost" gorm:"type:bigint(20) not null;default:0"`
|
||||
Success bool `json:"success" gorm:"type:tinyint(1) not null;default:0"`
|
||||
Base
|
||||
UserUuid string `json:"userUuid" gorm:"type:char(36)"`
|
||||
Ip string `json:"ip" gorm:"type:varchar(128) not null"`
|
||||
Host string `json:"host" gorm:"type:varchar(45) not null"`
|
||||
Uri string `json:"uri" gorm:"type:varchar(255) not null"`
|
||||
Params string `json:"params" gorm:"type:text"`
|
||||
Cost int64 `json:"cost" gorm:"type:bigint(20) not null;default:0"`
|
||||
Success bool `json:"success" gorm:"type:tinyint(1) not null;default:0"`
|
||||
}
|
||||
|
||||
// set File's table name to be `profiles`
|
||||
func (this *Footprint) TableName() string {
|
||||
return core.TABLE_PREFIX + "footprint"
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"github.com/eyebluecn/tank/code/tool/result"
|
||||
"github.com/eyebluecn/tank/code/tool/util"
|
||||
"github.com/eyebluecn/tank/code/tool/uuid"
|
||||
"gorm.io/gorm"
|
||||
"github.com/jinzhu/gorm"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
@@ -17,7 +17,7 @@ type ImageCacheDao struct {
|
||||
BaseDao
|
||||
}
|
||||
|
||||
// find by uuid. if not found return nil.
|
||||
//find by uuid. if not found return nil.
|
||||
func (this *ImageCacheDao) FindByUuid(uuid string) *ImageCache {
|
||||
var entity = &ImageCache{}
|
||||
db := core.CONTEXT.GetDB().Where("uuid = ?", uuid).First(entity)
|
||||
@@ -31,7 +31,7 @@ func (this *ImageCacheDao) FindByUuid(uuid string) *ImageCache {
|
||||
return entity
|
||||
}
|
||||
|
||||
// find by uuid. if not found panic NotFound error
|
||||
//find by uuid. if not found panic NotFound error
|
||||
func (this *ImageCacheDao) CheckByUuid(uuid string) *ImageCache {
|
||||
entity := this.FindByUuid(uuid)
|
||||
if entity == nil {
|
||||
@@ -67,7 +67,7 @@ func (this *ImageCacheDao) CheckByUuidAndUserUuid(uuid string, userUuid string)
|
||||
|
||||
// Read
|
||||
var imageCache = &ImageCache{}
|
||||
db := core.CONTEXT.GetDB().Where(&ImageCache{Uuid: uuid, UserUuid: userUuid}).First(imageCache)
|
||||
db := core.CONTEXT.GetDB().Where(&ImageCache{Base: Base{Uuid: uuid}, UserUuid: userUuid}).First(imageCache)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
return imageCache
|
||||
@@ -101,14 +101,14 @@ func (this *ImageCacheDao) Page(page int, pageSize int, userUuid string, matterU
|
||||
var conditionDB *gorm.DB
|
||||
conditionDB = core.CONTEXT.GetDB().Model(&ImageCache{}).Where(wp.Query, wp.Args...)
|
||||
|
||||
var count int64 = 0
|
||||
count := 0
|
||||
db := conditionDB.Count(&count)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
var imageCaches []*ImageCache
|
||||
db = conditionDB.Order(this.GetSortString(sortArray)).Offset(page * pageSize).Limit(pageSize).Find(&imageCaches)
|
||||
this.PanicError(db.Error)
|
||||
pager := NewPager(page, pageSize, int(count), imageCaches)
|
||||
pager := NewPager(page, pageSize, count, imageCaches)
|
||||
|
||||
return pager
|
||||
}
|
||||
@@ -137,7 +137,7 @@ func (this *ImageCacheDao) Save(imageCache *ImageCache) *ImageCache {
|
||||
|
||||
func (this *ImageCacheDao) deleteFileAndDir(imageCache *ImageCache) {
|
||||
|
||||
filePath := GetSpaceCacheRootDir(imageCache.Username) + imageCache.Path
|
||||
filePath := GetUserCacheRootDir(imageCache.Username) + imageCache.Path
|
||||
|
||||
dirPath := filepath.Dir(filePath)
|
||||
|
||||
@@ -152,7 +152,7 @@ func (this *ImageCacheDao) deleteFileAndDir(imageCache *ImageCache) {
|
||||
|
||||
}
|
||||
|
||||
// delete a file from db and disk.
|
||||
//delete a file from db and disk.
|
||||
func (this *ImageCacheDao) Delete(imageCache *ImageCache) {
|
||||
|
||||
db := core.CONTEXT.GetDB().Delete(&imageCache)
|
||||
@@ -162,7 +162,7 @@ func (this *ImageCacheDao) Delete(imageCache *ImageCache) {
|
||||
|
||||
}
|
||||
|
||||
// delete all the cache of a matter.
|
||||
//delete all the cache of a matter.
|
||||
func (this *ImageCacheDao) DeleteByMatterUuid(matterUuid string) {
|
||||
|
||||
var wp = &builder.WherePair{}
|
||||
@@ -208,7 +208,7 @@ func (this *ImageCacheDao) SizeBetweenTime(startTime time.Time, endTime time.Tim
|
||||
return size
|
||||
}
|
||||
|
||||
// System cleanup.
|
||||
//System cleanup.
|
||||
func (this *ImageCacheDao) Cleanup() {
|
||||
this.logger.Info("[ImageCacheDao]clean up. Delete all ImageCache ")
|
||||
db := core.CONTEXT.GetDB().Where("uuid is not null").Delete(ImageCache{})
|
||||
|
||||
@@ -1,28 +1,32 @@
|
||||
package rest
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
)
|
||||
|
||||
/**
|
||||
* image cache.
|
||||
*/
|
||||
type ImageCache struct {
|
||||
Uuid string `json:"uuid" gorm:"type:char(36);primary_key;unique"`
|
||||
Sort int64 `json:"sort" gorm:"type:bigint(20) not null"`
|
||||
UpdateTime time.Time `json:"updateTime" gorm:"type:timestamp not null;default:CURRENT_TIMESTAMP"`
|
||||
CreateTime time.Time `json:"createTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"`
|
||||
Name string `json:"name" gorm:"type:varchar(255) not null"`
|
||||
UserUuid string `json:"userUuid" gorm:"type:char(36)"`
|
||||
Username string `json:"username" gorm:"type:varchar(45) not null"`
|
||||
MatterUuid string `json:"matterUuid" gorm:"type:char(36);index:idx_mu"` //index should unique globally.
|
||||
MatterName string `json:"matterName" gorm:"type:varchar(255) not null"`
|
||||
Mode string `json:"mode" gorm:"type:varchar(512)"`
|
||||
Md5 string `json:"md5" gorm:"type:varchar(45)"`
|
||||
Size int64 `json:"size" gorm:"type:bigint(20) not null;default:0"`
|
||||
Path string `json:"path" gorm:"type:varchar(512)"`
|
||||
Matter *Matter `json:"matter" gorm:"-"`
|
||||
Base
|
||||
Name string `json:"name" gorm:"type:varchar(255) not null"`
|
||||
UserUuid string `json:"userUuid" gorm:"type:char(36)"`
|
||||
Username string `json:"username" gorm:"type:varchar(45) not null"`
|
||||
MatterUuid string `json:"matterUuid" gorm:"type:char(36);index:idx_mu"`
|
||||
MatterName string `json:"matterName" gorm:"type:varchar(255) not null"`
|
||||
Mode string `json:"mode" gorm:"type:varchar(512)"`
|
||||
Md5 string `json:"md5" gorm:"type:varchar(45)"`
|
||||
Size int64 `json:"size" gorm:"type:bigint(20) not null;default:0"`
|
||||
Path string `json:"path" gorm:"type:varchar(512)"`
|
||||
Matter *Matter `json:"matter" gorm:"-"`
|
||||
}
|
||||
|
||||
// set File's table name to be `profiles`
|
||||
func (this *ImageCache) TableName() string {
|
||||
return core.TABLE_PREFIX + "image_cache"
|
||||
}
|
||||
|
||||
// get the absolute path. path in db means relative path.
|
||||
func (this *ImageCache) AbsolutePath() string {
|
||||
return GetSpaceCacheRootDir(this.Username) + this.Path
|
||||
return GetUserCacheRootDir(this.Username) + this.Path
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// @Service
|
||||
//@Service
|
||||
type ImageCacheService struct {
|
||||
BaseBean
|
||||
imageCacheDao *ImageCacheDao
|
||||
@@ -92,7 +92,7 @@ func (this *ImageCacheService) ResizeParams(request *http.Request) (needProcess
|
||||
|
||||
}
|
||||
|
||||
// resize image.
|
||||
//resize image.
|
||||
func (this *ImageCacheService) ResizeImage(request *http.Request, filePath string) *image.NRGBA {
|
||||
|
||||
diskFile, err := os.Open(filePath)
|
||||
@@ -148,7 +148,7 @@ func (this *ImageCacheService) ResizeImage(request *http.Request, filePath strin
|
||||
}
|
||||
}
|
||||
|
||||
// cache an image
|
||||
//cache an image
|
||||
func (this *ImageCacheService) cacheImage(writer http.ResponseWriter, request *http.Request, matter *Matter) *ImageCache {
|
||||
|
||||
//only these image can do.
|
||||
@@ -177,7 +177,7 @@ func (this *ImageCacheService) cacheImage(writer http.ResponseWriter, request *h
|
||||
|
||||
cacheImageName := util.GetSimpleFileName(matter.Name) + "_" + mode + extension
|
||||
cacheImageRelativePath := util.GetSimpleFileName(matter.Path) + "_" + mode + extension
|
||||
cacheImageAbsolutePath := GetSpaceCacheRootDir(user.Username) + util.GetSimpleFileName(matter.Path) + "_" + mode + extension
|
||||
cacheImageAbsolutePath := GetUserCacheRootDir(user.Username) + util.GetSimpleFileName(matter.Path) + "_" + mode + extension
|
||||
|
||||
//create directory
|
||||
dir := filepath.Dir(cacheImageAbsolutePath)
|
||||
|
||||
@@ -6,24 +6,16 @@ import (
|
||||
"github.com/eyebluecn/tank/code/tool/builder"
|
||||
"github.com/eyebluecn/tank/code/tool/i18n"
|
||||
"github.com/eyebluecn/tank/code/tool/result"
|
||||
"github.com/eyebluecn/tank/code/tool/third"
|
||||
"github.com/eyebluecn/tank/code/tool/util"
|
||||
"github.com/eyebluecn/tank/code/tool/uuid"
|
||||
"github.com/glebarez/sqlite"
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
"gorm.io/gorm/schema"
|
||||
"log"
|
||||
"github.com/jinzhu/gorm"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// install apis. Only when installing period can be visited.
|
||||
//install apis. Only when installing period can be visited.
|
||||
type InstallController struct {
|
||||
BaseController
|
||||
uploadTokenDao *UploadTokenDao
|
||||
@@ -32,7 +24,7 @@ type InstallController struct {
|
||||
matterService *MatterService
|
||||
imageCacheDao *ImageCacheDao
|
||||
imageCacheService *ImageCacheService
|
||||
tableNames []interface{}
|
||||
tableNames []IBase
|
||||
}
|
||||
|
||||
func (this *InstallController) Init() {
|
||||
@@ -68,7 +60,7 @@ func (this *InstallController) Init() {
|
||||
this.imageCacheService = c
|
||||
}
|
||||
|
||||
this.tableNames = []interface{}{
|
||||
this.tableNames = []IBase{
|
||||
&Dashboard{},
|
||||
&Bridge{},
|
||||
&DownloadToken{},
|
||||
@@ -78,8 +70,6 @@ func (this *InstallController) Init() {
|
||||
&Preference{},
|
||||
&Session{},
|
||||
&Share{},
|
||||
&Space{},
|
||||
&SpaceMember{},
|
||||
&UploadToken{},
|
||||
&User{},
|
||||
}
|
||||
@@ -102,7 +92,6 @@ func (this *InstallController) RegisterRoutes() map[string]func(writer http.Resp
|
||||
}
|
||||
|
||||
func (this *InstallController) openDbConnection(writer http.ResponseWriter, request *http.Request) *gorm.DB {
|
||||
dbType := request.FormValue("dbType")
|
||||
mysqlPortStr := request.FormValue("mysqlPort")
|
||||
mysqlHost := request.FormValue("mysqlHost")
|
||||
mysqlSchema := request.FormValue("mysqlSchema")
|
||||
@@ -117,114 +106,55 @@ func (this *InstallController) openDbConnection(writer http.ResponseWriter, requ
|
||||
mysqlPort = tmp
|
||||
}
|
||||
|
||||
//log config
|
||||
dbLogger := logger.New(
|
||||
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
|
||||
logger.Config{
|
||||
SlowThreshold: time.Second, // slow SQL 1s
|
||||
LogLevel: logger.Silent, // log level. open when debug.
|
||||
IgnoreRecordNotFoundError: true, // ignore ErrRecordNotFound
|
||||
Colorful: false, // colorful print
|
||||
},
|
||||
)
|
||||
//table name strategy
|
||||
namingStrategy := core.CONFIG.NamingStrategy()
|
||||
mysqlUrl := util.GetMysqlUrl(mysqlPort, mysqlHost, mysqlSchema, mysqlUsername, mysqlPassword, mysqlCharset)
|
||||
|
||||
if dbType == "sqlite" {
|
||||
this.logger.Info("Connect MySQL %s", mysqlUrl)
|
||||
|
||||
var err error = nil
|
||||
sqliteFolder := core.CONFIG.SqliteFolder() + "/tank.sqlite"
|
||||
this.logger.Info("Connect Sqlite %s", sqliteFolder)
|
||||
db, err := gorm.Open(sqlite.Open(sqliteFolder), &gorm.Config{Logger: dbLogger, NamingStrategy: namingStrategy})
|
||||
var err error = nil
|
||||
db, err := gorm.Open("mysql", mysqlUrl)
|
||||
this.PanicError(err)
|
||||
|
||||
if err != nil {
|
||||
core.LOGGER.Panic("failed to connect sqlite database")
|
||||
}
|
||||
db.LogMode(false)
|
||||
|
||||
//sqlite lock issue. https://gist.github.com/mrnugget/0eda3b2b53a70fa4a894
|
||||
phyDb, err := db.DB()
|
||||
phyDb.SetMaxOpenConns(1)
|
||||
|
||||
return db
|
||||
|
||||
} else {
|
||||
mysqlUrl := util.GetMysqlUrl(mysqlPort, mysqlHost, mysqlSchema, mysqlUsername, mysqlPassword, mysqlCharset)
|
||||
|
||||
this.logger.Info("Connect MySQL %s", mysqlUrl)
|
||||
|
||||
var err error = nil
|
||||
db, err := gorm.Open(mysql.Open(mysqlUrl), &gorm.Config{Logger: dbLogger, NamingStrategy: namingStrategy})
|
||||
this.PanicError(err)
|
||||
|
||||
return db
|
||||
}
|
||||
return db
|
||||
|
||||
}
|
||||
|
||||
func (this *InstallController) closeDbConnection(db *gorm.DB) {
|
||||
|
||||
if db != nil {
|
||||
sqlDB, err := db.DB()
|
||||
err := db.Close()
|
||||
if err != nil {
|
||||
core.LOGGER.Error("occur error when get *sql.DB %s", err.Error())
|
||||
}
|
||||
err = sqlDB.Close()
|
||||
if err != nil {
|
||||
core.LOGGER.Error("occur error when closing db %s", err.Error())
|
||||
this.logger.Error("occur error when close db. %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// (tableName, exists, allFields, missingFields)
|
||||
func (this *InstallController) getTableMeta(gormDb *gorm.DB, entity interface{}) (string, bool, []*InstallFieldInfo, []*InstallFieldInfo) {
|
||||
func (this *InstallController) getTableMeta(gormDb *gorm.DB, entity IBase) (bool, []*gorm.StructField, []*gorm.StructField) {
|
||||
|
||||
//get all useful fields from model.
|
||||
entitySchema, err := schema.Parse(entity, &sync.Map{}, core.CONFIG.NamingStrategy())
|
||||
this.PanicError(err)
|
||||
db := gormDb.Unscoped()
|
||||
scope := db.NewScope(entity)
|
||||
|
||||
tableName := entitySchema.Table
|
||||
tableName := scope.TableName()
|
||||
modelStruct := scope.GetModelStruct()
|
||||
allFields := modelStruct.StructFields
|
||||
var missingFields = make([]*gorm.StructField, 0)
|
||||
|
||||
var allFields = make([]*InstallFieldInfo, 0)
|
||||
|
||||
for _, field := range entitySchema.Fields {
|
||||
allFields = append(allFields, &InstallFieldInfo{
|
||||
Name: field.DBName,
|
||||
DataType: string(field.DataType),
|
||||
})
|
||||
}
|
||||
|
||||
var missingFields = make([]*InstallFieldInfo, 0)
|
||||
|
||||
if !gormDb.Migrator().HasTable(tableName) {
|
||||
if !scope.Dialect().HasTable(tableName) {
|
||||
missingFields = append(missingFields, allFields...)
|
||||
|
||||
return tableName, false, allFields, missingFields
|
||||
return false, allFields, missingFields
|
||||
} else {
|
||||
|
||||
for _, field := range allFields {
|
||||
//tag with `gorm:"-"` will be ""
|
||||
if field.Name != "" {
|
||||
|
||||
database := gormDb.Migrator().CurrentDatabase()
|
||||
|
||||
//if sqlite
|
||||
if _, ok := gormDb.Dialector.(*sqlite.Dialector); ok {
|
||||
|
||||
if !gormDb.Migrator().HasColumn(tableName, field.Name) {
|
||||
missingFields = append(missingFields, field)
|
||||
}
|
||||
} else {
|
||||
|
||||
if !third.MysqlMigratorHasColumn(gormDb, database, tableName, field.Name) {
|
||||
missingFields = append(missingFields, field)
|
||||
}
|
||||
|
||||
if !scope.Dialect().HasColumn(tableName, field.DBName) {
|
||||
if field.IsNormal {
|
||||
missingFields = append(missingFields, field)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return tableName, true, allFields, missingFields
|
||||
return true, allFields, missingFields
|
||||
}
|
||||
|
||||
}
|
||||
@@ -234,10 +164,9 @@ func (this *InstallController) getTableMetaList(db *gorm.DB) []*InstallTableInfo
|
||||
var installTableInfos []*InstallTableInfo
|
||||
|
||||
for _, iBase := range this.tableNames {
|
||||
tableName, exist, allFields, missingFields := this.getTableMeta(db, iBase)
|
||||
|
||||
exist, allFields, missingFields := this.getTableMeta(db, iBase)
|
||||
installTableInfos = append(installTableInfos, &InstallTableInfo{
|
||||
Name: tableName,
|
||||
Name: iBase.TableName(),
|
||||
TableExist: exist,
|
||||
AllFields: allFields,
|
||||
MissingFields: missingFields,
|
||||
@@ -256,7 +185,7 @@ func (this *InstallController) validateTableMetaList(tableInfoList []*InstallTab
|
||||
|
||||
var strs []string
|
||||
for _, v := range tableInfo.MissingFields {
|
||||
strs = append(strs, v.Name)
|
||||
strs = append(strs, v.DBName)
|
||||
}
|
||||
|
||||
panic(result.BadRequest(fmt.Sprintf("table %s miss the following fields %v", tableInfo.Name, strs)))
|
||||
@@ -268,16 +197,14 @@ func (this *InstallController) validateTableMetaList(tableInfoList []*InstallTab
|
||||
|
||||
}
|
||||
|
||||
// Ping db.
|
||||
//Ping db.
|
||||
func (this *InstallController) Verify(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
db := this.openDbConnection(writer, request)
|
||||
defer this.closeDbConnection(db)
|
||||
|
||||
this.logger.Info("Ping DB")
|
||||
phyDb, err := db.DB()
|
||||
this.PanicError(err)
|
||||
err = phyDb.Ping()
|
||||
err := db.DB().Ping()
|
||||
this.PanicError(err)
|
||||
|
||||
return this.Success("OK")
|
||||
@@ -300,21 +227,13 @@ func (this *InstallController) CreateTable(writer http.ResponseWriter, request *
|
||||
|
||||
for _, iBase := range this.tableNames {
|
||||
|
||||
if _, ok := db.Dialector.(*sqlite.Dialector); ok {
|
||||
//if sqlite. no need to set CHARSET.
|
||||
err := db.AutoMigrate(iBase)
|
||||
this.PanicError(err)
|
||||
} else {
|
||||
//use utf8 charset
|
||||
mysqlCharset := request.FormValue("mysqlCharset")
|
||||
err := db.Set("gorm:table_options", fmt.Sprintf("CHARSET=%s", mysqlCharset)).AutoMigrate(iBase)
|
||||
this.PanicError(err)
|
||||
}
|
||||
//complete the missing fields or create table. use utf8 charset
|
||||
db1 := db.Set("gorm:table_options", "CHARSET=utf8mb4").AutoMigrate(iBase)
|
||||
this.PanicError(db1.Error)
|
||||
|
||||
//complete the missing fields or create table.
|
||||
tableName, exist, allFields, missingFields := this.getTableMeta(db, iBase)
|
||||
exist, allFields, missingFields := this.getTableMeta(db, iBase)
|
||||
installTableInfos = append(installTableInfos, &InstallTableInfo{
|
||||
Name: tableName,
|
||||
Name: iBase.TableName(),
|
||||
TableExist: exist,
|
||||
AllFields: allFields,
|
||||
MissingFields: missingFields,
|
||||
@@ -326,7 +245,7 @@ func (this *InstallController) CreateTable(writer http.ResponseWriter, request *
|
||||
|
||||
}
|
||||
|
||||
// get the list of admin.
|
||||
//get the list of admin.
|
||||
func (this *InstallController) AdminList(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
db := this.openDbConnection(writer, request)
|
||||
@@ -344,7 +263,7 @@ func (this *InstallController) AdminList(writer http.ResponseWriter, request *ht
|
||||
return this.Success(users)
|
||||
}
|
||||
|
||||
// create admin
|
||||
//create admin
|
||||
func (this *InstallController) CreateAdmin(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
db := this.openDbConnection(writer, request)
|
||||
@@ -370,20 +289,9 @@ func (this *InstallController) CreateAdmin(writer http.ResponseWriter, request *
|
||||
panic(result.BadRequestI18n(request, i18n.UsernameExist, adminUsername))
|
||||
}
|
||||
|
||||
space := &Space{}
|
||||
timeUUID, _ := uuid.NewV4()
|
||||
space.Uuid = timeUUID.String()
|
||||
space.CreateTime = time.Now()
|
||||
space.UpdateTime = time.Now()
|
||||
space.UserUuid = ""
|
||||
space.SizeLimit = -1
|
||||
space.Type = SPACE_TYPE_PRIVATE
|
||||
db3 := db.Create(space)
|
||||
this.PanicError(db3.Error)
|
||||
|
||||
user := &User{}
|
||||
timeUUID, _ = uuid.NewV4()
|
||||
user.Uuid = timeUUID.String()
|
||||
timeUUID, _ := uuid.NewV4()
|
||||
user.Uuid = string(timeUUID.String())
|
||||
user.CreateTime = time.Now()
|
||||
user.UpdateTime = time.Now()
|
||||
user.LastTime = time.Now()
|
||||
@@ -391,21 +299,17 @@ func (this *InstallController) CreateAdmin(writer http.ResponseWriter, request *
|
||||
user.Role = USER_ROLE_ADMINISTRATOR
|
||||
user.Username = adminUsername
|
||||
user.Password = util.GetBcrypt(adminPassword)
|
||||
user.SpaceUuid = space.Uuid
|
||||
user.SizeLimit = -1
|
||||
user.Status = USER_STATUS_OK
|
||||
|
||||
db4 := db.Create(user)
|
||||
this.PanicError(db4.Error)
|
||||
|
||||
space.UserUuid = user.Uuid
|
||||
db5 := db.Save(space)
|
||||
this.PanicError(db5.Error)
|
||||
db3 := db.Create(user)
|
||||
this.PanicError(db3.Error)
|
||||
|
||||
return this.Success("OK")
|
||||
|
||||
}
|
||||
|
||||
// (if there is admin in db)Validate admin.
|
||||
//(if there is admin in db)Validate admin.
|
||||
func (this *InstallController) ValidateAdmin(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
db := this.openDbConnection(writer, request)
|
||||
@@ -439,10 +343,9 @@ func (this *InstallController) ValidateAdmin(writer http.ResponseWriter, request
|
||||
|
||||
}
|
||||
|
||||
// Finish the installation
|
||||
//Finish the installation
|
||||
func (this *InstallController) Finish(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
dbType := request.FormValue("dbType")
|
||||
mysqlPortStr := request.FormValue("mysqlPort")
|
||||
mysqlHost := request.FormValue("mysqlHost")
|
||||
mysqlSchema := request.FormValue("mysqlSchema")
|
||||
@@ -474,7 +377,7 @@ func (this *InstallController) Finish(writer http.ResponseWriter, request *http.
|
||||
}
|
||||
|
||||
//announce the config to write config to tank.json
|
||||
core.CONFIG.FinishInstall(dbType, mysqlPort, mysqlHost, mysqlSchema, mysqlUsername, mysqlPassword, mysqlCharset)
|
||||
core.CONFIG.FinishInstall(mysqlPort, mysqlHost, mysqlSchema, mysqlUsername, mysqlPassword, mysqlCharset)
|
||||
|
||||
//announce the context to broadcast the installation news to bean.
|
||||
core.CONTEXT.InstallOk()
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
package rest
|
||||
|
||||
// InstallTableInfo /**
|
||||
// table meta info.
|
||||
type InstallTableInfo struct {
|
||||
Name string `json:"name"`
|
||||
TableExist bool `json:"tableExist"`
|
||||
AllFields []*InstallFieldInfo `json:"allFields"`
|
||||
MissingFields []*InstallFieldInfo `json:"missingFields"`
|
||||
}
|
||||
import "github.com/jinzhu/gorm"
|
||||
|
||||
/**
|
||||
* table meta info.
|
||||
*/
|
||||
type InstallFieldInfo struct {
|
||||
Name string `json:"name"`
|
||||
DataType string `json:"dataType"`
|
||||
type InstallTableInfo struct {
|
||||
Name string `json:"name"`
|
||||
TableExist bool `json:"tableExist"`
|
||||
AllFields []*gorm.StructField `json:"allFields"`
|
||||
MissingFields []*gorm.StructField `json:"missingFields"`
|
||||
}
|
||||
|
||||
@@ -2,10 +2,12 @@ package rest
|
||||
|
||||
import (
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
"github.com/eyebluecn/tank/code/tool/builder"
|
||||
"github.com/eyebluecn/tank/code/tool/i18n"
|
||||
"github.com/eyebluecn/tank/code/tool/result"
|
||||
"github.com/eyebluecn/tank/code/tool/util"
|
||||
"math"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -17,10 +19,12 @@ type MatterController struct {
|
||||
downloadTokenDao *DownloadTokenDao
|
||||
imageCacheDao *ImageCacheDao
|
||||
shareDao *ShareDao
|
||||
spaceDao *SpaceDao
|
||||
shareService *ShareService
|
||||
bridgeDao *BridgeDao
|
||||
imageCacheService *ImageCacheService
|
||||
ossService *OssService
|
||||
|
||||
ossUploading bool
|
||||
}
|
||||
|
||||
func (this *MatterController) Init() {
|
||||
@@ -51,11 +55,6 @@ func (this *MatterController) Init() {
|
||||
this.shareDao = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.spaceDao)
|
||||
if b, ok := b.(*SpaceDao); ok {
|
||||
this.spaceDao = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.shareService)
|
||||
if b, ok := b.(*ShareService); ok {
|
||||
this.shareService = b
|
||||
@@ -70,13 +69,17 @@ func (this *MatterController) Init() {
|
||||
if b, ok := b.(*ImageCacheService); ok {
|
||||
this.imageCacheService = b
|
||||
}
|
||||
b = core.CONTEXT.GetBean(this.ossService)
|
||||
if b, ok := b.(*OssService); ok {
|
||||
this.ossService = b
|
||||
}
|
||||
|
||||
this.ossUploading = false
|
||||
}
|
||||
|
||||
func (this *MatterController) RegisterRoutes() map[string]func(writer http.ResponseWriter, request *http.Request) {
|
||||
|
||||
routeMap := make(map[string]func(writer http.ResponseWriter, request *http.Request))
|
||||
routeMap["/api/matter/detail"] = this.Wrap(this.Detail, USER_ROLE_USER)
|
||||
routeMap["/api/matter/page"] = this.Wrap(this.Page, USER_ROLE_USER)
|
||||
|
||||
routeMap["/api/matter/create/directory"] = this.Wrap(this.CreateDirectory, USER_ROLE_USER)
|
||||
routeMap["/api/matter/upload"] = this.Wrap(this.Upload, USER_ROLE_USER)
|
||||
@@ -91,111 +94,160 @@ func (this *MatterController) RegisterRoutes() map[string]func(writer http.Respo
|
||||
routeMap["/api/matter/rename"] = this.Wrap(this.Rename, USER_ROLE_USER)
|
||||
routeMap["/api/matter/change/privacy"] = this.Wrap(this.ChangePrivacy, USER_ROLE_USER)
|
||||
routeMap["/api/matter/move"] = this.Wrap(this.Move, USER_ROLE_USER)
|
||||
routeMap["/api/matter/detail"] = this.Wrap(this.Detail, USER_ROLE_USER)
|
||||
routeMap["/api/matter/page"] = this.Wrap(this.Page, USER_ROLE_GUEST)
|
||||
|
||||
//mirror local files.
|
||||
routeMap["/api/matter/mirror"] = this.Wrap(this.Mirror, USER_ROLE_USER)
|
||||
routeMap["/api/matter/zip"] = this.Wrap(this.Zip, USER_ROLE_USER)
|
||||
|
||||
routeMap["/api/matter/oss"] = this.Wrap(this.Oss, USER_ROLE_ADMINISTRATOR)
|
||||
routeMap["/api/matter/stop"] = this.Wrap(this.Stop, USER_ROLE_ADMINISTRATOR)
|
||||
|
||||
return routeMap
|
||||
}
|
||||
|
||||
func (this *MatterController) Detail(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
uuid := util.ExtractRequestString(request, "uuid")
|
||||
user := this.checkUser(request)
|
||||
spaceUuid := util.ExtractRequestOptionalString(request, "spaceUuid", user.SpaceUuid)
|
||||
space := this.spaceService.CheckReadableByUuid(request, user, spaceUuid)
|
||||
uuid := request.FormValue("uuid")
|
||||
if uuid == "" {
|
||||
panic(result.BadRequest("uuid cannot be null"))
|
||||
}
|
||||
|
||||
matter := this.matterService.Detail(request, uuid)
|
||||
|
||||
if matter.SpaceUuid != space.Uuid {
|
||||
user := this.checkUser(request)
|
||||
if matter.UserUuid != user.Uuid {
|
||||
panic(result.UNAUTHORIZED)
|
||||
}
|
||||
|
||||
//add the user's info.
|
||||
if space.Uuid == user.SpaceUuid {
|
||||
matter.User = user
|
||||
} else {
|
||||
matter.User = this.userDao.FindByUuid(user.Uuid)
|
||||
}
|
||||
|
||||
return this.Success(matter)
|
||||
|
||||
}
|
||||
|
||||
func (this *MatterController) Page(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
page := util.ExtractRequestOptionalInt(request, "page", 0)
|
||||
pageSize := util.ExtractRequestOptionalInt(request, "pageSize", 200)
|
||||
orderCreateTime := util.ExtractRequestOptionalString(request, "orderCreateTime", "")
|
||||
orderUpdateTime := util.ExtractRequestOptionalString(request, "orderUpdateTime", "")
|
||||
orderDeleteTime := util.ExtractRequestOptionalString(request, "orderDeleteTime", "")
|
||||
orderSort := util.ExtractRequestOptionalString(request, "orderSort", "")
|
||||
orderTimes := util.ExtractRequestOptionalString(request, "orderTimes", "")
|
||||
orderDir := util.ExtractRequestOptionalString(request, "orderDir", "")
|
||||
orderSize := util.ExtractRequestOptionalString(request, "orderSize", "")
|
||||
orderName := util.ExtractRequestOptionalString(request, "orderName", "")
|
||||
pageStr := request.FormValue("page")
|
||||
pageSizeStr := request.FormValue("pageSize")
|
||||
orderCreateTime := request.FormValue("orderCreateTime")
|
||||
orderUpdateTime := request.FormValue("orderUpdateTime")
|
||||
orderDeleteTime := request.FormValue("orderDeleteTime")
|
||||
orderSort := request.FormValue("orderSort")
|
||||
orderTimes := request.FormValue("orderTimes")
|
||||
|
||||
puuid := util.ExtractRequestOptionalString(request, "puuid", "")
|
||||
name := util.ExtractRequestOptionalString(request, "name", "")
|
||||
dir := util.ExtractRequestOptionalString(request, "dir", "")
|
||||
deleted := util.ExtractRequestOptionalString(request, "deleted", "")
|
||||
extensionsStr := util.ExtractRequestOptionalString(request, "extensions", "")
|
||||
puuid := request.FormValue("puuid")
|
||||
name := request.FormValue("name")
|
||||
dir := request.FormValue("dir")
|
||||
deleted := request.FormValue("deleted")
|
||||
orderDir := request.FormValue("orderDir")
|
||||
orderSize := request.FormValue("orderSize")
|
||||
orderName := request.FormValue("orderName")
|
||||
extensionsStr := request.FormValue("extensions")
|
||||
|
||||
user := this.checkUser(request)
|
||||
spaceUuid := util.ExtractRequestOptionalString(request, "spaceUuid", user.SpaceUuid)
|
||||
this.spaceService.CheckReadableByUuid(request, user, spaceUuid)
|
||||
var userUuid string
|
||||
|
||||
//auth by shareUuid.
|
||||
shareUuid := request.FormValue("shareUuid")
|
||||
shareCode := request.FormValue("shareCode")
|
||||
shareRootUuid := request.FormValue("shareRootUuid")
|
||||
if shareUuid != "" {
|
||||
|
||||
if puuid == "" {
|
||||
panic(result.BadRequest("puuid cannot be null"))
|
||||
}
|
||||
|
||||
dirMatter := this.matterDao.CheckByUuid(puuid)
|
||||
if !dirMatter.Dir {
|
||||
panic(result.BadRequest("puuid is not a directory"))
|
||||
}
|
||||
|
||||
user := this.findUser(request)
|
||||
|
||||
this.shareService.ValidateMatter(request, shareUuid, shareCode, user, shareRootUuid, dirMatter)
|
||||
puuid = dirMatter.Uuid
|
||||
|
||||
} else {
|
||||
//if cannot auth by share. Then login is required.
|
||||
user := this.checkUser(request)
|
||||
userUuid = user.Uuid
|
||||
|
||||
}
|
||||
|
||||
var page int
|
||||
if pageStr != "" {
|
||||
page, _ = strconv.Atoi(pageStr)
|
||||
}
|
||||
|
||||
pageSize := 200
|
||||
if pageSizeStr != "" {
|
||||
tmp, err := strconv.Atoi(pageSizeStr)
|
||||
if err == nil {
|
||||
pageSize = tmp
|
||||
}
|
||||
}
|
||||
|
||||
var extensions []string
|
||||
if extensionsStr != "" {
|
||||
extensions = strings.Split(extensionsStr, ",")
|
||||
}
|
||||
|
||||
pager := this.matterService.Page(
|
||||
request,
|
||||
page,
|
||||
pageSize,
|
||||
orderCreateTime,
|
||||
orderUpdateTime,
|
||||
orderDeleteTime,
|
||||
orderSort,
|
||||
orderTimes,
|
||||
orderDir,
|
||||
orderSize,
|
||||
orderName,
|
||||
puuid,
|
||||
name,
|
||||
dir,
|
||||
deleted,
|
||||
extensions,
|
||||
spaceUuid,
|
||||
)
|
||||
sortArray := []builder.OrderPair{
|
||||
{
|
||||
Key: "dir",
|
||||
Value: orderDir,
|
||||
},
|
||||
{
|
||||
Key: "create_time",
|
||||
Value: orderCreateTime,
|
||||
},
|
||||
{
|
||||
Key: "update_time",
|
||||
Value: orderUpdateTime,
|
||||
},
|
||||
{
|
||||
Key: "delete_time",
|
||||
Value: orderDeleteTime,
|
||||
},
|
||||
{
|
||||
Key: "sort",
|
||||
Value: orderSort,
|
||||
},
|
||||
{
|
||||
Key: "size",
|
||||
Value: orderSize,
|
||||
},
|
||||
{
|
||||
Key: "name",
|
||||
Value: orderName,
|
||||
},
|
||||
{
|
||||
Key: "times",
|
||||
Value: orderTimes,
|
||||
},
|
||||
}
|
||||
|
||||
pager := this.matterDao.Page(page, pageSize, puuid, userUuid, name, dir, deleted, extensions, sortArray)
|
||||
|
||||
return this.Success(pager)
|
||||
}
|
||||
|
||||
func (this *MatterController) CreateDirectory(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
puuid := util.ExtractRequestString(request, "puuid")
|
||||
name := util.ExtractRequestString(request, "name")
|
||||
puuid := request.FormValue("puuid")
|
||||
name := request.FormValue("name")
|
||||
|
||||
user := this.checkUser(request)
|
||||
spaceUuid := util.ExtractRequestOptionalString(request, "spaceUuid", user.SpaceUuid)
|
||||
space := this.spaceService.CheckWritableByUuid(request, user, spaceUuid)
|
||||
|
||||
var dirMatter = this.matterDao.CheckWithRootByUuid(puuid, space)
|
||||
var dirMatter = this.matterDao.CheckWithRootByUuid(puuid, user)
|
||||
|
||||
matter := this.matterService.AtomicCreateDirectory(request, dirMatter, name, user, space)
|
||||
matter := this.matterService.AtomicCreateDirectory(request, dirMatter, name, user)
|
||||
return this.Success(matter)
|
||||
}
|
||||
|
||||
func (this *MatterController) Upload(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
puuid := util.ExtractRequestString(request, "puuid")
|
||||
privacy := util.ExtractRequestOptionalBool(request, "privacy", true)
|
||||
|
||||
user := this.checkUser(request)
|
||||
spaceUuid := util.ExtractRequestOptionalString(request, "spaceUuid", user.SpaceUuid)
|
||||
space := this.spaceService.CheckWritableByUuid(request, user, spaceUuid)
|
||||
|
||||
puuid := request.FormValue("puuid")
|
||||
privacyStr := request.FormValue("privacy")
|
||||
file, handler, err := request.FormFile("file")
|
||||
this.PanicError(err)
|
||||
defer func() {
|
||||
@@ -203,10 +255,14 @@ func (this *MatterController) Upload(writer http.ResponseWriter, request *http.R
|
||||
this.PanicError(err)
|
||||
}()
|
||||
|
||||
user := this.checkUser(request)
|
||||
|
||||
privacy := privacyStr == TRUE
|
||||
|
||||
err = request.ParseMultipartForm(32 << 20)
|
||||
this.PanicError(err)
|
||||
|
||||
//for IE browser. filename may contain filepath.
|
||||
//for IE browser. filename may contains filepath.
|
||||
fileName := handler.Filename
|
||||
pos := strings.LastIndex(fileName, "\\")
|
||||
if pos != -1 {
|
||||
@@ -217,77 +273,65 @@ func (this *MatterController) Upload(writer http.ResponseWriter, request *http.R
|
||||
fileName = fileName[pos+1:]
|
||||
}
|
||||
|
||||
dirMatter := this.matterDao.CheckWithRootByUuid(puuid, space)
|
||||
dirMatter := this.matterDao.CheckWithRootByUuid(puuid, user)
|
||||
|
||||
//support upload simultaneously
|
||||
matter := this.matterService.Upload(request, file, handler, user, space, dirMatter, fileName, privacy)
|
||||
matter := this.matterService.Upload(request, file, user, dirMatter, fileName, privacy)
|
||||
|
||||
return this.Success(matter)
|
||||
}
|
||||
|
||||
// crawl a file by url.
|
||||
//crawl a file by url.
|
||||
func (this *MatterController) Crawl(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
url := util.ExtractRequestString(request, "url")
|
||||
destPath := util.ExtractRequestOptionalString(request, "destPath", "")
|
||||
puuid := util.ExtractRequestOptionalString(request, "puuid", "")
|
||||
filename := util.ExtractRequestString(request, "filename")
|
||||
url := request.FormValue("url")
|
||||
destPath := request.FormValue("destPath")
|
||||
filename := request.FormValue("filename")
|
||||
|
||||
user := this.checkUser(request)
|
||||
spaceUuid := util.ExtractRequestOptionalString(request, "spaceUuid", user.SpaceUuid)
|
||||
space := this.spaceService.CheckWritableByUuid(request, user, spaceUuid)
|
||||
|
||||
var dirMatter *Matter
|
||||
if puuid != "" {
|
||||
dirMatter = this.matterDao.CheckWithRootByUuid(puuid, space)
|
||||
if dirMatter.SpaceUuid != space.Uuid {
|
||||
panic(result.UNAUTHORIZED)
|
||||
}
|
||||
if !dirMatter.Dir {
|
||||
panic(" puuid is not a dir.")
|
||||
}
|
||||
} else {
|
||||
if destPath == "" {
|
||||
panic(" puuid or destPath cannot be null")
|
||||
}
|
||||
dirMatter = this.matterService.CreateDirectories(request, user, space, destPath)
|
||||
}
|
||||
dirMatter := this.matterService.CreateDirectories(request, user, destPath)
|
||||
|
||||
if url == "" || (!strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://")) {
|
||||
panic(" url must start with http:// or https://")
|
||||
}
|
||||
|
||||
matter := this.matterService.AtomicCrawl(request, url, filename, user, space, dirMatter, true)
|
||||
if filename == "" {
|
||||
panic("filename cannot be null")
|
||||
}
|
||||
|
||||
matter := this.matterService.AtomicCrawl(request, url, filename, user, dirMatter, true)
|
||||
|
||||
return this.Success(matter)
|
||||
}
|
||||
|
||||
// soft delete.
|
||||
//soft delete.
|
||||
func (this *MatterController) SoftDelete(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
uuid := util.ExtractRequestString(request, "uuid")
|
||||
|
||||
user := this.checkUser(request)
|
||||
spaceUuid := util.ExtractRequestOptionalString(request, "spaceUuid", user.SpaceUuid)
|
||||
space := this.spaceService.CheckWritableByUuid(request, user, spaceUuid)
|
||||
uuid := request.FormValue("uuid")
|
||||
if uuid == "" {
|
||||
panic(result.BadRequest("uuid cannot be null"))
|
||||
}
|
||||
|
||||
matter := this.matterDao.CheckByUuid(uuid)
|
||||
if matter.SpaceUuid != space.Uuid {
|
||||
|
||||
user := this.checkUser(request)
|
||||
if matter.UserUuid != user.Uuid {
|
||||
panic(result.UNAUTHORIZED)
|
||||
}
|
||||
|
||||
this.matterService.AtomicSoftDelete(request, matter, user, space)
|
||||
this.matterService.AtomicSoftDelete(request, matter, user)
|
||||
|
||||
return this.Success("OK")
|
||||
}
|
||||
|
||||
func (this *MatterController) SoftDeleteBatch(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
uuids := util.ExtractRequestString(request, "uuids")
|
||||
|
||||
uuids := request.FormValue("uuids")
|
||||
if uuids == "" {
|
||||
panic(result.BadRequest("uuids cannot be null"))
|
||||
}
|
||||
user := this.checkUser(request)
|
||||
spaceUuid := util.ExtractRequestOptionalString(request, "spaceUuid", user.SpaceUuid)
|
||||
space := this.spaceService.CheckWritableByUuid(request, user, spaceUuid)
|
||||
|
||||
uuidArray := strings.Split(uuids, ",")
|
||||
|
||||
@@ -309,24 +353,24 @@ func (this *MatterController) SoftDeleteBatch(writer http.ResponseWriter, reques
|
||||
}
|
||||
|
||||
for _, matter := range matters {
|
||||
this.matterService.AtomicSoftDelete(request, matter, user, space)
|
||||
this.matterService.AtomicSoftDelete(request, matter, user)
|
||||
}
|
||||
|
||||
return this.Success("OK")
|
||||
}
|
||||
|
||||
// recovery delete.
|
||||
//recovery delete.
|
||||
func (this *MatterController) Recovery(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
uuid := util.ExtractRequestString(request, "uuid")
|
||||
|
||||
user := this.checkUser(request)
|
||||
spaceUuid := util.ExtractRequestOptionalString(request, "spaceUuid", user.SpaceUuid)
|
||||
space := this.spaceService.CheckWritableByUuid(request, user, spaceUuid)
|
||||
uuid := request.FormValue("uuid")
|
||||
if uuid == "" {
|
||||
panic(result.BadRequest("uuid cannot be null"))
|
||||
}
|
||||
|
||||
matter := this.matterDao.CheckByUuid(uuid)
|
||||
|
||||
if matter.SpaceUuid != space.Uuid {
|
||||
user := this.checkUser(request)
|
||||
if matter.UserUuid != user.Uuid {
|
||||
panic(result.UNAUTHORIZED)
|
||||
}
|
||||
|
||||
@@ -335,13 +379,13 @@ func (this *MatterController) Recovery(writer http.ResponseWriter, request *http
|
||||
return this.Success("OK")
|
||||
}
|
||||
|
||||
// recovery batch.
|
||||
//recovery batch.
|
||||
func (this *MatterController) RecoveryBatch(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
uuids := util.ExtractRequestString(request, "uuids")
|
||||
|
||||
user := this.checkUser(request)
|
||||
spaceUuid := util.ExtractRequestOptionalString(request, "spaceUuid", user.SpaceUuid)
|
||||
space := this.spaceService.CheckWritableByUuid(request, user, spaceUuid)
|
||||
uuids := request.FormValue("uuids")
|
||||
if uuids == "" {
|
||||
panic(result.BadRequest("uuids cannot be null"))
|
||||
}
|
||||
|
||||
uuidArray := strings.Split(uuids, ",")
|
||||
|
||||
@@ -354,7 +398,8 @@ func (this *MatterController) RecoveryBatch(writer http.ResponseWriter, request
|
||||
continue
|
||||
}
|
||||
|
||||
if matter.SpaceUuid != space.Uuid {
|
||||
user := this.checkUser(request)
|
||||
if matter.UserUuid != user.Uuid {
|
||||
panic(result.UNAUTHORIZED)
|
||||
}
|
||||
|
||||
@@ -365,34 +410,35 @@ func (this *MatterController) RecoveryBatch(writer http.ResponseWriter, request
|
||||
return this.Success("OK")
|
||||
}
|
||||
|
||||
// complete delete.
|
||||
//complete delete.
|
||||
func (this *MatterController) Delete(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
uuid := util.ExtractRequestString(request, "uuid")
|
||||
|
||||
user := this.checkUser(request)
|
||||
spaceUuid := util.ExtractRequestOptionalString(request, "spaceUuid", user.SpaceUuid)
|
||||
space := this.spaceService.CheckWritableByUuid(request, user, spaceUuid)
|
||||
uuid := request.FormValue("uuid")
|
||||
if uuid == "" {
|
||||
panic(result.BadRequest("uuid cannot be null"))
|
||||
}
|
||||
|
||||
matter := this.matterDao.CheckByUuid(uuid)
|
||||
if matter.SpaceUuid != space.Uuid {
|
||||
|
||||
user := this.checkUser(request)
|
||||
if matter.UserUuid != user.Uuid {
|
||||
panic(result.UNAUTHORIZED)
|
||||
}
|
||||
|
||||
this.matterService.AtomicDelete(request, matter, user, space)
|
||||
this.matterService.AtomicDelete(request, matter, user)
|
||||
|
||||
return this.Success("OK")
|
||||
}
|
||||
|
||||
func (this *MatterController) DeleteBatch(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
uuids := util.ExtractRequestString(request, "uuids")
|
||||
|
||||
user := this.checkUser(request)
|
||||
spaceUuid := util.ExtractRequestOptionalString(request, "spaceUuid", user.SpaceUuid)
|
||||
space := this.spaceService.CheckWritableByUuid(request, user, spaceUuid)
|
||||
uuids := request.FormValue("uuids")
|
||||
if uuids == "" {
|
||||
panic(result.BadRequest("uuids cannot be null"))
|
||||
}
|
||||
|
||||
uuidArray := strings.Split(uuids, ",")
|
||||
user := this.checkUser(request)
|
||||
matters := make([]*Matter, 0)
|
||||
for _, uuid := range uuidArray {
|
||||
|
||||
@@ -403,7 +449,7 @@ func (this *MatterController) DeleteBatch(writer http.ResponseWriter, request *h
|
||||
continue
|
||||
}
|
||||
|
||||
if matter.SpaceUuid != space.Uuid {
|
||||
if matter.UserUuid != user.Uuid {
|
||||
panic(result.UNAUTHORIZED)
|
||||
}
|
||||
|
||||
@@ -412,13 +458,13 @@ func (this *MatterController) DeleteBatch(writer http.ResponseWriter, request *h
|
||||
|
||||
for _, matter := range matters {
|
||||
|
||||
this.matterService.AtomicDelete(request, matter, user, space)
|
||||
this.matterService.AtomicDelete(request, matter, user)
|
||||
}
|
||||
|
||||
return this.Success("OK")
|
||||
}
|
||||
|
||||
// manual clean expired deleted matters.
|
||||
//manual clean expired deleted matters.
|
||||
func (this *MatterController) CleanExpiredDeletedMatters(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
this.matterService.CleanExpiredDeletedMatters()
|
||||
@@ -428,32 +474,29 @@ func (this *MatterController) CleanExpiredDeletedMatters(writer http.ResponseWri
|
||||
|
||||
func (this *MatterController) Rename(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
uuid := util.ExtractRequestString(request, "uuid")
|
||||
name := util.ExtractRequestString(request, "name")
|
||||
uuid := request.FormValue("uuid")
|
||||
name := request.FormValue("name")
|
||||
|
||||
user := this.checkUser(request)
|
||||
spaceUuid := util.ExtractRequestOptionalString(request, "spaceUuid", user.SpaceUuid)
|
||||
space := this.spaceService.CheckWritableByUuid(request, user, spaceUuid)
|
||||
|
||||
matter := this.matterDao.CheckByUuid(uuid)
|
||||
|
||||
if matter.SpaceUuid != space.Uuid {
|
||||
if matter.UserUuid != user.Uuid {
|
||||
panic(result.UNAUTHORIZED)
|
||||
}
|
||||
|
||||
this.matterService.AtomicRename(request, matter, name, false, user, space)
|
||||
this.matterService.AtomicRename(request, matter, name, false, user)
|
||||
|
||||
return this.Success(matter)
|
||||
}
|
||||
|
||||
func (this *MatterController) ChangePrivacy(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
uuid := util.ExtractRequestString(request, "uuid")
|
||||
privacy := util.ExtractRequestOptionalBool(request, "privacy", false)
|
||||
|
||||
user := this.checkUser(request)
|
||||
spaceUuid := util.ExtractRequestOptionalString(request, "spaceUuid", user.SpaceUuid)
|
||||
space := this.spaceService.CheckWritableByUuid(request, user, spaceUuid)
|
||||
uuid := request.FormValue("uuid")
|
||||
privacyStr := request.FormValue("privacy")
|
||||
privacy := false
|
||||
if privacyStr == TRUE {
|
||||
privacy = true
|
||||
}
|
||||
|
||||
matter := this.matterDao.CheckByUuid(uuid)
|
||||
|
||||
@@ -465,7 +508,8 @@ func (this *MatterController) ChangePrivacy(writer http.ResponseWriter, request
|
||||
panic(result.BadRequest("not changed. Invalid operation."))
|
||||
}
|
||||
|
||||
if matter.SpaceUuid != space.Uuid {
|
||||
user := this.checkUser(request)
|
||||
if matter.UserUuid != user.Uuid {
|
||||
panic(result.UNAUTHORIZED)
|
||||
}
|
||||
|
||||
@@ -476,21 +520,25 @@ func (this *MatterController) ChangePrivacy(writer http.ResponseWriter, request
|
||||
}
|
||||
|
||||
func (this *MatterController) Move(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
srcUuidsStr := util.ExtractRequestString(request, "srcUuids")
|
||||
destUuid := util.ExtractRequestString(request, "destUuid")
|
||||
user := this.checkUser(request)
|
||||
spaceUuid := util.ExtractRequestOptionalString(request, "spaceUuid", user.SpaceUuid)
|
||||
space := this.spaceService.CheckWritableByUuid(request, user, spaceUuid)
|
||||
|
||||
srcUuidsStr := request.FormValue("srcUuids")
|
||||
destUuid := request.FormValue("destUuid")
|
||||
|
||||
var srcUuids []string
|
||||
srcUuids = strings.Split(srcUuidsStr, ",")
|
||||
if srcUuidsStr == "" {
|
||||
panic(result.BadRequest("srcUuids cannot be null"))
|
||||
} else {
|
||||
srcUuids = strings.Split(srcUuidsStr, ",")
|
||||
}
|
||||
|
||||
var destMatter = this.matterDao.CheckWithRootByUuid(destUuid, space)
|
||||
user := this.checkUser(request)
|
||||
|
||||
var destMatter = this.matterDao.CheckWithRootByUuid(destUuid, user)
|
||||
if !destMatter.Dir {
|
||||
panic(result.BadRequest("destination is not a directory"))
|
||||
}
|
||||
|
||||
if destMatter.SpaceUuid != space.Uuid {
|
||||
if destMatter.UserUuid != user.Uuid {
|
||||
panic(result.UNAUTHORIZED)
|
||||
}
|
||||
|
||||
@@ -517,41 +565,49 @@ func (this *MatterController) Move(writer http.ResponseWriter, request *http.Req
|
||||
panic(result.BadRequestI18n(request, i18n.MatterExist, srcMatter.Name))
|
||||
}
|
||||
|
||||
if srcMatter.SpaceUuid != destMatter.SpaceUuid {
|
||||
panic("space not the same")
|
||||
if srcMatter.UserUuid != destMatter.UserUuid {
|
||||
panic("owner not the same")
|
||||
}
|
||||
|
||||
srcMatters = append(srcMatters, srcMatter)
|
||||
}
|
||||
|
||||
this.matterService.AtomicMoveBatch(request, srcMatters, destMatter, user, space)
|
||||
this.matterService.AtomicMoveBatch(request, srcMatters, destMatter, user)
|
||||
|
||||
return this.Success(nil)
|
||||
}
|
||||
|
||||
// mirror local files to EyeblueTank
|
||||
//mirror local files to EyeblueTank
|
||||
func (this *MatterController) Mirror(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
srcPath := util.ExtractRequestString(request, "srcPath")
|
||||
destPath := util.ExtractRequestString(request, "destPath")
|
||||
overwrite := util.ExtractRequestOptionalBool(request, "overwrite", false)
|
||||
srcPath := request.FormValue("srcPath")
|
||||
destPath := request.FormValue("destPath")
|
||||
overwriteStr := request.FormValue("overwrite")
|
||||
|
||||
user := this.checkUser(request)
|
||||
spaceUuid := util.ExtractRequestOptionalString(request, "spaceUuid", user.SpaceUuid)
|
||||
space := this.spaceService.CheckWritableByUuid(request, user, spaceUuid)
|
||||
if srcPath == "" {
|
||||
panic(result.BadRequest("srcPath cannot be null"))
|
||||
}
|
||||
|
||||
this.matterService.AtomicMirror(request, srcPath, destPath, overwrite, user, space)
|
||||
overwrite := false
|
||||
if overwriteStr == TRUE {
|
||||
overwrite = true
|
||||
}
|
||||
|
||||
user := this.userDao.checkUser(request)
|
||||
|
||||
this.matterService.AtomicMirror(request, srcPath, destPath, overwrite, user)
|
||||
|
||||
return this.Success(nil)
|
||||
|
||||
}
|
||||
|
||||
// download zip.
|
||||
//download zip.
|
||||
func (this *MatterController) Zip(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
uuids := util.ExtractRequestString(request, "uuids")
|
||||
user := this.checkUser(request)
|
||||
spaceUuid := util.ExtractRequestOptionalString(request, "spaceUuid", user.SpaceUuid)
|
||||
space := this.spaceService.CheckReadableByUuid(request, user, spaceUuid)
|
||||
|
||||
uuids := request.FormValue("uuids")
|
||||
if uuids == "" {
|
||||
panic(result.BadRequest("uuids cannot be null"))
|
||||
}
|
||||
|
||||
uuidArray := strings.Split(uuids, ",")
|
||||
|
||||
@@ -567,10 +623,11 @@ func (this *MatterController) Zip(writer http.ResponseWriter, request *http.Requ
|
||||
}
|
||||
}
|
||||
|
||||
user := this.checkUser(request)
|
||||
puuid := matters[0].Puuid
|
||||
|
||||
for _, m := range matters {
|
||||
if m.SpaceUuid != space.Uuid {
|
||||
if m.UserUuid != user.Uuid {
|
||||
panic(result.UNAUTHORIZED)
|
||||
} else if m.Puuid != puuid {
|
||||
panic(result.BadRequest("puuid not same"))
|
||||
@@ -581,3 +638,56 @@ func (this *MatterController) Zip(writer http.ResponseWriter, request *http.Requ
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//upload to oss.
|
||||
func (this *MatterController) Oss(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
if this.ossUploading {
|
||||
return this.Success("oss is running")
|
||||
} else {
|
||||
this.ossUploading = true
|
||||
}
|
||||
|
||||
pageSize := 100
|
||||
count, _ := this.matterDao.PlainPage(0, pageSize, "", "", "", "false", "", nil, nil, nil)
|
||||
if count > 0 {
|
||||
var totalPages = int(math.Ceil(float64(count) / float64(pageSize)))
|
||||
|
||||
var page int
|
||||
for page = 0; page < totalPages; page++ {
|
||||
|
||||
this.logger.Info("-- processing %d/%d", page+1, totalPages)
|
||||
|
||||
if !this.ossUploading {
|
||||
break
|
||||
}
|
||||
|
||||
_, matters := this.matterDao.PlainPage(page, pageSize, "", "", "", "false", "", nil, nil, nil)
|
||||
for _, matter := range matters {
|
||||
|
||||
if !this.ossUploading {
|
||||
break
|
||||
}
|
||||
|
||||
//保证不抛异常
|
||||
core.RunWithRecovery(func() {
|
||||
this.ossService.Upload(matter)
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.ossUploading = false
|
||||
|
||||
return this.Success(nil)
|
||||
}
|
||||
|
||||
//stop uploading to oss.
|
||||
func (this *MatterController) Stop(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
this.ossUploading = false
|
||||
|
||||
this.logger.Info("-- stop processing --")
|
||||
return this.Success("OK")
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"github.com/eyebluecn/tank/code/tool/result"
|
||||
"github.com/eyebluecn/tank/code/tool/util"
|
||||
"github.com/eyebluecn/tank/code/tool/uuid"
|
||||
"gorm.io/gorm"
|
||||
"github.com/jinzhu/gorm"
|
||||
"math"
|
||||
"os"
|
||||
"time"
|
||||
@@ -46,7 +46,7 @@ func (this *MatterDao) FindByUuid(uuid string) *Matter {
|
||||
return entity
|
||||
}
|
||||
|
||||
// find by uuid. if not found panic NotFound error
|
||||
//find by uuid. if not found panic NotFound error
|
||||
func (this *MatterDao) CheckByUuid(uuid string) *Matter {
|
||||
entity := this.FindByUuid(uuid)
|
||||
if entity == nil {
|
||||
@@ -56,7 +56,7 @@ func (this *MatterDao) CheckByUuid(uuid string) *Matter {
|
||||
}
|
||||
|
||||
// find by uuid. if uuid=root, then return the Root Matter
|
||||
func (this *MatterDao) CheckWithRootByUuid(uuid string, space *Space) *Matter {
|
||||
func (this *MatterDao) CheckWithRootByUuid(uuid string, user *User) *Matter {
|
||||
|
||||
if uuid == "" {
|
||||
panic(result.BadRequest("uuid cannot be null."))
|
||||
@@ -64,10 +64,10 @@ func (this *MatterDao) CheckWithRootByUuid(uuid string, space *Space) *Matter {
|
||||
|
||||
var matter *Matter
|
||||
if uuid == MATTER_ROOT {
|
||||
if space == nil {
|
||||
panic(result.BadRequest("space cannot be null."))
|
||||
if user == nil {
|
||||
panic(result.BadRequest("user cannot be null."))
|
||||
}
|
||||
matter = NewRootMatter(space)
|
||||
matter = NewRootMatter(user)
|
||||
} else {
|
||||
matter = this.CheckByUuid(uuid)
|
||||
}
|
||||
@@ -76,7 +76,7 @@ func (this *MatterDao) CheckWithRootByUuid(uuid string, space *Space) *Matter {
|
||||
}
|
||||
|
||||
// find by path. if path=/, then return the Root Matter
|
||||
func (this *MatterDao) CheckWithRootByPath(path string, user *User, space *Space) *Matter {
|
||||
func (this *MatterDao) CheckWithRootByPath(path string, user *User) *Matter {
|
||||
|
||||
var matter *Matter
|
||||
|
||||
@@ -85,7 +85,7 @@ func (this *MatterDao) CheckWithRootByPath(path string, user *User, space *Space
|
||||
}
|
||||
|
||||
if path == "" || path == "/" {
|
||||
matter = NewRootMatter(space)
|
||||
matter = NewRootMatter(user)
|
||||
} else {
|
||||
matter = this.checkByUserUuidAndPath(user.Uuid, path)
|
||||
}
|
||||
@@ -94,7 +94,7 @@ func (this *MatterDao) CheckWithRootByPath(path string, user *User, space *Space
|
||||
}
|
||||
|
||||
// find by path. if path=/, then return the Root Matter
|
||||
func (this *MatterDao) FindWithRootByPath(path string, user *User, space *Space) *Matter {
|
||||
func (this *MatterDao) FindWithRootByPath(path string, user *User) *Matter {
|
||||
|
||||
var matter *Matter
|
||||
|
||||
@@ -103,7 +103,7 @@ func (this *MatterDao) FindWithRootByPath(path string, user *User, space *Space)
|
||||
}
|
||||
|
||||
if path == "" || path == "/" {
|
||||
matter = NewRootMatter(space)
|
||||
matter = NewRootMatter(user)
|
||||
} else {
|
||||
matter = this.findByUserUuidAndPath(user.Uuid, path)
|
||||
}
|
||||
@@ -138,7 +138,7 @@ func (this *MatterDao) FindByUserUuidAndPuuidAndDirTrue(userUuid string, puuid s
|
||||
func (this *MatterDao) CheckByUuidAndUserUuid(uuid string, userUuid string) *Matter {
|
||||
|
||||
var matter = &Matter{}
|
||||
db := core.CONTEXT.GetDB().Where(&Matter{Uuid: uuid, UserUuid: userUuid}).First(matter)
|
||||
db := core.CONTEXT.GetDB().Where(&Matter{Base: Base{Uuid: uuid}, UserUuid: userUuid}).First(matter)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
return matter
|
||||
@@ -148,7 +148,7 @@ func (this *MatterDao) CheckByUuidAndUserUuid(uuid string, userUuid string) *Mat
|
||||
func (this *MatterDao) CountByUserUuidAndPuuidAndDirAndName(userUuid string, puuid string, dir bool, name string) int {
|
||||
|
||||
var matter Matter
|
||||
var count int64
|
||||
var count int
|
||||
|
||||
var wp = &builder.WherePair{}
|
||||
|
||||
@@ -172,37 +172,7 @@ func (this *MatterDao) CountByUserUuidAndPuuidAndDirAndName(userUuid string, puu
|
||||
Count(&count)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
return int(count)
|
||||
}
|
||||
|
||||
func (this *MatterDao) CountBySpaceUuidAndPuuidAndDirAndName(spaceUuid string, puuid string, dir bool, name string) int {
|
||||
|
||||
var matter Matter
|
||||
var count int64
|
||||
|
||||
var wp = &builder.WherePair{}
|
||||
|
||||
if puuid != "" {
|
||||
wp = wp.And(&builder.WherePair{Query: "puuid = ?", Args: []interface{}{puuid}})
|
||||
}
|
||||
|
||||
if spaceUuid != "" {
|
||||
wp = wp.And(&builder.WherePair{Query: "space_uuid = ?", Args: []interface{}{spaceUuid}})
|
||||
}
|
||||
|
||||
if name != "" {
|
||||
wp = wp.And(&builder.WherePair{Query: "name = ?", Args: []interface{}{name}})
|
||||
}
|
||||
|
||||
wp = wp.And(&builder.WherePair{Query: "dir = ?", Args: []interface{}{dir}})
|
||||
|
||||
db := core.CONTEXT.GetDB().
|
||||
Model(&matter).
|
||||
Where(wp.Query, wp.Args...).
|
||||
Count(&count)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
return int(count)
|
||||
return count
|
||||
}
|
||||
|
||||
func (this *MatterDao) FindByUserUuidAndPuuidAndDirAndName(userUuid string, puuid string, dir string, name string) *Matter {
|
||||
@@ -242,43 +212,6 @@ func (this *MatterDao) FindByUserUuidAndPuuidAndDirAndName(userUuid string, puui
|
||||
return matter
|
||||
}
|
||||
|
||||
func (this *MatterDao) FindBySpaceNameAndPuuidAndDirAndName(spaceName string, puuid string, dir string, name string) *Matter {
|
||||
|
||||
var matter = &Matter{}
|
||||
|
||||
var wp = &builder.WherePair{}
|
||||
|
||||
if puuid != "" {
|
||||
wp = wp.And(&builder.WherePair{Query: "puuid = ?", Args: []interface{}{puuid}})
|
||||
}
|
||||
|
||||
if spaceName != "" {
|
||||
wp = wp.And(&builder.WherePair{Query: "space_name = ?", Args: []interface{}{spaceName}})
|
||||
}
|
||||
|
||||
if name != "" {
|
||||
wp = wp.And(&builder.WherePair{Query: "name = ?", Args: []interface{}{name}})
|
||||
}
|
||||
|
||||
if dir == TRUE {
|
||||
wp = wp.And(&builder.WherePair{Query: "dir = ?", Args: []interface{}{true}})
|
||||
} else if dir == FALSE {
|
||||
wp = wp.And(&builder.WherePair{Query: "dir = ?", Args: []interface{}{false}})
|
||||
}
|
||||
|
||||
db := core.CONTEXT.GetDB().Where(wp.Query, wp.Args...).First(matter)
|
||||
|
||||
if db.Error != nil {
|
||||
if db.Error.Error() == result.DB_ERROR_NOT_FOUND {
|
||||
return nil
|
||||
} else {
|
||||
this.PanicError(db.Error)
|
||||
}
|
||||
}
|
||||
|
||||
return matter
|
||||
}
|
||||
|
||||
func (this *MatterDao) FindByPuuidAndUserUuid(puuid string, userUuid string, sortArray []builder.OrderPair) []*Matter {
|
||||
return this.FindByPuuidAndUserUuidAndDeleted(puuid, userUuid, "", sortArray)
|
||||
}
|
||||
@@ -327,7 +260,6 @@ func (this *MatterDao) PlainPage(
|
||||
pageSize int,
|
||||
puuid string,
|
||||
userUuid string,
|
||||
spaceUuid string,
|
||||
name string,
|
||||
dir string,
|
||||
deleted string,
|
||||
@@ -345,10 +277,6 @@ func (this *MatterDao) PlainPage(
|
||||
wp = wp.And(&builder.WherePair{Query: "user_uuid = ?", Args: []interface{}{userUuid}})
|
||||
}
|
||||
|
||||
if spaceUuid != "" {
|
||||
wp = wp.And(&builder.WherePair{Query: "space_uuid = ?", Args: []interface{}{spaceUuid}})
|
||||
}
|
||||
|
||||
if name != "" {
|
||||
wp = wp.And(&builder.WherePair{Query: "name LIKE ?", Args: []interface{}{"%" + name + "%"}})
|
||||
}
|
||||
@@ -382,7 +310,7 @@ func (this *MatterDao) PlainPage(
|
||||
conditionDB = core.CONTEXT.GetDB().Model(&Matter{}).Where(wp.Query, wp.Args...)
|
||||
}
|
||||
|
||||
var count int64 = 0
|
||||
count := 0
|
||||
db := conditionDB.Count(&count)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
@@ -390,21 +318,20 @@ func (this *MatterDao) PlainPage(
|
||||
db = conditionDB.Order(this.GetSortString(sortArray)).Offset(page * pageSize).Limit(pageSize).Find(&matters)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
return int(count), matters
|
||||
return count, matters
|
||||
}
|
||||
func (this *MatterDao) Page(page int, pageSize int, puuid string, userUuid string, spaceUuid string, name string, dir string, deleted string, extensions []string, sortArray []builder.OrderPair) *Pager {
|
||||
func (this *MatterDao) Page(page int, pageSize int, puuid string, userUuid string, name string, dir string, deleted string, extensions []string, sortArray []builder.OrderPair) *Pager {
|
||||
|
||||
count, matters := this.PlainPage(page, pageSize, puuid, userUuid, spaceUuid, name, dir, deleted, nil, extensions, sortArray)
|
||||
count, matters := this.PlainPage(page, pageSize, puuid, userUuid, name, dir, deleted, nil, extensions, sortArray)
|
||||
pager := NewPager(page, pageSize, count, matters)
|
||||
|
||||
return pager
|
||||
}
|
||||
|
||||
// handle matter page by page.
|
||||
//handle matter page by page.
|
||||
func (this *MatterDao) PageHandle(
|
||||
puuid string,
|
||||
userUuid string,
|
||||
spaceUuid string,
|
||||
name string,
|
||||
dir string,
|
||||
deleted string,
|
||||
@@ -422,13 +349,13 @@ func (this *MatterDao) PageHandle(
|
||||
}
|
||||
}
|
||||
|
||||
count, _ := this.PlainPage(0, pageSize, puuid, userUuid, spaceUuid, name, dir, deleted, deleteTimeBefore, nil, sortArray)
|
||||
count, _ := this.PlainPage(0, pageSize, puuid, userUuid, name, dir, deleted, deleteTimeBefore, nil, sortArray)
|
||||
if count > 0 {
|
||||
var totalPages = int(math.Ceil(float64(count) / float64(pageSize)))
|
||||
|
||||
var page int
|
||||
for page = 0; page < totalPages; page++ {
|
||||
_, matters := this.PlainPage(0, pageSize, puuid, userUuid, spaceUuid, name, dir, deleted, deleteTimeBefore, nil, sortArray)
|
||||
_, matters := this.PlainPage(page, pageSize, puuid, userUuid, name, dir, deleted, deleteTimeBefore, nil, sortArray)
|
||||
for _, matter := range matters {
|
||||
fun(matter)
|
||||
}
|
||||
@@ -458,9 +385,9 @@ func (this *MatterDao) Save(matter *Matter) *Matter {
|
||||
return matter
|
||||
}
|
||||
|
||||
// download time add 1
|
||||
//download time add 1
|
||||
func (this *MatterDao) TimesIncrement(matterUuid string) {
|
||||
db := core.CONTEXT.GetDB().Model(&Matter{}).Where("uuid = ?", matterUuid).Updates(map[string]interface{}{"times": gorm.Expr("times + 1"), "visit_time": time.Now()})
|
||||
db := core.CONTEXT.GetDB().Model(&Matter{}).Where("uuid = ?", matterUuid).Update(map[string]interface{}{"times": gorm.Expr("times + 1"), "visit_time": time.Now()})
|
||||
this.PanicError(db.Error)
|
||||
}
|
||||
|
||||
@@ -484,27 +411,7 @@ func (this *MatterDao) SizeByPuuidAndUserUuid(matterUuid string, userUuid string
|
||||
return sumSize
|
||||
}
|
||||
|
||||
func (this *MatterDao) SizeByPuuidAndSpaceUuid(matterUuid string, spaceUuid string) int64 {
|
||||
|
||||
var wp = &builder.WherePair{Query: "puuid = ? AND space_uuid = ?", Args: []interface{}{matterUuid, spaceUuid}}
|
||||
|
||||
var count int64
|
||||
db := core.CONTEXT.GetDB().Model(&Matter{}).Where(wp.Query, wp.Args...).Count(&count)
|
||||
if count == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
var sumSize int64
|
||||
db = core.CONTEXT.GetDB().Model(&Matter{}).Where(wp.Query, wp.Args...).Select("SUM(size)")
|
||||
this.PanicError(db.Error)
|
||||
row := db.Row()
|
||||
err := row.Scan(&sumSize)
|
||||
core.PanicError(err)
|
||||
|
||||
return sumSize
|
||||
}
|
||||
|
||||
// delete a file from db and disk.
|
||||
//delete a file from db and disk.
|
||||
func (this *MatterDao) Delete(matter *Matter) {
|
||||
|
||||
// recursive if dir
|
||||
@@ -543,20 +450,20 @@ func (this *MatterDao) Delete(matter *Matter) {
|
||||
}
|
||||
}
|
||||
|
||||
// soft delete a file or dir
|
||||
//soft delete a file or dir
|
||||
func (this *MatterDao) SoftDelete(matter *Matter) {
|
||||
|
||||
//soft delete from db.
|
||||
db := core.CONTEXT.GetDB().Model(&Matter{}).Where("uuid = ?", matter.Uuid).Updates(map[string]interface{}{"deleted": true, "delete_time": time.Now()})
|
||||
db := core.CONTEXT.GetDB().Model(&Matter{}).Where("uuid = ?", matter.Uuid).Update(map[string]interface{}{"deleted": true, "delete_time": time.Now()})
|
||||
this.PanicError(db.Error)
|
||||
|
||||
}
|
||||
|
||||
// recovery a file
|
||||
//recovery a file
|
||||
func (this *MatterDao) Recovery(matter *Matter) {
|
||||
|
||||
//recovery from db.
|
||||
db := core.CONTEXT.GetDB().Model(&Matter{}).Where("uuid = ?", matter.Uuid).Updates(map[string]interface{}{"deleted": false, "delete_time": time.Now()})
|
||||
db := core.CONTEXT.GetDB().Model(&Matter{}).Where("uuid = ?", matter.Uuid).Update(map[string]interface{}{"deleted": false, "delete_time": time.Now()})
|
||||
this.PanicError(db.Error)
|
||||
|
||||
}
|
||||
@@ -577,7 +484,7 @@ func (this *MatterDao) CountBetweenTime(startTime time.Time, endTime time.Time)
|
||||
|
||||
func (this *MatterDao) SizeBetweenTime(startTime time.Time, endTime time.Time) int64 {
|
||||
|
||||
var wp = &builder.WherePair{Query: "dir = 0 AND create_time >= ? AND create_time <= ?", Args: []interface{}{startTime, endTime}}
|
||||
var wp = &builder.WherePair{Query: "create_time >= ? AND create_time <= ?", Args: []interface{}{startTime, endTime}}
|
||||
|
||||
var count int64
|
||||
db := core.CONTEXT.GetDB().Model(&Matter{}).Where(wp.Query, wp.Args...).Count(&count)
|
||||
@@ -594,7 +501,7 @@ func (this *MatterDao) SizeBetweenTime(startTime time.Time, endTime time.Time) i
|
||||
return size
|
||||
}
|
||||
|
||||
// find by userUuid and path. if not found, return nil
|
||||
//find by userUuid and path. if not found, return nil
|
||||
func (this *MatterDao) findByUserUuidAndPath(userUuid string, path string) *Matter {
|
||||
|
||||
var wp = &builder.WherePair{Query: "user_uuid = ? AND path = ?", Args: []interface{}{userUuid, path}}
|
||||
@@ -613,7 +520,7 @@ func (this *MatterDao) findByUserUuidAndPath(userUuid string, path string) *Matt
|
||||
return matter
|
||||
}
|
||||
|
||||
// find by userUuid and path. if not found, panic
|
||||
//find by userUuid and path. if not found, panic
|
||||
func (this *MatterDao) checkByUserUuidAndPath(userUuid string, path string) *Matter {
|
||||
|
||||
if path == "" {
|
||||
@@ -660,19 +567,7 @@ func (this *MatterDao) CountByUserUuidAndPath(userUuid string, path string) int6
|
||||
|
||||
}
|
||||
|
||||
func (this *MatterDao) CountByUserUuid(userUuid string) int64 {
|
||||
|
||||
var wp = &builder.WherePair{Query: "user_uuid = ?", Args: []interface{}{userUuid}}
|
||||
|
||||
var count int64
|
||||
db := core.CONTEXT.GetDB().Model(&Matter{}).Where(wp.Query, wp.Args...).Count(&count)
|
||||
core.PanicError(db.Error)
|
||||
|
||||
return count
|
||||
|
||||
}
|
||||
|
||||
// 统计总共有多少条。
|
||||
//统计总共有多少条。
|
||||
func (this *MatterDao) Count() int64 {
|
||||
|
||||
var count int64
|
||||
@@ -683,7 +578,7 @@ func (this *MatterDao) Count() int64 {
|
||||
|
||||
}
|
||||
|
||||
// System cleanup.
|
||||
//System cleanup.
|
||||
func (this *MatterDao) Cleanup() {
|
||||
this.logger.Info("[MatterDao] clean up. Delete all Matter record in db and on disk.")
|
||||
db := core.CONTEXT.GetDB().Where("uuid is not null").Delete(Matter{})
|
||||
|
||||
@@ -30,57 +30,55 @@ const (
|
||||
* file is too common. so we use matter as file.
|
||||
*/
|
||||
type Matter struct {
|
||||
Uuid string `json:"uuid" gorm:"type:char(36);primary_key;unique"`
|
||||
Sort int64 `json:"sort" gorm:"type:bigint(20) not null"`
|
||||
UpdateTime time.Time `json:"updateTime" gorm:"type:timestamp not null;default:CURRENT_TIMESTAMP"`
|
||||
CreateTime time.Time `json:"createTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"`
|
||||
Puuid string `json:"puuid" gorm:"type:char(36);index:idx_puuid"` //index should unique globally.
|
||||
Base
|
||||
Puuid string `json:"puuid" gorm:"type:char(36);index:idx_puuid"`
|
||||
UserUuid string `json:"userUuid" gorm:"type:char(36);index:idx_uu"`
|
||||
//TODO: check field usage.
|
||||
SpaceName string `json:"space_name" gorm:"type:varchar(45) not null"`
|
||||
Username string `json:"username" gorm:"type:varchar(45) not null"`
|
||||
Dir bool `json:"dir" gorm:"type:tinyint(1) not null;default:0"`
|
||||
Name string `json:"name" gorm:"type:varchar(255) not null"`
|
||||
Md5 string `json:"md5" gorm:"type:varchar(45)"`
|
||||
Md5 string `json:"md5" gorm:"type:varchar(512)"`
|
||||
Size int64 `json:"size" gorm:"type:bigint(20) not null;default:0"`
|
||||
Privacy bool `json:"privacy" gorm:"type:tinyint(1) not null;default:0"`
|
||||
Path string `json:"path" gorm:"type:varchar(1024)"`
|
||||
Times int64 `json:"times" gorm:"type:bigint(20) not null;default:0"`
|
||||
Parent *Matter `json:"parent" gorm:"-"`
|
||||
Children []*Matter `json:"-" gorm:"-"`
|
||||
Prop string `json:"prop" gorm:"type:varchar(1024) not null;default:'{}'"`
|
||||
VisitTime time.Time `json:"visitTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"`
|
||||
Deleted bool `json:"deleted" gorm:"type:tinyint(1) not null;index:idx_del;default:0"`
|
||||
DeleteTime time.Time `json:"deleteTime" gorm:"type:timestamp not null;index:idx_delt;default:'2018-01-01 00:00:00'"`
|
||||
SpaceUuid string `json:"spaceUuid" gorm:"type:char(36) not null;index:idx_space_uuid"`
|
||||
User *User `json:"user" gorm:"-"`
|
||||
Parent *Matter `json:"parent" gorm:"-"`
|
||||
Children []*Matter `json:"-" gorm:"-"`
|
||||
}
|
||||
|
||||
// set File's table name to be `profiles`
|
||||
func (Matter) TableName() string {
|
||||
return core.TABLE_PREFIX + "matter"
|
||||
}
|
||||
|
||||
// get matter's absolute path. the Path property is relative path in db.
|
||||
func (this *Matter) AbsolutePath() string {
|
||||
return GetSpaceMatterRootDir(this.SpaceName) + this.Path
|
||||
return GetUserMatterRootDir(this.Username) + this.Path
|
||||
}
|
||||
|
||||
func (this *Matter) MimeType() string {
|
||||
return util.GetMimeType(util.GetExtension(this.Name))
|
||||
}
|
||||
|
||||
// Create a root matter. It's convenient for copy and move
|
||||
func NewRootMatter(space *Space) *Matter {
|
||||
//Create a root matter. It's convenient for copy and move
|
||||
func NewRootMatter(user *User) *Matter {
|
||||
matter := &Matter{}
|
||||
matter.Uuid = MATTER_ROOT
|
||||
matter.UserUuid = space.UserUuid
|
||||
matter.SpaceUuid = space.Uuid
|
||||
matter.SpaceName = space.Name
|
||||
matter.UserUuid = user.Uuid
|
||||
matter.Username = user.Username
|
||||
matter.Dir = true
|
||||
matter.Path = ""
|
||||
matter.CreateTime = space.CreateTime
|
||||
matter.UpdateTime = space.UpdateTime
|
||||
matter.VisitTime = space.UpdateTime
|
||||
matter.CreateTime = user.CreateTime
|
||||
matter.UpdateTime = user.UpdateTime
|
||||
matter.VisitTime = user.UpdateTime
|
||||
|
||||
return matter
|
||||
}
|
||||
|
||||
// get user's space absolute path
|
||||
//get user's space absolute path
|
||||
func GetUserSpaceRootDir(username string) (rootDirPath string) {
|
||||
|
||||
rootDirPath = fmt.Sprintf("%s/%s", core.CONFIG.MatterPath(), username)
|
||||
@@ -88,31 +86,31 @@ func GetUserSpaceRootDir(username string) (rootDirPath string) {
|
||||
return rootDirPath
|
||||
}
|
||||
|
||||
// get user's root absolute path
|
||||
func GetSpaceMatterRootDir(spaceName string) (rootDirPath string) {
|
||||
//get user's root absolute path
|
||||
func GetUserMatterRootDir(username string) (rootDirPath string) {
|
||||
|
||||
rootDirPath = fmt.Sprintf("%s/%s/%s", core.CONFIG.MatterPath(), spaceName, MATTER_ROOT)
|
||||
rootDirPath = fmt.Sprintf("%s/%s/%s", core.CONFIG.MatterPath(), username, MATTER_ROOT)
|
||||
|
||||
return rootDirPath
|
||||
}
|
||||
|
||||
// get user's cache absolute path
|
||||
func GetSpaceCacheRootDir(spaceName string) (rootDirPath string) {
|
||||
//get user's cache absolute path
|
||||
func GetUserCacheRootDir(username string) (rootDirPath string) {
|
||||
|
||||
rootDirPath = fmt.Sprintf("%s/%s/%s", core.CONFIG.MatterPath(), spaceName, MATTER_CACHE)
|
||||
rootDirPath = fmt.Sprintf("%s/%s/%s", core.CONFIG.MatterPath(), username, MATTER_CACHE)
|
||||
|
||||
return rootDirPath
|
||||
}
|
||||
|
||||
// get user's zip absolute path
|
||||
func GetSpaceZipRootDir(spaceName string) (rootDirPath string) {
|
||||
//get user's zip absolute path
|
||||
func GetUserZipRootDir(username string) (rootDirPath string) {
|
||||
|
||||
rootDirPath = fmt.Sprintf("%s/%s/%s", core.CONFIG.MatterPath(), spaceName, MATTER_ZIP)
|
||||
rootDirPath = fmt.Sprintf("%s/%s/%s", core.CONFIG.MatterPath(), username, MATTER_ZIP)
|
||||
|
||||
return rootDirPath
|
||||
}
|
||||
|
||||
// check matter's name. If error, panic.
|
||||
//check matter's name. If error, panic.
|
||||
func CheckMatterName(request *http.Request, name string) string {
|
||||
|
||||
if name == "" {
|
||||
@@ -131,7 +129,7 @@ func CheckMatterName(request *http.Request, name string) string {
|
||||
return name
|
||||
}
|
||||
|
||||
// fetch the props
|
||||
//fetch the props
|
||||
func (this *Matter) FetchPropMap() map[string]string {
|
||||
|
||||
m := make(map[string]string)
|
||||
@@ -148,12 +146,13 @@ func (this *Matter) FetchPropMap() map[string]string {
|
||||
return m
|
||||
}
|
||||
|
||||
// fetch the props
|
||||
//fetch the props
|
||||
func (this *Matter) SetPropMap(propMap map[string]string) {
|
||||
|
||||
b, err := jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(propMap)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
this.Prop = string(b)
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"github.com/eyebluecn/tank/code/tool/util"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
@@ -28,7 +27,6 @@ import (
|
||||
type MatterService struct {
|
||||
BaseBean
|
||||
matterDao *MatterDao
|
||||
spaceDao *SpaceDao
|
||||
userDao *UserDao
|
||||
userService *UserService
|
||||
imageCacheDao *ImageCacheDao
|
||||
@@ -49,11 +47,6 @@ func (this *MatterService) Init() {
|
||||
this.userDao = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.spaceDao)
|
||||
if b, ok := b.(*SpaceDao); ok {
|
||||
this.spaceDao = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.userService)
|
||||
if b, ok := b.(*UserService); ok {
|
||||
this.userService = b
|
||||
@@ -76,68 +69,7 @@ func (this *MatterService) Init() {
|
||||
|
||||
}
|
||||
|
||||
// get the page of matters.
|
||||
func (this *MatterService) Page(
|
||||
request *http.Request,
|
||||
page int,
|
||||
pageSize int,
|
||||
orderCreateTime string,
|
||||
orderUpdateTime string,
|
||||
orderDeleteTime string,
|
||||
orderSort string,
|
||||
orderTimes string,
|
||||
orderDir string,
|
||||
orderSize string,
|
||||
orderName string,
|
||||
puuid string,
|
||||
name string,
|
||||
dir string,
|
||||
deleted string,
|
||||
extensions []string,
|
||||
spaceUuid string,
|
||||
) *Pager {
|
||||
|
||||
sortArray := []builder.OrderPair{
|
||||
{
|
||||
Key: "dir",
|
||||
Value: orderDir,
|
||||
},
|
||||
{
|
||||
Key: "create_time",
|
||||
Value: orderCreateTime,
|
||||
},
|
||||
{
|
||||
Key: "update_time",
|
||||
Value: orderUpdateTime,
|
||||
},
|
||||
{
|
||||
Key: "delete_time",
|
||||
Value: orderDeleteTime,
|
||||
},
|
||||
{
|
||||
Key: "sort",
|
||||
Value: orderSort,
|
||||
},
|
||||
{
|
||||
Key: "size",
|
||||
Value: orderSize,
|
||||
},
|
||||
{
|
||||
Key: "name",
|
||||
Value: orderName,
|
||||
},
|
||||
{
|
||||
Key: "times",
|
||||
Value: orderTimes,
|
||||
},
|
||||
}
|
||||
|
||||
pager := this.matterDao.Page(page, pageSize, puuid, "", spaceUuid, name, dir, deleted, extensions, sortArray)
|
||||
|
||||
return pager
|
||||
}
|
||||
|
||||
// Download. Support chunk download.
|
||||
//Download. Support chunk download.
|
||||
func (this *MatterService) DownloadFile(
|
||||
writer http.ResponseWriter,
|
||||
request *http.Request,
|
||||
@@ -148,7 +80,7 @@ func (this *MatterService) DownloadFile(
|
||||
download.DownloadFile(writer, request, filePath, filename, withContentDisposition)
|
||||
}
|
||||
|
||||
// Download specified matters. matters must have the same puuid.
|
||||
//Download specified matters. matters must have the same puuid.
|
||||
func (this *MatterService) DownloadZip(
|
||||
writer http.ResponseWriter,
|
||||
request *http.Request,
|
||||
@@ -195,7 +127,7 @@ func (this *MatterService) DownloadZip(
|
||||
}
|
||||
|
||||
//prepare the temp zip dir
|
||||
destZipDirPath := fmt.Sprintf("%s/%d", GetSpaceZipRootDir(matters[0].SpaceName), time.Now().UnixNano()/1e6)
|
||||
destZipDirPath := fmt.Sprintf("%s/%d", GetUserZipRootDir(matters[0].Username), time.Now().UnixNano()/1e6)
|
||||
util.MakeDirAll(destZipDirPath)
|
||||
|
||||
destZipName := fmt.Sprintf("%s.zip", matters[0].Name)
|
||||
@@ -218,7 +150,7 @@ func (this *MatterService) DownloadZip(
|
||||
|
||||
}
|
||||
|
||||
// zip matters.
|
||||
//zip matters.
|
||||
func (this *MatterService) zipMatters(request *http.Request, matters []*Matter, destPath string) {
|
||||
|
||||
if util.PathExists(destPath) {
|
||||
@@ -311,8 +243,8 @@ func (this *MatterService) zipMatters(request *http.Request, matters []*Matter,
|
||||
}
|
||||
}
|
||||
|
||||
// delete files.
|
||||
func (this *MatterService) Delete(request *http.Request, matter *Matter, user *User, space *Space) {
|
||||
//delete files.
|
||||
func (this *MatterService) Delete(request *http.Request, matter *Matter, user *User) {
|
||||
|
||||
if matter == nil {
|
||||
panic(result.BadRequest("matter cannot be nil"))
|
||||
@@ -321,10 +253,10 @@ func (this *MatterService) Delete(request *http.Request, matter *Matter, user *U
|
||||
this.matterDao.Delete(matter)
|
||||
|
||||
//re compute the size of Route.
|
||||
this.ComputeRouteSize(matter.Puuid, user, space)
|
||||
this.ComputeRouteSize(matter.Puuid, user)
|
||||
}
|
||||
|
||||
// soft delete files.
|
||||
//soft delete files.
|
||||
func (this *MatterService) SoftDelete(request *http.Request, matter *Matter, user *User) {
|
||||
|
||||
if matter == nil {
|
||||
@@ -339,7 +271,7 @@ func (this *MatterService) SoftDelete(request *http.Request, matter *Matter, use
|
||||
//no need to recompute size.
|
||||
}
|
||||
|
||||
// recovery delete files.
|
||||
//recovery delete files.
|
||||
func (this *MatterService) Recovery(request *http.Request, matter *Matter, user *User) {
|
||||
|
||||
if matter == nil {
|
||||
@@ -354,8 +286,8 @@ func (this *MatterService) Recovery(request *http.Request, matter *Matter, user
|
||||
//no need to recompute size.
|
||||
}
|
||||
|
||||
// atomic delete files
|
||||
func (this *MatterService) AtomicDelete(request *http.Request, matter *Matter, user *User, space *Space) {
|
||||
//atomic delete files
|
||||
func (this *MatterService) AtomicDelete(request *http.Request, matter *Matter, user *User) {
|
||||
|
||||
if matter == nil {
|
||||
panic(result.BadRequest("matter cannot be nil"))
|
||||
@@ -365,11 +297,11 @@ func (this *MatterService) AtomicDelete(request *http.Request, matter *Matter, u
|
||||
this.userService.MatterLock(matter.UserUuid)
|
||||
defer this.userService.MatterUnlock(matter.UserUuid)
|
||||
|
||||
this.Delete(request, matter, user, space)
|
||||
this.Delete(request, matter, user)
|
||||
}
|
||||
|
||||
// atomic soft delete files
|
||||
func (this *MatterService) AtomicSoftDelete(request *http.Request, matter *Matter, user *User, space *Space) {
|
||||
//atomic soft delete files
|
||||
func (this *MatterService) AtomicSoftDelete(request *http.Request, matter *Matter, user *User) {
|
||||
|
||||
if matter == nil {
|
||||
panic(result.BadRequest("matter cannot be nil"))
|
||||
@@ -386,14 +318,14 @@ func (this *MatterService) AtomicSoftDelete(request *http.Request, matter *Matte
|
||||
//if disabled the recycle feature. then we hard delete.
|
||||
preference := this.preferenceService.Fetch()
|
||||
if preference.DeletedKeepDays == 0 {
|
||||
this.Delete(request, matter, user, space)
|
||||
this.Delete(request, matter, user)
|
||||
} else {
|
||||
this.SoftDelete(request, matter, user)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// atomic recovery delete files
|
||||
//atomic recovery delete files
|
||||
func (this *MatterService) AtomicRecovery(request *http.Request, matter *Matter, user *User) {
|
||||
|
||||
if matter == nil {
|
||||
@@ -411,8 +343,8 @@ func (this *MatterService) AtomicRecovery(request *http.Request, matter *Matter,
|
||||
this.Recovery(request, matter, user)
|
||||
}
|
||||
|
||||
// upload files.
|
||||
func (this *MatterService) Upload(request *http.Request, file io.Reader, fileHeader *multipart.FileHeader, user *User, space *Space, dirMatter *Matter, filename string, privacy bool) *Matter {
|
||||
//upload files.
|
||||
func (this *MatterService) Upload(request *http.Request, file io.Reader, user *User, dirMatter *Matter, filename string, privacy bool) *Matter {
|
||||
|
||||
if user == nil {
|
||||
panic(result.BadRequest("user cannot be nil."))
|
||||
@@ -430,26 +362,9 @@ func (this *MatterService) Upload(request *http.Request, file io.Reader, fileHea
|
||||
panic(result.BadRequestI18n(request, i18n.MatterNameLengthExceedLimit, len(filename), MATTER_NAME_MAX_LENGTH))
|
||||
}
|
||||
|
||||
//if fileHeader.Size not nill . check size in advance.
|
||||
if fileHeader != nil {
|
||||
//check the size limit.
|
||||
if space.SizeLimit >= 0 {
|
||||
if fileHeader.Size > space.SizeLimit {
|
||||
panic(result.BadRequestI18n(request, i18n.MatterSizeExceedLimit, util.HumanFileSize(fileHeader.Size), util.HumanFileSize(space.SizeLimit)))
|
||||
}
|
||||
}
|
||||
|
||||
//check total size.
|
||||
if space.TotalSizeLimit >= 0 {
|
||||
if space.TotalSize+fileHeader.Size > space.TotalSizeLimit {
|
||||
panic(result.BadRequestI18n(request, i18n.MatterSizeExceedTotalLimit, util.HumanFileSize(space.TotalSize), util.HumanFileSize(space.TotalSizeLimit)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dirAbsolutePath := dirMatter.AbsolutePath()
|
||||
|
||||
count := this.matterDao.CountBySpaceUuidAndPuuidAndDirAndName(space.Uuid, dirMatter.Uuid, false, filename)
|
||||
count := this.matterDao.CountByUserUuidAndPuuidAndDirAndName(user.Uuid, dirMatter.Uuid, false, filename)
|
||||
if count > 0 {
|
||||
panic(result.BadRequestI18n(request, i18n.MatterExist, filename))
|
||||
}
|
||||
@@ -468,53 +383,47 @@ func (this *MatterService) Upload(request *http.Request, file io.Reader, fileHea
|
||||
|
||||
destFile, err := os.OpenFile(fileAbsolutePath, os.O_WRONLY|os.O_CREATE, 0777)
|
||||
this.PanicError(err)
|
||||
closeDestFile := func() {
|
||||
|
||||
defer func() {
|
||||
err := destFile.Close()
|
||||
this.PanicError(err)
|
||||
}
|
||||
}()
|
||||
|
||||
fileSize, err := io.Copy(destFile, file)
|
||||
this.PanicError(err)
|
||||
|
||||
this.logger.Info("upload %s %v ", filename, util.HumanFileSize(fileSize))
|
||||
|
||||
if fileHeader == nil {
|
||||
//check the size limit.
|
||||
if space.SizeLimit >= 0 {
|
||||
if fileSize > space.SizeLimit {
|
||||
closeDestFile()
|
||||
//check the size limit.
|
||||
if user.SizeLimit >= 0 {
|
||||
if fileSize > user.SizeLimit {
|
||||
//delete the file on disk.
|
||||
err = os.Remove(fileAbsolutePath)
|
||||
this.PanicError(err)
|
||||
|
||||
//delete the file on disk.
|
||||
err = os.Remove(fileAbsolutePath)
|
||||
this.PanicError(err)
|
||||
|
||||
panic(result.BadRequestI18n(request, i18n.MatterSizeExceedLimit, util.HumanFileSize(fileSize), util.HumanFileSize(space.SizeLimit)))
|
||||
}
|
||||
}
|
||||
|
||||
//check total size.
|
||||
if space.TotalSizeLimit >= 0 {
|
||||
if space.TotalSize+fileSize > space.TotalSizeLimit {
|
||||
closeDestFile()
|
||||
|
||||
//delete the file on disk.
|
||||
err = os.Remove(fileAbsolutePath)
|
||||
this.PanicError(err)
|
||||
|
||||
panic(result.BadRequestI18n(request, i18n.MatterSizeExceedTotalLimit, util.HumanFileSize(space.TotalSize), util.HumanFileSize(space.TotalSizeLimit)))
|
||||
}
|
||||
panic(result.BadRequestI18n(request, i18n.MatterSizeExceedLimit, util.HumanFileSize(fileSize), util.HumanFileSize(user.SizeLimit)))
|
||||
}
|
||||
}
|
||||
|
||||
closeDestFile()
|
||||
//check total size.
|
||||
if user.TotalSizeLimit >= 0 {
|
||||
if user.TotalSize+fileSize > user.TotalSizeLimit {
|
||||
|
||||
matter := this.createNonDirMatter(dirMatter, filename, fileSize, privacy, user, space)
|
||||
//delete the file on disk.
|
||||
err = os.Remove(fileAbsolutePath)
|
||||
this.PanicError(err)
|
||||
|
||||
panic(result.BadRequestI18n(request, i18n.MatterSizeExceedTotalLimit, util.HumanFileSize(user.TotalSize), util.HumanFileSize(user.TotalSizeLimit)))
|
||||
}
|
||||
}
|
||||
|
||||
matter := this.createNonDirMatter(dirMatter, filename, fileSize, privacy, user)
|
||||
|
||||
return matter
|
||||
}
|
||||
|
||||
// create a non dir matter.
|
||||
func (this *MatterService) createNonDirMatter(dirMatter *Matter, filename string, fileSize int64, privacy bool, user *User, space *Space) *Matter {
|
||||
func (this *MatterService) createNonDirMatter(dirMatter *Matter, filename string, fileSize int64, privacy bool, user *User) *Matter {
|
||||
dirRelativePath := dirMatter.Path
|
||||
fileRelativePath := dirRelativePath + "/" + filename
|
||||
|
||||
@@ -522,8 +431,7 @@ func (this *MatterService) createNonDirMatter(dirMatter *Matter, filename string
|
||||
matter := &Matter{
|
||||
Puuid: dirMatter.Uuid,
|
||||
UserUuid: user.Uuid,
|
||||
SpaceName: space.Name,
|
||||
SpaceUuid: space.Uuid,
|
||||
Username: user.Username,
|
||||
Dir: false,
|
||||
Name: filename,
|
||||
Md5: "",
|
||||
@@ -537,14 +445,14 @@ func (this *MatterService) createNonDirMatter(dirMatter *Matter, filename string
|
||||
|
||||
//compute the size of directory
|
||||
go core.RunWithRecovery(func() {
|
||||
this.ComputeRouteSize(dirMatter.Uuid, user, space)
|
||||
this.ComputeRouteSize(dirMatter.Uuid, user)
|
||||
})
|
||||
|
||||
return matter
|
||||
}
|
||||
|
||||
// create a non dir matter.
|
||||
func (this *MatterService) updateNonDirMatter(matter *Matter, fileSize int64, user *User, space *Space) *Matter {
|
||||
func (this *MatterService) updateNonDirMatter(matter *Matter, fileSize int64, user *User) *Matter {
|
||||
|
||||
matter.Size = fileSize
|
||||
|
||||
@@ -552,24 +460,25 @@ func (this *MatterService) updateNonDirMatter(matter *Matter, fileSize int64, us
|
||||
|
||||
//compute the size of directory
|
||||
go core.RunWithRecovery(func() {
|
||||
this.ComputeRouteSize(matter.Puuid, user, space)
|
||||
this.ComputeRouteSize(matter.Puuid, user)
|
||||
})
|
||||
|
||||
return matter
|
||||
}
|
||||
|
||||
// compute route size. It will compute upward until root directory
|
||||
func (this *MatterService) ComputeRouteSize(matterUuid string, user *User, space *Space) {
|
||||
func (this *MatterService) ComputeRouteSize(matterUuid string, user *User) {
|
||||
|
||||
//if to root directory, then update to user's info.
|
||||
if matterUuid == MATTER_ROOT {
|
||||
|
||||
size := this.matterDao.SizeByPuuidAndSpaceUuid(MATTER_ROOT, space.Uuid)
|
||||
size := this.matterDao.SizeByPuuidAndUserUuid(MATTER_ROOT, user.Uuid)
|
||||
|
||||
this.spaceDao.UpdateTotalSize(space.Uuid, size)
|
||||
db := core.CONTEXT.GetDB().Model(&User{}).Where("uuid = ?", user.Uuid).Update("total_size", size)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
//update user total size info in cache.
|
||||
space.TotalSize = size
|
||||
user.TotalSize = size
|
||||
|
||||
return
|
||||
}
|
||||
@@ -579,63 +488,66 @@ func (this *MatterService) ComputeRouteSize(matterUuid string, user *User, space
|
||||
//only compute dir
|
||||
if matter.Dir {
|
||||
//compute the total size.
|
||||
size := this.matterDao.SizeByPuuidAndSpaceUuid(matterUuid, space.Uuid)
|
||||
size := this.matterDao.SizeByPuuidAndUserUuid(matterUuid, user.Uuid)
|
||||
|
||||
//when changed, we update
|
||||
if matter.Size != size {
|
||||
this.spaceDao.UpdateTotalSize(space.Uuid, size)
|
||||
db := core.CONTEXT.GetDB().Model(&Matter{}).Where("uuid = ?", matterUuid).Update("size", size)
|
||||
this.PanicError(db.Error)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//update parent recursively.
|
||||
this.ComputeRouteSize(matter.Puuid, user, space)
|
||||
this.ComputeRouteSize(matter.Puuid, user)
|
||||
}
|
||||
|
||||
// compute all dir's size.
|
||||
func (this *MatterService) ComputeAllDirSize(user *User, space *Space) {
|
||||
func (this *MatterService) ComputeAllDirSize(user *User) {
|
||||
|
||||
this.logger.Info("Compute all dir's size for user %s %s", user.Uuid, user.Username)
|
||||
|
||||
rootMatter := NewRootMatter(space)
|
||||
this.ComputeDirSize(rootMatter, user, space)
|
||||
rootMatter := NewRootMatter(user)
|
||||
this.ComputeDirSize(rootMatter, user)
|
||||
}
|
||||
|
||||
// compute a dir's size.
|
||||
func (this *MatterService) ComputeDirSize(dirMatter *Matter, user *User, space *Space) {
|
||||
func (this *MatterService) ComputeDirSize(dirMatter *Matter, user *User) {
|
||||
|
||||
this.logger.Info("Compute dir's size %s %s", dirMatter.Uuid, dirMatter.Name)
|
||||
|
||||
//update sub dir first
|
||||
childrenDirMatters := this.matterDao.FindByUserUuidAndPuuidAndDirTrue(user.Uuid, dirMatter.Uuid)
|
||||
for _, childrenDirMatter := range childrenDirMatters {
|
||||
this.ComputeDirSize(childrenDirMatter, user, space)
|
||||
this.ComputeDirSize(childrenDirMatter, user)
|
||||
}
|
||||
|
||||
//if to root directory, then update to user's info.
|
||||
if dirMatter.Uuid == MATTER_ROOT {
|
||||
|
||||
size := this.matterDao.SizeByPuuidAndSpaceUuid(MATTER_ROOT, space.Uuid)
|
||||
size := this.matterDao.SizeByPuuidAndUserUuid(MATTER_ROOT, user.Uuid)
|
||||
|
||||
this.spaceDao.UpdateTotalSize(space.Uuid, size)
|
||||
db := core.CONTEXT.GetDB().Model(&User{}).Where("uuid = ?", user.Uuid).Update("total_size", size)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
//update user total size info in cache.
|
||||
space.TotalSize = size
|
||||
user.TotalSize = size
|
||||
} else {
|
||||
|
||||
//compute self.
|
||||
size := this.matterDao.SizeByPuuidAndSpaceUuid(dirMatter.Uuid, user.Uuid)
|
||||
size := this.matterDao.SizeByPuuidAndUserUuid(dirMatter.Uuid, user.Uuid)
|
||||
|
||||
//when changed, we update
|
||||
if dirMatter.Size != size {
|
||||
this.spaceDao.UpdateTotalSize(space.Uuid, size)
|
||||
db := core.CONTEXT.GetDB().Model(&Matter{}).Where("uuid = ?", dirMatter.Uuid).Update("size", size)
|
||||
this.PanicError(db.Error)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// inner create directory.
|
||||
func (this *MatterService) createDirectory(request *http.Request, dirMatter *Matter, name string, user *User, space *Space) *Matter {
|
||||
//inner create directory.
|
||||
func (this *MatterService) createDirectory(request *http.Request, dirMatter *Matter, name string, user *User) *Matter {
|
||||
|
||||
if dirMatter == nil {
|
||||
panic(result.BadRequest("dirMatter cannot be nil"))
|
||||
@@ -649,9 +561,9 @@ func (this *MatterService) createDirectory(request *http.Request, dirMatter *Mat
|
||||
panic(result.BadRequest("Dir has been deleted. Cannot create dir under it."))
|
||||
}
|
||||
|
||||
if dirMatter.SpaceUuid != space.Uuid {
|
||||
if dirMatter.UserUuid != user.Uuid {
|
||||
|
||||
panic(result.BadRequest("file's space not the same"))
|
||||
panic(result.BadRequest("file's user not the same"))
|
||||
}
|
||||
|
||||
name = strings.TrimSpace(name)
|
||||
@@ -670,7 +582,7 @@ func (this *MatterService) createDirectory(request *http.Request, dirMatter *Mat
|
||||
}
|
||||
|
||||
//if exist. return.
|
||||
matter := this.matterDao.FindBySpaceNameAndPuuidAndDirAndName(space.Name, dirMatter.Uuid, TRUE, name)
|
||||
matter := this.matterDao.FindByUserUuidAndPuuidAndDirAndName(user.Uuid, dirMatter.Uuid, TRUE, name)
|
||||
if matter != nil {
|
||||
return matter
|
||||
}
|
||||
@@ -681,7 +593,7 @@ func (this *MatterService) createDirectory(request *http.Request, dirMatter *Mat
|
||||
panic(result.BadRequestI18n(request, i18n.MatterDepthExceedLimit, len(parts), MATTER_NAME_MAX_DEPTH))
|
||||
}
|
||||
|
||||
absolutePath := GetSpaceMatterRootDir(space.Name) + dirMatter.Path + "/" + name
|
||||
absolutePath := GetUserMatterRootDir(user.Username) + dirMatter.Path + "/" + name
|
||||
|
||||
relativePath := dirMatter.Path + "/" + name
|
||||
|
||||
@@ -693,8 +605,7 @@ func (this *MatterService) createDirectory(request *http.Request, dirMatter *Mat
|
||||
matter = &Matter{
|
||||
Puuid: dirMatter.Uuid,
|
||||
UserUuid: user.Uuid,
|
||||
SpaceUuid: space.Uuid,
|
||||
SpaceName: space.Name,
|
||||
Username: user.Username,
|
||||
Dir: true,
|
||||
Name: name,
|
||||
Path: relativePath,
|
||||
@@ -706,7 +617,7 @@ func (this *MatterService) createDirectory(request *http.Request, dirMatter *Mat
|
||||
return matter
|
||||
}
|
||||
|
||||
func (this *MatterService) AtomicCreateDirectory(request *http.Request, dirMatter *Matter, name string, user *User, space *Space) *Matter {
|
||||
func (this *MatterService) AtomicCreateDirectory(request *http.Request, dirMatter *Matter, name string, user *User) *Matter {
|
||||
|
||||
if dirMatter.Deleted {
|
||||
panic(result.BadRequest("Dir has been deleted. Cannot create sub dir under it."))
|
||||
@@ -715,20 +626,20 @@ func (this *MatterService) AtomicCreateDirectory(request *http.Request, dirMatte
|
||||
this.userService.MatterLock(user.Uuid)
|
||||
defer this.userService.MatterUnlock(user.Uuid)
|
||||
|
||||
matter := this.createDirectory(request, dirMatter, name, user, space)
|
||||
matter := this.createDirectory(request, dirMatter, name, user)
|
||||
|
||||
return matter
|
||||
}
|
||||
|
||||
// copy or move may overwrite.
|
||||
func (this *MatterService) handleOverwrite(request *http.Request, user *User, space *Space, destinationPath string, overwrite bool) {
|
||||
//copy or move may overwrite.
|
||||
func (this *MatterService) handleOverwrite(request *http.Request, user *User, destinationPath string, overwrite bool) {
|
||||
|
||||
destMatter := this.matterDao.findByUserUuidAndPath(user.Uuid, destinationPath)
|
||||
if destMatter != nil {
|
||||
//if exist
|
||||
if overwrite {
|
||||
//delete.
|
||||
this.Delete(request, destMatter, user, space)
|
||||
this.Delete(request, destMatter, user)
|
||||
} else {
|
||||
//throw precondition failed. (RFC4918:10.6)
|
||||
panic(result.CustomWebResult(result.PRECONDITION_FAILED, fmt.Sprintf("%s exists", destMatter.Path)))
|
||||
@@ -737,8 +648,8 @@ func (this *MatterService) handleOverwrite(request *http.Request, user *User, sp
|
||||
|
||||
}
|
||||
|
||||
// move srcMatter to destMatter. invoker must handled the overwrite and lock.
|
||||
func (this *MatterService) move(request *http.Request, srcMatter *Matter, destDirMatter *Matter, user *User, space *Space) {
|
||||
//move srcMatter to destMatter. invoker must handled the overwrite and lock.
|
||||
func (this *MatterService) move(request *http.Request, srcMatter *Matter, destDirMatter *Matter, user *User) {
|
||||
|
||||
if srcMatter == nil {
|
||||
panic(result.BadRequest("srcMatter cannot be nil."))
|
||||
@@ -793,13 +704,13 @@ func (this *MatterService) move(request *http.Request, srcMatter *Matter, destDi
|
||||
}
|
||||
|
||||
//reCompute the size of src and dest.
|
||||
this.ComputeRouteSize(srcPuuid, user, space)
|
||||
this.ComputeRouteSize(destDirUuid, user, space)
|
||||
this.ComputeRouteSize(srcPuuid, user)
|
||||
this.ComputeRouteSize(destDirUuid, user)
|
||||
|
||||
}
|
||||
|
||||
// move srcMatter to destMatter(must be dir)
|
||||
func (this *MatterService) AtomicMove(request *http.Request, srcMatter *Matter, destDirMatter *Matter, overwrite bool, user *User, space *Space) {
|
||||
//move srcMatter to destMatter(must be dir)
|
||||
func (this *MatterService) AtomicMove(request *http.Request, srcMatter *Matter, destDirMatter *Matter, overwrite bool, user *User) {
|
||||
|
||||
if srcMatter == nil {
|
||||
panic(result.BadRequest("srcMatter cannot be nil."))
|
||||
@@ -827,14 +738,14 @@ func (this *MatterService) AtomicMove(request *http.Request, srcMatter *Matter,
|
||||
|
||||
//handle the overwrite
|
||||
destinationPath := destDirMatter.Path + "/" + srcMatter.Name
|
||||
this.handleOverwrite(request, user, space, destinationPath, overwrite)
|
||||
this.handleOverwrite(request, user, destinationPath, overwrite)
|
||||
|
||||
//do the move operation.
|
||||
this.move(request, srcMatter, destDirMatter, user, space)
|
||||
this.move(request, srcMatter, destDirMatter, user)
|
||||
}
|
||||
|
||||
// move srcMatters to destMatter(must be dir)
|
||||
func (this *MatterService) AtomicMoveBatch(request *http.Request, srcMatters []*Matter, destDirMatter *Matter, user *User, space *Space) {
|
||||
//move srcMatters to destMatter(must be dir)
|
||||
func (this *MatterService) AtomicMoveBatch(request *http.Request, srcMatters []*Matter, destDirMatter *Matter, user *User) {
|
||||
|
||||
if destDirMatter == nil {
|
||||
panic(result.BadRequest("destDirMatter cannot be nil."))
|
||||
@@ -865,12 +776,12 @@ func (this *MatterService) AtomicMoveBatch(request *http.Request, srcMatters []*
|
||||
}
|
||||
|
||||
for _, srcMatter := range srcMatters {
|
||||
this.move(request, srcMatter, destDirMatter, user, space)
|
||||
this.move(request, srcMatter, destDirMatter, user)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// copy srcMatter to destMatter. invoker must handled the overwrite and lock.
|
||||
//copy srcMatter to destMatter. invoker must handled the overwrite and lock.
|
||||
func (this *MatterService) copy(request *http.Request, srcMatter *Matter, destDirMatter *Matter, name string) {
|
||||
|
||||
this.logger.Info("copy srcPath = %s destPath = %s/%s", srcMatter.Path, destDirMatter.Path, name)
|
||||
@@ -880,7 +791,7 @@ func (this *MatterService) copy(request *http.Request, srcMatter *Matter, destDi
|
||||
newMatter := &Matter{
|
||||
Puuid: destDirMatter.Uuid,
|
||||
UserUuid: srcMatter.UserUuid,
|
||||
SpaceName: srcMatter.SpaceName,
|
||||
Username: srcMatter.Username,
|
||||
Dir: srcMatter.Dir,
|
||||
Name: name,
|
||||
Md5: "",
|
||||
@@ -913,7 +824,7 @@ func (this *MatterService) copy(request *http.Request, srcMatter *Matter, destDi
|
||||
newMatter := &Matter{
|
||||
Puuid: destDirMatter.Uuid,
|
||||
UserUuid: srcMatter.UserUuid,
|
||||
SpaceName: srcMatter.SpaceName,
|
||||
Username: srcMatter.Username,
|
||||
Dir: srcMatter.Dir,
|
||||
Name: name,
|
||||
Md5: "",
|
||||
@@ -928,8 +839,8 @@ func (this *MatterService) copy(request *http.Request, srcMatter *Matter, destDi
|
||||
}
|
||||
}
|
||||
|
||||
// copy srcMatter to destMatter.
|
||||
func (this *MatterService) AtomicCopy(request *http.Request, srcMatter *Matter, destDirMatter *Matter, name string, overwrite bool, user *User, space *Space) {
|
||||
//copy srcMatter to destMatter.
|
||||
func (this *MatterService) AtomicCopy(request *http.Request, srcMatter *Matter, destDirMatter *Matter, name string, overwrite bool, user *User) {
|
||||
|
||||
if srcMatter == nil {
|
||||
panic(result.BadRequest("srcMatter cannot be nil."))
|
||||
@@ -943,13 +854,13 @@ func (this *MatterService) AtomicCopy(request *http.Request, srcMatter *Matter,
|
||||
}
|
||||
|
||||
destinationPath := destDirMatter.Path + "/" + name
|
||||
this.handleOverwrite(request, user, space, destinationPath, overwrite)
|
||||
this.handleOverwrite(request, user, destinationPath, overwrite)
|
||||
|
||||
this.copy(request, srcMatter, destDirMatter, name)
|
||||
}
|
||||
|
||||
// rename matter to name
|
||||
func (this *MatterService) AtomicRename(request *http.Request, matter *Matter, name string, overwrite bool, user *User, space *Space) {
|
||||
//rename matter to name
|
||||
func (this *MatterService) AtomicRename(request *http.Request, matter *Matter, name string, overwrite bool, user *User) {
|
||||
|
||||
this.logger.Info("Try to rename srcPath = %s to name = %s", matter.Path, name)
|
||||
|
||||
@@ -971,11 +882,11 @@ func (this *MatterService) AtomicRename(request *http.Request, matter *Matter, n
|
||||
}
|
||||
|
||||
//check whether the name used by another matter.
|
||||
oldMatter := this.matterDao.FindBySpaceNameAndPuuidAndDirAndName(space.Name, matter.Puuid, "", name)
|
||||
oldMatter := this.matterDao.FindByUserUuidAndPuuidAndDirAndName(user.Uuid, matter.Puuid, "", name)
|
||||
if oldMatter != nil {
|
||||
if overwrite {
|
||||
//delete this one.
|
||||
this.Delete(request, oldMatter, user, space)
|
||||
this.Delete(request, oldMatter, user)
|
||||
} else {
|
||||
panic(result.CustomWebResult(result.PRECONDITION_FAILED, fmt.Sprintf("%s already exists", name)))
|
||||
}
|
||||
@@ -1030,8 +941,8 @@ func (this *MatterService) AtomicRename(request *http.Request, matter *Matter, n
|
||||
return
|
||||
}
|
||||
|
||||
// 将本地文件映射到蓝眼云盘中去。
|
||||
func (this *MatterService) AtomicMirror(request *http.Request, srcPath string, destPath string, overwrite bool, user *User, space *Space) {
|
||||
//将本地文件映射到蓝眼云盘中去。
|
||||
func (this *MatterService) AtomicMirror(request *http.Request, srcPath string, destPath string, overwrite bool, user *User) {
|
||||
|
||||
if user == nil {
|
||||
panic(result.BadRequest("user cannot be nil"))
|
||||
@@ -1046,17 +957,17 @@ func (this *MatterService) AtomicMirror(request *http.Request, srcPath string, d
|
||||
panic(result.BadRequest("dest cannot be null"))
|
||||
}
|
||||
|
||||
destDirMatter := this.CreateDirectories(request, user, space, destPath)
|
||||
destDirMatter := this.CreateDirectories(request, user, destPath)
|
||||
|
||||
if destDirMatter.Deleted {
|
||||
panic(result.BadRequest("dest matter has been deleted. Cannot mirror."))
|
||||
}
|
||||
|
||||
this.mirror(request, srcPath, destDirMatter, overwrite, user, space)
|
||||
this.mirror(request, srcPath, destDirMatter, overwrite, user)
|
||||
}
|
||||
|
||||
// 将本地文件/文件夹映射到蓝眼云盘中去。
|
||||
func (this *MatterService) mirror(request *http.Request, srcPath string, destDirMatter *Matter, overwrite bool, user *User, space *Space) {
|
||||
//将本地文件/文件夹映射到蓝眼云盘中去。
|
||||
func (this *MatterService) mirror(request *http.Request, srcPath string, destDirMatter *Matter, overwrite bool, user *User) {
|
||||
|
||||
if user == nil {
|
||||
panic(result.BadRequest("user cannot be nil"))
|
||||
@@ -1079,10 +990,10 @@ func (this *MatterService) mirror(request *http.Request, srcPath string, destDir
|
||||
if fileStat.IsDir() {
|
||||
|
||||
//判断当前文件夹下,文件是否已经存在了。
|
||||
srcDirMatter := this.matterDao.FindBySpaceNameAndPuuidAndDirAndName(space.Name, destDirMatter.Uuid, TRUE, fileStat.Name())
|
||||
srcDirMatter := this.matterDao.FindByUserUuidAndPuuidAndDirAndName(user.Uuid, destDirMatter.Uuid, TRUE, fileStat.Name())
|
||||
|
||||
if srcDirMatter == nil {
|
||||
srcDirMatter = this.createDirectory(request, destDirMatter, fileStat.Name(), user, space)
|
||||
srcDirMatter = this.createDirectory(request, destDirMatter, fileStat.Name(), user)
|
||||
}
|
||||
|
||||
fileInfos, err := ioutil.ReadDir(srcPath)
|
||||
@@ -1092,17 +1003,17 @@ func (this *MatterService) mirror(request *http.Request, srcPath string, destDir
|
||||
for _, fileInfo := range fileInfos {
|
||||
|
||||
path := fmt.Sprintf("%s/%s", srcPath, fileInfo.Name())
|
||||
this.mirror(request, path, srcDirMatter, overwrite, user, space)
|
||||
this.mirror(request, path, srcDirMatter, overwrite, user)
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
//判断当前文件夹下,文件是否已经存在了。
|
||||
matter := this.matterDao.FindBySpaceNameAndPuuidAndDirAndName(space.Name, destDirMatter.Uuid, FALSE, fileStat.Name())
|
||||
matter := this.matterDao.FindByUserUuidAndPuuidAndDirAndName(user.Uuid, destDirMatter.Uuid, FALSE, fileStat.Name())
|
||||
if matter != nil {
|
||||
//如果是覆盖,那么删除之前的文件
|
||||
if overwrite {
|
||||
this.Delete(request, matter, user, space)
|
||||
this.Delete(request, matter, user)
|
||||
} else {
|
||||
//直接完成。
|
||||
return
|
||||
@@ -1117,19 +1028,19 @@ func (this *MatterService) mirror(request *http.Request, srcPath string, destDir
|
||||
this.PanicError(err)
|
||||
}()
|
||||
|
||||
this.Upload(request, file, nil, user, space, destDirMatter, fileStat.Name(), true)
|
||||
this.Upload(request, file, user, destDirMatter, fileStat.Name(), true)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 根据一个文件夹路径,依次创建,找到最后一个文件夹的matter,如果中途出错,返回err. 如果存在了那就直接返回即可。
|
||||
func (this *MatterService) CreateDirectories(request *http.Request, user *User, space *Space, dirPath string) *Matter {
|
||||
//根据一个文件夹路径,依次创建,找到最后一个文件夹的matter,如果中途出错,返回err. 如果存在了那就直接返回即可。
|
||||
func (this *MatterService) CreateDirectories(request *http.Request, user *User, dirPath string) *Matter {
|
||||
|
||||
dirPath = path.Clean(dirPath)
|
||||
|
||||
if dirPath == "/" {
|
||||
return NewRootMatter(space)
|
||||
return NewRootMatter(user)
|
||||
}
|
||||
|
||||
//ignore the last slash.
|
||||
@@ -1154,17 +1065,17 @@ func (this *MatterService) CreateDirectories(request *http.Request, user *User,
|
||||
|
||||
//ignore the first element.
|
||||
if k == 0 {
|
||||
dirMatter = NewRootMatter(space)
|
||||
dirMatter = NewRootMatter(user)
|
||||
continue
|
||||
}
|
||||
|
||||
dirMatter = this.createDirectory(request, dirMatter, name, user, space)
|
||||
dirMatter = this.createDirectory(request, dirMatter, name, user)
|
||||
}
|
||||
|
||||
return dirMatter
|
||||
}
|
||||
|
||||
// wrap a matter. put its parent.
|
||||
//wrap a matter. put its parent.
|
||||
func (this *MatterService) WrapParentDetail(request *http.Request, matter *Matter) *Matter {
|
||||
|
||||
if matter == nil {
|
||||
@@ -1187,7 +1098,7 @@ func (this *MatterService) WrapParentDetail(request *http.Request, matter *Matte
|
||||
return matter
|
||||
}
|
||||
|
||||
// wrap a matter ,put its children
|
||||
//wrap a matter ,put its children
|
||||
func (this *MatterService) WrapChildrenDetail(request *http.Request, matter *Matter) {
|
||||
|
||||
if matter == nil {
|
||||
@@ -1206,14 +1117,14 @@ func (this *MatterService) WrapChildrenDetail(request *http.Request, matter *Mat
|
||||
|
||||
}
|
||||
|
||||
// fetch a matter's detail with parent info.
|
||||
//fetch a matter's detail with parent info.
|
||||
func (this *MatterService) Detail(request *http.Request, uuid string) *Matter {
|
||||
matter := this.matterDao.CheckByUuid(uuid)
|
||||
return this.WrapParentDetail(request, matter)
|
||||
}
|
||||
|
||||
// crawl a url to dirMatter
|
||||
func (this *MatterService) AtomicCrawl(request *http.Request, url string, filename string, user *User, space *Space, dirMatter *Matter, privacy bool) *Matter {
|
||||
//crawl a url to dirMatter
|
||||
func (this *MatterService) AtomicCrawl(request *http.Request, url string, filename string, user *User, dirMatter *Matter, privacy bool) *Matter {
|
||||
|
||||
if user == nil {
|
||||
panic(result.BadRequest("user cannot be nil."))
|
||||
@@ -1237,15 +1148,11 @@ func (this *MatterService) AtomicCrawl(request *http.Request, url string, filena
|
||||
//download from url.
|
||||
resp, err := http.Get(url)
|
||||
this.PanicError(err)
|
||||
//if resp is not ok.
|
||||
if resp.StatusCode != 200 {
|
||||
panic(result.BadRequest("error when crawl from url."))
|
||||
}
|
||||
|
||||
return this.Upload(request, resp.Body, nil, user, space, dirMatter, filename, privacy)
|
||||
return this.Upload(request, resp.Body, user, dirMatter, filename, privacy)
|
||||
}
|
||||
|
||||
// adjust a matter's path.
|
||||
//adjust a matter's path.
|
||||
func (this *MatterService) adjustPath(matter *Matter, parentMatter *Matter) {
|
||||
|
||||
if matter.Dir {
|
||||
@@ -1269,45 +1176,45 @@ func (this *MatterService) adjustPath(matter *Matter, parentMatter *Matter) {
|
||||
|
||||
}
|
||||
|
||||
// delete someone's EyeblueTank files according to physics files.
|
||||
func (this *MatterService) DeleteByPhysics(request *http.Request, user *User, space *Space) {
|
||||
//delete someone's EyeblueTank files according to physics files.
|
||||
func (this *MatterService) DeleteByPhysics(request *http.Request, user *User) {
|
||||
|
||||
if user == nil {
|
||||
panic(result.BadRequest("user cannot be nil."))
|
||||
}
|
||||
|
||||
//scan user's file. scan level by level.
|
||||
rootMatter := NewRootMatter(space)
|
||||
this.deleteFolderByPhysics(request, rootMatter, user, space)
|
||||
rootMatter := NewRootMatter(user)
|
||||
this.deleteFolderByPhysics(request, rootMatter, user)
|
||||
|
||||
}
|
||||
|
||||
func (this *MatterService) deleteFolderByPhysics(request *http.Request, dirMatter *Matter, user *User, space *Space) {
|
||||
func (this *MatterService) deleteFolderByPhysics(request *http.Request, dirMatter *Matter, user *User) {
|
||||
|
||||
//scan user's file. scan level by level.
|
||||
this.matterDao.PageHandle(dirMatter.Uuid, "", space.Uuid, "", "", "", nil, nil, func(matter *Matter) {
|
||||
this.matterDao.PageHandle(dirMatter.Uuid, user.Uuid, "", "", "", nil, nil, func(matter *Matter) {
|
||||
|
||||
if matter.Dir {
|
||||
//delete children first.
|
||||
this.deleteFolderByPhysics(request, matter, user, space)
|
||||
this.deleteFolderByPhysics(request, matter, user)
|
||||
}
|
||||
|
||||
if !util.PathExists(matter.AbsolutePath()) {
|
||||
this.logger.Info("physics file not exist. delete from tank. %s", matter.Name)
|
||||
this.AtomicDelete(nil, matter, user, space)
|
||||
this.AtomicDelete(nil, matter, user)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
// scan someone's physics files to EyeblueTank
|
||||
func (this *MatterService) ScanPhysics(request *http.Request, user *User, space *Space) {
|
||||
//scan someone's physics files to EyeblueTank
|
||||
func (this *MatterService) ScanPhysics(request *http.Request, user *User) {
|
||||
|
||||
if user == nil {
|
||||
panic(result.BadRequest("user cannot be nil."))
|
||||
}
|
||||
|
||||
rootDirPath := GetSpaceMatterRootDir(user.Username)
|
||||
rootDirPath := GetUserMatterRootDir(user.Username)
|
||||
this.logger.Info("scan %s's root dir %s", user.Username, rootDirPath)
|
||||
|
||||
rootExists := util.PathExists(rootDirPath)
|
||||
@@ -1319,17 +1226,17 @@ func (this *MatterService) ScanPhysics(request *http.Request, user *User, space
|
||||
panic(result.BadRequest("cannot get root file info."))
|
||||
}
|
||||
|
||||
rootMatter := NewRootMatter(space)
|
||||
this.scanPhysicsFolder(request, rootFileInfo, rootMatter, user, space)
|
||||
rootMatter := NewRootMatter(user)
|
||||
this.scanPhysicsFolder(request, rootFileInfo, rootMatter, user)
|
||||
}
|
||||
|
||||
func (this *MatterService) scanPhysicsFolder(request *http.Request, dirInfo os.FileInfo, dirMatter *Matter, user *User, space *Space) {
|
||||
func (this *MatterService) scanPhysicsFolder(request *http.Request, dirInfo os.FileInfo, dirMatter *Matter, user *User) {
|
||||
if !dirInfo.IsDir() {
|
||||
return
|
||||
}
|
||||
|
||||
//fetch all matters under this folder.
|
||||
_, matters := this.matterDao.PlainPage(0, 1000, dirMatter.Uuid, "", space.Uuid, "", "", "", nil, nil, nil)
|
||||
_, matters := this.matterDao.PlainPage(0, 1000, dirMatter.Uuid, user.Uuid, "", "", "", nil, nil, nil)
|
||||
nameMatterMap := make(map[string]*Matter)
|
||||
for _, m := range matters {
|
||||
nameMatterMap[m.Name] = m
|
||||
@@ -1359,12 +1266,12 @@ func (this *MatterService) scanPhysicsFolder(request *http.Request, dirInfo os.F
|
||||
if !matter.Dir {
|
||||
if matter.Size != fileInfo.Size() {
|
||||
this.logger.Info("update matter: %s size:%d -> %d", name, matter.Size, fileInfo.Size())
|
||||
this.updateNonDirMatter(matter, fileInfo.Size(), user, space)
|
||||
this.updateNonDirMatter(matter, fileInfo.Size(), user)
|
||||
}
|
||||
} else {
|
||||
|
||||
//recursive scan this folder.
|
||||
this.scanPhysicsFolder(request, fileInfo, matter, user, space)
|
||||
this.scanPhysicsFolder(request, fileInfo, matter, user)
|
||||
|
||||
}
|
||||
|
||||
@@ -1373,16 +1280,16 @@ func (this *MatterService) scanPhysicsFolder(request *http.Request, dirInfo os.F
|
||||
if fileInfo.IsDir() {
|
||||
|
||||
//create folder.
|
||||
matter = this.createDirectory(request, dirMatter, name, user, space)
|
||||
matter = this.createDirectory(request, dirMatter, name, user)
|
||||
|
||||
//recursive scan this folder.
|
||||
this.scanPhysicsFolder(request, fileInfo, matter, user, space)
|
||||
this.scanPhysicsFolder(request, fileInfo, matter, user)
|
||||
|
||||
} else {
|
||||
|
||||
//not exist. add basic info.
|
||||
this.logger.Info("Create matter: %s size:%d", name, fileInfo.Size())
|
||||
matter = this.createNonDirMatter(dirMatter, name, fileInfo.Size(), true, user, space)
|
||||
matter = this.createNonDirMatter(dirMatter, name, fileInfo.Size(), true, user)
|
||||
|
||||
}
|
||||
|
||||
@@ -1390,14 +1297,14 @@ func (this *MatterService) scanPhysicsFolder(request *http.Request, dirInfo os.F
|
||||
}
|
||||
}
|
||||
|
||||
// clean all the expired deleted matters
|
||||
//clean all the expired deleted matters
|
||||
func (this *MatterService) CleanExpiredDeletedMatters() {
|
||||
//mock a request.
|
||||
request := &http.Request{}
|
||||
|
||||
preference := this.preferenceService.Fetch()
|
||||
|
||||
this.userDao.PageHandle("", "", func(user *User, space *Space) {
|
||||
this.userDao.PageHandle("", "", func(user *User) {
|
||||
|
||||
this.logger.Info("Clean %s 's deleted matters", user.Username)
|
||||
|
||||
@@ -1408,8 +1315,8 @@ func (this *MatterService) CleanExpiredDeletedMatters() {
|
||||
}
|
||||
|
||||
//first remove all the matter(not dir).
|
||||
this.matterDao.PageHandle("", "", "", "", FALSE, TRUE, &thenDate, nil, func(matter *Matter) {
|
||||
this.Delete(request, matter, user, space)
|
||||
this.matterDao.PageHandle("", "", "", FALSE, TRUE, &thenDate, nil, func(matter *Matter) {
|
||||
this.Delete(request, matter, user)
|
||||
})
|
||||
|
||||
sortArray := []builder.OrderPair{
|
||||
@@ -1420,8 +1327,8 @@ func (this *MatterService) CleanExpiredDeletedMatters() {
|
||||
}
|
||||
|
||||
//remove all the deleted directories. sort by path.
|
||||
this.matterDao.PageHandle("", "", "", "", TRUE, TRUE, &thenDate, sortArray, func(matter *Matter) {
|
||||
this.Delete(request, matter, user, space)
|
||||
this.matterDao.PageHandle("", "", "", TRUE, TRUE, &thenDate, sortArray, func(matter *Matter) {
|
||||
this.Delete(request, matter, user)
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/aliyun/aliyun-oss-go-sdk/oss"
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
)
|
||||
|
||||
// oss service
|
||||
//@Service
|
||||
type OssService struct {
|
||||
BaseBean
|
||||
matterDao *MatterDao
|
||||
|
||||
//whether scan task is running
|
||||
client *oss.Client
|
||||
bucket *oss.Bucket
|
||||
}
|
||||
|
||||
func (this *OssService) Init() {
|
||||
this.BaseBean.Init()
|
||||
|
||||
b := core.CONTEXT.GetBean(this.matterDao)
|
||||
if b, ok := b.(*MatterDao); ok {
|
||||
this.matterDao = b
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//upload a matter to oss.
|
||||
func (this *OssService) Upload(matter *Matter) {
|
||||
|
||||
//只上传文件,忽略文件夹。
|
||||
if matter.Dir {
|
||||
return
|
||||
}
|
||||
|
||||
//只上传没有传过的。
|
||||
if matter.Md5 != "" {
|
||||
return
|
||||
}
|
||||
|
||||
// <yourObjectName>上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。
|
||||
objectName := matter.Path
|
||||
if len(matter.Path) > 1 {
|
||||
objectName = matter.Path[1:]
|
||||
}
|
||||
|
||||
// <yourLocalFileName>由本地文件路径加文件名包括后缀组成,例如/users/local/myfile.txt。
|
||||
localFileName := matter.AbsolutePath()
|
||||
|
||||
// 上传文件。
|
||||
err := this.bucket.PutObjectFromFile(objectName, localFileName)
|
||||
this.PanicError(err)
|
||||
|
||||
// 修改本地文件的md5字段
|
||||
matter.Md5 = fmt.Sprintf("%s/%s", core.CONFIG.OssCustomHost(), objectName)
|
||||
this.matterDao.Save(matter)
|
||||
|
||||
this.logger.Info("upload %s %s to oss path = %s", matter.Uuid, matter.Name, objectName)
|
||||
|
||||
}
|
||||
|
||||
func (this *OssService) Bootstrap() {
|
||||
|
||||
// Endpoint以杭州为例,其它Region请按实际情况填写。
|
||||
// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
|
||||
|
||||
// 创建OSSClient实例。
|
||||
client, err := oss.New(fmt.Sprintf("http://%s", core.CONFIG.OssEndpoint()), core.CONFIG.OssAccessKey(), core.CONFIG.OssSecretKey())
|
||||
this.client = client
|
||||
this.PanicError(err)
|
||||
|
||||
// 获取存储空间。
|
||||
bucket, err := this.client.Bucket(core.CONFIG.OssBucket())
|
||||
this.bucket = bucket
|
||||
this.PanicError(err)
|
||||
|
||||
this.logger.Info("OssService bootstrap.")
|
||||
|
||||
}
|
||||
@@ -1,28 +1,30 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Preference struct {
|
||||
Uuid string `json:"uuid" gorm:"type:char(36);primary_key;unique"`
|
||||
Sort int64 `json:"sort" gorm:"type:bigint(20) not null"`
|
||||
UpdateTime time.Time `json:"updateTime" gorm:"type:timestamp not null;default:CURRENT_TIMESTAMP"`
|
||||
CreateTime time.Time `json:"createTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"`
|
||||
Name string `json:"name" gorm:"type:varchar(45)"`
|
||||
LogoUrl string `json:"logoUrl" gorm:"type:varchar(255)"`
|
||||
FaviconUrl string `json:"faviconUrl" gorm:"type:varchar(255)"`
|
||||
Copyright string `json:"copyright" gorm:"type:varchar(1024)"`
|
||||
Record string `json:"record" gorm:"type:varchar(1024)"`
|
||||
DownloadDirMaxSize int64 `json:"downloadDirMaxSize" gorm:"type:bigint(20) not null;default:-1"`
|
||||
DownloadDirMaxNum int64 `json:"downloadDirMaxNum" gorm:"type:bigint(20) not null;default:-1"`
|
||||
DefaultTotalSizeLimit int64 `json:"defaultTotalSizeLimit" gorm:"type:bigint(20) not null;default:-1"`
|
||||
AllowRegister bool `json:"allowRegister" gorm:"type:tinyint(1) not null;default:0"`
|
||||
PreviewConfig string `json:"previewConfig" gorm:"type:text"`
|
||||
ScanConfig string `json:"scanConfig" gorm:"type:text"`
|
||||
DeletedKeepDays int64 `json:"deletedKeepDays" gorm:"type:bigint(20) not null;default:7"`
|
||||
Version string `json:"version" gorm:"-"`
|
||||
Base
|
||||
Name string `json:"name" gorm:"type:varchar(45)"`
|
||||
LogoUrl string `json:"logoUrl" gorm:"type:varchar(255)"`
|
||||
FaviconUrl string `json:"faviconUrl" gorm:"type:varchar(255)"`
|
||||
Copyright string `json:"copyright" gorm:"type:varchar(1024)"`
|
||||
Record string `json:"record" gorm:"type:varchar(1024)"`
|
||||
DownloadDirMaxSize int64 `json:"downloadDirMaxSize" gorm:"type:bigint(20) not null;default:-1"`
|
||||
DownloadDirMaxNum int64 `json:"downloadDirMaxNum" gorm:"type:bigint(20) not null;default:-1"`
|
||||
DefaultTotalSizeLimit int64 `json:"defaultTotalSizeLimit" gorm:"type:bigint(20) not null;default:-1"`
|
||||
AllowRegister bool `json:"allowRegister" gorm:"type:tinyint(1) not null;default:0"`
|
||||
PreviewConfig string `json:"previewConfig" gorm:"type:text"`
|
||||
ScanConfig string `json:"scanConfig" gorm:"type:text"`
|
||||
DeletedKeepDays int64 `json:"deletedKeepDays" gorm:"type:bigint(20) not null;default:7"`
|
||||
Version string `json:"version" gorm:"-"`
|
||||
}
|
||||
|
||||
// set File's table name to be `profiles`
|
||||
func (this *Preference) TableName() string {
|
||||
return core.TABLE_PREFIX + "preference"
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Session struct {
|
||||
Uuid string `json:"uuid" gorm:"type:char(36);primary_key;unique"`
|
||||
Sort int64 `json:"sort" gorm:"type:bigint(20) not null"`
|
||||
UpdateTime time.Time `json:"updateTime" gorm:"type:timestamp not null;default:CURRENT_TIMESTAMP"`
|
||||
CreateTime time.Time `json:"createTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"`
|
||||
Base
|
||||
UserUuid string `json:"userUuid" gorm:"type:char(36)"`
|
||||
Ip string `json:"ip" gorm:"type:varchar(128) not null"`
|
||||
ExpireTime time.Time `json:"expireTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"`
|
||||
}
|
||||
|
||||
// set User's table name to be `profiles`
|
||||
func (this *Session) TableName() string {
|
||||
return core.TABLE_PREFIX + "session"
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ type ShareController struct {
|
||||
matterDao *MatterDao
|
||||
matterService *MatterService
|
||||
shareService *ShareService
|
||||
alienService *AlienService
|
||||
}
|
||||
|
||||
func (this *ShareController) Init() {
|
||||
@@ -50,11 +49,6 @@ func (this *ShareController) Init() {
|
||||
this.shareService = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.alienService)
|
||||
if b, ok := b.(*AlienService); ok {
|
||||
this.alienService = b
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (this *ShareController) RegisterRoutes() map[string]func(writer http.ResponseWriter, request *http.Request) {
|
||||
@@ -69,28 +63,43 @@ func (this *ShareController) RegisterRoutes() map[string]func(writer http.Respon
|
||||
routeMap["/api/share/browse"] = this.Wrap(this.Browse, USER_ROLE_GUEST)
|
||||
routeMap["/api/share/zip"] = this.Wrap(this.Zip, USER_ROLE_GUEST)
|
||||
|
||||
routeMap["/api/share/matter/page"] = this.Wrap(this.MatterPage, USER_ROLE_GUEST)
|
||||
routeMap["/api/share/matter/preview"] = this.WrapPure(this.MatterPreview, USER_ROLE_GUEST)
|
||||
routeMap["/api/share/matter/download"] = this.WrapPure(this.MatterDownload, USER_ROLE_GUEST)
|
||||
|
||||
return routeMap
|
||||
}
|
||||
|
||||
func (this *ShareController) Create(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
uuidArray := util.ExtractRequestArray(request, "matterUuids")
|
||||
expireInfinity := util.ExtractRequestBool(request, "expireInfinity")
|
||||
spaceUuid := util.ExtractRequestString(request, "spaceUuid")
|
||||
matterUuids := request.FormValue("matterUuids")
|
||||
expireInfinityStr := request.FormValue("expireInfinity")
|
||||
expireTimeStr := request.FormValue("expireTime")
|
||||
|
||||
if matterUuids == "" {
|
||||
panic(result.BadRequest("matterUuids cannot be null"))
|
||||
}
|
||||
|
||||
var expireTime time.Time
|
||||
expireInfinity := false
|
||||
if expireInfinityStr == TRUE {
|
||||
expireInfinity = true
|
||||
expireTime = time.Now()
|
||||
} else {
|
||||
|
||||
if expireTimeStr == "" {
|
||||
panic(result.BadRequest("time format error"))
|
||||
} else {
|
||||
expireTime = util.ConvertDateTimeStringToTime(expireTimeStr)
|
||||
}
|
||||
|
||||
var expireTime = time.Now()
|
||||
if !expireInfinity {
|
||||
expireTime = util.ExtractRequestTime(request, "expireTime")
|
||||
if expireTime.Before(time.Now()) {
|
||||
panic(result.BadRequest("expire time cannot before now"))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if len(uuidArray) > SHARE_MAX_NUM {
|
||||
uuidArray := strings.Split(matterUuids, ",")
|
||||
|
||||
if len(uuidArray) == 0 {
|
||||
panic(result.BadRequest("share at least one file"))
|
||||
} else if len(uuidArray) > SHARE_MAX_NUM {
|
||||
panic(result.BadRequestI18n(request, i18n.ShareNumExceedLimit, len(uuidArray), SHARE_MAX_NUM))
|
||||
}
|
||||
|
||||
@@ -139,7 +148,6 @@ func (this *ShareController) Create(writer http.ResponseWriter, request *http.Re
|
||||
Code: util.RandomString4(),
|
||||
ExpireInfinity: expireInfinity,
|
||||
ExpireTime: expireTime,
|
||||
SpaceUuid: spaceUuid,
|
||||
}
|
||||
this.shareDao.Create(share)
|
||||
|
||||
@@ -184,14 +192,14 @@ func (this *ShareController) DeleteBatch(writer http.ResponseWriter, request *ht
|
||||
|
||||
for _, uuid := range uuidArray {
|
||||
|
||||
share := this.shareDao.FindByUuid(uuid)
|
||||
imageCache := this.shareDao.FindByUuid(uuid)
|
||||
|
||||
user := this.checkUser(request)
|
||||
if share.UserUuid != user.Uuid {
|
||||
if imageCache.UserUuid != user.Uuid {
|
||||
panic(result.UNAUTHORIZED)
|
||||
}
|
||||
|
||||
this.shareDao.Delete(share)
|
||||
this.shareDao.Delete(imageCache)
|
||||
}
|
||||
|
||||
return this.Success("OK")
|
||||
@@ -258,7 +266,6 @@ func (this *ShareController) CheckShare(writer http.ResponseWriter, request *htt
|
||||
return this.shareService.CheckShare(request, shareUuid, code, user)
|
||||
}
|
||||
|
||||
// get the basic info of this share.
|
||||
func (this *ShareController) Browse(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
shareUuid := request.FormValue("shareUuid")
|
||||
@@ -271,10 +278,6 @@ func (this *ShareController) Browse(writer http.ResponseWriter, request *http.Re
|
||||
user := this.findUser(request)
|
||||
share := this.shareService.CheckShare(request, shareUuid, code, user)
|
||||
bridges := this.bridgeDao.FindByShareUuid(share.Uuid)
|
||||
shareOwner := this.userDao.FindByUuid(share.UserUuid)
|
||||
if shareOwner.Status == USER_STATUS_DISABLED {
|
||||
panic(result.BadRequestI18n(request, i18n.UserDisabled))
|
||||
}
|
||||
|
||||
if puuid == MATTER_ROOT {
|
||||
|
||||
@@ -368,89 +371,3 @@ func (this *ShareController) Zip(writer http.ResponseWriter, request *http.Reque
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// matter list under a share.
|
||||
func (this *ShareController) MatterPage(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
page := util.ExtractRequestOptionalInt(request, "page", 0)
|
||||
pageSize := util.ExtractRequestOptionalInt(request, "pageSize", 200)
|
||||
orderCreateTime := util.ExtractRequestOptionalString(request, "orderCreateTime", "")
|
||||
orderUpdateTime := util.ExtractRequestOptionalString(request, "orderUpdateTime", "")
|
||||
orderDeleteTime := util.ExtractRequestOptionalString(request, "orderDeleteTime", "")
|
||||
orderSort := util.ExtractRequestOptionalString(request, "orderSort", "")
|
||||
orderTimes := util.ExtractRequestOptionalString(request, "orderTimes", "")
|
||||
orderDir := util.ExtractRequestOptionalString(request, "orderDir", "")
|
||||
orderSize := util.ExtractRequestOptionalString(request, "orderSize", "")
|
||||
orderName := util.ExtractRequestOptionalString(request, "orderName", "")
|
||||
|
||||
puuid := util.ExtractRequestString(request, "puuid")
|
||||
name := util.ExtractRequestOptionalString(request, "name", "")
|
||||
dir := util.ExtractRequestOptionalString(request, "dir", "")
|
||||
deleted := util.ExtractRequestOptionalString(request, "deleted", "")
|
||||
extensionsStr := util.ExtractRequestOptionalString(request, "extensions", "")
|
||||
|
||||
//auth by shareUuid.
|
||||
shareUuid := util.ExtractRequestString(request, "shareUuid")
|
||||
shareCode := util.ExtractRequestString(request, "shareCode")
|
||||
shareRootUuid := util.ExtractRequestString(request, "shareRootUuid")
|
||||
|
||||
//validate the puuid.
|
||||
dirMatter := this.matterDao.CheckByUuid(puuid)
|
||||
if !dirMatter.Dir {
|
||||
panic(result.BadRequest("puuid is not a directory"))
|
||||
}
|
||||
|
||||
//validate the shareUuid,shareCode,shareRootUuid.
|
||||
user := this.findUser(request)
|
||||
share := this.shareService.ValidateMatter(request, shareUuid, shareCode, user, shareRootUuid, dirMatter)
|
||||
puuid = dirMatter.Uuid
|
||||
|
||||
var extensions []string
|
||||
if extensionsStr != "" {
|
||||
extensions = strings.Split(extensionsStr, ",")
|
||||
}
|
||||
|
||||
pager := this.matterService.Page(
|
||||
request,
|
||||
page,
|
||||
pageSize,
|
||||
orderCreateTime,
|
||||
orderUpdateTime,
|
||||
orderDeleteTime,
|
||||
orderSort,
|
||||
orderTimes,
|
||||
orderDir,
|
||||
orderSize,
|
||||
orderName,
|
||||
puuid,
|
||||
name,
|
||||
dir,
|
||||
deleted,
|
||||
extensions,
|
||||
share.SpaceUuid,
|
||||
)
|
||||
|
||||
return this.Success(pager)
|
||||
}
|
||||
|
||||
func (this *ShareController) MatterPreviewOrDownload(writer http.ResponseWriter, request *http.Request, withContentDisposition bool) {
|
||||
//auth by shareUuid.
|
||||
matterUuid := util.ExtractRequestString(request, "matterUuid")
|
||||
shareUuid := util.ExtractRequestString(request, "shareUuid")
|
||||
shareCode := util.ExtractRequestString(request, "shareCode")
|
||||
shareRootUuid := util.ExtractRequestString(request, "shareRootUuid")
|
||||
|
||||
matter := this.matterDao.CheckByUuid(matterUuid)
|
||||
operator := this.findUser(request)
|
||||
|
||||
this.shareService.ValidateMatter(request, shareUuid, shareCode, operator, shareRootUuid, matter)
|
||||
this.alienService.PreviewOrDownload(writer, request, matter, withContentDisposition)
|
||||
}
|
||||
|
||||
func (this *ShareController) MatterPreview(writer http.ResponseWriter, request *http.Request) {
|
||||
this.MatterPreviewOrDownload(writer, request, false)
|
||||
}
|
||||
|
||||
func (this *ShareController) MatterDownload(writer http.ResponseWriter, request *http.Request) {
|
||||
this.MatterPreviewOrDownload(writer, request, true)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
"github.com/eyebluecn/tank/code/tool/builder"
|
||||
"github.com/eyebluecn/tank/code/tool/result"
|
||||
"gorm.io/gorm"
|
||||
"github.com/jinzhu/gorm"
|
||||
|
||||
"github.com/eyebluecn/tank/code/tool/uuid"
|
||||
"time"
|
||||
@@ -56,7 +56,7 @@ func (this *ShareDao) PlainPage(page int, pageSize int, userUuid string, sortArr
|
||||
var conditionDB *gorm.DB
|
||||
conditionDB = core.CONTEXT.GetDB().Model(&Share{}).Where(wp.Query, wp.Args...)
|
||||
|
||||
var count int64 = 0
|
||||
count := 0
|
||||
db := conditionDB.Count(&count)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
@@ -64,7 +64,7 @@ func (this *ShareDao) PlainPage(page int, pageSize int, userUuid string, sortArr
|
||||
db = conditionDB.Order(this.GetSortString(sortArray)).Offset(page * pageSize).Limit(pageSize).Find(&shares)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
return int(count), shares
|
||||
return count, shares
|
||||
}
|
||||
|
||||
func (this *ShareDao) Create(share *Share) *Share {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -21,10 +22,7 @@ const (
|
||||
* share record
|
||||
*/
|
||||
type Share struct {
|
||||
Uuid string `json:"uuid" gorm:"type:char(36);primary_key;unique"`
|
||||
Sort int64 `json:"sort" gorm:"type:bigint(20) not null"`
|
||||
UpdateTime time.Time `json:"updateTime" gorm:"type:timestamp not null;default:CURRENT_TIMESTAMP"`
|
||||
CreateTime time.Time `json:"createTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"`
|
||||
Base
|
||||
Name string `json:"name" gorm:"type:varchar(255)"`
|
||||
ShareType string `json:"shareType" gorm:"type:varchar(45)"`
|
||||
Username string `json:"username" gorm:"type:varchar(45)"`
|
||||
@@ -33,7 +31,11 @@ type Share struct {
|
||||
Code string `json:"code" gorm:"type:varchar(45) not null"`
|
||||
ExpireInfinity bool `json:"expireInfinity" gorm:"type:tinyint(1) not null;default:0"`
|
||||
ExpireTime time.Time `json:"expireTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"`
|
||||
SpaceUuid string `json:"spaceUuid" gorm:"type:char(36) not null;index:idx_space_uuid"`
|
||||
DirMatter *Matter `json:"dirMatter" gorm:"-"`
|
||||
Matters []*Matter `json:"matters" gorm:"-"`
|
||||
}
|
||||
|
||||
// set File's table name to be `profiles`
|
||||
func (this *Share) TableName() string {
|
||||
return core.TABLE_PREFIX + "share"
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// @Service
|
||||
//@Service
|
||||
type ShareService struct {
|
||||
BaseBean
|
||||
shareDao *ShareDao
|
||||
@@ -74,24 +74,24 @@ func (this *ShareService) CheckShare(request *http.Request, shareUuid string, co
|
||||
return share
|
||||
}
|
||||
|
||||
// check whether a user can access a matter. shareRootUuid is matter's parent(or parent's parent and so on)
|
||||
func (this *ShareService) ValidateMatter(request *http.Request, shareUuid string, code string, user *User, shareRootUuid string, matter *Matter) *Share {
|
||||
//check whether a user can access a matter. shareRootUuid is matter's parent(or parent's parent and so on)
|
||||
func (this *ShareService) ValidateMatter(request *http.Request, shareUuid string, code string, user *User, shareRootUuid string, matter *Matter) {
|
||||
|
||||
if matter == nil {
|
||||
panic(result.Unauthorized("matter cannot be nil"))
|
||||
}
|
||||
|
||||
//if self's matter, ok.
|
||||
if user != nil && matter.UserUuid == user.Uuid {
|
||||
return
|
||||
}
|
||||
|
||||
if shareUuid == "" || code == "" || shareRootUuid == "" {
|
||||
panic(result.Unauthorized("shareUuid,code,shareRootUuid cannot be null"))
|
||||
}
|
||||
|
||||
share := this.CheckShare(request, shareUuid, code, user)
|
||||
|
||||
shareOwner := this.userDao.FindByUuid(share.UserUuid)
|
||||
if shareOwner.Status == USER_STATUS_DISABLED {
|
||||
panic(result.BadRequestI18n(request, i18n.UserDisabled))
|
||||
}
|
||||
|
||||
//if shareRootUuid is root. Bridge must has record.
|
||||
if shareRootUuid == MATTER_ROOT {
|
||||
|
||||
@@ -109,11 +109,9 @@ func (this *ShareService) ValidateMatter(request *http.Request, shareUuid string
|
||||
}
|
||||
}
|
||||
|
||||
return share
|
||||
|
||||
}
|
||||
|
||||
// delete user's shares and corresponding bridges.
|
||||
//delete user's shares and corresponding bridges.
|
||||
func (this *ShareService) DeleteSharesByUser(request *http.Request, currentUser *User) {
|
||||
|
||||
//delete share and bridges.
|
||||
@@ -137,8 +135,3 @@ func (this *ShareService) DeleteSharesByUser(request *http.Request, currentUser
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// edit space's info.
|
||||
func (this *ShareService) Edit(spaceUuid string, sizeLimit int64, totalSizeLimit int64) {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
"github.com/eyebluecn/tank/code/tool/builder"
|
||||
"github.com/eyebluecn/tank/code/tool/i18n"
|
||||
"github.com/eyebluecn/tank/code/tool/result"
|
||||
"github.com/eyebluecn/tank/code/tool/util"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type SpaceController struct {
|
||||
BaseController
|
||||
spaceDao *SpaceDao
|
||||
spaceMemberDao *SpaceMemberDao
|
||||
spaceMemberService *SpaceMemberService
|
||||
matterDao *MatterDao
|
||||
matterService *MatterService
|
||||
spaceService *SpaceService
|
||||
userService *UserService
|
||||
}
|
||||
|
||||
func (this *SpaceController) Init() {
|
||||
this.BaseController.Init()
|
||||
|
||||
b := core.CONTEXT.GetBean(this.spaceDao)
|
||||
if b, ok := b.(*SpaceDao); ok {
|
||||
this.spaceDao = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.spaceMemberDao)
|
||||
if b, ok := b.(*SpaceMemberDao); ok {
|
||||
this.spaceMemberDao = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.spaceMemberService)
|
||||
if b, ok := b.(*SpaceMemberService); ok {
|
||||
this.spaceMemberService = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.matterDao)
|
||||
if b, ok := b.(*MatterDao); ok {
|
||||
this.matterDao = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.matterService)
|
||||
if b, ok := b.(*MatterService); ok {
|
||||
this.matterService = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.spaceService)
|
||||
if b, ok := b.(*SpaceService); ok {
|
||||
this.spaceService = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.userService)
|
||||
if b, ok := b.(*UserService); ok {
|
||||
this.userService = b
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (this *SpaceController) RegisterRoutes() map[string]func(writer http.ResponseWriter, request *http.Request) {
|
||||
|
||||
routeMap := make(map[string]func(writer http.ResponseWriter, request *http.Request))
|
||||
|
||||
routeMap["/api/space/create"] = this.Wrap(this.Create, USER_ROLE_ADMINISTRATOR)
|
||||
routeMap["/api/space/edit"] = this.Wrap(this.Edit, USER_ROLE_ADMINISTRATOR)
|
||||
routeMap["/api/space/delete"] = this.Wrap(this.Delete, USER_ROLE_ADMINISTRATOR)
|
||||
routeMap["/api/space/detail"] = this.Wrap(this.Detail, USER_ROLE_USER)
|
||||
routeMap["/api/space/page"] = this.Wrap(this.Page, USER_ROLE_USER)
|
||||
|
||||
return routeMap
|
||||
}
|
||||
|
||||
func (this *SpaceController) Create(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
//space's name
|
||||
name := util.ExtractRequestString(request, "name")
|
||||
sizeLimit := util.ExtractRequestInt64(request, "sizeLimit")
|
||||
totalSizeLimit := util.ExtractRequestInt64(request, "totalSizeLimit")
|
||||
|
||||
//create related space.
|
||||
space := this.spaceService.CreateSpace(request, name, nil, sizeLimit, totalSizeLimit, SPACE_TYPE_SHARED)
|
||||
|
||||
return this.Success(space)
|
||||
}
|
||||
|
||||
func (this *SpaceController) Edit(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
//space's uuid
|
||||
uuid := util.ExtractRequestString(request, "uuid")
|
||||
sizeLimit := util.ExtractRequestInt64(request, "sizeLimit")
|
||||
totalSizeLimit := util.ExtractRequestInt64(request, "totalSizeLimit")
|
||||
|
||||
user := this.checkUser(request)
|
||||
space := this.spaceService.Edit(request, user, uuid, sizeLimit, totalSizeLimit)
|
||||
|
||||
return this.Success(space)
|
||||
}
|
||||
|
||||
func (this *SpaceController) Delete(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
//space's name
|
||||
uuid := util.ExtractRequestString(request, "uuid")
|
||||
space := this.spaceDao.CheckByUuid(uuid)
|
||||
|
||||
//when space has members, cannot delete.
|
||||
memberCount := this.spaceMemberDao.CountBySpaceUuid(uuid)
|
||||
if memberCount > 0 {
|
||||
panic(result.BadRequest("space has members, cannot be deleted."))
|
||||
}
|
||||
|
||||
//TODO: when space has files, cannot delete.
|
||||
|
||||
//delete the space.
|
||||
this.spaceDao.Delete(space)
|
||||
|
||||
return this.Success(nil)
|
||||
}
|
||||
|
||||
func (this *SpaceController) Detail(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
uuid := util.ExtractRequestString(request, "uuid")
|
||||
|
||||
user := this.checkUser(request)
|
||||
space := this.spaceDao.CheckByUuid(uuid)
|
||||
canRead := this.spaceMemberService.canRead(user, space.Uuid)
|
||||
if !canRead {
|
||||
panic(result.BadRequestI18n(request, i18n.PermissionDenied))
|
||||
}
|
||||
|
||||
return this.Success(space)
|
||||
|
||||
}
|
||||
|
||||
func (this *SpaceController) Page(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
page := util.ExtractRequestOptionalInt(request, "page", 0)
|
||||
pageSize := util.ExtractRequestOptionalInt(request, "pageSize", 20)
|
||||
orderCreateTime := util.ExtractRequestOptionalString(request, "orderCreateTime", "")
|
||||
spaceType := util.ExtractRequestOptionalString(request, "type", SPACE_TYPE_SHARED)
|
||||
|
||||
user := this.checkUser(request)
|
||||
|
||||
sortArray := []builder.OrderPair{
|
||||
{
|
||||
Key: "create_time",
|
||||
Value: orderCreateTime,
|
||||
},
|
||||
}
|
||||
|
||||
var pager *Pager
|
||||
if user.Role == USER_ROLE_USER {
|
||||
pager = this.spaceDao.SelfPage(page, pageSize, user.Uuid, spaceType, sortArray)
|
||||
} else if user.Role == USER_ROLE_ADMINISTRATOR {
|
||||
pager = this.spaceDao.Page(page, pageSize, spaceType, sortArray)
|
||||
}
|
||||
|
||||
return this.Success(pager)
|
||||
}
|
||||
@@ -1,152 +0,0 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
"github.com/eyebluecn/tank/code/tool/builder"
|
||||
"github.com/eyebluecn/tank/code/tool/result"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/eyebluecn/tank/code/tool/uuid"
|
||||
"time"
|
||||
)
|
||||
|
||||
type SpaceDao struct {
|
||||
BaseDao
|
||||
}
|
||||
|
||||
// find by uuid. if not found return nil.
|
||||
func (this *SpaceDao) FindByUuid(uuid string) *Space {
|
||||
var entity = &Space{}
|
||||
db := core.CONTEXT.GetDB().Where("uuid = ?", uuid).First(entity)
|
||||
if db.Error != nil {
|
||||
if db.Error.Error() == result.DB_ERROR_NOT_FOUND {
|
||||
return nil
|
||||
} else {
|
||||
panic(db.Error)
|
||||
}
|
||||
}
|
||||
return entity
|
||||
}
|
||||
|
||||
// find by uuid. if not found panic NotFound error
|
||||
func (this *SpaceDao) CheckByUuid(uuid string) *Space {
|
||||
entity := this.FindByUuid(uuid)
|
||||
if entity == nil {
|
||||
panic(result.NotFound("not found record with uuid = %s", uuid))
|
||||
}
|
||||
return entity
|
||||
}
|
||||
|
||||
func (this *SpaceDao) CountByName(name string) int {
|
||||
var count int64
|
||||
db := core.CONTEXT.GetDB().
|
||||
Model(&Space{}).
|
||||
Where("name = ?", name).
|
||||
Count(&count)
|
||||
this.PanicError(db.Error)
|
||||
return int(count)
|
||||
}
|
||||
|
||||
func (this *SpaceDao) CountByUserUuid(userUuid string) int {
|
||||
var count int64
|
||||
db := core.CONTEXT.GetDB().
|
||||
Model(&Space{}).
|
||||
Where("user_uuid = ?", userUuid).
|
||||
Count(&count)
|
||||
this.PanicError(db.Error)
|
||||
return int(count)
|
||||
}
|
||||
|
||||
// TODO:
|
||||
func (this *SpaceDao) SelfPage(page int, pageSize int, userUuid string, spaceType string, sortArray []builder.OrderPair) *Pager {
|
||||
|
||||
countSqlTemplate := fmt.Sprintf("SELECT COUNT(*) FROM `%sspace` WHERE uuid IN (SELECT space_uuid FROM `%sspace_member` WHERE user_uuid = ?) AND type = ?", core.TABLE_PREFIX, core.TABLE_PREFIX)
|
||||
if spaceType == SPACE_TYPE_PRIVATE {
|
||||
countSqlTemplate = fmt.Sprintf("SELECT COUNT(*) FROM `%sspace` WHERE user_uuid = ? AND type = ?", core.TABLE_PREFIX)
|
||||
}
|
||||
var count int
|
||||
core.CONTEXT.GetDB().Raw(countSqlTemplate, userUuid, spaceType).Scan(&count)
|
||||
|
||||
orderByString := this.GetSortString(sortArray)
|
||||
if orderByString == "" {
|
||||
orderByString = "uuid"
|
||||
}
|
||||
querySqlTemplate := fmt.Sprintf("SELECT * FROM `%sspace` WHERE uuid IN (SELECT space_uuid FROM `%sspace_member` WHERE user_uuid = ?) AND type = ? ORDER BY ? LIMIT ?,?", core.TABLE_PREFIX, core.TABLE_PREFIX)
|
||||
if spaceType == SPACE_TYPE_PRIVATE {
|
||||
querySqlTemplate = fmt.Sprintf("SELECT * FROM `%sspace` WHERE user_uuid = ? AND type = ? ORDER BY ? LIMIT ?,?", core.TABLE_PREFIX)
|
||||
}
|
||||
var spaces []*Space
|
||||
core.CONTEXT.GetDB().Raw(querySqlTemplate, userUuid, spaceType, orderByString, page*pageSize, pageSize).Scan(&spaces)
|
||||
|
||||
pager := NewPager(page, pageSize, count, spaces)
|
||||
|
||||
return pager
|
||||
|
||||
}
|
||||
|
||||
func (this *SpaceDao) Page(page int, pageSize int, spaceType string, sortArray []builder.OrderPair) *Pager {
|
||||
count, spaces := this.PlainPage(page, pageSize, spaceType, sortArray)
|
||||
pager := NewPager(page, pageSize, count, spaces)
|
||||
|
||||
return pager
|
||||
}
|
||||
|
||||
func (this *SpaceDao) PlainPage(page int, pageSize int, spaceType string, sortArray []builder.OrderPair) (int, []*Space) {
|
||||
|
||||
var wp = &builder.WherePair{Query: "type = ?", Args: []interface{}{spaceType}}
|
||||
|
||||
var conditionDB *gorm.DB
|
||||
conditionDB = core.CONTEXT.GetDB().Model(&Space{}).Where(wp.Query, wp.Args...)
|
||||
|
||||
var count int64 = 0
|
||||
db := conditionDB.Count(&count)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
var spaces []*Space
|
||||
db = conditionDB.Order(this.GetSortString(sortArray)).Offset(page * pageSize).Limit(pageSize).Find(&spaces)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
return int(count), spaces
|
||||
}
|
||||
|
||||
func (this *SpaceDao) Create(space *Space) *Space {
|
||||
|
||||
timeUUID, _ := uuid.NewV4()
|
||||
space.Uuid = string(timeUUID.String())
|
||||
space.CreateTime = time.Now()
|
||||
space.UpdateTime = time.Now()
|
||||
space.Sort = time.Now().UnixNano() / 1e6
|
||||
db := core.CONTEXT.GetDB().Create(space)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
return space
|
||||
}
|
||||
|
||||
func (this *SpaceDao) Save(space *Space) *Space {
|
||||
|
||||
space.UpdateTime = time.Now()
|
||||
db := core.CONTEXT.GetDB().Save(space)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
return space
|
||||
}
|
||||
|
||||
func (this *SpaceDao) UpdateTotalSize(spaceUuid string, totalSize int64) {
|
||||
db := core.CONTEXT.GetDB().Model(&Space{}).Where("uuid = ?", spaceUuid).Update("total_size", totalSize)
|
||||
this.PanicError(db.Error)
|
||||
}
|
||||
|
||||
func (this *SpaceDao) Delete(space *Space) {
|
||||
|
||||
db := core.CONTEXT.GetDB().Delete(&space)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
}
|
||||
|
||||
// System cleanup.
|
||||
func (this *SpaceDao) Cleanup() {
|
||||
this.logger.Info("[SpaceDao] clean up. Delete all Space")
|
||||
db := core.CONTEXT.GetDB().Where("uuid is not null").Delete(Space{})
|
||||
this.PanicError(db.Error)
|
||||
}
|
||||
@@ -1,205 +0,0 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
"github.com/eyebluecn/tank/code/tool/builder"
|
||||
"github.com/eyebluecn/tank/code/tool/i18n"
|
||||
"github.com/eyebluecn/tank/code/tool/result"
|
||||
"github.com/eyebluecn/tank/code/tool/util"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type SpaceMemberController struct {
|
||||
BaseController
|
||||
spaceMemberDao *SpaceMemberDao
|
||||
spaceDao *SpaceDao
|
||||
bridgeDao *BridgeDao
|
||||
matterDao *MatterDao
|
||||
matterService *MatterService
|
||||
spaceMemberService *SpaceMemberService
|
||||
}
|
||||
|
||||
func (this *SpaceMemberController) Init() {
|
||||
this.BaseController.Init()
|
||||
|
||||
b := core.CONTEXT.GetBean(this.spaceMemberDao)
|
||||
if b, ok := b.(*SpaceMemberDao); ok {
|
||||
this.spaceMemberDao = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.spaceDao)
|
||||
if b, ok := b.(*SpaceDao); ok {
|
||||
this.spaceDao = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.bridgeDao)
|
||||
if b, ok := b.(*BridgeDao); ok {
|
||||
this.bridgeDao = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.matterDao)
|
||||
if b, ok := b.(*MatterDao); ok {
|
||||
this.matterDao = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.matterService)
|
||||
if b, ok := b.(*MatterService); ok {
|
||||
this.matterService = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.spaceMemberService)
|
||||
if b, ok := b.(*SpaceMemberService); ok {
|
||||
this.spaceMemberService = b
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (this *SpaceMemberController) RegisterRoutes() map[string]func(writer http.ResponseWriter, request *http.Request) {
|
||||
|
||||
routeMap := make(map[string]func(writer http.ResponseWriter, request *http.Request))
|
||||
|
||||
//admin user can create/edit/delete
|
||||
routeMap["/api/space/member/create"] = this.Wrap(this.Create, USER_ROLE_USER)
|
||||
routeMap["/api/space/member/edit"] = this.Wrap(this.Edit, USER_ROLE_USER)
|
||||
routeMap["/api/space/member/delete"] = this.Wrap(this.Delete, USER_ROLE_USER)
|
||||
|
||||
routeMap["/api/space/member/detail"] = this.Wrap(this.Detail, USER_ROLE_USER)
|
||||
routeMap["/api/space/member/mine"] = this.Wrap(this.Mine, USER_ROLE_USER)
|
||||
routeMap["/api/space/member/page"] = this.Wrap(this.Page, USER_ROLE_USER)
|
||||
|
||||
return routeMap
|
||||
}
|
||||
|
||||
func (this *SpaceMemberController) Create(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
spaceUuid := util.ExtractRequestString(request, "spaceUuid")
|
||||
userUuid := util.ExtractRequestString(request, "userUuid")
|
||||
spaceRole := util.ExtractRequestString(request, "role")
|
||||
|
||||
if spaceRole != SPACE_MEMBER_ROLE_READ_ONLY && spaceRole != SPACE_MEMBER_ROLE_READ_WRITE && spaceRole != SPACE_MEMBER_ROLE_ADMIN {
|
||||
panic("spaceRole is not correct")
|
||||
}
|
||||
|
||||
currentUser := this.checkUser(request)
|
||||
canManage := this.spaceMemberService.canManage(currentUser, spaceUuid)
|
||||
if !canManage {
|
||||
panic(result.BadRequestI18n(request, i18n.PermissionDenied))
|
||||
}
|
||||
|
||||
//check whether exists.
|
||||
spaceMember := this.spaceMemberDao.FindBySpaceUuidAndUserUuid(spaceUuid, userUuid)
|
||||
if spaceMember != nil {
|
||||
panic(result.BadRequestI18n(request, i18n.SpaceMemberExist))
|
||||
}
|
||||
|
||||
//check whether space exists.
|
||||
space := this.spaceDao.CheckByUuid(spaceUuid)
|
||||
user := this.userDao.CheckByUuid(userUuid)
|
||||
|
||||
spaceMember = this.spaceMemberService.CreateMember(space, user, spaceRole)
|
||||
|
||||
return this.Success(spaceMember)
|
||||
}
|
||||
|
||||
func (this *SpaceMemberController) Edit(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
uuid := util.ExtractRequestString(request, "uuid")
|
||||
spaceRole := util.ExtractRequestString(request, "role")
|
||||
|
||||
if spaceRole != SPACE_MEMBER_ROLE_READ_ONLY && spaceRole != SPACE_MEMBER_ROLE_READ_WRITE && spaceRole != SPACE_MEMBER_ROLE_ADMIN {
|
||||
panic("spaceRole is not correct")
|
||||
}
|
||||
|
||||
spaceMember := this.spaceMemberDao.CheckByUuid(uuid)
|
||||
|
||||
currentUser := this.checkUser(request)
|
||||
canManage := this.spaceMemberService.canManage(currentUser, spaceMember.SpaceUuid)
|
||||
if !canManage {
|
||||
panic(result.BadRequestI18n(request, i18n.PermissionDenied))
|
||||
}
|
||||
|
||||
spaceMember.Role = spaceRole
|
||||
spaceMember = this.spaceMemberDao.Save(spaceMember)
|
||||
|
||||
return this.Success(spaceMember)
|
||||
}
|
||||
|
||||
func (this *SpaceMemberController) Delete(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
uuid := util.ExtractRequestString(request, "uuid")
|
||||
|
||||
spaceMember := this.spaceMemberDao.CheckByUuid(uuid)
|
||||
user := this.checkUser(request)
|
||||
canManage := this.spaceMemberService.canManage(user, spaceMember.SpaceUuid)
|
||||
if !canManage {
|
||||
panic(result.BadRequestI18n(request, i18n.PermissionDenied))
|
||||
}
|
||||
|
||||
this.spaceMemberDao.Delete(spaceMember)
|
||||
|
||||
return this.Success("OK")
|
||||
}
|
||||
|
||||
func (this *SpaceMemberController) Detail(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
uuid := util.ExtractRequestString(request, "uuid")
|
||||
|
||||
spaceMember := this.spaceMemberDao.CheckByUuid(uuid)
|
||||
|
||||
user := this.checkUser(request)
|
||||
|
||||
if spaceMember.UserUuid != user.Uuid {
|
||||
panic(result.UNAUTHORIZED)
|
||||
}
|
||||
|
||||
return this.Success(spaceMember)
|
||||
|
||||
}
|
||||
|
||||
// find my role in the space.
|
||||
func (this *SpaceMemberController) Mine(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
spaceUuid := util.ExtractRequestString(request, "spaceUuid")
|
||||
|
||||
user := this.checkUser(request)
|
||||
spaceMember := this.spaceMemberDao.FindBySpaceUuidAndUserUuid(spaceUuid, user.Uuid)
|
||||
if spaceMember == nil {
|
||||
spaceMember = &SpaceMember{SpaceUuid: spaceUuid, Role: SPACE_MEMBER_GUEST}
|
||||
}
|
||||
if user.Role == USER_ROLE_ADMINISTRATOR {
|
||||
spaceMember.Role = SPACE_MEMBER_ROLE_ADMIN
|
||||
}
|
||||
|
||||
return this.Success(spaceMember)
|
||||
|
||||
}
|
||||
|
||||
func (this *SpaceMemberController) Page(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
page := util.ExtractRequestOptionalInt(request, "page", 0)
|
||||
pageSize := util.ExtractRequestOptionalInt(request, "pageSize", 20)
|
||||
orderCreateTime := util.ExtractRequestOptionalString(request, "orderCreateTime", "")
|
||||
spaceUuid := util.ExtractRequestString(request, "spaceUuid")
|
||||
|
||||
user := this.checkUser(request)
|
||||
canRead := this.spaceMemberService.canRead(user, spaceUuid)
|
||||
if !canRead {
|
||||
panic(result.BadRequestI18n(request, i18n.PermissionDenied))
|
||||
}
|
||||
|
||||
sortArray := []builder.OrderPair{
|
||||
{
|
||||
Key: "create_time",
|
||||
Value: orderCreateTime,
|
||||
},
|
||||
}
|
||||
|
||||
pager := this.spaceMemberDao.Page(page, pageSize, spaceUuid, sortArray)
|
||||
|
||||
//fill the space's user. FIXME: user better way to get User.
|
||||
if pager != nil {
|
||||
for _, spaceMember := range pager.Data.([]*SpaceMember) {
|
||||
spaceMember.User = this.userDao.FindByUuid(spaceMember.UserUuid)
|
||||
}
|
||||
}
|
||||
|
||||
return this.Success(pager)
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
"github.com/eyebluecn/tank/code/tool/builder"
|
||||
"github.com/eyebluecn/tank/code/tool/result"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/eyebluecn/tank/code/tool/uuid"
|
||||
"time"
|
||||
)
|
||||
|
||||
type SpaceMemberDao struct {
|
||||
BaseDao
|
||||
}
|
||||
|
||||
// find by uuid. if not found return nil.
|
||||
func (this *SpaceMemberDao) FindByUuid(uuid string) *SpaceMember {
|
||||
var entity = &SpaceMember{}
|
||||
db := core.CONTEXT.GetDB().Where("uuid = ?", uuid).First(entity)
|
||||
if db.Error != nil {
|
||||
if db.Error.Error() == result.DB_ERROR_NOT_FOUND {
|
||||
return nil
|
||||
} else {
|
||||
panic(db.Error)
|
||||
}
|
||||
}
|
||||
return entity
|
||||
}
|
||||
|
||||
// find by uuid. if not found panic NotFound error
|
||||
func (this *SpaceMemberDao) CheckByUuid(uuid string) *SpaceMember {
|
||||
entity := this.FindByUuid(uuid)
|
||||
if entity == nil {
|
||||
panic(result.NotFound("not found record with uuid = %s", uuid))
|
||||
}
|
||||
return entity
|
||||
}
|
||||
|
||||
// find by spaceUuid and userUuid. if not found return nil.
|
||||
func (this *SpaceMemberDao) FindBySpaceUuidAndUserUuid(spaceUuid string, userUuid string) *SpaceMember {
|
||||
var entity = &SpaceMember{}
|
||||
db := core.CONTEXT.GetDB().Where("space_uuid = ? AND user_uuid = ?", spaceUuid, userUuid).First(entity)
|
||||
|
||||
if db.Error != nil {
|
||||
if db.Error.Error() == result.DB_ERROR_NOT_FOUND {
|
||||
return nil
|
||||
} else {
|
||||
panic(db.Error)
|
||||
}
|
||||
}
|
||||
return entity
|
||||
}
|
||||
|
||||
func (this *SpaceMemberDao) Page(page int, pageSize int, spaceUuid string, sortArray []builder.OrderPair) *Pager {
|
||||
|
||||
count, spaceMembers := this.PlainPage(page, pageSize, spaceUuid, sortArray)
|
||||
pager := NewPager(page, pageSize, count, spaceMembers)
|
||||
|
||||
return pager
|
||||
}
|
||||
|
||||
func (this *SpaceMemberDao) PlainPage(page int, pageSize int, spaceUuid string, sortArray []builder.OrderPair) (int, []*SpaceMember) {
|
||||
|
||||
var wp = &builder.WherePair{}
|
||||
|
||||
if spaceUuid != "" {
|
||||
wp = wp.And(&builder.WherePair{Query: "space_uuid = ?", Args: []interface{}{spaceUuid}})
|
||||
}
|
||||
|
||||
var conditionDB *gorm.DB
|
||||
conditionDB = core.CONTEXT.GetDB().Model(&SpaceMember{}).Where(wp.Query, wp.Args...)
|
||||
|
||||
var count int64 = 0
|
||||
db := conditionDB.Count(&count)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
var spaceMembers []*SpaceMember
|
||||
db = conditionDB.Order(this.GetSortString(sortArray)).Offset(page * pageSize).Limit(pageSize).Find(&spaceMembers)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
return int(count), spaceMembers
|
||||
}
|
||||
|
||||
func (this *SpaceMemberDao) Create(spaceMember *SpaceMember) *SpaceMember {
|
||||
|
||||
timeUUID, _ := uuid.NewV4()
|
||||
spaceMember.Uuid = string(timeUUID.String())
|
||||
spaceMember.CreateTime = time.Now()
|
||||
spaceMember.UpdateTime = time.Now()
|
||||
spaceMember.Sort = time.Now().UnixNano() / 1e6
|
||||
db := core.CONTEXT.GetDB().Create(spaceMember)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
return spaceMember
|
||||
}
|
||||
|
||||
func (this *SpaceMemberDao) Save(spaceMember *SpaceMember) *SpaceMember {
|
||||
|
||||
spaceMember.UpdateTime = time.Now()
|
||||
db := core.CONTEXT.GetDB().Save(spaceMember)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
return spaceMember
|
||||
}
|
||||
|
||||
func (this *SpaceMemberDao) Delete(spaceMember *SpaceMember) {
|
||||
|
||||
db := core.CONTEXT.GetDB().Delete(&spaceMember)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
}
|
||||
|
||||
func (this *SpaceMemberDao) DeleteBySpaceUuid(spaceUuid string) {
|
||||
|
||||
var wp = &builder.WherePair{}
|
||||
|
||||
wp = wp.And(&builder.WherePair{Query: "space_uuid = ?", Args: []interface{}{spaceUuid}})
|
||||
|
||||
db := core.CONTEXT.GetDB().Where(wp.Query, wp.Args).Delete(SpaceMember{})
|
||||
this.PanicError(db.Error)
|
||||
}
|
||||
|
||||
func (this *SpaceMemberDao) CountBySpaceUuid(spaceUuid string) int {
|
||||
var count int64
|
||||
db := core.CONTEXT.GetDB().
|
||||
Model(&SpaceMember{}).
|
||||
Where("space_uuid = ?", spaceUuid).
|
||||
Count(&count)
|
||||
this.PanicError(db.Error)
|
||||
return int(count)
|
||||
}
|
||||
|
||||
// System cleanup.
|
||||
func (this *SpaceMemberDao) Cleanup() {
|
||||
this.logger.Info("[SpaceMemberDao] clean up. Delete all SpaceMember")
|
||||
db := core.CONTEXT.GetDB().Where("uuid is not null").Delete(SpaceMember{})
|
||||
this.PanicError(db.Error)
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
//guest member
|
||||
SPACE_MEMBER_GUEST = "GUEST"
|
||||
//read only member
|
||||
SPACE_MEMBER_ROLE_READ_ONLY = "READ_ONLY"
|
||||
//read write member
|
||||
SPACE_MEMBER_ROLE_READ_WRITE = "READ_WRITE"
|
||||
//admin member
|
||||
SPACE_MEMBER_ROLE_ADMIN = "ADMIN"
|
||||
)
|
||||
|
||||
/**
|
||||
* space member
|
||||
*/
|
||||
type SpaceMember struct {
|
||||
Uuid string `json:"uuid" gorm:"type:char(36);primary_key;unique"`
|
||||
Sort int64 `json:"sort" gorm:"type:bigint(20) not null"`
|
||||
UpdateTime time.Time `json:"updateTime" gorm:"type:timestamp not null;default:CURRENT_TIMESTAMP"`
|
||||
CreateTime time.Time `json:"createTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"`
|
||||
SpaceUuid string `json:"spaceUuid" gorm:"type:char(36);index:idx_space_uuid"`
|
||||
UserUuid string `json:"userUuid" gorm:"type:char(36);index:idx_user_uuid"`
|
||||
Role string `json:"role" gorm:"type:varchar(45)"`
|
||||
User *User `json:"user" gorm:"-"`
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
)
|
||||
|
||||
// @Service
|
||||
type SpaceMemberService struct {
|
||||
BaseBean
|
||||
spaceMemberDao *SpaceMemberDao
|
||||
matterDao *MatterDao
|
||||
bridgeDao *BridgeDao
|
||||
userDao *UserDao
|
||||
}
|
||||
|
||||
func (this *SpaceMemberService) Init() {
|
||||
this.BaseBean.Init()
|
||||
|
||||
b := core.CONTEXT.GetBean(this.spaceMemberDao)
|
||||
if b, ok := b.(*SpaceMemberDao); ok {
|
||||
this.spaceMemberDao = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.matterDao)
|
||||
if b, ok := b.(*MatterDao); ok {
|
||||
this.matterDao = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.bridgeDao)
|
||||
if b, ok := b.(*BridgeDao); ok {
|
||||
this.bridgeDao = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.userDao)
|
||||
if b, ok := b.(*UserDao); ok {
|
||||
this.userDao = b
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (this *SpaceMemberService) Detail(uuid string) *SpaceMember {
|
||||
|
||||
spaceMember := this.spaceMemberDao.CheckByUuid(uuid)
|
||||
|
||||
return spaceMember
|
||||
}
|
||||
|
||||
// create space
|
||||
func (this *SpaceMemberService) CreateMember(space *Space, user *User, spaceRole string) *SpaceMember {
|
||||
|
||||
spaceMember := &SpaceMember{
|
||||
SpaceUuid: space.Uuid,
|
||||
UserUuid: user.Uuid,
|
||||
Role: spaceRole,
|
||||
}
|
||||
|
||||
spaceMember = this.spaceMemberDao.Create(spaceMember)
|
||||
|
||||
return spaceMember
|
||||
|
||||
}
|
||||
|
||||
// 当前用户对于此空间,是否有管理权限。
|
||||
func (this *SpaceMemberService) canManage(user *User, spaceUuid string) bool {
|
||||
if user.Role == USER_ROLE_ADMINISTRATOR {
|
||||
return true
|
||||
}
|
||||
if user.SpaceUuid == spaceUuid {
|
||||
return true
|
||||
}
|
||||
|
||||
//only space's admin can add member.
|
||||
spaceMember := this.spaceMemberDao.FindBySpaceUuidAndUserUuid(spaceUuid, user.Uuid)
|
||||
return this.canManageBySpaceMember(user, spaceMember)
|
||||
}
|
||||
|
||||
// 当前用户对于此空间,是否有可读权限。
|
||||
func (this *SpaceMemberService) canRead(user *User, spaceUuid string) bool {
|
||||
if user.Role == USER_ROLE_ADMINISTRATOR {
|
||||
return true
|
||||
}
|
||||
if user.SpaceUuid == spaceUuid {
|
||||
return true
|
||||
}
|
||||
|
||||
//only space's admin can add member.
|
||||
spaceMember := this.spaceMemberDao.FindBySpaceUuidAndUserUuid(spaceUuid, user.Uuid)
|
||||
return this.canReadBySpaceMember(user, spaceMember)
|
||||
}
|
||||
|
||||
// 当前用户对于此空间,是否有可写权限。
|
||||
func (this *SpaceMemberService) canWrite(user *User, spaceUuid string) bool {
|
||||
if user.Role == USER_ROLE_ADMINISTRATOR {
|
||||
return true
|
||||
}
|
||||
if user.SpaceUuid == spaceUuid {
|
||||
return true
|
||||
}
|
||||
|
||||
//only space's admin can add member.
|
||||
spaceMember := this.spaceMemberDao.FindBySpaceUuidAndUserUuid(spaceUuid, user.Uuid)
|
||||
return this.canWriteBySpaceMember(user, spaceMember)
|
||||
}
|
||||
|
||||
// 当前用户对于此空间,是否有管理权限。
|
||||
func (this *SpaceMemberService) canManageBySpaceMember(user *User, member *SpaceMember) bool {
|
||||
if user.Role == USER_ROLE_ADMINISTRATOR {
|
||||
return true
|
||||
}
|
||||
|
||||
//only space's admin can add member.
|
||||
if member != nil && member.Role == SPACE_MEMBER_ROLE_ADMIN {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// 当前用户对于此空间,是否有可读权限。
|
||||
func (this *SpaceMemberService) canReadBySpaceMember(user *User, member *SpaceMember) bool {
|
||||
if user.Role == USER_ROLE_ADMINISTRATOR {
|
||||
return true
|
||||
}
|
||||
|
||||
//only space's admin can add member.
|
||||
if member != nil {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// 当前用户对于此空间,是否有科协权限。
|
||||
func (this *SpaceMemberService) canWriteBySpaceMember(user *User, member *SpaceMember) bool {
|
||||
if user.Role == USER_ROLE_ADMINISTRATOR {
|
||||
return true
|
||||
}
|
||||
|
||||
//only space's admin can add member.
|
||||
if member != nil && (member.Role == SPACE_MEMBER_ROLE_ADMIN || member.Role == SPACE_MEMBER_ROLE_READ_WRITE) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
//private space
|
||||
SPACE_TYPE_PRIVATE = "PRIVATE"
|
||||
//group shared space.
|
||||
SPACE_TYPE_SHARED = "SHARED"
|
||||
)
|
||||
|
||||
/**
|
||||
* shared space
|
||||
*/
|
||||
type Space struct {
|
||||
Uuid string `json:"uuid" gorm:"type:char(36);primary_key;unique"`
|
||||
Sort int64 `json:"sort" gorm:"type:bigint(20) not null"`
|
||||
UpdateTime time.Time `json:"updateTime" gorm:"type:timestamp not null;default:CURRENT_TIMESTAMP"`
|
||||
CreateTime time.Time `json:"createTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"`
|
||||
Name string `json:"name" gorm:"type:varchar(100) not null;unique"`
|
||||
UserUuid string `json:"userUuid" gorm:"type:char(36)"`
|
||||
SizeLimit int64 `json:"sizeLimit" gorm:"type:bigint(20) not null;default:-1"`
|
||||
TotalSizeLimit int64 `json:"totalSizeLimit" gorm:"type:bigint(20) not null;default:-1"`
|
||||
TotalSize int64 `json:"totalSize" gorm:"type:bigint(20) not null;default:0"`
|
||||
Type string `json:"type" gorm:"type:varchar(45)"`
|
||||
User *User `json:"user" gorm:"-"`
|
||||
}
|
||||
@@ -1,170 +0,0 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
"github.com/eyebluecn/tank/code/tool/i18n"
|
||||
"github.com/eyebluecn/tank/code/tool/result"
|
||||
"net/http"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// @Service
|
||||
type SpaceService struct {
|
||||
BaseBean
|
||||
spaceDao *SpaceDao
|
||||
spaceMemberService *SpaceMemberService
|
||||
matterDao *MatterDao
|
||||
bridgeDao *BridgeDao
|
||||
userDao *UserDao
|
||||
}
|
||||
|
||||
func (this *SpaceService) Init() {
|
||||
this.BaseBean.Init()
|
||||
|
||||
b := core.CONTEXT.GetBean(this.spaceDao)
|
||||
if b, ok := b.(*SpaceDao); ok {
|
||||
this.spaceDao = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.spaceMemberService)
|
||||
if b, ok := b.(*SpaceMemberService); ok {
|
||||
this.spaceMemberService = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.matterDao)
|
||||
if b, ok := b.(*MatterDao); ok {
|
||||
this.matterDao = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.bridgeDao)
|
||||
if b, ok := b.(*BridgeDao); ok {
|
||||
this.bridgeDao = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.userDao)
|
||||
if b, ok := b.(*UserDao); ok {
|
||||
this.userDao = b
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (this *SpaceService) Detail(uuid string) *Space {
|
||||
|
||||
space := this.spaceDao.CheckByUuid(uuid)
|
||||
|
||||
return space
|
||||
}
|
||||
|
||||
// create space
|
||||
func (this *SpaceService) CreateSpace(
|
||||
request *http.Request,
|
||||
name string,
|
||||
user *User,
|
||||
sizeLimit int64,
|
||||
totalSizeLimit int64,
|
||||
spaceType string) *Space {
|
||||
|
||||
userUuid := ""
|
||||
//validation work.
|
||||
if m, _ := regexp.MatchString(USERNAME_PATTERN, name); !m {
|
||||
panic(result.BadRequestI18n(request, i18n.SpaceNameError))
|
||||
}
|
||||
|
||||
if spaceType == SPACE_TYPE_PRIVATE {
|
||||
if user == nil {
|
||||
panic("private space requires user.")
|
||||
}
|
||||
|
||||
userUuid = user.Uuid
|
||||
if this.spaceDao.CountByUserUuid(userUuid) > 0 {
|
||||
panic(result.BadRequestI18n(request, i18n.SpaceExclusive, name))
|
||||
}
|
||||
|
||||
} else if spaceType == SPACE_TYPE_SHARED {
|
||||
|
||||
} else {
|
||||
panic("Not supported spaceType:" + spaceType)
|
||||
}
|
||||
|
||||
if this.spaceDao.CountByName(name) > 0 {
|
||||
panic(result.BadRequestI18n(request, i18n.SpaceNameExist, name))
|
||||
}
|
||||
|
||||
space := &Space{
|
||||
Name: name,
|
||||
UserUuid: userUuid,
|
||||
SizeLimit: sizeLimit,
|
||||
TotalSizeLimit: totalSizeLimit,
|
||||
TotalSize: 0,
|
||||
Type: spaceType,
|
||||
}
|
||||
|
||||
space = this.spaceDao.Create(space)
|
||||
|
||||
return space
|
||||
|
||||
}
|
||||
|
||||
// checkout a adminAble space.
|
||||
func (this *SpaceService) CheckAdminAbleByUuid(request *http.Request, user *User, spaceUuid string) *Space {
|
||||
space := this.spaceDao.CheckByUuid(spaceUuid)
|
||||
if space.Type == SPACE_TYPE_PRIVATE && user.Uuid == space.UserUuid {
|
||||
return space
|
||||
}
|
||||
|
||||
manage := this.spaceMemberService.canManage(user, spaceUuid)
|
||||
if !manage {
|
||||
panic(result.BadRequestI18n(request, i18n.PermissionDenied))
|
||||
}
|
||||
|
||||
return space
|
||||
}
|
||||
|
||||
// checkout a writable space.
|
||||
func (this *SpaceService) CheckWritableByUuid(request *http.Request, user *User, spaceUuid string) *Space {
|
||||
space := this.spaceDao.CheckByUuid(spaceUuid)
|
||||
if space.Type == SPACE_TYPE_PRIVATE && user.Uuid == space.UserUuid {
|
||||
return space
|
||||
}
|
||||
|
||||
writable := this.spaceMemberService.canWrite(user, spaceUuid)
|
||||
if !writable {
|
||||
panic(result.BadRequestI18n(request, i18n.PermissionDenied))
|
||||
}
|
||||
|
||||
return space
|
||||
}
|
||||
|
||||
// checkout a readable space.
|
||||
func (this *SpaceService) CheckReadableByUuid(request *http.Request, user *User, spaceUuid string) *Space {
|
||||
space := this.spaceDao.CheckByUuid(spaceUuid)
|
||||
if space.Type == SPACE_TYPE_PRIVATE && user.Uuid == space.UserUuid {
|
||||
return space
|
||||
}
|
||||
|
||||
manage := this.spaceMemberService.canRead(user, spaceUuid)
|
||||
if !manage {
|
||||
panic(result.BadRequestI18n(request, i18n.PermissionDenied))
|
||||
}
|
||||
|
||||
return space
|
||||
}
|
||||
|
||||
// edit space's info
|
||||
func (this *SpaceService) Edit(request *http.Request, user *User, spaceUuid string, sizeLimit int64, totalSizeLimit int64) *Space {
|
||||
space := this.CheckAdminAbleByUuid(request, user, spaceUuid)
|
||||
|
||||
if sizeLimit < 0 && sizeLimit != -1 {
|
||||
panic("sizeLimit cannot be negative expect -1.")
|
||||
}
|
||||
|
||||
if totalSizeLimit < 0 && totalSizeLimit != -1 {
|
||||
panic("totalSizeLimit cannot be negative expect -1.")
|
||||
}
|
||||
|
||||
space.SizeLimit = sizeLimit
|
||||
space.TotalSizeLimit = totalSizeLimit
|
||||
space = this.spaceDao.Save(space)
|
||||
|
||||
return space
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
// system tasks service
|
||||
// @Service
|
||||
//@Service
|
||||
type TaskService struct {
|
||||
BaseBean
|
||||
footprintService *FootprintService
|
||||
@@ -16,7 +16,6 @@ type TaskService struct {
|
||||
preferenceService *PreferenceService
|
||||
matterService *MatterService
|
||||
userDao *UserDao
|
||||
spaceDao *SpaceDao
|
||||
|
||||
//whether scan task is running
|
||||
scanTaskRunning bool
|
||||
@@ -49,15 +48,11 @@ func (this *TaskService) Init() {
|
||||
if b, ok := b.(*UserDao); ok {
|
||||
this.userDao = b
|
||||
}
|
||||
b = core.CONTEXT.GetBean(this.spaceDao)
|
||||
if b, ok := b.(*SpaceDao); ok {
|
||||
this.spaceDao = b
|
||||
}
|
||||
|
||||
this.scanTaskRunning = false
|
||||
}
|
||||
|
||||
// init the clean footprint task.
|
||||
//init the clean footprint task.
|
||||
func (this *TaskService) InitCleanFootprintTask() {
|
||||
|
||||
//use standard cron expression. 5 fields. ()
|
||||
@@ -70,7 +65,7 @@ func (this *TaskService) InitCleanFootprintTask() {
|
||||
this.logger.Info("[cron job] Every day 00:10 delete Footprint data of 8 days ago.")
|
||||
}
|
||||
|
||||
// init the elt task.
|
||||
//init the elt task.
|
||||
func (this *TaskService) InitEtlTask() {
|
||||
|
||||
expression := "5 0 * * *"
|
||||
@@ -82,7 +77,7 @@ func (this *TaskService) InitEtlTask() {
|
||||
this.logger.Info("[cron job] Everyday 00:05 ETL dashboard data.")
|
||||
}
|
||||
|
||||
// init the clean deleted matters task.
|
||||
//init the clean deleted matters task.
|
||||
func (this *TaskService) InitCleanDeletedMattersTask() {
|
||||
|
||||
expression := "0 1 * * *"
|
||||
@@ -94,7 +89,7 @@ func (this *TaskService) InitCleanDeletedMattersTask() {
|
||||
this.logger.Info("[cron job] Everyday 01:00 Clean deleted matters.")
|
||||
}
|
||||
|
||||
// scan task.
|
||||
//scan task.
|
||||
func (this *TaskService) doScanTask() {
|
||||
|
||||
if this.scanTaskRunning {
|
||||
@@ -126,12 +121,12 @@ func (this *TaskService) doScanTask() {
|
||||
|
||||
if scanConfig.Scope == SCAN_SCOPE_ALL {
|
||||
//scan all user's root folder.
|
||||
this.userDao.PageHandle("", "", func(user *User, space *Space) {
|
||||
this.userDao.PageHandle("", "", func(user *User) {
|
||||
|
||||
core.RunWithRecovery(func() {
|
||||
|
||||
this.matterService.DeleteByPhysics(request, user, space)
|
||||
this.matterService.ScanPhysics(request, user, space)
|
||||
this.matterService.DeleteByPhysics(request, user)
|
||||
this.matterService.ScanPhysics(request, user)
|
||||
|
||||
})
|
||||
|
||||
@@ -147,11 +142,10 @@ func (this *TaskService) doScanTask() {
|
||||
} else {
|
||||
this.logger.Info("scan custom user folder. username = %s", username)
|
||||
|
||||
space := this.spaceDao.CheckByUuid(user.SpaceUuid)
|
||||
core.RunWithRecovery(func() {
|
||||
|
||||
this.matterService.DeleteByPhysics(request, user, space)
|
||||
this.matterService.ScanPhysics(request, user, space)
|
||||
this.matterService.DeleteByPhysics(request, user)
|
||||
this.matterService.ScanPhysics(request, user)
|
||||
|
||||
})
|
||||
|
||||
@@ -161,7 +155,7 @@ func (this *TaskService) doScanTask() {
|
||||
|
||||
}
|
||||
|
||||
// init the scan task.
|
||||
//init the scan task.
|
||||
func (this *TaskService) InitScanTask() {
|
||||
|
||||
if this.scanTaskCron != nil {
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
"time"
|
||||
)
|
||||
|
||||
type UploadToken struct {
|
||||
Uuid string `json:"uuid" gorm:"type:char(36);primary_key;unique"`
|
||||
Sort int64 `json:"sort" gorm:"type:bigint(20) not null"`
|
||||
UpdateTime time.Time `json:"updateTime" gorm:"type:timestamp not null;default:CURRENT_TIMESTAMP"`
|
||||
CreateTime time.Time `json:"createTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"`
|
||||
Base
|
||||
UserUuid string `json:"userUuid" gorm:"type:char(36) not null"`
|
||||
FolderUuid string `json:"folderUuid" gorm:"type:char(36) not null"`
|
||||
MatterUuid string `json:"matterUuid" gorm:"type:char(36) not null"`
|
||||
@@ -18,3 +16,7 @@ type UploadToken struct {
|
||||
Size int64 `json:"size" gorm:"type:bigint(20) not null;default:0"`
|
||||
Ip string `json:"ip" gorm:"type:varchar(128) not null"`
|
||||
}
|
||||
|
||||
func (this *UploadToken) TableName() string {
|
||||
return core.TABLE_PREFIX + "upload_token"
|
||||
}
|
||||
|
||||
@@ -16,8 +16,6 @@ type UserController struct {
|
||||
BaseController
|
||||
preferenceService *PreferenceService
|
||||
userService *UserService
|
||||
spaceDao *SpaceDao
|
||||
spaceService *SpaceService
|
||||
matterService *MatterService
|
||||
}
|
||||
|
||||
@@ -34,14 +32,6 @@ func (this *UserController) Init() {
|
||||
this.userService = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.spaceDao)
|
||||
if b, ok := b.(*SpaceDao); ok {
|
||||
this.spaceDao = b
|
||||
}
|
||||
b = core.CONTEXT.GetBean(this.spaceService)
|
||||
if b, ok := b.(*SpaceService); ok {
|
||||
this.spaceService = b
|
||||
}
|
||||
b = core.CONTEXT.GetBean(this.matterService)
|
||||
if b, ok := b.(*MatterService); ok {
|
||||
this.matterService = b
|
||||
@@ -106,7 +96,7 @@ func (this *UserController) innerLogin(writer http.ResponseWriter, request *http
|
||||
this.userDao.Save(user)
|
||||
}
|
||||
|
||||
// login by username and password
|
||||
//login by username and password
|
||||
func (this *UserController) Login(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
username := request.FormValue("username")
|
||||
@@ -126,14 +116,10 @@ func (this *UserController) Login(writer http.ResponseWriter, request *http.Requ
|
||||
}
|
||||
this.innerLogin(writer, request, user)
|
||||
|
||||
//append the space info.
|
||||
space := this.spaceDao.FindByUuid(user.SpaceUuid)
|
||||
user.Space = space
|
||||
|
||||
return this.Success(user)
|
||||
}
|
||||
|
||||
// login by authentication.
|
||||
//login by authentication.
|
||||
func (this *UserController) AuthenticationLogin(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
authentication := request.FormValue("authentication")
|
||||
@@ -154,18 +140,13 @@ func (this *UserController) AuthenticationLogin(writer http.ResponseWriter, requ
|
||||
return this.Success(user)
|
||||
}
|
||||
|
||||
// fetch current user's info.
|
||||
//fetch current user's info.
|
||||
func (this *UserController) Info(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
user := this.checkUser(request)
|
||||
|
||||
//append the space info.
|
||||
space := this.spaceDao.FindByUuid(user.SpaceUuid)
|
||||
user.Space = space
|
||||
|
||||
return this.Success(user)
|
||||
}
|
||||
|
||||
// register by username and password. After registering, will auto login.
|
||||
//register by username and password. After registering, will auto login.
|
||||
func (this *UserController) Register(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
username := request.FormValue("username")
|
||||
@@ -188,7 +169,15 @@ func (this *UserController) Register(writer http.ResponseWriter, request *http.R
|
||||
panic(result.BadRequestI18n(request, i18n.UsernameExist, username))
|
||||
}
|
||||
|
||||
user := this.userService.CreateUser(request, username, -1, preference.DefaultTotalSizeLimit, password, USER_ROLE_USER)
|
||||
user := &User{
|
||||
Role: USER_ROLE_USER,
|
||||
Username: username,
|
||||
Password: util.GetBcrypt(password),
|
||||
TotalSizeLimit: preference.DefaultTotalSizeLimit,
|
||||
Status: USER_STATUS_OK,
|
||||
}
|
||||
|
||||
user = this.userDao.Create(user)
|
||||
|
||||
//auto login
|
||||
this.innerLogin(writer, request, user)
|
||||
@@ -201,11 +190,32 @@ func (this *UserController) Create(writer http.ResponseWriter, request *http.Req
|
||||
username := request.FormValue("username")
|
||||
password := request.FormValue("password")
|
||||
role := request.FormValue("role")
|
||||
sizeLimitStr := request.FormValue("sizeLimit")
|
||||
totalSizeLimitStr := request.FormValue("totalSizeLimit")
|
||||
|
||||
sizeLimit := util.ExtractRequestInt64(request, "sizeLimit")
|
||||
totalSizeLimit := util.ExtractRequestInt64(request, "totalSizeLimit")
|
||||
//only admin can edit user's sizeLimit
|
||||
var sizeLimit int64 = 0
|
||||
if sizeLimitStr == "" {
|
||||
panic("user's limit size is required")
|
||||
} else {
|
||||
intSizeLimit, err := strconv.Atoi(sizeLimitStr)
|
||||
if err != nil {
|
||||
this.PanicError(err)
|
||||
}
|
||||
sizeLimit = int64(intSizeLimit)
|
||||
}
|
||||
|
||||
var totalSizeLimit int64 = 0
|
||||
if totalSizeLimitStr == "" {
|
||||
panic("user's total limit size is required")
|
||||
} else {
|
||||
intTotalSizeLimit, err := strconv.Atoi(totalSizeLimitStr)
|
||||
if err != nil {
|
||||
this.PanicError(err)
|
||||
}
|
||||
totalSizeLimit = int64(intTotalSizeLimit)
|
||||
}
|
||||
|
||||
//validation work.
|
||||
if m, _ := regexp.MatchString(USERNAME_PATTERN, username); !m {
|
||||
panic(result.BadRequestI18n(request, i18n.UsernameError))
|
||||
}
|
||||
@@ -217,16 +227,21 @@ func (this *UserController) Create(writer http.ResponseWriter, request *http.Req
|
||||
if this.userDao.CountByUsername(username) > 0 {
|
||||
panic(result.BadRequestI18n(request, i18n.UsernameExist, username))
|
||||
}
|
||||
if this.spaceDao.CountByName(username) > 0 {
|
||||
panic(result.BadRequestI18n(request, i18n.SpaceNameExist, username))
|
||||
}
|
||||
|
||||
//check user role.
|
||||
if role != USER_ROLE_USER && role != USER_ROLE_ADMINISTRATOR {
|
||||
panic(result.BadRequestI18n(request, i18n.UserRoleError))
|
||||
role = USER_ROLE_USER
|
||||
}
|
||||
|
||||
user := this.userService.CreateUser(request, username, sizeLimit, totalSizeLimit, password, role)
|
||||
user := &User{
|
||||
Username: username,
|
||||
Password: util.GetBcrypt(password),
|
||||
Role: role,
|
||||
SizeLimit: sizeLimit,
|
||||
TotalSizeLimit: totalSizeLimit,
|
||||
Status: USER_STATUS_OK,
|
||||
}
|
||||
|
||||
user = this.userDao.Create(user)
|
||||
|
||||
return this.Success(user)
|
||||
}
|
||||
@@ -235,11 +250,10 @@ func (this *UserController) Edit(writer http.ResponseWriter, request *http.Reque
|
||||
|
||||
uuid := request.FormValue("uuid")
|
||||
avatarUrl := request.FormValue("avatarUrl")
|
||||
sizeLimitStr := request.FormValue("sizeLimit")
|
||||
totalSizeLimitStr := request.FormValue("totalSizeLimit")
|
||||
role := request.FormValue("role")
|
||||
|
||||
sizeLimit := util.ExtractRequestInt64(request, "sizeLimit")
|
||||
totalSizeLimit := util.ExtractRequestInt64(request, "totalSizeLimit")
|
||||
|
||||
user := this.checkUser(request)
|
||||
currentUser := this.userDao.CheckByUuid(uuid)
|
||||
|
||||
@@ -247,6 +261,29 @@ func (this *UserController) Edit(writer http.ResponseWriter, request *http.Reque
|
||||
|
||||
if user.Role == USER_ROLE_ADMINISTRATOR {
|
||||
//only admin can edit user's sizeLimit
|
||||
var sizeLimit int64 = 0
|
||||
if sizeLimitStr == "" {
|
||||
panic("user's limit size is required")
|
||||
} else {
|
||||
intSizeLimit, err := strconv.Atoi(sizeLimitStr)
|
||||
if err != nil {
|
||||
this.PanicError(err)
|
||||
}
|
||||
sizeLimit = int64(intSizeLimit)
|
||||
}
|
||||
currentUser.SizeLimit = sizeLimit
|
||||
|
||||
var totalSizeLimit int64 = 0
|
||||
if totalSizeLimitStr == "" {
|
||||
panic("user's total limit size is required")
|
||||
} else {
|
||||
intTotalSizeLimit, err := strconv.Atoi(totalSizeLimitStr)
|
||||
if err != nil {
|
||||
this.PanicError(err)
|
||||
}
|
||||
totalSizeLimit = int64(intTotalSizeLimit)
|
||||
}
|
||||
currentUser.TotalSizeLimit = totalSizeLimit
|
||||
|
||||
if role == USER_ROLE_USER || role == USER_ROLE_ADMINISTRATOR {
|
||||
currentUser.Role = role
|
||||
@@ -256,17 +293,11 @@ func (this *UserController) Edit(writer http.ResponseWriter, request *http.Reque
|
||||
panic(result.UNAUTHORIZED)
|
||||
}
|
||||
|
||||
//edit user's info
|
||||
currentUser = this.userDao.Save(currentUser)
|
||||
|
||||
//edit user's private space info.
|
||||
space := this.spaceService.Edit(request, user, currentUser.SpaceUuid, sizeLimit, totalSizeLimit)
|
||||
|
||||
//remove cache user.
|
||||
this.userService.RemoveCacheUserByUuid(currentUser.Uuid)
|
||||
|
||||
currentUser.Space = space
|
||||
|
||||
return this.Success(currentUser)
|
||||
}
|
||||
|
||||
@@ -276,10 +307,6 @@ func (this *UserController) Detail(writer http.ResponseWriter, request *http.Req
|
||||
|
||||
user := this.userDao.CheckByUuid(uuid)
|
||||
|
||||
//append the space info.
|
||||
space := this.spaceDao.FindByUuid(user.SpaceUuid)
|
||||
user.Space = space
|
||||
|
||||
return this.Success(user)
|
||||
|
||||
}
|
||||
@@ -364,12 +391,6 @@ func (this *UserController) Page(writer http.ResponseWriter, request *http.Reque
|
||||
|
||||
pager := this.userDao.Page(page, pageSize, username, status, sortArray)
|
||||
|
||||
//append the space info. FIXME: user better way to get Space.
|
||||
for _, u := range pager.Data.([]*User) {
|
||||
space := this.spaceDao.FindByUuid(u.SpaceUuid)
|
||||
u.Space = space
|
||||
}
|
||||
|
||||
return this.Success(pager)
|
||||
}
|
||||
|
||||
@@ -418,14 +439,13 @@ func (this *UserController) Transfiguration(writer http.ResponseWriter, request
|
||||
return this.Success(session.Uuid)
|
||||
}
|
||||
|
||||
// scan user's physics files. create index into EyeblueTank
|
||||
//scan user's physics files. create index into EyeblueTank
|
||||
func (this *UserController) Scan(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
uuid := request.FormValue("uuid")
|
||||
currentUser := this.userDao.CheckByUuid(uuid)
|
||||
space := this.spaceDao.CheckByUuid(currentUser.SpaceUuid)
|
||||
this.matterService.DeleteByPhysics(request, currentUser, space)
|
||||
this.matterService.ScanPhysics(request, currentUser, space)
|
||||
this.matterService.DeleteByPhysics(request, currentUser)
|
||||
this.matterService.ScanPhysics(request, currentUser)
|
||||
|
||||
return this.Success("OK")
|
||||
}
|
||||
@@ -474,7 +494,7 @@ func (this *UserController) ChangePassword(writer http.ResponseWriter, request *
|
||||
return this.Success(user)
|
||||
}
|
||||
|
||||
// admin reset password.
|
||||
//admin reset password.
|
||||
func (this *UserController) ResetPassword(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
||||
|
||||
userUuid := request.FormValue("userUuid")
|
||||
|
||||
@@ -11,17 +11,10 @@ import (
|
||||
|
||||
type UserDao struct {
|
||||
BaseDao
|
||||
spaceDao *SpaceDao
|
||||
}
|
||||
|
||||
func (this *UserDao) Init() {
|
||||
this.BaseDao.Init()
|
||||
|
||||
b := core.CONTEXT.GetBean(this.spaceDao)
|
||||
if b, ok := b.(*SpaceDao); ok {
|
||||
this.spaceDao = b
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (this *UserDao) Create(user *User) *User {
|
||||
@@ -43,7 +36,7 @@ func (this *UserDao) Create(user *User) *User {
|
||||
return user
|
||||
}
|
||||
|
||||
// find by uuid. if not found return nil.
|
||||
//find by uuid. if not found return nil.
|
||||
func (this *UserDao) FindByUuid(uuid string) *User {
|
||||
var entity = &User{}
|
||||
db := core.CONTEXT.GetDB().Where("uuid = ?", uuid).First(entity)
|
||||
@@ -57,7 +50,7 @@ func (this *UserDao) FindByUuid(uuid string) *User {
|
||||
return entity
|
||||
}
|
||||
|
||||
// find by uuid. if not found panic NotFound error
|
||||
//find by uuid. if not found panic NotFound error
|
||||
func (this *UserDao) CheckByUuid(uuid string) *User {
|
||||
entity := this.FindByUuid(uuid)
|
||||
if entity == nil {
|
||||
@@ -101,7 +94,7 @@ func (this *UserDao) PlainPage(page int, pageSize int, username string, status s
|
||||
wp = wp.And(&builder.WherePair{Query: "status = ?", Args: []interface{}{status}})
|
||||
}
|
||||
|
||||
var count int64 = 0
|
||||
count := 0
|
||||
db := core.CONTEXT.GetDB().Model(&User{}).Where(wp.Query, wp.Args...).Count(&count)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
@@ -115,11 +108,11 @@ func (this *UserDao) PlainPage(page int, pageSize int, username string, status s
|
||||
|
||||
this.PanicError(db.Error)
|
||||
|
||||
return int(count), users
|
||||
return count, users
|
||||
}
|
||||
|
||||
// handle user page by page.
|
||||
func (this *UserDao) PageHandle(username string, status string, fun func(user *User, space *Space)) {
|
||||
//handle user page by page.
|
||||
func (this *UserDao) PageHandle(username string, status string, fun func(user *User)) {
|
||||
|
||||
//delete share and bridges.
|
||||
pageSize := 1000
|
||||
@@ -136,21 +129,20 @@ func (this *UserDao) PageHandle(username string, status string, fun func(user *U
|
||||
for page = 0; page < totalPages; page++ {
|
||||
_, users := this.PlainPage(0, pageSize, username, status, sortArray)
|
||||
for _, u := range users {
|
||||
space := this.spaceDao.CheckByUuid(u.SpaceUuid)
|
||||
fun(u, space)
|
||||
fun(u)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *UserDao) CountByUsername(username string) int {
|
||||
var count int64
|
||||
var count int
|
||||
db := core.CONTEXT.GetDB().
|
||||
Model(&User{}).
|
||||
Where("username = ?", username).
|
||||
Count(&count)
|
||||
this.PanicError(db.Error)
|
||||
return int(count)
|
||||
return count
|
||||
}
|
||||
|
||||
func (this *UserDao) Save(user *User) *User {
|
||||
@@ -162,7 +154,7 @@ func (this *UserDao) Save(user *User) *User {
|
||||
return user
|
||||
}
|
||||
|
||||
// find all 2.0 users.
|
||||
//find all 2.0 users.
|
||||
func (this *UserDao) FindUsers20() []*User {
|
||||
var users []*User
|
||||
var wp = &builder.WherePair{}
|
||||
@@ -187,7 +179,7 @@ func (this *UserDao) Delete(user *User) {
|
||||
this.PanicError(db.Error)
|
||||
}
|
||||
|
||||
// System cleanup.
|
||||
//System cleanup.
|
||||
func (this *UserDao) Cleanup() {
|
||||
this.logger.Info("[UserDao] clean up. Delete all User")
|
||||
db := core.CONTEXT.GetDB().Where("uuid is not null and role != ?", USER_ROLE_ADMINISTRATOR).Delete(User{})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package rest
|
||||
|
||||
import (
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -27,18 +28,20 @@ const (
|
||||
)
|
||||
|
||||
type User struct {
|
||||
Uuid string `json:"uuid" gorm:"type:char(36);primary_key;unique"`
|
||||
Sort int64 `json:"sort" gorm:"type:bigint(20) not null"`
|
||||
UpdateTime time.Time `json:"updateTime" gorm:"type:timestamp not null;default:CURRENT_TIMESTAMP"`
|
||||
CreateTime time.Time `json:"createTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"`
|
||||
Role string `json:"role" gorm:"type:varchar(45)"`
|
||||
Username string `json:"username" gorm:"type:varchar(45) not null;unique"`
|
||||
Password string `json:"-" gorm:"type:varchar(255)"`
|
||||
AvatarUrl string `json:"avatarUrl" gorm:"type:varchar(255)"`
|
||||
LastIp string `json:"lastIp" gorm:"type:varchar(128)"`
|
||||
LastTime time.Time `json:"lastTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"`
|
||||
Base
|
||||
Role string `json:"role" gorm:"type:varchar(45)"`
|
||||
Username string `json:"username" gorm:"type:varchar(45) not null;unique"`
|
||||
Password string `json:"-" gorm:"type:varchar(255)"`
|
||||
AvatarUrl string `json:"avatarUrl" gorm:"type:varchar(255)"`
|
||||
LastIp string `json:"lastIp" gorm:"type:varchar(128)"`
|
||||
LastTime time.Time `json:"lastTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"`
|
||||
SizeLimit int64 `json:"sizeLimit" gorm:"type:bigint(20) not null;default:-1"`
|
||||
TotalSizeLimit int64 `json:"totalSizeLimit" gorm:"type:bigint(20) not null;default:-1"`
|
||||
TotalSize int64 `json:"totalSize" gorm:"type:bigint(20) not null;default:0"`
|
||||
Status string `json:"status" gorm:"type:varchar(45)"`
|
||||
}
|
||||
|
||||
SpaceUuid string `json:"spaceUuid" gorm:"type:char(36);unique"`
|
||||
Status string `json:"status" gorm:"type:varchar(45)"`
|
||||
Space *Space `json:"space" gorm:"-"`
|
||||
// set User's table name to be `profiles`
|
||||
func (this *User) TableName() string {
|
||||
return core.TABLE_PREFIX + "user"
|
||||
}
|
||||
|
||||
@@ -11,14 +11,12 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// @Service
|
||||
//@Service
|
||||
type UserService struct {
|
||||
BaseBean
|
||||
userDao *UserDao
|
||||
sessionDao *SessionDao
|
||||
|
||||
spaceService *SpaceService
|
||||
|
||||
//file lock
|
||||
locker *cache.Table
|
||||
|
||||
@@ -45,11 +43,6 @@ func (this *UserService) Init() {
|
||||
this.sessionDao = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.spaceService)
|
||||
if b, ok := b.(*SpaceService); ok {
|
||||
this.spaceService = b
|
||||
}
|
||||
|
||||
b = core.CONTEXT.GetBean(this.matterDao)
|
||||
if b, ok := b.(*MatterDao); ok {
|
||||
this.matterDao = b
|
||||
@@ -89,7 +82,7 @@ func (this *UserService) Init() {
|
||||
this.locker = cache.NewTable()
|
||||
}
|
||||
|
||||
// lock a user's operation. If lock, user cannot operate file.
|
||||
//lock a user's operation. If lock, user cannot operate file.
|
||||
func (this *UserService) MatterLock(userUuid string) {
|
||||
|
||||
cacheItem, err := this.locker.Value(userUuid)
|
||||
@@ -105,7 +98,7 @@ func (this *UserService) MatterLock(userUuid string) {
|
||||
this.locker.Add(userUuid, duration, true)
|
||||
}
|
||||
|
||||
// unlock
|
||||
//unlock
|
||||
func (this *UserService) MatterUnlock(userUuid string) {
|
||||
|
||||
exist := this.locker.Exists(userUuid)
|
||||
@@ -117,8 +110,8 @@ func (this *UserService) MatterUnlock(userUuid string) {
|
||||
}
|
||||
}
|
||||
|
||||
// load session to SessionCache. This method will be invoked in every request.
|
||||
// authorize by 1. cookie 2. username and password in request form. 3. Basic Auth
|
||||
//load session to SessionCache. This method will be invoked in every request.
|
||||
//authorize by 1. cookie 2. username and password in request form. 3. Basic Auth
|
||||
func (this *UserService) PreHandle(writer http.ResponseWriter, request *http.Request) {
|
||||
|
||||
sessionId := util.GetSessionUuidFromRequest(request, core.COOKIE_AUTH_KEY)
|
||||
@@ -189,7 +182,7 @@ func (this *UserService) PreHandle(writer http.ResponseWriter, request *http.Req
|
||||
|
||||
}
|
||||
|
||||
// find a cache user by its userUuid
|
||||
//find a cache user by its userUuid
|
||||
func (this *UserService) FindCacheUsersByUuid(userUuid string) []*User {
|
||||
|
||||
var users []*User
|
||||
@@ -211,7 +204,7 @@ func (this *UserService) FindCacheUsersByUuid(userUuid string) []*User {
|
||||
return users
|
||||
}
|
||||
|
||||
// remove cache user by its userUuid
|
||||
//remove cache user by its userUuid
|
||||
func (this *UserService) RemoveCacheUserByUuid(userUuid string) {
|
||||
|
||||
var sessionId interface{}
|
||||
@@ -240,32 +233,7 @@ func (this *UserService) RemoveCacheUserByUuid(userUuid string) {
|
||||
}
|
||||
}
|
||||
|
||||
// create user
|
||||
func (this *UserService) CreateUser(request *http.Request, username string, sizeLimit int64, totalSizeLimit int64, password string, role string) *User {
|
||||
|
||||
user := &User{
|
||||
Username: username,
|
||||
Password: util.GetBcrypt(password),
|
||||
Role: role,
|
||||
Status: USER_STATUS_OK,
|
||||
}
|
||||
|
||||
user = this.userDao.Create(user)
|
||||
|
||||
//create space.
|
||||
space := this.spaceService.CreateSpace(request, username, user, sizeLimit, totalSizeLimit, SPACE_TYPE_PRIVATE)
|
||||
|
||||
//update user's space.
|
||||
user.SpaceUuid = space.Uuid
|
||||
this.userDao.Save(user)
|
||||
|
||||
user.Space = space
|
||||
|
||||
return user
|
||||
|
||||
}
|
||||
|
||||
// delete user
|
||||
//delete user
|
||||
func (this *UserService) DeleteUser(request *http.Request, currentUser *User) {
|
||||
|
||||
//delete from cache
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
"github.com/eyebluecn/tank/code/tool/util"
|
||||
"github.com/json-iterator/go"
|
||||
"gorm.io/gorm/schema"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"time"
|
||||
@@ -20,8 +19,6 @@ type TankConfig struct {
|
||||
matterPath string
|
||||
//mysql url.
|
||||
mysqlUrl string
|
||||
//sqlite file path
|
||||
sqliteFolder string
|
||||
//configs in tank.json
|
||||
item *ConfigItem
|
||||
}
|
||||
@@ -32,10 +29,7 @@ type ConfigItem struct {
|
||||
ServerPort int
|
||||
//file storage location. eg./var/www/matter
|
||||
MatterPath string
|
||||
//********db configurations.********
|
||||
//default value is "mysql"
|
||||
DbType string
|
||||
//********mysql configurations..********
|
||||
//mysql configurations.
|
||||
//mysql port
|
||||
MysqlPort int
|
||||
//mysql host
|
||||
@@ -48,9 +42,12 @@ type ConfigItem struct {
|
||||
MysqlPassword string
|
||||
//mysql charset
|
||||
MysqlCharset string
|
||||
//********sqlite configurations..********
|
||||
//default value is matter/
|
||||
SqliteFolder string
|
||||
|
||||
OssAccessKey string
|
||||
OssSecretKey string
|
||||
OssEndpoint string
|
||||
OssCustomHost string
|
||||
OssBucket string
|
||||
}
|
||||
|
||||
//validate whether the config file is ok
|
||||
@@ -61,39 +58,57 @@ func (this *ConfigItem) validate() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
if this.DbType == "sqlite" {
|
||||
if this.MysqlUsername == "" {
|
||||
core.LOGGER.Error("MysqlUsername is not configured")
|
||||
return false
|
||||
}
|
||||
|
||||
} else {
|
||||
if this.MysqlPassword == "" {
|
||||
core.LOGGER.Error("MysqlPassword is not configured")
|
||||
return false
|
||||
}
|
||||
|
||||
if this.MysqlUsername == "" {
|
||||
core.LOGGER.Error("MysqlUsername is not configured")
|
||||
return false
|
||||
}
|
||||
if this.MysqlHost == "" {
|
||||
core.LOGGER.Error("MysqlHost is not configured")
|
||||
return false
|
||||
}
|
||||
|
||||
if this.MysqlPassword == "" {
|
||||
core.LOGGER.Error("MysqlPassword is not configured")
|
||||
return false
|
||||
}
|
||||
if this.MysqlPort == 0 {
|
||||
core.LOGGER.Error("MysqlPort is not configured")
|
||||
return false
|
||||
}
|
||||
|
||||
if this.MysqlHost == "" {
|
||||
core.LOGGER.Error("MysqlHost is not configured")
|
||||
return false
|
||||
}
|
||||
if this.MysqlSchema == "" {
|
||||
core.LOGGER.Error("MysqlSchema is not configured")
|
||||
return false
|
||||
}
|
||||
if this.MysqlCharset == "" {
|
||||
core.LOGGER.Error("MysqlCharset is not configured")
|
||||
return false
|
||||
}
|
||||
|
||||
if this.MysqlPort == 0 {
|
||||
core.LOGGER.Error("MysqlPort is not configured")
|
||||
return false
|
||||
}
|
||||
if this.OssAccessKey == "" {
|
||||
core.LOGGER.Error("OssAccessKey is not configured")
|
||||
return false
|
||||
}
|
||||
|
||||
if this.MysqlSchema == "" {
|
||||
core.LOGGER.Error("MysqlSchema is not configured")
|
||||
return false
|
||||
}
|
||||
if this.OssSecretKey == "" {
|
||||
core.LOGGER.Error("OssSecretKey is not configured")
|
||||
return false
|
||||
}
|
||||
|
||||
if this.MysqlCharset == "" {
|
||||
core.LOGGER.Error("MysqlCharset is not configured")
|
||||
return false
|
||||
}
|
||||
if this.OssEndpoint == "" {
|
||||
core.LOGGER.Error("OssEndpoint is not configured")
|
||||
return false
|
||||
}
|
||||
|
||||
if this.OssCustomHost == "" {
|
||||
core.LOGGER.Error("OssCustomHost is not configured")
|
||||
return false
|
||||
}
|
||||
if this.OssBucket == "" {
|
||||
core.LOGGER.Error("OssBucket is not configured")
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
@@ -183,49 +198,40 @@ func (this *TankConfig) ServerPort() int {
|
||||
return this.serverPort
|
||||
}
|
||||
|
||||
//get the db type
|
||||
func (this *TankConfig) DbType() string {
|
||||
return this.item.DbType
|
||||
}
|
||||
|
||||
//mysql url
|
||||
func (this *TankConfig) MysqlUrl() string {
|
||||
return this.mysqlUrl
|
||||
}
|
||||
|
||||
//get the sqlite path
|
||||
func (this *TankConfig) SqliteFolder() string {
|
||||
if this.sqliteFolder == "" {
|
||||
//use default file location.
|
||||
if this.item == nil || this.item.SqliteFolder == "" {
|
||||
this.sqliteFolder = util.GetHomePath() + "/matter"
|
||||
} else {
|
||||
this.sqliteFolder = util.UniformPath(this.item.SqliteFolder)
|
||||
}
|
||||
util.MakeDirAll(this.sqliteFolder)
|
||||
}
|
||||
|
||||
return this.sqliteFolder
|
||||
}
|
||||
|
||||
//matter path
|
||||
func (this *TankConfig) MatterPath() string {
|
||||
return this.matterPath
|
||||
}
|
||||
|
||||
//matter path
|
||||
func (this *TankConfig) NamingStrategy() schema.NamingStrategy {
|
||||
return schema.NamingStrategy{
|
||||
TablePrefix: core.TABLE_PREFIX,
|
||||
SingularTable: true,
|
||||
}
|
||||
func (this *TankConfig) OssAccessKey() string {
|
||||
return this.item.OssAccessKey
|
||||
}
|
||||
|
||||
//TODO: Finish the installation. Write config to tank.json. add sqlite support.
|
||||
func (this *TankConfig) FinishInstall(dbType string, mysqlPort int, mysqlHost string, mysqlSchema string, mysqlUsername string, mysqlPassword string, mysqlCharset string) {
|
||||
func (this *TankConfig) OssSecretKey() string {
|
||||
return this.item.OssSecretKey
|
||||
}
|
||||
|
||||
func (this *TankConfig) OssEndpoint() string {
|
||||
return this.item.OssEndpoint
|
||||
}
|
||||
|
||||
func (this *TankConfig) OssCustomHost() string {
|
||||
return this.item.OssCustomHost
|
||||
}
|
||||
|
||||
func (this *TankConfig) OssBucket() string {
|
||||
return this.item.OssBucket
|
||||
}
|
||||
|
||||
//Finish the installation. Write config to tank.json
|
||||
func (this *TankConfig) FinishInstall(mysqlPort int, mysqlHost string, mysqlSchema string, mysqlUsername string, mysqlPassword string, mysqlCharset string) {
|
||||
|
||||
var configItem = &ConfigItem{
|
||||
DbType: dbType,
|
||||
//server port
|
||||
ServerPort: core.CONFIG.ServerPort(),
|
||||
//file storage location. eg./var/www/matter
|
||||
|
||||
@@ -4,15 +4,9 @@ import (
|
||||
"github.com/eyebluecn/tank/code/core"
|
||||
"github.com/eyebluecn/tank/code/rest"
|
||||
"github.com/eyebluecn/tank/code/tool/cache"
|
||||
"github.com/glebarez/sqlite"
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
"log"
|
||||
"github.com/jinzhu/gorm"
|
||||
"net/http"
|
||||
"os"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
type TankContext struct {
|
||||
@@ -69,60 +63,28 @@ func (this *TankContext) Cleanup() {
|
||||
}
|
||||
}
|
||||
|
||||
// can serve as http server.
|
||||
//can serve as http server.
|
||||
func (this *TankContext) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
|
||||
this.Router.ServeHTTP(writer, request)
|
||||
}
|
||||
|
||||
func (this *TankContext) OpenDb() {
|
||||
|
||||
//log strategy.
|
||||
dbLogger := logger.New(
|
||||
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
|
||||
logger.Config{
|
||||
SlowThreshold: time.Second, // slow SQL 1s
|
||||
LogLevel: logger.Warn, // log level. open when debug.
|
||||
IgnoreRecordNotFoundError: true, // ignore ErrRecordNotFound
|
||||
Colorful: false, // colorful print
|
||||
},
|
||||
)
|
||||
var err error = nil
|
||||
this.db, err = gorm.Open("mysql", core.CONFIG.MysqlUrl())
|
||||
|
||||
//table name strategy.
|
||||
namingStrategy := core.CONFIG.NamingStrategy()
|
||||
|
||||
if core.CONFIG.DbType() == "sqlite" {
|
||||
|
||||
var err error = nil
|
||||
this.db, err = gorm.Open(sqlite.Open(core.CONFIG.SqliteFolder()+"/tank.sqlite"), &gorm.Config{Logger: dbLogger, NamingStrategy: namingStrategy})
|
||||
|
||||
if err != nil {
|
||||
core.LOGGER.Panic("failed to connect mysql database")
|
||||
}
|
||||
|
||||
//sqlite lock issue. https://gist.github.com/mrnugget/0eda3b2b53a70fa4a894
|
||||
phyDb, err := this.db.DB()
|
||||
phyDb.SetMaxOpenConns(1)
|
||||
|
||||
} else {
|
||||
|
||||
var err error = nil
|
||||
this.db, err = gorm.Open(mysql.Open(core.CONFIG.MysqlUrl()), &gorm.Config{Logger: dbLogger, NamingStrategy: namingStrategy})
|
||||
|
||||
if err != nil {
|
||||
core.LOGGER.Panic("failed to connect mysql database")
|
||||
}
|
||||
if err != nil {
|
||||
core.LOGGER.Panic("failed to connect mysql database")
|
||||
}
|
||||
|
||||
//whether open the db sql log. (only true when debug)
|
||||
this.db.LogMode(false)
|
||||
}
|
||||
|
||||
func (this *TankContext) CloseDb() {
|
||||
|
||||
if this.db != nil {
|
||||
db, err := this.db.DB()
|
||||
if err != nil {
|
||||
core.LOGGER.Error("occur error when get *sql.DB %s", err.Error())
|
||||
}
|
||||
err = db.Close()
|
||||
err := this.db.Close()
|
||||
if err != nil {
|
||||
core.LOGGER.Error("occur error when closing db %s", err.Error())
|
||||
}
|
||||
@@ -185,6 +147,9 @@ func (this *TankContext) registerBeans() {
|
||||
this.registerBean(new(rest.MatterDao))
|
||||
this.registerBean(new(rest.MatterService))
|
||||
|
||||
//oss
|
||||
this.registerBean(new(rest.OssService))
|
||||
|
||||
//preference
|
||||
this.registerBean(new(rest.PreferenceController))
|
||||
this.registerBean(new(rest.PreferenceDao))
|
||||
@@ -204,16 +169,6 @@ func (this *TankContext) registerBeans() {
|
||||
this.registerBean(new(rest.ShareDao))
|
||||
this.registerBean(new(rest.ShareService))
|
||||
|
||||
//space
|
||||
this.registerBean(new(rest.SpaceController))
|
||||
this.registerBean(new(rest.SpaceDao))
|
||||
this.registerBean(new(rest.SpaceService))
|
||||
|
||||
//space member
|
||||
this.registerBean(new(rest.SpaceMemberController))
|
||||
this.registerBean(new(rest.SpaceMemberDao))
|
||||
this.registerBean(new(rest.SpaceMemberService))
|
||||
|
||||
//uploadToken
|
||||
this.registerBean(new(rest.UploadTokenDao))
|
||||
|
||||
@@ -251,7 +206,7 @@ func (this *TankContext) initBeans() {
|
||||
}
|
||||
}
|
||||
|
||||
// if application installed. invoke this method.
|
||||
//if application installed. invoke this method.
|
||||
func (this *TankContext) InstallOk() {
|
||||
|
||||
if core.CONFIG.Installed() {
|
||||
|
||||