Compare commits
9 Commits
cffa82226d
...
symbol_lin
Author | SHA1 | Date | |
---|---|---|---|
4687aa64ec | |||
3f38998fe5 | |||
1ec66adda0 | |||
60c8843734 | |||
f779053040 | |||
6becac74d0 | |||
e64a73eb67 | |||
6626afa6b6 | |||
6d35063027 |
@ -2,7 +2,7 @@
|
||||
|
||||
[English Version](https://tank-doc.eyeblue.cn/en)
|
||||
|
||||
# 蓝眼云盘(3.1.5)
|
||||
# 蓝眼云盘(3.1.6)
|
||||
[在线Demo](https://tanker.eyeblue.cn) (体验账号: demo 密码:123456)
|
||||
|
||||
蓝眼云盘是蓝眼开源系列代表作品之一,致力于打造精致,优雅,简约的云盘。核心功能如下:
|
||||
@ -42,11 +42,11 @@
|
||||
|
||||
如果您也想参与进来,请尽情的fork, star, post issue, pull requests
|
||||
|
||||
当然你可以加入钉钉群一起直接交流,在钉钉群中可以获取最新beta版本。
|
||||
当然你可以加入钉钉群(一群已满员)一起直接交流,在钉钉群中可以获取最新beta版本。
|
||||
|
||||

|
||||
|
||||
群号:23156361
|
||||
群号:44754005
|
||||
|
||||
|
||||
### Support
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 208 KiB After Width: | Height: | Size: 136 KiB |
@ -1,7 +1,7 @@
|
||||
{
|
||||
"files": {
|
||||
"main.css": "/static/css/main.8994a208.css",
|
||||
"main.js": "/static/js/main.7a2a6dcd.js",
|
||||
"main.css": "/static/css/main.b03c51fb.css",
|
||||
"main.js": "/static/js/main.b94b1947.js",
|
||||
"static/media/logo.png": "/static/media/logo.847e54ef7fb4b744fad4.png",
|
||||
"static/media/empty.svg": "/static/media/empty.20ceb38d310075aa4c3cdaae210afb65.svg",
|
||||
"static/media/psd.svg": "/static/media/psd.bf2ac5411c0132f292787f45855934f2.svg",
|
||||
@ -18,11 +18,11 @@
|
||||
"static/media/folder.svg": "/static/media/folder.0bdd7430280c98bf4970b6af5a061c2c.svg",
|
||||
"static/media/archive.svg": "/static/media/archive.684c1e42f233aa9d53a8910d4fee091e.svg",
|
||||
"index.html": "/index.html",
|
||||
"main.8994a208.css.map": "/static/css/main.8994a208.css.map",
|
||||
"main.7a2a6dcd.js.map": "/static/js/main.7a2a6dcd.js.map"
|
||||
"main.b03c51fb.css.map": "/static/css/main.b03c51fb.css.map",
|
||||
"main.b94b1947.js.map": "/static/js/main.b94b1947.js.map"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/css/main.8994a208.css",
|
||||
"static/js/main.7a2a6dcd.js"
|
||||
"static/css/main.b03c51fb.css",
|
||||
"static/js/main.b94b1947.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.7a2a6dcd.js"></script><link href="/static/css/main.8994a208.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><script defer="defer" src="/static/js/main.b94b1947.js"></script><link href="/static/css/main.b03c51fb.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run EyeblueTank.</noscript><div id="root"></div></body></html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
8
build/html/static/css/main.b03c51fb.css
Normal file
8
build/html/static/css/main.b03c51fb.css
Normal file
File diff suppressed because one or more lines are too long
1
build/html/static/css/main.b03c51fb.css.map
Normal file
1
build/html/static/css/main.b03c51fb.css.map
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -11,7 +11,7 @@
|
||||
@REM prepare the variables.
|
||||
|
||||
@REM version name
|
||||
SET VERSION_NAME=tank-3.1.5
|
||||
SET VERSION_NAME=tank-3.1.6
|
||||
ECHO VERSION_NAME: %VERSION_NAME%
|
||||
@REM golang proxy
|
||||
SET GOPROXY=https://goproxy.cn
|
||||
|
@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
@ -9,7 +10,7 @@
|
||||
#prepare the variables.
|
||||
|
||||
# version name
|
||||
VERSION_NAME=tank-3.1.5
|
||||
VERSION_NAME=tank-3.1.6
|
||||
echo "VERSION_NAME: ${VERSION_NAME}"
|
||||
# golang proxy
|
||||
GOPROXY=https://goproxy.cn
|
||||
|
@ -14,7 +14,7 @@ const (
|
||||
//db table's prefix. tank31_ means current version is tank:3.1.x
|
||||
TABLE_PREFIX = "tank31_"
|
||||
|
||||
VERSION = "3.1.5"
|
||||
VERSION = "3.1.6"
|
||||
)
|
||||
|
||||
type Config interface {
|
||||
|
@ -412,23 +412,35 @@ func (this *MatterDao) SizeByPuuidAndUserUuid(matterUuid string, userUuid string
|
||||
}
|
||||
|
||||
//delete a file from db and disk.
|
||||
func (this *MatterDao) Delete(matter *Matter) {
|
||||
func (this *MatterDao) Delete(matter *Matter, symbolLinkDir bool, symbolLevel int) {
|
||||
|
||||
// recursive if dir
|
||||
if matter.Dir {
|
||||
stat, err := os.Lstat(matter.AbsolutePath())
|
||||
if err == nil && stat.Mode()&os.ModeSymlink > 0 {
|
||||
symbolLinkDir = true
|
||||
}
|
||||
if symbolLinkDir {
|
||||
symbolLevel++
|
||||
}
|
||||
matters := this.FindByPuuidAndUserUuid(matter.Uuid, matter.UserUuid, nil)
|
||||
|
||||
for _, f := range matters {
|
||||
this.Delete(f)
|
||||
this.Delete(f, symbolLinkDir, symbolLevel)
|
||||
}
|
||||
|
||||
//delete from db.
|
||||
db := core.CONTEXT.GetDB().Delete(&matter)
|
||||
this.PanicError(db.Error)
|
||||
|
||||
if symbolLinkDir {
|
||||
if symbolLevel == 0 {
|
||||
os.Remove(matter.AbsolutePath())
|
||||
}
|
||||
} else {
|
||||
//delete dir from disk.
|
||||
util.DeleteEmptyDir(matter.AbsolutePath())
|
||||
|
||||
}
|
||||
} else {
|
||||
|
||||
//delete from db.
|
||||
@ -442,11 +454,12 @@ func (this *MatterDao) Delete(matter *Matter) {
|
||||
this.bridgeDao.DeleteByMatterUuid(matter.Uuid)
|
||||
|
||||
//delete from disk.
|
||||
if !symbolLinkDir {
|
||||
err := os.Remove(matter.AbsolutePath())
|
||||
if err != nil {
|
||||
this.logger.Error("occur error when deleting file. %v", err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,7 +250,7 @@ func (this *MatterService) Delete(request *http.Request, matter *Matter, user *U
|
||||
panic(result.BadRequest("matter cannot be nil"))
|
||||
}
|
||||
|
||||
this.matterDao.Delete(matter)
|
||||
this.matterDao.Delete(matter, false, -1)
|
||||
|
||||
//re compute the size of Route.
|
||||
this.ComputeRouteSize(matter.Puuid, user)
|
||||
@ -987,7 +987,7 @@ func (this *MatterService) mirror(request *http.Request, srcPath string, destDir
|
||||
|
||||
this.logger.Info("mirror srcPath = %s destPath = %s", srcPath, destDirMatter.Path)
|
||||
|
||||
if fileStat.IsDir() {
|
||||
if fileStat.IsDir() || (fileStat.Mode()&os.ModeSymlink > 0) {
|
||||
|
||||
//判断当前文件夹下,文件是否已经存在了。
|
||||
srcDirMatter := this.matterDao.FindByUserUuidAndPuuidAndDirAndName(user.Uuid, destDirMatter.Uuid, TRUE, fileStat.Name())
|
||||
@ -1231,7 +1231,7 @@ func (this *MatterService) ScanPhysics(request *http.Request, user *User) {
|
||||
}
|
||||
|
||||
func (this *MatterService) scanPhysicsFolder(request *http.Request, dirInfo os.FileInfo, dirMatter *Matter, user *User) {
|
||||
if !dirInfo.IsDir() {
|
||||
if !dirInfo.IsDir() && !(dirInfo.Mode()&os.ModeSymlink > 0) {
|
||||
return
|
||||
}
|
||||
|
||||
@ -1277,7 +1277,7 @@ func (this *MatterService) scanPhysicsFolder(request *http.Request, dirInfo os.F
|
||||
|
||||
} else {
|
||||
|
||||
if fileInfo.IsDir() {
|
||||
if fileInfo.IsDir() || (fileInfo.Mode()&os.ModeSymlink > 0) {
|
||||
|
||||
//create folder.
|
||||
matter = this.createDirectory(request, dirMatter, name, user)
|
||||
|
@ -278,6 +278,10 @@ 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 {
|
||||
|
||||
|
@ -92,6 +92,11 @@ func (this *ShareService) ValidateMatter(request *http.Request, shareUuid string
|
||||
|
||||
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 {
|
||||
|
||||
|
@ -53,7 +53,7 @@ func Zip(srcPath string, destPath string) error {
|
||||
fileHeader.Name = strings.TrimPrefix(path, baseDirPath)
|
||||
|
||||
// directory need /
|
||||
if fileInfo.IsDir() {
|
||||
if fileInfo.IsDir() || (fileInfo.Mode()&os.ModeSymlink > 0) {
|
||||
fileHeader.Name += "/"
|
||||
}
|
||||
|
||||
|
@ -203,7 +203,7 @@ func (fs *memFS) walk(op, fullname string, f func(dir *memFSNode, frag string, f
|
||||
Err: os.ErrNotExist,
|
||||
}
|
||||
}
|
||||
if !child.mode.IsDir() {
|
||||
if !child.mode.IsDir() && !(child.mode&os.ModeSymlink > 0) {
|
||||
return &os.PathError{
|
||||
Op: op,
|
||||
Path: original,
|
||||
@ -468,7 +468,7 @@ func (f *memFileInfo) Name() string { return f.name }
|
||||
func (f *memFileInfo) Size() int64 { return f.size }
|
||||
func (f *memFileInfo) Mode() os.FileMode { return f.mode }
|
||||
func (f *memFileInfo) ModTime() time.Time { return f.modTime }
|
||||
func (f *memFileInfo) IsDir() bool { return f.mode.IsDir() }
|
||||
func (f *memFileInfo) IsDir() bool { return f.mode.IsDir() || (f.mode&os.ModeSymlink > 0) }
|
||||
func (f *memFileInfo) Sys() interface{} { return nil }
|
||||
|
||||
// A memFile is a File implementation for a memFSNode. It is a per-file (not
|
||||
@ -495,7 +495,7 @@ func (f *memFile) Close() error {
|
||||
func (f *memFile) Read(p []byte) (int, error) {
|
||||
f.n.mu.Lock()
|
||||
defer f.n.mu.Unlock()
|
||||
if f.n.mode.IsDir() {
|
||||
if f.n.mode.IsDir() || (f.n.mode&os.ModeSymlink > 0) {
|
||||
return 0, os.ErrInvalid
|
||||
}
|
||||
if f.pos >= len(f.n.data) {
|
||||
@ -509,7 +509,7 @@ func (f *memFile) Read(p []byte) (int, error) {
|
||||
func (f *memFile) Readdir(count int) ([]os.FileInfo, error) {
|
||||
f.n.mu.Lock()
|
||||
defer f.n.mu.Unlock()
|
||||
if !f.n.mode.IsDir() {
|
||||
if !f.n.mode.IsDir() && !(f.n.mode&os.ModeSymlink > 0) {
|
||||
return nil, os.ErrInvalid
|
||||
}
|
||||
old := f.pos
|
||||
@ -564,7 +564,7 @@ func (f *memFile) Write(p []byte) (int, error) {
|
||||
f.n.mu.Lock()
|
||||
defer f.n.mu.Unlock()
|
||||
|
||||
if f.n.mode.IsDir() {
|
||||
if f.n.mode.IsDir() || (f.n.mode&os.ModeSymlink > 0) {
|
||||
return 0, os.ErrInvalid
|
||||
}
|
||||
if f.pos < len(f.n.data) {
|
||||
@ -693,7 +693,7 @@ func copyFiles(ctx context.Context, fs FileSystem, src, dst string, overwrite bo
|
||||
}
|
||||
}
|
||||
|
||||
if srcStat.IsDir() {
|
||||
if srcStat.IsDir() || (srcStat.Mode()&os.ModeSymlink > 0) {
|
||||
if err := fs.Mkdir(ctx, dst, srcPerm); err != nil {
|
||||
return http.StatusForbidden, err
|
||||
}
|
||||
@ -752,12 +752,12 @@ func walkFS(ctx context.Context, fs FileSystem, depth int, name string, info os.
|
||||
// This implementation is based on Walk's code in the standard path/filepath package.
|
||||
err := walkFn(name, info, nil)
|
||||
if err != nil {
|
||||
if info.IsDir() && err == filepath.SkipDir {
|
||||
if (info.IsDir() || (info.Mode()&os.ModeSymlink > 0)) && err == filepath.SkipDir {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
if !info.IsDir() || depth == 0 {
|
||||
if (!info.IsDir() && !(info.Mode()&os.ModeSymlink > 0)) || depth == 0 {
|
||||
return nil
|
||||
}
|
||||
if depth == 1 {
|
||||
@ -785,7 +785,7 @@ func walkFS(ctx context.Context, fs FileSystem, depth int, name string, info os.
|
||||
} else {
|
||||
err = walkFS(ctx, fs, depth, filename, fileInfo, walkFn)
|
||||
if err != nil {
|
||||
if !fileInfo.IsDir() || err != filepath.SkipDir {
|
||||
if (!fileInfo.IsDir() && !(fileInfo.Mode()&os.ModeSymlink > 0)) || err != filepath.SkipDir {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -240,7 +240,7 @@ func find(ctx context.Context, ss []string, fs FileSystem, name string) ([]strin
|
||||
return nil, err
|
||||
}
|
||||
ss = append(ss, name)
|
||||
if stat.IsDir() {
|
||||
if stat.IsDir() || (stat.Mode()&os.ModeSymlink > 0) {
|
||||
f, err := fs.OpenFile(ctx, name, os.O_RDONLY, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -480,7 +480,7 @@ func testFS(t *testing.T, fs FileSystem) {
|
||||
var stat os.FileInfo
|
||||
fileName := parts[0]
|
||||
if stat, opErr = fs.Stat(ctx, fileName); opErr == nil {
|
||||
if stat.IsDir() {
|
||||
if stat.IsDir() || (stat.Mode()&os.ModeSymlink > 0) {
|
||||
got = "dir"
|
||||
} else {
|
||||
got = strconv.Itoa(int(stat.Size()))
|
||||
@ -538,7 +538,7 @@ func TestMemFSRoot(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("i=%d: Stat: %v", i, err)
|
||||
}
|
||||
if !stat.IsDir() {
|
||||
if !stat.IsDir() && !(stat.Mode()&os.ModeSymlink > 0) {
|
||||
t.Fatalf("i=%d: Stat.IsDir is false, want true", i)
|
||||
}
|
||||
|
||||
|
@ -176,7 +176,7 @@ func Props(ctx context.Context, fs FileSystem, ls LockSystem, name string, pname
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
isDir := fi.IsDir()
|
||||
isDir := fi.IsDir() || (fi.Mode()&os.ModeSymlink > 0)
|
||||
|
||||
var deadProps map[xml.Name]Property
|
||||
if dph, ok := f.(DeadPropsHolder); ok {
|
||||
|
@ -177,7 +177,7 @@ func (h *Handler) handleOptions(w http.ResponseWriter, r *http.Request) (status
|
||||
ctx := r.Context()
|
||||
allow := "OPTIONS, LOCK, PUT, MKCOL"
|
||||
if fi, err := h.FileSystem.Stat(ctx, reqPath); err == nil {
|
||||
if fi.IsDir() {
|
||||
if fi.IsDir() || (fi.Mode()&os.ModeSymlink > 0) {
|
||||
allow = "OPTIONS, LOCK, DELETE, PROPPATCH, COPY, MOVE, UNLOCK, PROPFIND"
|
||||
} else {
|
||||
allow = "OPTIONS, LOCK, GET, HEAD, POST, DELETE, PROPPATCH, COPY, MOVE, UNLOCK, PROPFIND, PUT"
|
||||
@ -207,7 +207,7 @@ func (h *Handler) handleGetHeadPost(w http.ResponseWriter, r *http.Request) (sta
|
||||
if err != nil {
|
||||
return http.StatusNotFound, err
|
||||
}
|
||||
if fi.IsDir() {
|
||||
if fi.IsDir() || (fi.Mode()&os.ModeSymlink > 0) {
|
||||
return http.StatusMethodNotAllowed, nil
|
||||
}
|
||||
etag, err := findETag(ctx, h.FileSystem, h.LockSystem, reqPath, fi)
|
||||
@ -557,7 +557,7 @@ func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request) (status
|
||||
return err
|
||||
}
|
||||
href := path.Join(h.Prefix, reqPath)
|
||||
if href != "/" && info.IsDir() {
|
||||
if href != "/" && (info.IsDir() || (info.Mode()&os.ModeSymlink > 0)) {
|
||||
href += "/"
|
||||
}
|
||||
return mw.write(MakePropstatResponse(href, pstats))
|
||||
|
Reference in New Issue
Block a user