ali path and link

pull/548/head
微凉 2021-10-28 22:50:09 +08:00
parent 98f7dffed9
commit 0a50fbd080
13 changed files with 207 additions and 41 deletions

View File

@ -2,9 +2,9 @@ package bootstrap
import (
"github.com/Xhofe/alist/conf"
"github.com/allegro/bigcache/v3"
"github.com/eko/gocache/v2/cache"
"github.com/eko/gocache/v2/store"
goCache "github.com/patrickmn/go-cache"
log "github.com/sirupsen/logrus"
"time"
)
@ -12,9 +12,7 @@ import (
// InitCache init cache
func InitCache() {
log.Infof("init cache...")
bigCacheConfig := bigcache.DefaultConfig(60 * time.Minute)
bigCacheConfig.HardMaxCacheSize = 512
bigCacheClient, _ := bigcache.NewBigCache(bigCacheConfig)
bigCacheStore := store.NewBigcache(bigCacheClient, nil)
conf.Cache = cache.New(bigCacheStore)
goCacheClient := goCache.New(60*time.Minute, 120*time.Minute)
goCacheStore := store.NewGoCache(goCacheClient, nil)
conf.Cache = cache.New(goCacheStore)
}

View File

@ -67,7 +67,7 @@ func InitModel() {
log.Fatalf("not supported database type: %s", config.Type)
}
log.Infof("auto migrate model")
err := conf.DB.AutoMigrate(&model.SettingItem{}, &model.Account{})
err := conf.DB.AutoMigrate(&model.SettingItem{}, &model.Account{},&model.Meta{})
if err != nil {
log.Fatalf("failed to auto migrate")
}
@ -87,7 +87,7 @@ func initAccounts() {
model.RegisterAccount(account)
driver, ok := drivers.GetDriver(account.Type)
if !ok {
log.Error("no [%s] driver", driver)
log.Errorf("no [%s] driver", driver)
} else {
err := driver.Save(&account, nil)
if err != nil {

View File

@ -8,6 +8,7 @@ import (
"github.com/go-resty/resty/v2"
"github.com/robfig/cron/v3"
log "github.com/sirupsen/logrus"
"path/filepath"
"time"
)
@ -29,16 +30,22 @@ type AliRespError struct {
Message string `json:"message"`
}
type AliFiles struct {
Items []AliFile `json:"items"`
NextMarker string `json:"next_marker"`
}
type AliFile struct {
DriveId string `json:"drive_id"`
CreatedAt *time.Time `json:"created_at"`
FileExtension string `json:"file_extension"`
FileId string `json:"file_id"`
Type string `json:"type"`
Name string `json:"name"`
ParentFileId string `json:"parent_file_id"`
UpdatedAt *time.Time `json:"updated_at"`
Size int64 `json:"size"`
//Thumbnail string `json:"thumbnail"`
Thumbnail string `json:"thumbnail"`
Url string `json:"url"`
}
@ -51,8 +58,47 @@ func AliToFile(file AliFile) *model.File {
}
}
func (a AliDrive) GetFiles(fileId string, account *model.Account) ([]AliFile, error) {
marker := "first"
res := make([]AliFile, 0)
for marker != "" {
if marker == "first" {
marker = ""
}
var resp AliFiles
var e AliRespError
_, err := aliClient.R().
SetResult(&resp).
SetError(&e).
SetHeader("authorization", "Bearer\t"+account.AccessToken).
SetBody(JsonStr(Json{
"drive_id": account.DriveId,
"fields": "*",
"image_thumbnail_process": "image/resize,w_50",
"image_url_process": "image/resize,w_1920/format,jpeg",
"limit": account.Limit,
"marker": marker,
"order_by": account.OrderBy,
"order_direction": account.OrderDirection,
"parent_file_id": fileId,
"video_thumbnail_process": "video/snapshot,t_0,f_jpg,w_50",
})).Post("https://api.aliyundrive.com/v2/file/list")
if err != nil {
return nil, err
}
if e.Code != "" {
return nil, fmt.Errorf("%s", e.Message)
}
marker = resp.NextMarker
res = append(res, resp.Items...)
}
return res, nil
}
// path: /aaa/bbb
func (a AliDrive) Path(path string, account *model.Account) (*model.File, []*model.File, error) {
path = utils.ParsePath(path)
log.Debugf("ali path: %s", path)
cache, err := conf.Cache.Get(conf.Ctx, path)
if err == nil {
file, ok := cache.(AliFile)
@ -67,15 +113,80 @@ func (a AliDrive) Path(path string, account *model.Account) (*model.File, []*mod
return nil, res, nil
}
} else {
fileId := account.RootFolder
if path != "/" {
dir, name := filepath.Split(path)
dir = utils.ParsePath(dir)
_, _, err = a.Path(dir, account)
if err != nil {
return nil, nil, err
}
parentFiles_, _ := conf.Cache.Get(conf.Ctx, dir)
parentFiles, _ := parentFiles_.([]AliFile)
found := false
for _, file := range parentFiles {
if file.Name == name {
found = true
if file.Type == "file" {
return AliToFile(file), nil, nil
} else {
fileId = file.FileId
break
}
}
panic("implement me")
}
if !found {
return nil, nil, fmt.Errorf("path not found")
}
}
files, err := a.GetFiles(fileId, account)
if err != nil {
return nil, nil, err
}
_ = conf.Cache.Set(conf.Ctx, path, files, nil)
res := make([]*model.File, 0)
for _, file := range files {
res = append(res, AliToFile(file))
}
return nil, res, nil
}
}
func (a AliDrive) Link(path string, account *model.Account) (string, error) {
panic("implement me")
dir, name := filepath.Split(path)
dir = utils.ParsePath(dir)
_, _, err := a.Path(dir, account)
if err != nil {
return "", err
}
parentFiles_, _ := conf.Cache.Get(conf.Ctx, dir)
parentFiles, _ := parentFiles_.([]AliFile)
for _, file := range parentFiles {
if file.Name == name {
if file.Type == "file" {
var resp Json
var e AliRespError
_, err = aliClient.R().SetResult(&resp).
SetError(&e).
SetHeader("authorization", "Bearer\t"+account.AccessToken).
SetBody(Json{
"drive_id": account.DriveId,
"file_id": file.FileId,
"expire_sec": 14400,
}).Post("https://api.aliyundrive.com/v2/file/get_download_url")
if err != nil {
return "", err
}
if e.Code != "" {
return "", fmt.Errorf("%s",e.Message)
}
return resp["url"].(string), nil
} else {
return "", fmt.Errorf("can't down folder")
}
}
}
return "", fmt.Errorf("path not found")
}
type AliTokenResp struct {
@ -111,6 +222,13 @@ func (a AliDrive) Save(account *model.Account, old *model.Account) error {
if err != nil {
return err
}
var resp Json
_, _ = aliClient.R().SetResult(&resp).
SetBody("{}").
SetHeader("authorization", "Bearer\t"+access).
Post("https://api.aliyundrive.com/v2/user/get")
log.Debugf("user info: %+v", resp)
account.DriveId = resp["default_drive_id"].(string)
account.RefreshToken, account.AccessToken = refresh, access
cronId, err := conf.Cron.AddFunc("@every 2h", func() {
name := account.Name

6
go.mod
View File

@ -3,10 +3,12 @@ module github.com/Xhofe/alist
go 1.17
require (
github.com/allegro/bigcache/v3 v3.0.1
github.com/eko/gocache/v2 v2.1.0
github.com/go-playground/validator/v10 v10.9.0
github.com/go-resty/resty/v2 v2.6.0
github.com/gofiber/fiber/v2 v2.20.2
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/robfig/cron/v3 v3.0.0
github.com/sirupsen/logrus v1.8.1
gorm.io/driver/mysql v1.1.2
gorm.io/driver/postgres v1.1.2
@ -25,7 +27,6 @@ require (
github.com/go-playground/locales v0.14.0 // indirect
github.com/go-playground/universal-translator v0.18.0 // indirect
github.com/go-redis/redis/v8 v8.9.0 // indirect
github.com/go-resty/resty/v2 v2.6.0 // indirect
github.com/go-sql-driver/mysql v1.6.0 // indirect
github.com/golang/protobuf v1.4.3 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
@ -47,7 +48,6 @@ require (
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.18.0 // indirect
github.com/prometheus/procfs v0.6.0 // indirect
github.com/robfig/cron/v3 v3.0.0 // indirect
github.com/spf13/cast v1.3.1 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.31.0 // indirect

2
go.sum
View File

@ -22,8 +22,6 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/allegro/bigcache/v2 v2.2.5 h1:mRc8r6GQjuJsmSKQNPsR5jQVXc8IJ1xsW5YXUYMLfqI=
github.com/allegro/bigcache/v2 v2.2.5/go.mod h1:FppZsIO+IZk7gCuj5FiIDHGygD9xvWQcqg1uIPMb6tY=
github.com/allegro/bigcache/v3 v3.0.1 h1:Q4Xl3chywXuJNOw7NV+MeySd3zGQDj4KCpkCg0te8mc=
github.com/allegro/bigcache/v3 v3.0.1/go.mod h1:aPyh7jEvrog9zAwx5N7+JUQX5dZTSGpxF1LAR4dr35I=
github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
github.com/andybalholm/brotli v1.0.3 h1:fpcw+r1N1h0Poc1F/pHbW40cUm/lMEQslZtCkBQ0UnM=
github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=

View File

@ -13,7 +13,7 @@ import (
"net/http"
)
func init() {
func Init() {
flag.StringVar(&conf.ConfigFile, "conf", "config.json", "config file")
flag.BoolVar(&conf.Debug,"debug",false,"start with debug mode")
flag.Parse()
@ -25,6 +25,7 @@ func init() {
}
func main() {
Init()
app := fiber.New()
app.Use("/",filesystem.New(filesystem.Config{
Root: http.FS(public.Public),

12
main_test.go Normal file
View File

@ -0,0 +1,12 @@
package main
import (
"fmt"
"net/url"
"testing"
)
func TestUrl(t *testing.T) {
s,_ := url.QueryUnescape("/ali/%E7%8C%AA%E5%A4%B4%E7%9A%84%E6%96%87%E4%BB%B6%5B%E5%98%BF%E5%98%BF%5D/%E9%82%B9%E9%82%B9%E7%9A%84%E6%96%87%E4%BB%B6/%E6%A1%8C%E9%9D%A2%E5%A3%81%E7%BA%B8/v2-e8f266ba17ae387eefed1cb22b2b5e4e_r.jpg")
fmt.Print(s)
}

View File

@ -15,6 +15,7 @@ type Account struct {
Status string
CronId int
DriveId string
Limit int `json:"limit"`
OrderBy string `json:"order_by"`
OrderDirection string `json:"order_direction"`
}
@ -79,4 +80,3 @@ func GetAccounts() []*Account {
}
return accounts
}

View File

@ -1,8 +1,20 @@
package model
import "github.com/Xhofe/alist/conf"
type Meta struct {
Path string `json:"path" gorm:"primaryKey"`
Password string `json:"password"`
Hide bool `json:"hide"`
Ignore bool `json:"ignore"`
}
func GetMetaByPath(path string) (*Meta,error) {
var meta Meta
meta.Path = path
err := conf.DB.First(&meta).Error
if err != nil {
return nil, err
}
return &meta, nil
}

View File

@ -27,7 +27,7 @@ func ParsePath(rawPath string) (*model.Account,string,drivers.Driver,error) {
break
default:
paths := strings.Split(rawPath,"/")
path = strings.Join(paths[2:],"/")
path = "/" + strings.Join(paths[2:],"/")
name = paths[1]
}
account,ok := model.GetAccount(name)

View File

@ -1,9 +1,19 @@
package server
import "github.com/gofiber/fiber/v2"
import (
"github.com/Xhofe/alist/utils"
"github.com/gofiber/fiber/v2"
log "github.com/sirupsen/logrus"
"net/url"
)
func Down(ctx *fiber.Ctx) error {
rawPath := ctx.Params("*")
rawPath, err:= url.QueryUnescape(ctx.Params("*"))
if err != nil {
return ErrorResp(ctx,err,500)
}
rawPath = utils.ParsePath(rawPath)
log.Debugf("down: %s",rawPath)
account, path, driver, err := ParsePath(rawPath)
if err != nil {
return ErrorResp(ctx, err, 500)

View File

@ -1,9 +1,11 @@
package server
import (
"fmt"
"github.com/Xhofe/alist/model"
"github.com/Xhofe/alist/utils"
"github.com/gofiber/fiber/v2"
"strings"
log "github.com/sirupsen/logrus"
)
type PathReq struct {
@ -16,8 +18,14 @@ func Path(ctx *fiber.Ctx) error {
if err := ctx.BodyParser(&req); err != nil {
return ErrorResp(ctx, err, 400)
}
if !strings.HasPrefix(req.Path, "/") {
req.Path = "/"+req.Path
req.Path = utils.ParsePath(req.Path)
log.Debugf("path: %s",req.Path)
meta, err := model.GetMetaByPath(req.Path)
if err == nil {
if meta.Password != "" && meta.Password!= req.Password {
return ErrorResp(ctx,fmt.Errorf("wrong password"),401)
}
// TODO hide or ignore?
}
if model.AccountsCount() > 1 && req.Path == "/" {
return ctx.JSON(Resp{

View File

@ -7,6 +7,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"strings"
)
// Exists determine whether the file exists
@ -76,3 +77,11 @@ func WriteToJson(src string, conf interface{}) bool {
}
return true
}
func ParsePath(path string) string {
path = strings.TrimRight(path, "/")
if !strings.HasPrefix(path, "/") {
path = "/" + path
}
return path
}