mirror of
https://github.com/OpenListTeam/OpenList.git
synced 2025-09-20 12:46:17 +08:00
Compare commits
18 Commits
Author | SHA1 | Date | |
---|---|---|---|
f029df88e4 | |||
00f825d9e2 | |||
732dcfa5b1 | |||
e2ad8eabb8 | |||
affedc845b | |||
382cd6425f | |||
e880acb71d | |||
a0d1eadf3e | |||
70a0a32b7b | |||
2f32120908 | |||
0fdfa2b365 | |||
82713611c0 | |||
41acb3e865 | |||
77aca6609a | |||
63a597f802 | |||
fcf7530dd8 | |||
5f0645ded8 | |||
0f7ba9599d |
28
.github/workflows/beta_release.yml
vendored
28
.github/workflows/beta_release.yml
vendored
@ -2,7 +2,7 @@ name: Beta Release builds
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["main"]
|
||||
branches: [ 'main' ]
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
@ -17,7 +17,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
platform: [ ubuntu-latest ]
|
||||
go-version: ["1.21"]
|
||||
go-version: [ '1.21' ]
|
||||
name: Beta Release Changelog
|
||||
runs-on: ${{ matrix.platform }}
|
||||
steps:
|
||||
@ -65,17 +65,17 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- target: "!(*musl*|*windows-arm64*|*android*|*freebsd*)" # xgo
|
||||
- target: '!(*musl*|*windows-arm64*|*android*|*freebsd*)' # xgo
|
||||
hash: "md5"
|
||||
- target: "linux-!(arm*)-musl*" #musl-not-arm
|
||||
- target: 'linux-!(arm*)-musl*' #musl-not-arm
|
||||
hash: "md5-linux-musl"
|
||||
- target: "linux-arm*-musl*" #musl-arm
|
||||
- target: 'linux-arm*-musl*' #musl-arm
|
||||
hash: "md5-linux-musl-arm"
|
||||
- target: "windows-arm64" #win-arm64
|
||||
- target: 'windows-arm64' #win-arm64
|
||||
hash: "md5-windows-arm64"
|
||||
- target: "android-*" #android
|
||||
- target: 'android-*' #android
|
||||
hash: "md5-android"
|
||||
- target: "freebsd-*" #freebsd
|
||||
- target: 'freebsd-*' #freebsd
|
||||
hash: "md5-freebsd"
|
||||
|
||||
name: Beta Release
|
||||
@ -89,7 +89,7 @@ jobs:
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.22"
|
||||
go-version: '1.22'
|
||||
|
||||
- name: Setup web
|
||||
run: bash build.sh dev web
|
||||
@ -105,11 +105,11 @@ jobs:
|
||||
output: openlist-$target$ext
|
||||
musl-base-url: "https://github.com/OpenListTeam/musl-compilers/releases/latest/download/"
|
||||
x-flags: |
|
||||
github.com/OpenListTeam/OpenList/v4/internal/conf.BuiltAt=$built_at
|
||||
github.com/OpenListTeam/OpenList/v4/internal/conf.GitAuthor=OpenList
|
||||
github.com/OpenListTeam/OpenList/v4/internal/conf.GitCommit=$git_commit
|
||||
github.com/OpenListTeam/OpenList/v4/internal/conf.Version=$tag
|
||||
github.com/OpenListTeam/OpenList/v4/internal/conf.WebVersion=dev
|
||||
github.com/OpenListTeam/OpenList/internal/conf.BuiltAt=$built_at
|
||||
github.com/OpenListTeam/OpenList/internal/conf.GitAuthor=OpenList
|
||||
github.com/OpenListTeam/OpenList/internal/conf.GitCommit=$git_commit
|
||||
github.com/OpenListTeam/OpenList/internal/conf.Version=$tag
|
||||
github.com/OpenListTeam/OpenList/internal/conf.WebVersion=dev
|
||||
|
||||
- name: Compress
|
||||
run: |
|
||||
|
17
.github/workflows/build.yml
vendored
17
.github/workflows/build.yml
vendored
@ -2,9 +2,9 @@ name: Test Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["main"]
|
||||
branches: [ 'main' ]
|
||||
pull_request:
|
||||
branches: ["main"]
|
||||
branches: [ 'main' ]
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
@ -27,6 +27,7 @@ jobs:
|
||||
name: Build
|
||||
runs-on: ${{ matrix.platform }}
|
||||
steps:
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
@ -36,7 +37,7 @@ jobs:
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: "1.22"
|
||||
go-version: '1.22'
|
||||
|
||||
- name: Setup web
|
||||
run: bash build.sh dev web
|
||||
@ -50,11 +51,11 @@ jobs:
|
||||
musl-target-format: $os-$musl-$arch
|
||||
out-dir: build
|
||||
x-flags: |
|
||||
github.com/OpenListTeam/OpenList/v4/internal/conf.BuiltAt=$built_at
|
||||
github.com/OpenListTeam/OpenList/v4/internal/conf.GitAuthor=OpenList
|
||||
github.com/OpenListTeam/OpenList/v4/internal/conf.GitCommit=$git_commit
|
||||
github.com/OpenListTeam/OpenList/v4/internal/conf.Version=$tag
|
||||
github.com/OpenListTeam/OpenList/v4/internal/conf.WebVersion=dev
|
||||
github.com/OpenListTeam/OpenList/internal/conf.BuiltAt=$built_at
|
||||
github.com/OpenListTeam/OpenList/internal/conf.GitAuthor=OpenList
|
||||
github.com/OpenListTeam/OpenList/internal/conf.GitCommit=$git_commit
|
||||
github.com/OpenListTeam/OpenList/internal/conf.Version=$tag
|
||||
github.com/OpenListTeam/OpenList/internal/conf.WebVersion=dev
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
|
@ -80,6 +80,8 @@
|
||||
|
||||
- 📘 [Docs & Install Guide](https://docs.oplist.org)
|
||||
- 📚 [Backup Docs Site](https://docs.openlist.team)
|
||||
- ⚖️ [Terms of Use](https://docs.oplist.org/terms)
|
||||
- 🔒 [Privacy Policy](https://docs.oplist.org/privacy)
|
||||
|
||||
## Demo
|
||||
|
||||
|
@ -80,6 +80,8 @@
|
||||
|
||||
- 📘 [文档与安装指南](https://docs.oplist.org)
|
||||
- 📚 [备用文档站点](https://docs.openlist.team)
|
||||
- ⚖️ [使用条款](https://docs.oplist.org/terms)
|
||||
- 🔒 [隐私政策](https://docs.oplist.org/privacy)
|
||||
|
||||
## 演示
|
||||
|
||||
|
@ -80,6 +80,8 @@
|
||||
|
||||
- 📘 [ドキュメント・インストールガイド](https://docs.oplist.org)
|
||||
- 📚 [バックアップドキュメントサイト](https://docs.openlist.team)
|
||||
- ⚖️ [利用規約](https://docs.oplist.org/terms)
|
||||
- 🔒 [プライバシーポリシー](https://docs.oplist.org/privacy)
|
||||
|
||||
## デモ
|
||||
|
||||
|
@ -80,6 +80,8 @@
|
||||
|
||||
- 📘 [Documentatie & Installatiegids](https://docs.oplist.org)
|
||||
- 📚 [Back-up documentatiesite](https://docs.openlist.team)
|
||||
- ⚖️ [Gebruiksvoorwaarden](https://docs.oplist.org/terms)
|
||||
- 🔒 [Privacybeleid](https://docs.oplist.org/privacy)
|
||||
|
||||
## Demo
|
||||
|
||||
|
10
build.sh
10
build.sh
@ -38,11 +38,11 @@ fi
|
||||
|
||||
ldflags="\
|
||||
-w -s \
|
||||
-X 'github.com/OpenListTeam/OpenList/v4/internal/conf.BuiltAt=$builtAt' \
|
||||
-X 'github.com/OpenListTeam/OpenList/v4/internal/conf.GitAuthor=$gitAuthor' \
|
||||
-X 'github.com/OpenListTeam/OpenList/v4/internal/conf.GitCommit=$gitCommit' \
|
||||
-X 'github.com/OpenListTeam/OpenList/v4/internal/conf.Version=$version' \
|
||||
-X 'github.com/OpenListTeam/OpenList/v4/internal/conf.WebVersion=$webVersion' \
|
||||
-X 'github.com/OpenListTeam/OpenList/internal/conf.BuiltAt=$builtAt' \
|
||||
-X 'github.com/OpenListTeam/OpenList/internal/conf.GitAuthor=$gitAuthor' \
|
||||
-X 'github.com/OpenListTeam/OpenList/internal/conf.GitCommit=$gitCommit' \
|
||||
-X 'github.com/OpenListTeam/OpenList/internal/conf.Version=$version' \
|
||||
-X 'github.com/OpenListTeam/OpenList/internal/conf.WebVersion=$webVersion' \
|
||||
"
|
||||
|
||||
FetchWebDev() {
|
||||
|
@ -43,7 +43,7 @@ func (d *AliyundriveOpen) _refreshToken() (string, string, error) {
|
||||
if resp.ErrorMessage != "" {
|
||||
return "", "", fmt.Errorf("failed to refresh token: %s", resp.ErrorMessage)
|
||||
}
|
||||
return "", "", fmt.Errorf("empty token returned from official API, a wrong refresh token may have been used")
|
||||
return "", "", fmt.Errorf("empty token returned from official API")
|
||||
}
|
||||
return resp.RefreshToken, resp.AccessToken, nil
|
||||
}
|
||||
|
@ -57,7 +57,6 @@ import (
|
||||
_ "github.com/OpenListTeam/OpenList/v4/drivers/seafile"
|
||||
_ "github.com/OpenListTeam/OpenList/v4/drivers/sftp"
|
||||
_ "github.com/OpenListTeam/OpenList/v4/drivers/smb"
|
||||
_ "github.com/OpenListTeam/OpenList/v4/drivers/strm"
|
||||
_ "github.com/OpenListTeam/OpenList/v4/drivers/teambition"
|
||||
_ "github.com/OpenListTeam/OpenList/v4/drivers/terabox"
|
||||
_ "github.com/OpenListTeam/OpenList/v4/drivers/thunder"
|
||||
|
@ -55,7 +55,7 @@ func (d *BaiduNetdisk) _refreshToken() error {
|
||||
if resp.ErrorMessage != "" {
|
||||
return fmt.Errorf("failed to refresh token: %s", resp.ErrorMessage)
|
||||
}
|
||||
return fmt.Errorf("empty token returned from official API, a wrong refresh token may have been used")
|
||||
return fmt.Errorf("empty token returned from official API")
|
||||
}
|
||||
d.AccessToken = resp.AccessToken
|
||||
d.RefreshToken = resp.RefreshToken
|
||||
|
@ -39,7 +39,7 @@ func (d *Dropbox) refreshToken() error {
|
||||
if resp.ErrorMessage != "" {
|
||||
return fmt.Errorf("failed to refresh token: %s", resp.ErrorMessage)
|
||||
}
|
||||
return fmt.Errorf("empty token returned from official API, a wrong refresh token may have been used")
|
||||
return fmt.Errorf("empty token returned from official API")
|
||||
}
|
||||
d.AccessToken = resp.AccessToken
|
||||
d.RefreshToken = resp.RefreshToken
|
||||
|
@ -62,7 +62,7 @@ func (d *GoogleDrive) refreshToken() error {
|
||||
if resp.ErrorMessage != "" {
|
||||
return fmt.Errorf("failed to refresh token: %s", resp.ErrorMessage)
|
||||
}
|
||||
return fmt.Errorf("empty token returned from official API, a wrong refresh token may have been used")
|
||||
return fmt.Errorf("empty token returned from official API")
|
||||
}
|
||||
d.AccessToken = resp.AccessToken
|
||||
d.RefreshToken = resp.RefreshToken
|
||||
|
@ -96,7 +96,7 @@ func (d *Onedrive) _refreshToken() error {
|
||||
if resp.ErrorMessage != "" {
|
||||
return fmt.Errorf("failed to refresh token: %s", resp.ErrorMessage)
|
||||
}
|
||||
return fmt.Errorf("empty token returned from official API, a wrong refresh token may have been used")
|
||||
return fmt.Errorf("empty token returned from official API")
|
||||
}
|
||||
d.AccessToken = resp.AccessToken
|
||||
d.RefreshToken = resp.RefreshToken
|
||||
|
@ -458,7 +458,7 @@ func (d *QuarkOpen) _refreshToken() (string, string, error) {
|
||||
if resp.ErrorMessage != "" {
|
||||
return "", "", fmt.Errorf("failed to refresh token: %s", resp.ErrorMessage)
|
||||
}
|
||||
return "", "", fmt.Errorf("empty token returned from official API, a wrong refresh token may have been used")
|
||||
return "", "", fmt.Errorf("empty token returned from official API")
|
||||
}
|
||||
return resp.RefreshToken, resp.AccessToken, nil
|
||||
}
|
||||
|
@ -36,14 +36,6 @@ func (d *QuarkOrUC) GetAddition() driver.Additional {
|
||||
|
||||
func (d *QuarkOrUC) Init(ctx context.Context) error {
|
||||
_, err := d.request("/config", http.MethodGet, nil, nil)
|
||||
if err == nil {
|
||||
if d.AdditionVersion != 1 {
|
||||
d.AdditionVersion = 1
|
||||
if !d.UseTransCodingAddress {
|
||||
d.WebProxy = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,6 @@ type Addition struct {
|
||||
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" default:"asc"`
|
||||
UseTransCodingAddress bool `json:"use_transcoding_address" help:"You can watch the transcoded video and support 302 redirection" required:"true" default:"false"`
|
||||
OnlyListVideoFile bool `json:"only_list_video_file" default:"false"`
|
||||
AdditionVersion int
|
||||
}
|
||||
|
||||
type Conf struct {
|
||||
|
@ -97,10 +97,7 @@ func (d *S3) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*mo
|
||||
input.ResponseContentDisposition = &disposition
|
||||
}
|
||||
|
||||
req, reqErr := d.linkClient.GetObjectRequest(input)
|
||||
if reqErr != nil {
|
||||
return nil, fmt.Errorf("failed to create GetObject request: %w", reqErr)
|
||||
}
|
||||
req, _ := d.linkClient.GetObjectRequest(input)
|
||||
var link model.Link
|
||||
var err error
|
||||
if d.CustomHost != "" {
|
||||
@ -110,30 +107,8 @@ func (d *S3) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*mo
|
||||
err = req.Build()
|
||||
link.URL = req.HTTPRequest.URL.String()
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate link URL: %w", err)
|
||||
}
|
||||
|
||||
if d.RemoveBucket {
|
||||
parsedURL, parseErr := url.Parse(link.URL)
|
||||
if parseErr != nil {
|
||||
log.Errorf("Failed to parse URL for bucket removal: %v, URL: %s", parseErr, link.URL)
|
||||
return nil, fmt.Errorf("failed to parse URL for bucket removal: %w", parseErr)
|
||||
}
|
||||
|
||||
path := parsedURL.Path
|
||||
bucketPrefix := "/" + d.Bucket
|
||||
if strings.HasPrefix(path, bucketPrefix) {
|
||||
path = strings.TrimPrefix(path, bucketPrefix)
|
||||
if path == "" {
|
||||
path = "/"
|
||||
}
|
||||
parsedURL.Path = path
|
||||
link.URL = parsedURL.String()
|
||||
log.Debugf("Removed bucket '%s' from URL path: %s -> %s", d.Bucket, bucketPrefix, path)
|
||||
} else {
|
||||
log.Warnf("URL path does not contain expected bucket prefix '%s': %s", bucketPrefix, path)
|
||||
}
|
||||
link.URL = strings.Replace(link.URL, "/"+d.Bucket, "", 1)
|
||||
}
|
||||
} else {
|
||||
if common.ShouldProxy(d, fileName) {
|
||||
|
@ -1,145 +0,0 @@
|
||||
package strm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/driver"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/errs"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/fs"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/model"
|
||||
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
|
||||
)
|
||||
|
||||
type Strm struct {
|
||||
model.Storage
|
||||
Addition
|
||||
pathMap map[string][]string
|
||||
autoFlatten bool
|
||||
oneKey string
|
||||
}
|
||||
|
||||
func (d *Strm) Config() driver.Config {
|
||||
return config
|
||||
}
|
||||
|
||||
func (d *Strm) GetAddition() driver.Additional {
|
||||
return &d.Addition
|
||||
}
|
||||
|
||||
func (d *Strm) Init(ctx context.Context) error {
|
||||
if d.Paths == "" {
|
||||
return errors.New("paths is required")
|
||||
}
|
||||
d.pathMap = make(map[string][]string)
|
||||
for _, path := range strings.Split(d.Paths, "\n") {
|
||||
path = strings.TrimSpace(path)
|
||||
if path == "" {
|
||||
continue
|
||||
}
|
||||
k, v := getPair(path)
|
||||
d.pathMap[k] = append(d.pathMap[k], v)
|
||||
}
|
||||
if len(d.pathMap) == 1 {
|
||||
for k := range d.pathMap {
|
||||
d.oneKey = k
|
||||
}
|
||||
d.autoFlatten = true
|
||||
} else {
|
||||
d.oneKey = ""
|
||||
d.autoFlatten = false
|
||||
}
|
||||
|
||||
if d.FilterFileTypes != "" {
|
||||
types := strings.Split(d.FilterFileTypes, ",")
|
||||
for _, ext := range types {
|
||||
ext = strings.ToLower(strings.TrimSpace(ext))
|
||||
if ext != "" {
|
||||
supportSuffix[ext] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Strm) Drop(ctx context.Context) error {
|
||||
d.pathMap = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Strm) Get(ctx context.Context, path string) (model.Obj, error) {
|
||||
if utils.PathEqual(path, "/") {
|
||||
return &model.Object{
|
||||
Name: "Root",
|
||||
IsFolder: true,
|
||||
Path: "/",
|
||||
}, nil
|
||||
}
|
||||
root, sub := d.getRootAndPath(path)
|
||||
dsts, ok := d.pathMap[root]
|
||||
if !ok {
|
||||
return nil, errs.ObjectNotFound
|
||||
}
|
||||
for _, dst := range dsts {
|
||||
obj, err := d.get(ctx, path, dst, sub)
|
||||
if err == nil {
|
||||
return obj, nil
|
||||
}
|
||||
}
|
||||
return nil, errs.ObjectNotFound
|
||||
}
|
||||
|
||||
func (d *Strm) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
|
||||
path := dir.GetPath()
|
||||
if utils.PathEqual(path, "/") && !d.autoFlatten {
|
||||
return d.listRoot(), nil
|
||||
}
|
||||
root, sub := d.getRootAndPath(path)
|
||||
dsts, ok := d.pathMap[root]
|
||||
if !ok {
|
||||
return nil, errs.ObjectNotFound
|
||||
}
|
||||
var objs []model.Obj
|
||||
fsArgs := &fs.ListArgs{NoLog: true, Refresh: args.Refresh}
|
||||
for _, dst := range dsts {
|
||||
tmp, err := d.list(ctx, dst, sub, fsArgs)
|
||||
if err == nil {
|
||||
objs = append(objs, tmp...)
|
||||
}
|
||||
}
|
||||
return objs, nil
|
||||
}
|
||||
|
||||
func (d *Strm) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
|
||||
link := d.getLink(ctx, file.GetPath())
|
||||
return &model.Link{
|
||||
MFile: model.NewNopMFile(strings.NewReader(link)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *Strm) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
|
||||
return errors.New("strm Driver cannot make dir")
|
||||
}
|
||||
|
||||
func (d *Strm) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
|
||||
return errors.New("strm Driver cannot move file")
|
||||
}
|
||||
|
||||
func (d *Strm) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
|
||||
return errors.New("strm Driver cannot rename file")
|
||||
}
|
||||
|
||||
func (d *Strm) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
|
||||
return errors.New("strm Driver cannot copy file")
|
||||
}
|
||||
|
||||
func (d *Strm) Remove(ctx context.Context, obj model.Obj) error {
|
||||
return errors.New("strm Driver cannot remove file")
|
||||
}
|
||||
|
||||
func (d *Strm) Put(ctx context.Context, dstDir model.Obj, s model.FileStreamer, up driver.UpdateProgress) error {
|
||||
return errors.New("strm Driver cannot put file")
|
||||
}
|
||||
|
||||
var _ driver.Driver = (*Strm)(nil)
|
@ -1,29 +0,0 @@
|
||||
package strm
|
||||
|
||||
import (
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/driver"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/op"
|
||||
)
|
||||
|
||||
type Addition struct {
|
||||
Paths string `json:"paths" required:"true" type:"text"`
|
||||
ProtectSameName bool `json:"protect_same_name" default:"true" required:"false" help:"Protects same-name files from Delete or Rename"`
|
||||
SiteUrl string `json:"siteUrl" type:"text" required:"false" help:"The prefix URL of the strm file"`
|
||||
FilterFileTypes string `json:"filterFileTypes" type:"text" default:"strm" required:"false" help:"Supports suffix name of strm file"`
|
||||
}
|
||||
|
||||
var config = driver.Config{
|
||||
Name: "Strm",
|
||||
LocalSort: true,
|
||||
NoCache: true,
|
||||
NoUpload: true,
|
||||
DefaultRoot: "/",
|
||||
OnlyLocal: true,
|
||||
OnlyProxy: true,
|
||||
}
|
||||
|
||||
func init() {
|
||||
op.RegisterDriver(func() driver.Driver {
|
||||
return &Strm{}
|
||||
})
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package strm
|
||||
|
||||
var supportSuffix = map[string]struct{}{
|
||||
// video
|
||||
"mp4": {},
|
||||
"mkv": {},
|
||||
"flv": {},
|
||||
"avi": {},
|
||||
"wmv": {},
|
||||
"ts": {},
|
||||
"rmvb": {},
|
||||
"webm": {},
|
||||
// audio
|
||||
"mp3": {},
|
||||
"flac": {},
|
||||
"aac": {},
|
||||
"wav": {},
|
||||
"ogg": {},
|
||||
"m4a": {},
|
||||
"wma": {},
|
||||
"alac": {},
|
||||
}
|
@ -1,140 +0,0 @@
|
||||
package strm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
stdpath "path"
|
||||
"strings"
|
||||
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/fs"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/model"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/sign"
|
||||
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
|
||||
"github.com/OpenListTeam/OpenList/v4/server/common"
|
||||
)
|
||||
|
||||
func (d *Strm) listRoot() []model.Obj {
|
||||
var objs []model.Obj
|
||||
for k := range d.pathMap {
|
||||
obj := model.Object{
|
||||
Name: k,
|
||||
IsFolder: true,
|
||||
Modified: d.Modified,
|
||||
}
|
||||
objs = append(objs, &obj)
|
||||
}
|
||||
return objs
|
||||
}
|
||||
|
||||
// do others that not defined in Driver interface
|
||||
func getPair(path string) (string, string) {
|
||||
//path = strings.TrimSpace(path)
|
||||
if strings.Contains(path, ":") {
|
||||
pair := strings.SplitN(path, ":", 2)
|
||||
if !strings.Contains(pair[0], "/") {
|
||||
return pair[0], pair[1]
|
||||
}
|
||||
}
|
||||
return stdpath.Base(path), path
|
||||
}
|
||||
|
||||
func (d *Strm) getRootAndPath(path string) (string, string) {
|
||||
if d.autoFlatten {
|
||||
return d.oneKey, path
|
||||
}
|
||||
path = strings.TrimPrefix(path, "/")
|
||||
parts := strings.SplitN(path, "/", 2)
|
||||
if len(parts) == 1 {
|
||||
return parts[0], ""
|
||||
}
|
||||
return parts[0], parts[1]
|
||||
}
|
||||
|
||||
func (d *Strm) get(ctx context.Context, path string, dst, sub string) (model.Obj, error) {
|
||||
reqPath := stdpath.Join(dst, sub)
|
||||
obj, err := fs.Get(ctx, reqPath, &fs.GetArgs{NoLog: true})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
size := int64(0)
|
||||
if !obj.IsDir() {
|
||||
if utils.Ext(obj.GetName()) == "strm" {
|
||||
size = obj.GetSize()
|
||||
} else {
|
||||
file := stdpath.Join(reqPath, obj.GetName())
|
||||
size = int64(len(d.getLink(ctx, file)))
|
||||
}
|
||||
}
|
||||
return &model.Object{
|
||||
Path: path,
|
||||
Name: obj.GetName(),
|
||||
Size: size,
|
||||
Modified: obj.ModTime(),
|
||||
IsFolder: obj.IsDir(),
|
||||
HashInfo: obj.GetHash(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *Strm) list(ctx context.Context, dst, sub string, args *fs.ListArgs) ([]model.Obj, error) {
|
||||
reqPath := stdpath.Join(dst, sub)
|
||||
objs, err := fs.List(ctx, reqPath, args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var validObjs []model.Obj
|
||||
for _, obj := range objs {
|
||||
if !obj.IsDir() {
|
||||
ext := strings.ToLower(utils.Ext(obj.GetName()))
|
||||
if _, ok := supportSuffix[ext]; !ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
validObjs = append(validObjs, obj)
|
||||
}
|
||||
return utils.SliceConvert(validObjs, func(obj model.Obj) (model.Obj, error) {
|
||||
name := obj.GetName()
|
||||
size := int64(0)
|
||||
if !obj.IsDir() {
|
||||
ext := utils.Ext(name)
|
||||
name = strings.TrimSuffix(name, ext) + "strm"
|
||||
if ext == "strm" {
|
||||
size = obj.GetSize()
|
||||
} else {
|
||||
file := stdpath.Join(reqPath, obj.GetName())
|
||||
size = int64(len(d.getLink(ctx, file)))
|
||||
}
|
||||
}
|
||||
objRes := model.Object{
|
||||
Name: name,
|
||||
Size: size,
|
||||
Modified: obj.ModTime(),
|
||||
IsFolder: obj.IsDir(),
|
||||
Path: stdpath.Join(reqPath, obj.GetName()),
|
||||
}
|
||||
thumb, ok := model.GetThumb(obj)
|
||||
if !ok {
|
||||
return &objRes, nil
|
||||
}
|
||||
return &model.ObjThumb{
|
||||
Object: objRes,
|
||||
Thumbnail: model.Thumbnail{
|
||||
Thumbnail: thumb,
|
||||
},
|
||||
}, nil
|
||||
})
|
||||
}
|
||||
|
||||
func (d *Strm) getLink(ctx context.Context, path string) string {
|
||||
apiUrl := d.SiteUrl
|
||||
if len(apiUrl) > 0 {
|
||||
apiUrl = strings.TrimSuffix(apiUrl, "/")
|
||||
} else {
|
||||
apiUrl = common.GetApiUrl(ctx)
|
||||
}
|
||||
return fmt.Sprintf("%s/d%s?sign=%s",
|
||||
apiUrl,
|
||||
utils.EncodePath(path, true),
|
||||
sign.Sign(path))
|
||||
}
|
@ -38,7 +38,7 @@ func (d *YandexDisk) refreshToken() error {
|
||||
if resp.ErrorMessage != "" {
|
||||
return fmt.Errorf("failed to refresh token: %s", resp.ErrorMessage)
|
||||
}
|
||||
return fmt.Errorf("empty token returned from official API , a wrong refresh token may have been used")
|
||||
return fmt.Errorf("empty token returned from official API")
|
||||
}
|
||||
d.AccessToken = resp.AccessToken
|
||||
d.RefreshToken = resp.RefreshToken
|
||||
|
13
go.mod
13
go.mod
@ -47,7 +47,7 @@ require (
|
||||
github.com/kdomanski/iso9660 v0.4.0
|
||||
github.com/maruel/natural v1.1.1
|
||||
github.com/meilisearch/meilisearch-go v0.27.2
|
||||
github.com/mholt/archives v0.1.3
|
||||
github.com/mholt/archives v0.1.0
|
||||
github.com/natefinch/lumberjack v2.0.0+incompatible
|
||||
github.com/ncw/swift/v2 v2.0.3
|
||||
github.com/pkg/errors v0.9.1
|
||||
@ -66,6 +66,7 @@ require (
|
||||
github.com/yeka/zip v0.0.0-20231116150916-03d6312748a9
|
||||
github.com/zzzhr1990/go-common-entity v0.0.0-20250202070650-1a200048f0d3
|
||||
golang.org/x/crypto v0.36.0
|
||||
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e
|
||||
golang.org/x/image v0.19.0
|
||||
golang.org/x/net v0.38.0
|
||||
golang.org/x/oauth2 v0.22.0
|
||||
@ -82,8 +83,6 @@ require (
|
||||
cloud.google.com/go/compute/metadata v0.7.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/mikelolasagasti/xz v1.0.1 // indirect
|
||||
github.com/minio/minlz v1.0.0 // indirect
|
||||
github.com/minio/xxml v0.0.3 // indirect
|
||||
)
|
||||
|
||||
@ -94,7 +93,7 @@ require (
|
||||
github.com/blevesearch/go-faiss v1.0.20 // indirect
|
||||
github.com/blevesearch/zapx/v16 v16.1.5 // indirect
|
||||
github.com/bodgit/plumbing v1.3.0 // indirect
|
||||
github.com/bodgit/sevenzip v1.6.1
|
||||
github.com/bodgit/sevenzip v1.6.0
|
||||
github.com/bodgit/windows v1.0.1 // indirect
|
||||
github.com/bytedance/sonic/loader v0.1.1 // indirect
|
||||
github.com/charmbracelet/x/ansi v0.2.3 // indirect
|
||||
@ -114,7 +113,7 @@ require (
|
||||
github.com/klauspost/pgzip v1.2.6 // indirect
|
||||
github.com/matoous/go-nanoid/v2 v2.1.0 // indirect
|
||||
github.com/microcosm-cc/bluemonday v1.0.27
|
||||
github.com/nwaples/rardecode/v2 v2.1.0
|
||||
github.com/nwaples/rardecode/v2 v2.0.0-beta.4.0.20241112120701-034e449c6e78
|
||||
github.com/sorairolake/lzip-go v0.3.5 // indirect
|
||||
github.com/taruti/bytepool v0.0.0-20160310082835-5e3a9ea56543 // indirect
|
||||
github.com/therootcompany/xz v1.0.1 // indirect
|
||||
@ -131,7 +130,7 @@ require (
|
||||
github.com/abbot/go-http-auth v0.4.0 // indirect
|
||||
github.com/aead/ecdh v0.2.0 // indirect
|
||||
github.com/andreburgaud/crypt2go v1.8.0 // indirect
|
||||
github.com/andybalholm/brotli v1.1.2-0.20250424173009-453214e765f3 // indirect
|
||||
github.com/andybalholm/brotli v1.1.1 // indirect
|
||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||
github.com/benbjohnson/clock v1.3.0 // indirect
|
||||
@ -225,7 +224,7 @@ require (
|
||||
github.com/multiformats/go-varint v0.0.7 // indirect
|
||||
github.com/otiai10/copy v1.14.0
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.22 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.21 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
|
||||
github.com/pquerna/cachecontrol v0.1.0 // indirect
|
||||
|
16
go.sum
16
go.sum
@ -71,8 +71,6 @@ github.com/andreburgaud/crypt2go v1.8.0/go.mod h1:L5nfShQ91W78hOWhUH2tlGRPO+POAP
|
||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
|
||||
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
||||
github.com/andybalholm/brotli v1.1.2-0.20250424173009-453214e765f3 h1:8PmGpDEZl9yDpcdEr6Odf23feCxK3LNUNMxjXg41pZQ=
|
||||
github.com/andybalholm/brotli v1.1.2-0.20250424173009-453214e765f3/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
||||
github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0=
|
||||
github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY=
|
||||
github.com/aws/aws-sdk-go v1.38.20/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
|
||||
@ -160,8 +158,6 @@ github.com/bodgit/plumbing v1.3.0 h1:pf9Itz1JOQgn7vEOE7v7nlEfBykYqvUYioC61TwWCFU
|
||||
github.com/bodgit/plumbing v1.3.0/go.mod h1:JOTb4XiRu5xfnmdnDJo6GmSbSbtSyufrsyZFByMtKEs=
|
||||
github.com/bodgit/sevenzip v1.6.0 h1:a4R0Wu6/P1o1pP/3VV++aEOcyeBxeO/xE2Y9NSTrr6A=
|
||||
github.com/bodgit/sevenzip v1.6.0/go.mod h1:zOBh9nJUof7tcrlqJFv1koWRrhz3LbDbUNngkuZxLMc=
|
||||
github.com/bodgit/sevenzip v1.6.1 h1:kikg2pUMYC9ljU7W9SaqHXhym5HyKm8/M/jd31fYan4=
|
||||
github.com/bodgit/sevenzip v1.6.1/go.mod h1:GVoYQbEVbOGT8n2pfqCIMRUaRjQ8F9oSqoBEqZh5fQ8=
|
||||
github.com/bodgit/windows v1.0.1 h1:tF7K6KOluPYygXa3Z2594zxlkbKPAOvqr97etrGNIz4=
|
||||
github.com/bodgit/windows v1.0.1/go.mod h1:a6JLwrB4KrTR5hBpp8FI9/9W9jJfeQ2h4XDXU74ZCdM=
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI=
|
||||
@ -472,14 +468,8 @@ github.com/meilisearch/meilisearch-go v0.27.2 h1:3G21dJ5i208shnLPDsIEZ0L0Geg/5oe
|
||||
github.com/meilisearch/meilisearch-go v0.27.2/go.mod h1:SxuSqDcPBIykjWz1PX+KzsYzArNLSCadQodWs8extS0=
|
||||
github.com/mholt/archives v0.1.0 h1:FacgJyrjiuyomTuNA92X5GyRBRZjE43Y/lrzKIlF35Q=
|
||||
github.com/mholt/archives v0.1.0/go.mod h1:j/Ire/jm42GN7h90F5kzj6hf6ZFzEH66de+hmjEKu+I=
|
||||
github.com/mholt/archives v0.1.3 h1:aEAaOtNra78G+TvV5ohmXrJOAzf++dIlYeDW3N9q458=
|
||||
github.com/mholt/archives v0.1.3/go.mod h1:LUCGp++/IbV/I0Xq4SzcIR6uwgeh2yjnQWamjRQfLTU=
|
||||
github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk=
|
||||
github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA=
|
||||
github.com/mikelolasagasti/xz v1.0.1 h1:Q2F2jX0RYJUG3+WsM+FJknv+6eVjsjXNDV0KJXZzkD0=
|
||||
github.com/mikelolasagasti/xz v1.0.1/go.mod h1:muAirjiOUxPRXwm9HdDtB3uoRPrGnL85XHtokL9Hcgc=
|
||||
github.com/minio/minlz v1.0.0 h1:Kj7aJZ1//LlTP1DM8Jm7lNKvvJS2m74gyyXXn3+uJWQ=
|
||||
github.com/minio/minlz v1.0.0/go.mod h1:qT0aEB35q79LLornSzeDH75LBf3aH1MV+jB5w9Wasec=
|
||||
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
|
||||
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
|
||||
github.com/minio/xxml v0.0.3 h1:ZIpPQpfyG5uZQnqqC0LZuWtPk/WT8G/qkxvO6jb7zMU=
|
||||
@ -527,8 +517,6 @@ github.com/ncw/swift/v2 v2.0.3 h1:8R9dmgFIWs+RiVlisCEfiQiik1hjuR0JnOkLxaP9ihg=
|
||||
github.com/ncw/swift/v2 v2.0.3/go.mod h1:cbAO76/ZwcFrFlHdXPjaqWZ9R7Hdar7HpjRXBfbjigk=
|
||||
github.com/nwaples/rardecode/v2 v2.0.0-beta.4.0.20241112120701-034e449c6e78 h1:MYzLheyVx1tJVDqfu3YnN4jtnyALNzLvwl+f58TcvQY=
|
||||
github.com/nwaples/rardecode/v2 v2.0.0-beta.4.0.20241112120701-034e449c6e78/go.mod h1:yntwv/HfMc/Hbvtq9I19D1n58te3h6KsqCf3GxyfBGY=
|
||||
github.com/nwaples/rardecode/v2 v2.1.0 h1:JQl9ZoBPDy+nIZGb1mx8+anfHp/LV3NE2MjMiv0ct/U=
|
||||
github.com/nwaples/rardecode/v2 v2.1.0/go.mod h1:7uz379lSxPe6j9nvzxUZ+n7mnJNgjsRNb6IbvGVHRmw=
|
||||
github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU=
|
||||
github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w=
|
||||
github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks=
|
||||
@ -538,8 +526,6 @@ github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6
|
||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
||||
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU=
|
||||
github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@ -722,6 +708,8 @@ golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e h1:I88y4caeGeuDQxgdoFPUq097j7kNfw6uvuiNxUBfcBk=
|
||||
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
|
@ -111,7 +111,7 @@ func InitialSettings() []model.SettingItem {
|
||||
{Key: "home_container", Value: "max_980px", Type: conf.TypeSelect, Options: "max_980px,hope_container", Group: model.STYLE},
|
||||
{Key: "settings_layout", Value: "list", Type: conf.TypeSelect, Options: "list,responsive", Group: model.STYLE},
|
||||
// preview settings
|
||||
{Key: conf.TextTypes, Value: "txt,htm,html,xml,java,properties,sql,js,md,json,conf,ini,vue,php,py,bat,gitignore,yml,go,sh,c,cpp,h,hpp,tsx,vtt,srt,ass,rs,lrc,strm", Type: conf.TypeText, Group: model.PREVIEW, Flag: model.PRIVATE},
|
||||
{Key: conf.TextTypes, Value: "txt,htm,html,xml,java,properties,sql,js,md,json,conf,ini,vue,php,py,bat,gitignore,yml,go,sh,c,cpp,h,hpp,tsx,vtt,srt,ass,rs,lrc", Type: conf.TypeText, Group: model.PREVIEW, Flag: model.PRIVATE},
|
||||
{Key: conf.AudioTypes, Value: "mp3,flac,ogg,m4a,wav,opus,wma", Type: conf.TypeText, Group: model.PREVIEW, Flag: model.PRIVATE},
|
||||
{Key: conf.VideoTypes, Value: "mp4,mkv,avi,mov,rmvb,webm,flv,m3u8", Type: conf.TypeText, Group: model.PREVIEW, Flag: model.PRIVATE},
|
||||
{Key: conf.ImageTypes, Value: "jpg,tiff,jpeg,png,gif,bmp,svg,ico,swf,webp,avif", Type: conf.TypeText, Group: model.PREVIEW, Flag: model.PRIVATE},
|
||||
|
@ -16,8 +16,8 @@ import (
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/task"
|
||||
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
|
||||
"github.com/OpenListTeam/OpenList/v4/server/common"
|
||||
"github.com/OpenListTeam/tache"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/OpenListTeam/tache"
|
||||
)
|
||||
|
||||
type CopyTask struct {
|
||||
|
@ -16,8 +16,8 @@ import (
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/task"
|
||||
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
|
||||
"github.com/OpenListTeam/OpenList/v4/server/common"
|
||||
"github.com/OpenListTeam/tache"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/OpenListTeam/tache"
|
||||
)
|
||||
|
||||
type MoveTask struct {
|
||||
|
@ -14,19 +14,11 @@ import (
|
||||
|
||||
"github.com/OpenListTeam/OpenList/v4/pkg/http_range"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
var buf22MB = make([]byte, 1024*1024*22)
|
||||
|
||||
func containsString(slice []string, val string) bool {
|
||||
for _, item := range slice {
|
||||
if item == val {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func dummyHttpRequest(data []byte, p http_range.Range) io.ReadCloser {
|
||||
|
||||
end := p.Start + p.Length - 1
|
||||
@ -80,7 +72,7 @@ func TestDownloadOrder(t *testing.T) {
|
||||
|
||||
expectRngs := []string{"2-3", "5-3", "8-3", "11-1"}
|
||||
for _, rng := range expectRngs {
|
||||
if !!containsString(*ranges, rng) {
|
||||
if !slices.Contains(*ranges, rng) {
|
||||
t.Errorf("expect range %v, but absent in return", rng)
|
||||
}
|
||||
}
|
||||
@ -132,7 +124,7 @@ func TestDownloadSingle(t *testing.T) {
|
||||
|
||||
expectRngs := []string{"2-10"}
|
||||
for _, rng := range expectRngs {
|
||||
if !!containsString(*ranges, rng) {
|
||||
if !slices.Contains(*ranges, rng) {
|
||||
t.Errorf("expect range %v, but absent in return", rng)
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ import (
|
||||
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/model"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/offline_download/tool"
|
||||
"github.com/OpenListTeam/OpenList/v4/pkg/http_range"
|
||||
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
|
||||
)
|
||||
|
||||
@ -54,18 +53,10 @@ func (s SimpleHttp) Run(task *tool.DownloadTask) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
streamPut := task.DeletePolicy == tool.UploadDownloadStream
|
||||
method := http.MethodGet
|
||||
if streamPut {
|
||||
method = http.MethodHead
|
||||
}
|
||||
req, err := http.NewRequestWithContext(task.Ctx(), method, u, nil)
|
||||
req, err := http.NewRequestWithContext(task.Ctx(), http.MethodGet, u, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if streamPut {
|
||||
req.Header.Set("Range", "bytes=0-")
|
||||
}
|
||||
resp, err := s.client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -83,17 +74,6 @@ func (s SimpleHttp) Run(task *tool.DownloadTask) error {
|
||||
if n, err := parseFilenameFromContentDisposition(resp.Header.Get("Content-Disposition")); err == nil {
|
||||
filename = n
|
||||
}
|
||||
fileSize := resp.ContentLength
|
||||
if streamPut {
|
||||
if fileSize == 0 {
|
||||
start, end, _ := http_range.ParseContentRange(resp.Header.Get("Content-Range"))
|
||||
fileSize = start + end
|
||||
}
|
||||
task.SetTotalBytes(fileSize)
|
||||
task.TempDir = filename
|
||||
return nil
|
||||
}
|
||||
task.SetTotalBytes(fileSize)
|
||||
// save to temp dir
|
||||
_ = os.MkdirAll(task.TempDir, os.ModePerm)
|
||||
filePath := filepath.Join(task.TempDir, filename)
|
||||
@ -102,6 +82,8 @@ func (s SimpleHttp) Run(task *tool.DownloadTask) error {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
fileSize := resp.ContentLength
|
||||
task.SetTotalBytes(fileSize)
|
||||
err = utils.CopyWithCtx(task.Ctx(), file, resp.Body, fileSize, task.SetProgress)
|
||||
return err
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ const (
|
||||
DeleteOnUploadFailed DeletePolicy = "delete_on_upload_failed"
|
||||
DeleteNever DeletePolicy = "delete_never"
|
||||
DeleteAlways DeletePolicy = "delete_always"
|
||||
UploadDownloadStream DeletePolicy = "upload_download_stream"
|
||||
)
|
||||
|
||||
type AddURLArgs struct {
|
||||
|
@ -6,13 +6,11 @@ import (
|
||||
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/conf"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/errs"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/model"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/op"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/setting"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/task"
|
||||
"github.com/OpenListTeam/tache"
|
||||
"github.com/pkg/errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/OpenListTeam/tache"
|
||||
)
|
||||
|
||||
type DownloadTask struct {
|
||||
@ -173,27 +171,6 @@ func (t *DownloadTask) Transfer() error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if t.DeletePolicy == UploadDownloadStream {
|
||||
dstStorage, dstDirActualPath, err := op.GetStorageAndActualPath(t.DstDirPath)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "failed get dst storage")
|
||||
}
|
||||
taskCreator, _ := t.Ctx().Value("user").(*model.User)
|
||||
task := &TransferTask{
|
||||
TaskExtension: task.TaskExtension{
|
||||
Creator: taskCreator,
|
||||
},
|
||||
SrcObjPath: t.TempDir,
|
||||
DstDirPath: dstDirActualPath,
|
||||
DstStorage: dstStorage,
|
||||
DstStorageMp: dstStorage.GetStorage().MountPath,
|
||||
DeletePolicy: t.DeletePolicy,
|
||||
Url: t.Url,
|
||||
}
|
||||
task.SetTotalBytes(t.GetTotalBytes())
|
||||
TransferTaskManager.Add(task)
|
||||
return nil
|
||||
}
|
||||
return transferStd(t.Ctx(), t.TempDir, t.DstDirPath, t.DeletePolicy)
|
||||
}
|
||||
|
||||
|
@ -14,11 +14,10 @@ import (
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/op"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/stream"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/task"
|
||||
"github.com/OpenListTeam/OpenList/v4/pkg/http_range"
|
||||
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
|
||||
"github.com/OpenListTeam/tache"
|
||||
"github.com/pkg/errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/OpenListTeam/tache"
|
||||
)
|
||||
|
||||
type TransferTask struct {
|
||||
@ -31,7 +30,6 @@ type TransferTask struct {
|
||||
SrcStorageMp string `json:"src_storage_mp"`
|
||||
DstStorageMp string `json:"dst_storage_mp"`
|
||||
DeletePolicy DeletePolicy `json:"delete_policy"`
|
||||
Url string `json:"-"`
|
||||
}
|
||||
|
||||
func (t *TransferTask) Run() error {
|
||||
@ -42,32 +40,6 @@ func (t *TransferTask) Run() error {
|
||||
t.SetStartTime(time.Now())
|
||||
defer func() { t.SetEndTime(time.Now()) }()
|
||||
if t.SrcStorage == nil {
|
||||
if t.DeletePolicy == UploadDownloadStream {
|
||||
rrc, err := stream.GetRangeReadCloserFromLink(t.GetTotalBytes(), &model.Link{URL: t.Url})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r, err := rrc.RangeRead(t.Ctx(), http_range.Range{Length: t.GetTotalBytes()})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name := t.SrcObjPath
|
||||
mimetype := utils.GetMimeType(name)
|
||||
s := &stream.FileStream{
|
||||
Ctx: nil,
|
||||
Obj: &model.Object{
|
||||
Name: name,
|
||||
Size: t.GetTotalBytes(),
|
||||
Modified: time.Now(),
|
||||
IsFolder: false,
|
||||
},
|
||||
Reader: r,
|
||||
Mimetype: mimetype,
|
||||
Closers: utils.NewClosers(rrc),
|
||||
}
|
||||
defer s.Close()
|
||||
return op.Put(t.Ctx(), t.DstStorage, t.DstDirPath, s, t.SetProgress)
|
||||
}
|
||||
return transferStdPath(t)
|
||||
} else {
|
||||
return transferObjPath(t)
|
||||
@ -75,9 +47,6 @@ func (t *TransferTask) Run() error {
|
||||
}
|
||||
|
||||
func (t *TransferTask) GetName() string {
|
||||
if t.DeletePolicy == UploadDownloadStream {
|
||||
return fmt.Sprintf("upload [%s](%s) to [%s](%s)", t.SrcObjPath, t.Url, t.DstStorageMp, t.DstDirPath)
|
||||
}
|
||||
return fmt.Sprintf("transfer [%s](%s) to [%s](%s)", t.SrcStorageMp, t.SrcObjPath, t.DstStorageMp, t.DstDirPath)
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/exp/constraints"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
@ -191,21 +193,13 @@ func NewClosers(c ...io.Closer) Closers {
|
||||
return Closers{c}
|
||||
}
|
||||
|
||||
type Ordered interface {
|
||||
~int | ~int8 | ~int16 | ~int32 | ~int64 |
|
||||
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
|
||||
~float32 | ~float64 |
|
||||
~string
|
||||
}
|
||||
|
||||
func Min[T Ordered](a, b T) T {
|
||||
func Min[T constraints.Ordered](a, b T) T {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func Max[T Ordered](a, b T) T {
|
||||
func Max[T constraints.Ordered](a, b T) T {
|
||||
if a < b {
|
||||
return b
|
||||
}
|
||||
|
Reference in New Issue
Block a user