Compare commits
13 Commits
v3.0.0-bet
...
v3.0.0-bet
Author | SHA1 | Date | |
---|---|---|---|
40882443c2 | |||
05f19cad78 | |||
7249f277b2 | |||
849124f177 | |||
f5c7a11da5 | |||
043a79189d | |||
5ed43fd17d | |||
220cd4d6b8 | |||
f692e6c011 | |||
f48365929e | |||
56219bf096 | |||
5ad3849bb6 | |||
4af9124162 |
3
.github/workflows/issue_check_inactive.yml
vendored
3
.github/workflows/issue_check_inactive.yml
vendored
@ -13,4 +13,5 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
actions: 'check-inactive'
|
actions: 'check-inactive'
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
inactive-day: 30
|
inactive-day: 30
|
||||||
|
body: Hello, this issue has been inactive for more than 30 days and will be closed if inactive for another 30 days.
|
20
.github/workflows/issue_close_inactive.yml
vendored
Normal file
20
.github/workflows/issue_close_inactive.yml
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
name: Close inactive
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "0 0 */7 * *"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
close-inactive:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: close-issues
|
||||||
|
uses: actions-cool/issues-helper@v3
|
||||||
|
with:
|
||||||
|
actions: 'close-issues'
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
labels: 'inactive'
|
||||||
|
inactive-day: 30
|
||||||
|
close-reason: 'not_planned'
|
||||||
|
body: |
|
||||||
|
Hello @${{ github.event.issue.user.login }}, this issue was closed due to inactive more than 60 days. You can reopen or recreate it if you think it should continue.
|
@ -1,11 +1,11 @@
|
|||||||
name: Check need info
|
name: Close need info
|
||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 0 */7 * *"
|
- cron: "0 0 */7 * *"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-need-info:
|
close-need-info:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: close-issues
|
- name: close-issues
|
3
.github/workflows/issue_similarity.yml
vendored
3
.github/workflows/issue_similarity.yml
vendored
@ -15,4 +15,5 @@ jobs:
|
|||||||
comment-title: '### See'
|
comment-title: '### See'
|
||||||
comment-body: '${index}. ${similarity} #${number}'
|
comment-body: '${index}. ${similarity} #${number}'
|
||||||
show-footer: false
|
show-footer: false
|
||||||
show-mentioned: true
|
show-mentioned: true
|
||||||
|
since-days: 730
|
@ -11,15 +11,16 @@ import (
|
|||||||
|
|
||||||
// passwordCmd represents the password command
|
// passwordCmd represents the password command
|
||||||
var passwordCmd = &cobra.Command{
|
var passwordCmd = &cobra.Command{
|
||||||
Use: "password",
|
Use: "admin",
|
||||||
Short: "Show admin user's password",
|
Aliases: []string{"password"},
|
||||||
|
Short: "Show admin user's info",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
Init()
|
Init()
|
||||||
admin, err := db.GetAdmin()
|
admin, err := db.GetAdmin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Log.Errorf("failed get admin user: %+v", err)
|
utils.Log.Errorf("failed get admin user: %+v", err)
|
||||||
} else {
|
} else {
|
||||||
utils.Log.Infof("admin user's password is: %s", admin.Password)
|
utils.Log.Infof("admin user's info: \nusername: %s\npassword: %s", admin.Username, admin.Password)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
@ -9,10 +9,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/alist-org/alist/v3/drivers/base"
|
"github.com/alist-org/alist/v3/drivers/base"
|
||||||
"github.com/alist-org/alist/v3/internal/conf"
|
|
||||||
"github.com/alist-org/alist/v3/internal/driver"
|
"github.com/alist-org/alist/v3/internal/driver"
|
||||||
"github.com/alist-org/alist/v3/internal/errs"
|
"github.com/alist-org/alist/v3/internal/errs"
|
||||||
"github.com/alist-org/alist/v3/internal/model"
|
"github.com/alist-org/alist/v3/internal/model"
|
||||||
@ -22,6 +22,7 @@ import (
|
|||||||
"github.com/aws/aws-sdk-go/aws/session"
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
"github.com/aws/aws-sdk-go/service/s3/s3manager"
|
"github.com/aws/aws-sdk-go/service/s3/s3manager"
|
||||||
"github.com/go-resty/resty/v2"
|
"github.com/go-resty/resty/v2"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Pan123 struct {
|
type Pan123 struct {
|
||||||
@ -68,9 +69,47 @@ func (d *Pan123) List(ctx context.Context, dir model.Obj, args model.ListArgs) (
|
|||||||
|
|
||||||
func (d *Pan123) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
|
func (d *Pan123) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
|
||||||
if f, ok := file.(File); ok {
|
if f, ok := file.(File); ok {
|
||||||
return &model.Link{
|
var resp DownResp
|
||||||
URL: f.DownloadUrl,
|
var headers map[string]string
|
||||||
}, nil
|
if !utils.IsLocalIPAddr(args.IP) {
|
||||||
|
headers = map[string]string{
|
||||||
|
//"X-Real-IP": "1.1.1.1",
|
||||||
|
"X-Forwarded-For": args.IP,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data := base.Json{
|
||||||
|
"driveId": 0,
|
||||||
|
"etag": f.Etag,
|
||||||
|
"fileId": f.FileId,
|
||||||
|
"fileName": f.FileName,
|
||||||
|
"s3keyFlag": f.S3KeyFlag,
|
||||||
|
"size": f.Size,
|
||||||
|
"type": f.Type,
|
||||||
|
}
|
||||||
|
_, err := d.request("https://www.123pan.com/api/file/download_info", http.MethodPost, func(req *resty.Request) {
|
||||||
|
req.SetBody(data).SetHeaders(headers)
|
||||||
|
}, &resp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
u, err := url.Parse(resp.Data.DownloadUrl)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
u_ := fmt.Sprintf("https://%s%s", u.Host, u.Path)
|
||||||
|
res, err := base.NoRedirectClient.R().SetQueryParamsFromValues(u.Query()).Head(u_)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
log.Debug(res.String())
|
||||||
|
link := model.Link{
|
||||||
|
URL: resp.Data.DownloadUrl,
|
||||||
|
}
|
||||||
|
log.Debugln("res code: ", res.StatusCode())
|
||||||
|
if res.StatusCode() == 302 {
|
||||||
|
link.URL = res.Header().Get("location")
|
||||||
|
}
|
||||||
|
return &link, nil
|
||||||
} else {
|
} else {
|
||||||
return nil, fmt.Errorf("can't convert obj")
|
return nil, fmt.Errorf("can't convert obj")
|
||||||
}
|
}
|
||||||
@ -153,7 +192,7 @@ func (d *Pan123) Put(ctx context.Context, dstDir model.Obj, stream model.FileStr
|
|||||||
uploadFile = io.MultiReader(buf, stream)
|
uploadFile = io.MultiReader(buf, stream)
|
||||||
} else {
|
} else {
|
||||||
// 计算完整文件MD5
|
// 计算完整文件MD5
|
||||||
tempFile, err := os.CreateTemp(conf.Conf.TempDir, "file-*")
|
tempFile, err := utils.CreateTempFile(stream.GetReadCloser())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -161,11 +200,9 @@ func (d *Pan123) Put(ctx context.Context, dstDir model.Obj, stream model.FileStr
|
|||||||
_ = tempFile.Close()
|
_ = tempFile.Close()
|
||||||
_ = os.Remove(tempFile.Name())
|
_ = os.Remove(tempFile.Name())
|
||||||
}()
|
}()
|
||||||
|
if _, err = io.Copy(h, tempFile); err != nil {
|
||||||
if _, err = io.Copy(io.MultiWriter(tempFile, h), stream); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = tempFile.Seek(0, io.SeekStart)
|
_, err = tempFile.Seek(0, io.SeekStart)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -506,14 +506,15 @@ func (y *Yun189PC) CommonUpload(ctx context.Context, dstDir model.Obj, file mode
|
|||||||
// 快传
|
// 快传
|
||||||
func (y *Yun189PC) FastUpload(ctx context.Context, dstDir model.Obj, file model.FileStreamer, up driver.UpdateProgress) (err error) {
|
func (y *Yun189PC) FastUpload(ctx context.Context, dstDir model.Obj, file model.FileStreamer, up driver.UpdateProgress) (err error) {
|
||||||
// 需要获取完整文件md5,必须支持 io.Seek
|
// 需要获取完整文件md5,必须支持 io.Seek
|
||||||
if _, ok := file.GetReadCloser().(*os.File); !ok {
|
tempFile, err := utils.CreateTempFile(file.GetReadCloser())
|
||||||
r, err := utils.CreateTempFile(file)
|
if err != nil {
|
||||||
if err != nil {
|
return err
|
||||||
return err
|
|
||||||
}
|
|
||||||
file.Close()
|
|
||||||
file.SetReadCloser(r)
|
|
||||||
}
|
}
|
||||||
|
defer func() {
|
||||||
|
_ = tempFile.Close()
|
||||||
|
_ = os.Remove(tempFile.Name())
|
||||||
|
}()
|
||||||
|
file.SetReadCloser(tempFile)
|
||||||
|
|
||||||
const DEFAULT int64 = 10485760
|
const DEFAULT int64 = 10485760
|
||||||
count := int(math.Ceil(float64(file.GetSize()) / float64(DEFAULT)))
|
count := int(math.Ceil(float64(file.GetSize()) / float64(DEFAULT)))
|
||||||
|
@ -14,7 +14,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/alist-org/alist/v3/drivers/base"
|
"github.com/alist-org/alist/v3/drivers/base"
|
||||||
"github.com/alist-org/alist/v3/internal/conf"
|
|
||||||
"github.com/alist-org/alist/v3/internal/driver"
|
"github.com/alist-org/alist/v3/internal/driver"
|
||||||
"github.com/alist-org/alist/v3/internal/errs"
|
"github.com/alist-org/alist/v3/internal/errs"
|
||||||
"github.com/alist-org/alist/v3/internal/model"
|
"github.com/alist-org/alist/v3/internal/model"
|
||||||
@ -119,28 +118,14 @@ func (d *BaiduNetdisk) Remove(ctx context.Context, obj model.Obj) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *BaiduNetdisk) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
|
func (d *BaiduNetdisk) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
|
||||||
var tempFile *os.File
|
tempFile, err := utils.CreateTempFile(stream.GetReadCloser())
|
||||||
var err error
|
if err != nil {
|
||||||
if f, ok := stream.GetReadCloser().(*os.File); ok {
|
return err
|
||||||
tempFile = f
|
|
||||||
} else {
|
|
||||||
tempFile, err = os.CreateTemp(conf.Conf.TempDir, "file-*")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
_ = tempFile.Close()
|
|
||||||
_ = os.Remove(tempFile.Name())
|
|
||||||
}()
|
|
||||||
_, err = io.Copy(tempFile, stream)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = tempFile.Seek(0, io.SeekStart)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
defer func() {
|
||||||
|
_ = tempFile.Close()
|
||||||
|
_ = os.Remove(tempFile.Name())
|
||||||
|
}()
|
||||||
var Default int64 = 4 * 1024 * 1024
|
var Default int64 = 4 * 1024 * 1024
|
||||||
defaultByteData := make([]byte, Default)
|
defaultByteData := make([]byte, Default)
|
||||||
count := int(math.Ceil(float64(stream.GetSize()) / float64(Default)))
|
count := int(math.Ceil(float64(stream.GetSize()) / float64(Default)))
|
||||||
|
@ -34,7 +34,7 @@ func fileToObj(f File) *model.ObjThumb {
|
|||||||
Name: f.Name,
|
Name: f.Name,
|
||||||
Size: size,
|
Size: size,
|
||||||
Modified: time.Time{},
|
Modified: time.Time{},
|
||||||
IsFolder: false,
|
IsFolder: f.MimeType == "application/vnd.google-apps.folder",
|
||||||
},
|
},
|
||||||
Thumbnail: model.Thumbnail{},
|
Thumbnail: model.Thumbnail{},
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/alist-org/alist/v3/drivers/base"
|
"github.com/alist-org/alist/v3/drivers/base"
|
||||||
"github.com/alist-org/alist/v3/internal/conf"
|
|
||||||
"github.com/alist-org/alist/v3/internal/driver"
|
"github.com/alist-org/alist/v3/internal/driver"
|
||||||
"github.com/alist-org/alist/v3/internal/errs"
|
"github.com/alist-org/alist/v3/internal/errs"
|
||||||
"github.com/alist-org/alist/v3/internal/model"
|
"github.com/alist-org/alist/v3/internal/model"
|
||||||
@ -177,7 +176,7 @@ func (d *MediaTrack) Put(ctx context.Context, dstDir model.Obj, stream model.Fil
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
tempFile, err := os.CreateTemp(conf.Conf.TempDir, "file-*")
|
tempFile, err := utils.CreateTempFile(stream.GetReadCloser())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -185,14 +184,6 @@ func (d *MediaTrack) Put(ctx context.Context, dstDir model.Obj, stream model.Fil
|
|||||||
_ = tempFile.Close()
|
_ = tempFile.Close()
|
||||||
_ = os.Remove(tempFile.Name())
|
_ = os.Remove(tempFile.Name())
|
||||||
}()
|
}()
|
||||||
_, err = io.Copy(tempFile, stream)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = tempFile.Seek(0, io.SeekStart)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
uploader := s3manager.NewUploader(s)
|
uploader := s3manager.NewUploader(s)
|
||||||
input := &s3manager.UploadInput{
|
input := &s3manager.UploadInput{
|
||||||
Bucket: &resp.Data.Bucket,
|
Bucket: &resp.Data.Bucket,
|
||||||
|
@ -11,7 +11,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/alist-org/alist/v3/drivers/base"
|
"github.com/alist-org/alist/v3/drivers/base"
|
||||||
"github.com/alist-org/alist/v3/internal/conf"
|
|
||||||
"github.com/alist-org/alist/v3/internal/driver"
|
"github.com/alist-org/alist/v3/internal/driver"
|
||||||
"github.com/alist-org/alist/v3/internal/errs"
|
"github.com/alist-org/alist/v3/internal/errs"
|
||||||
"github.com/alist-org/alist/v3/internal/model"
|
"github.com/alist-org/alist/v3/internal/model"
|
||||||
@ -134,28 +133,14 @@ func (d *PikPak) Remove(ctx context.Context, obj model.Obj) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *PikPak) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
|
func (d *PikPak) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
|
||||||
var tempFile *os.File
|
tempFile, err := utils.CreateTempFile(stream.GetReadCloser())
|
||||||
var err error
|
if err != nil {
|
||||||
if f, ok := stream.GetReadCloser().(*os.File); ok {
|
return err
|
||||||
tempFile = f
|
|
||||||
} else {
|
|
||||||
tempFile, err = os.CreateTemp(conf.Conf.TempDir, "file-*")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
_ = tempFile.Close()
|
|
||||||
_ = os.Remove(tempFile.Name())
|
|
||||||
}()
|
|
||||||
_, err = io.Copy(tempFile, stream)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = tempFile.Seek(0, io.SeekStart)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
defer func() {
|
||||||
|
_ = tempFile.Close()
|
||||||
|
_ = os.Remove(tempFile.Name())
|
||||||
|
}()
|
||||||
// cal sha1
|
// cal sha1
|
||||||
s := sha1.New()
|
s := sha1.New()
|
||||||
_, err = io.Copy(s, tempFile)
|
_, err = io.Copy(s, tempFile)
|
||||||
@ -182,6 +167,10 @@ func (d *PikPak) Put(ctx context.Context, dstDir model.Obj, stream model.FileStr
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if stream.GetSize() == 0 {
|
||||||
|
log.Debugln(string(res))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
params := jsoniter.Get(res, "resumable").Get("params")
|
params := jsoniter.Get(res, "resumable").Get("params")
|
||||||
endpoint := params.Get("endpoint").ToString()
|
endpoint := params.Get("endpoint").ToString()
|
||||||
endpointS := strings.Split(endpoint, ".")
|
endpointS := strings.Split(endpoint, ".")
|
||||||
|
@ -10,7 +10,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/alist-org/alist/v3/drivers/base"
|
"github.com/alist-org/alist/v3/drivers/base"
|
||||||
"github.com/alist-org/alist/v3/internal/conf"
|
|
||||||
"github.com/alist-org/alist/v3/internal/driver"
|
"github.com/alist-org/alist/v3/internal/driver"
|
||||||
"github.com/alist-org/alist/v3/internal/errs"
|
"github.com/alist-org/alist/v3/internal/errs"
|
||||||
"github.com/alist-org/alist/v3/internal/model"
|
"github.com/alist-org/alist/v3/internal/model"
|
||||||
@ -135,28 +134,14 @@ func (d *Quark) Remove(ctx context.Context, obj model.Obj) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Quark) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
|
func (d *Quark) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
|
||||||
var tempFile *os.File
|
tempFile, err := utils.CreateTempFile(stream.GetReadCloser())
|
||||||
var err error
|
if err != nil {
|
||||||
if f, ok := stream.GetReadCloser().(*os.File); ok {
|
return err
|
||||||
tempFile = f
|
|
||||||
} else {
|
|
||||||
tempFile, err = os.CreateTemp(conf.Conf.TempDir, "file-*")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
_ = tempFile.Close()
|
|
||||||
_ = os.Remove(tempFile.Name())
|
|
||||||
}()
|
|
||||||
_, err = io.Copy(tempFile, stream)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = tempFile.Seek(0, io.SeekStart)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
defer func() {
|
||||||
|
_ = tempFile.Close()
|
||||||
|
_ = os.Remove(tempFile.Name())
|
||||||
|
}()
|
||||||
m := md5.New()
|
m := md5.New()
|
||||||
_, err = io.Copy(m, tempFile)
|
_, err = io.Copy(m, tempFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -13,8 +13,9 @@ type Addition struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var config = driver.Config{
|
var config = driver.Config{
|
||||||
Name: "Quark",
|
Name: "Quark",
|
||||||
OnlyProxy: true,
|
OnlyProxy: true,
|
||||||
|
DefaultRoot: "0",
|
||||||
}
|
}
|
||||||
|
|
||||||
func New() driver.Driver {
|
func New() driver.Driver {
|
||||||
|
@ -119,7 +119,7 @@ func (d *S3) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *S3) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
|
func (d *S3) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
|
||||||
err := d.copy(srcObj.GetPath(), stdpath.Join(stdpath.Dir(srcObj.GetPath()), newName), srcObj.IsDir())
|
err := d.copy(ctx, srcObj.GetPath(), stdpath.Join(stdpath.Dir(srcObj.GetPath()), newName), srcObj.IsDir())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -127,7 +127,7 @@ func (d *S3) Rename(ctx context.Context, srcObj model.Obj, newName string) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *S3) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
|
func (d *S3) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
|
||||||
return d.copy(srcObj.GetPath(), stdpath.Join(dstDir.GetPath(), srcObj.GetName()), srcObj.IsDir())
|
return d.copy(ctx, srcObj.GetPath(), stdpath.Join(dstDir.GetPath(), srcObj.GetName()), srcObj.IsDir())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *S3) Remove(ctx context.Context, obj model.Obj) error {
|
func (d *S3) Remove(ctx context.Context, obj model.Obj) error {
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
package s3
|
package s3
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/alist-org/alist/v3/internal/model"
|
"github.com/alist-org/alist/v3/internal/model"
|
||||||
|
"github.com/alist-org/alist/v3/internal/op"
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
@ -165,14 +167,41 @@ func (d *S3) listV2(prefix string) ([]model.Obj, error) {
|
|||||||
return files, nil
|
return files, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *S3) copy(src string, dst string, isDir bool) error {
|
func (d *S3) copy(ctx context.Context, src string, dst string, isDir bool) error {
|
||||||
srcKey := getKey(src, isDir)
|
if isDir {
|
||||||
dstKey := getKey(dst, isDir)
|
return d.copyDir(ctx, src, dst)
|
||||||
|
}
|
||||||
|
return d.copyFile(ctx, src, dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *S3) copyFile(ctx context.Context, src string, dst string) error {
|
||||||
|
srcKey := getKey(src, false)
|
||||||
|
dstKey := getKey(dst, false)
|
||||||
input := &s3.CopyObjectInput{
|
input := &s3.CopyObjectInput{
|
||||||
Bucket: &d.Bucket,
|
Bucket: &d.Bucket,
|
||||||
CopySource: &srcKey,
|
CopySource: aws.String("/" + d.Bucket + "/" + srcKey),
|
||||||
Key: &dstKey,
|
Key: &dstKey,
|
||||||
}
|
}
|
||||||
_, err := d.client.CopyObject(input)
|
_, err := d.client.CopyObject(input)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *S3) copyDir(ctx context.Context, src string, dst string) error {
|
||||||
|
objs, err := op.List(ctx, d, src, model.ListArgs{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, obj := range objs {
|
||||||
|
cSrc := path.Join(src, obj.GetName())
|
||||||
|
cDst := path.Join(dst, obj.GetName())
|
||||||
|
if obj.IsDir() {
|
||||||
|
err = d.copyDir(ctx, cSrc, cDst)
|
||||||
|
} else {
|
||||||
|
err = d.copyFile(ctx, cSrc, cDst)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -48,16 +48,14 @@ func InitConfig() {
|
|||||||
confFromEnv()
|
confFromEnv()
|
||||||
}
|
}
|
||||||
// convert abs path
|
// convert abs path
|
||||||
var absPath string
|
|
||||||
var err error
|
|
||||||
if !filepath.IsAbs(conf.Conf.TempDir) {
|
if !filepath.IsAbs(conf.Conf.TempDir) {
|
||||||
absPath, err = filepath.Abs(conf.Conf.TempDir)
|
absPath, err := filepath.Abs(conf.Conf.TempDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("get abs path error: %+v", err)
|
log.Fatalf("get abs path error: %+v", err)
|
||||||
}
|
}
|
||||||
|
conf.Conf.TempDir = absPath
|
||||||
}
|
}
|
||||||
conf.Conf.TempDir = absPath
|
err := os.RemoveAll(filepath.Join(conf.Conf.TempDir))
|
||||||
err = os.RemoveAll(filepath.Join(conf.Conf.TempDir))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorln("failed delete temp file:", err)
|
log.Errorln("failed delete temp file:", err)
|
||||||
}
|
}
|
||||||
|
@ -35,15 +35,12 @@ func initSettings() {
|
|||||||
for i := range initialSettingItems {
|
for i := range initialSettingItems {
|
||||||
v := initialSettingItems[i]
|
v := initialSettingItems[i]
|
||||||
_, err := db.GetSettingItemByKey(v.Key)
|
_, err := db.GetSettingItemByKey(v.Key)
|
||||||
if err == nil {
|
if errors.Is(err, gorm.ErrRecordNotFound) || v.Key == conf.VERSION {
|
||||||
continue
|
|
||||||
}
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
err = db.SaveSettingItem(v)
|
err = db.SaveSettingItem(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed create setting: %+v", err)
|
log.Fatalf("failed create setting: %+v", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else if err != nil {
|
||||||
log.Fatalf("failed get setting: %+v", err)
|
log.Fatalf("failed get setting: %+v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@ func Link(ctx context.Context, storage driver.Driver, path string, args model.Li
|
|||||||
if file.IsDir() {
|
if file.IsDir() {
|
||||||
return nil, nil, errors.WithStack(errs.NotFile)
|
return nil, nil, errors.WithStack(errs.NotFile)
|
||||||
}
|
}
|
||||||
key := stdpath.Join(storage.GetStorage().MountPath, path)
|
key := stdpath.Join(storage.GetStorage().MountPath, path) + ":" + args.IP
|
||||||
if link, ok := linkCache.Get(key); ok {
|
if link, ok := linkCache.Get(key); ok {
|
||||||
return link, file, nil
|
return link, file, nil
|
||||||
}
|
}
|
||||||
|
@ -34,16 +34,21 @@ func CreateNestedFile(path string) (*os.File, error) {
|
|||||||
|
|
||||||
// CreateTempFile create temp file from io.ReadCloser, and seek to 0
|
// CreateTempFile create temp file from io.ReadCloser, and seek to 0
|
||||||
func CreateTempFile(r io.ReadCloser) (*os.File, error) {
|
func CreateTempFile(r io.ReadCloser) (*os.File, error) {
|
||||||
|
if f, ok := r.(*os.File); ok {
|
||||||
|
return f, nil
|
||||||
|
}
|
||||||
f, err := os.CreateTemp(conf.Conf.TempDir, "file-*")
|
f, err := os.CreateTemp(conf.Conf.TempDir, "file-*")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_, err = io.Copy(f, r)
|
_, err = io.Copy(f, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
_ = os.Remove(f.Name())
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_, err = f.Seek(0, io.SeekStart)
|
_, err = f.Seek(0, io.SeekStart)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
_ = os.Remove(f.Name())
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return f, nil
|
return f, nil
|
||||||
|
@ -24,3 +24,26 @@ func ClientIP(r *http.Request) string {
|
|||||||
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsLocalIPAddr(ip string) bool {
|
||||||
|
return IsLocalIP(net.ParseIP(ip))
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsLocalIP(ip net.IP) bool {
|
||||||
|
if ip == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if ip.IsLoopback() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
ip4 := ip.To4()
|
||||||
|
if ip4 == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return ip4[0] == 10 || // 10.0.0.0/8
|
||||||
|
(ip4[0] == 172 && ip4[1] >= 16 && ip4[1] <= 31) || // 172.16.0.0/12
|
||||||
|
(ip4[0] == 169 && ip4[1] == 254) || // 169.254.0.0/16
|
||||||
|
(ip4[0] == 192 && ip4[1] == 168) // 192.168.0.0/16
|
||||||
|
}
|
||||||
|
@ -52,7 +52,7 @@ func Proxy(c *gin.Context) {
|
|||||||
downProxyUrl := storage.GetStorage().DownProxyUrl
|
downProxyUrl := storage.GetStorage().DownProxyUrl
|
||||||
if downProxyUrl != "" {
|
if downProxyUrl != "" {
|
||||||
_, ok := c.GetQuery("d")
|
_, ok := c.GetQuery("d")
|
||||||
if ok {
|
if !ok {
|
||||||
URL := fmt.Sprintf("%s%s?sign=%s",
|
URL := fmt.Sprintf("%s%s?sign=%s",
|
||||||
strings.Split(downProxyUrl, "\n")[0],
|
strings.Split(downProxyUrl, "\n")[0],
|
||||||
utils.EncodePath(rawPath, true),
|
utils.EncodePath(rawPath, true),
|
||||||
@ -103,7 +103,7 @@ func shouldProxy(storage driver.Driver, filename string) bool {
|
|||||||
// 4. proxy_types
|
// 4. proxy_types
|
||||||
// solution: text_file + shouldProxy()
|
// solution: text_file + shouldProxy()
|
||||||
func canProxy(storage driver.Driver, filename string) bool {
|
func canProxy(storage driver.Driver, filename string) bool {
|
||||||
if storage.Config().MustProxy() || storage.GetStorage().WebProxy {
|
if storage.Config().MustProxy() || storage.GetStorage().WebProxy || storage.GetStorage().WebdavProxy() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if utils.SliceContains(conf.TypesMap[conf.ProxyTypes], utils.Ext(filename)) {
|
if utils.SliceContains(conf.TypesMap[conf.ProxyTypes], utils.Ext(filename)) {
|
||||||
|
Reference in New Issue
Block a user