mirror of
https://github.com/OpenListTeam/OpenList.git
synced 2026-10-10 21:13:10 +08:00
Compare commits
35 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 80487122ea | |||
| f99a1f9a50 | |||
| ff3cb8b931 | |||
| 7aea393a6d | |||
| 36168c86a0 | |||
| 24332e371f | |||
| 6b702afc0f | |||
| 78db0f7aff | |||
| e469693114 | |||
| 5961289b83 | |||
| 0527dc41af | |||
| b1d298d192 | |||
| 651b5cea1c | |||
| 5aeaf7a8c8 | |||
| 651da18da4 | |||
| 5a5d8d6e0e | |||
| 061c1e2e1e | |||
| caed356200 | |||
| 74af297471 | |||
| 7c54b0e3e4 | |||
| a632356902 | |||
| 82ea8d0d01 | |||
| eb48671202 | |||
| f3e74fbdf1 | |||
| e670322ee3 | |||
| 8930e1945e | |||
| daaba0d7ea | |||
| a81f54488f | |||
| 59bd343140 | |||
| 757f9d383d | |||
| 7ded6dfe2c | |||
| a283f2b52a | |||
| bb3bc31609 | |||
| 744021d80d | |||
| 94eac2e91e |
@@ -18,7 +18,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -108,12 +108,12 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v6
|
||||
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
|
||||
with:
|
||||
go-version: "1.26.4"
|
||||
|
||||
|
||||
@@ -25,13 +25,13 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- uses: benjlevesque/short-sha@v3.0
|
||||
- uses: benjlevesque/short-sha@dbe07338b37c456ce06d23409b35a56a7815eef4 # v4.0
|
||||
id: short-sha
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v6
|
||||
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
|
||||
with:
|
||||
go-version: "1.26.4"
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
@@ -44,12 +44,12 @@ jobs:
|
||||
swap-storage: true
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v6
|
||||
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
|
||||
with:
|
||||
go-version: '1.26.4'
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 1
|
||||
fetch-tags: true
|
||||
|
||||
@@ -43,15 +43,15 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- uses: actions/setup-go@v6
|
||||
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
|
||||
with:
|
||||
go-version: '1.26'
|
||||
|
||||
- name: Cache Musl
|
||||
id: cache-musl
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: build/musl-libs
|
||||
key: docker-musl-libs-v2
|
||||
@@ -83,15 +83,15 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- uses: actions/setup-go@v6
|
||||
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
|
||||
with:
|
||||
go-version: '1.26.4'
|
||||
|
||||
- name: Cache Musl
|
||||
id: cache-musl
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: build/musl-libs
|
||||
key: docker-musl-libs-v2
|
||||
@@ -146,21 +146,21 @@ jobs:
|
||||
tag_favor: "suffix=-aio,onlatest=true"
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
- uses: actions/download-artifact@v4
|
||||
uses: actions/checkout@v7
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: ${{ env.ARTIFACT_NAME }}
|
||||
path: 'build/'
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
if: env.IMAGE_PUSH == 'true'
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
@@ -168,14 +168,14 @@ jobs:
|
||||
|
||||
- name: Login to DockerHub Container Registry
|
||||
if: env.IMAGE_PUSH == 'true'
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4
|
||||
with:
|
||||
username: ${{ vars.DOCKERHUB_ORG_NAME_BACKUP || env.DOCKERHUB_ORG_NAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6
|
||||
with:
|
||||
images: |
|
||||
${{ env.REGISTRY }}/${{ env.GHCR_ORG_NAME }}/${{ env.IMAGE_NAME }}
|
||||
@@ -190,7 +190,7 @@ jobs:
|
||||
|
||||
- name: Build and push
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile.ci
|
||||
@@ -230,21 +230,21 @@ jobs:
|
||||
tag_favor: "suffix=-lite-aio,onlatest=true"
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
- uses: actions/download-artifact@v4
|
||||
uses: actions/checkout@v7
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: ${{ env.ARTIFACT_NAME_LITE }}
|
||||
path: 'build/'
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
if: env.IMAGE_PUSH == 'true'
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
@@ -252,14 +252,14 @@ jobs:
|
||||
|
||||
- name: Login to DockerHub Container Registry
|
||||
if: env.IMAGE_PUSH == 'true'
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4
|
||||
with:
|
||||
username: ${{ vars.DOCKERHUB_ORG_NAME_BACKUP || env.DOCKERHUB_ORG_NAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6
|
||||
with:
|
||||
images: |
|
||||
${{ env.REGISTRY }}/${{ env.GHCR_ORG_NAME }}/${{ env.IMAGE_NAME }}
|
||||
@@ -274,7 +274,7 @@ jobs:
|
||||
|
||||
- name: Build and push
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile.ci
|
||||
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
name: Sync GitHub to Gitee
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
@@ -32,15 +32,15 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- uses: actions/setup-go@v6
|
||||
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
|
||||
with:
|
||||
go-version: '1.26.4'
|
||||
|
||||
- name: Cache Musl
|
||||
id: cache-musl
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6
|
||||
with:
|
||||
path: build/musl-libs
|
||||
key: docker-musl-libs-v2
|
||||
@@ -97,21 +97,21 @@ jobs:
|
||||
tag_favor: "suffix=-aio,onlatest=true"
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
- uses: actions/download-artifact@v4
|
||||
uses: actions/checkout@v7
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: ${{ env.ARTIFACT_NAME }}
|
||||
path: 'build/'
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
if: env.IMAGE_PUSH == 'true'
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
@@ -119,14 +119,14 @@ jobs:
|
||||
|
||||
- name: Login to DockerHub Container Registry
|
||||
if: env.IMAGE_PUSH == 'true'
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4
|
||||
with:
|
||||
username: ${{ vars.DOCKERHUB_ORG_NAME_BACKUP || env.DOCKERHUB_ORG_NAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6
|
||||
with:
|
||||
images: |
|
||||
${{ env.REGISTRY }}/${{ env.GHCR_ORG_NAME }}/${{ env.IMAGE_NAME }}
|
||||
@@ -137,7 +137,7 @@ jobs:
|
||||
|
||||
- name: Build and push
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile.ci
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/OpenListTeam/OpenList/v4/drivers/base"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/driver"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/model"
|
||||
streamPkg "github.com/OpenListTeam/OpenList/v4/internal/stream"
|
||||
@@ -69,9 +68,6 @@ func (d *Pan115) Link(ctx context.Context, file model.Obj, args model.LinkArgs)
|
||||
return nil, err
|
||||
}
|
||||
userAgent := args.Header.Get("User-Agent")
|
||||
if userAgent == "" {
|
||||
userAgent = base.UserAgent
|
||||
}
|
||||
downloadInfo, err := d.client.DownloadWithUA(file.(*FileObj).PickCode, userAgent)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -182,6 +182,7 @@ func (d *Open115) Get(ctx context.Context, path string) (model.Obj, error) {
|
||||
Fc: resp.FileCategory,
|
||||
Sha1: resp.Sha1,
|
||||
Pc: resp.PickCode,
|
||||
FS: resp.SizeByte,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -90,9 +90,6 @@ func (d *Pan115Share) Link(ctx context.Context, file model.Obj, args model.LinkA
|
||||
if args.Header != nil {
|
||||
ua = args.Header.Get("User-Agent")
|
||||
}
|
||||
if ua == "" {
|
||||
ua = base.UserAgent
|
||||
}
|
||||
downloadInfo, err := d.client.DownloadByShareCodeWithUA(ua, d.ShareCode, d.ReceiveCode, file.GetID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
+14
-21
@@ -18,10 +18,10 @@ import (
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/model"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/stream"
|
||||
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/s3/s3manager"
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/credentials"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager"
|
||||
"github.com/go-resty/resty/v2"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
@@ -212,29 +212,22 @@ func (d *Pan123) Put(ctx context.Context, dstDir model.Obj, file model.FileStrea
|
||||
err = d.newUpload(ctx, &resp, file, up)
|
||||
return err
|
||||
} else {
|
||||
cfg := &aws.Config{
|
||||
Credentials: credentials.NewStaticCredentials(resp.Data.AccessKeyId, resp.Data.SecretAccessKey, resp.Data.SessionToken),
|
||||
Region: aws.String("123pan"),
|
||||
Endpoint: aws.String(resp.Data.EndPoint),
|
||||
S3ForcePathStyle: aws.Bool(true),
|
||||
}
|
||||
s, err := session.NewSession(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
uploader := s3manager.NewUploader(s)
|
||||
if file.GetSize() > s3manager.MaxUploadParts*s3manager.DefaultUploadPartSize {
|
||||
uploader.PartSize = file.GetSize() / (s3manager.MaxUploadParts - 1)
|
||||
}
|
||||
input := &s3manager.UploadInput{
|
||||
s3Client := s3.NewFromConfig(aws.Config{
|
||||
Credentials: credentials.NewStaticCredentialsProvider(resp.Data.AccessKeyId, resp.Data.SecretAccessKey, resp.Data.SessionToken),
|
||||
Region: "123pan",
|
||||
}, func(o *s3.Options) {
|
||||
o.BaseEndpoint = aws.String(resp.Data.EndPoint)
|
||||
o.UsePathStyle = true
|
||||
})
|
||||
tmClient := transfermanager.New(s3Client)
|
||||
_, err = tmClient.UploadObject(ctx, &transfermanager.UploadObjectInput{
|
||||
Bucket: &resp.Data.Bucket,
|
||||
Key: &resp.Data.Key,
|
||||
Body: driver.NewLimitedUploadStream(ctx, &driver.ReaderUpdatingProgress{
|
||||
Reader: file,
|
||||
UpdateProgress: up,
|
||||
}),
|
||||
}
|
||||
_, err = uploader.UploadWithContext(ctx, input)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package azure_blob
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"path"
|
||||
@@ -12,10 +13,13 @@ import (
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/container"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/sas"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/driver"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/model"
|
||||
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Azure Blob Storage based on the blob APIs
|
||||
@@ -283,6 +287,26 @@ func (d *AzureBlob) Put(ctx context.Context, dstDir model.Obj, stream model.File
|
||||
// Determine optimal upload options based on file size
|
||||
options := optimizedUploadOptions(stream.GetSize())
|
||||
|
||||
// Preserve the file content type for direct Azure Blob downloads.
|
||||
contentType := stream.GetMimetype()
|
||||
if contentType == "" {
|
||||
contentType = "application/octet-stream"
|
||||
}
|
||||
options.HTTPHeaders = &blob.HTTPHeaders{
|
||||
BlobContentType: &contentType,
|
||||
}
|
||||
|
||||
// Preserve the MD5 checksum when it is available.
|
||||
md5Hex := stream.GetHash().GetHash(utils.MD5)
|
||||
if md5Hex != "" {
|
||||
md5, err := hex.DecodeString(md5Hex)
|
||||
if err == nil && len(md5) == 16 {
|
||||
options.HTTPHeaders.BlobContentMD5 = md5
|
||||
} else {
|
||||
log.Warnf("Invalid MD5 hash: %s, error: %v", md5Hex, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Track upload progress
|
||||
progressTracker := &progressTracker{
|
||||
total: stream.GetSize(),
|
||||
|
||||
@@ -45,134 +45,126 @@ func (d *GithubReleases) List(ctx context.Context, dir model.Obj, args model.Lis
|
||||
for i := range d.points {
|
||||
point := &d.points[i]
|
||||
|
||||
if !d.Addition.ShowAllVersion { // latest
|
||||
err := point.RequestRelease(d.GetRequest, args.Refresh)
|
||||
if !d.Addition.ShowAllVersion {
|
||||
// latest version mode
|
||||
release, err := d.getLatestRelease(point.Repo)
|
||||
if err != nil {
|
||||
log.Warnf("failed to request release for %s: %v", point.Repo, err)
|
||||
continue
|
||||
}
|
||||
if release == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if point.Point == path { // 与仓库路径相同
|
||||
if point.Release == nil {
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get release for %s: %w", point.Repo, err)
|
||||
}
|
||||
return nil, fmt.Errorf("failed to get release for %s: unknown error", point.Repo)
|
||||
}
|
||||
files = append(files, point.GetLatestRelease()...)
|
||||
if point.Point == path {
|
||||
// 当前目录就是仓库挂载点
|
||||
files = append(files, releaseToFiles(point.Point, release)...)
|
||||
if d.Addition.ShowReadme {
|
||||
otherFiles, err := point.GetOtherFile(d.GetRequest, args.Refresh)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get other files for %s: %w", point.Repo, err)
|
||||
other, err := d.fetchRepoFiles(point.Repo)
|
||||
if err == nil {
|
||||
files = append(files, otherFiles(point.Point, other)...)
|
||||
} else {
|
||||
log.Warnf("failed to get other files for %s: %v", point.Repo, err)
|
||||
}
|
||||
files = append(files, otherFiles...)
|
||||
}
|
||||
if d.Addition.ShowSourceCode {
|
||||
files = append(files, point.GetSourceCode()...)
|
||||
files = append(files, sourceCodeFiles(point.Point, release)...)
|
||||
}
|
||||
} else if strings.HasPrefix(point.Point, path) { // 仓库目录的父目录
|
||||
} else if strings.HasPrefix(point.Point, path) {
|
||||
// 仓库目录的父目录,需要聚合显示
|
||||
nextDir := GetNextDir(point.Point, path)
|
||||
if nextDir == "" {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get release for %s: %w", point.Repo, err)
|
||||
}
|
||||
|
||||
hasSameDir := false
|
||||
for index := range files {
|
||||
if files[index].GetName() == nextDir {
|
||||
hasSameDir = true
|
||||
files[index].Size += point.GetLatestSize()
|
||||
files[index].Size += releaseSize(release)
|
||||
break
|
||||
}
|
||||
}
|
||||
if !hasSameDir {
|
||||
var updateAt, createAt string
|
||||
if point.Release != nil {
|
||||
updateAt = point.Release.PublishedAt
|
||||
createAt = point.Release.CreatedAt
|
||||
}
|
||||
files = append(files, File{
|
||||
Path: stdpath.Join(path, nextDir),
|
||||
FileName: nextDir,
|
||||
Size: point.GetLatestSize(),
|
||||
UpdateAt: updateAt,
|
||||
CreateAt: createAt,
|
||||
Size: releaseSize(release),
|
||||
UpdateAt: release.PublishedAt,
|
||||
CreateAt: release.CreatedAt,
|
||||
Type: "dir",
|
||||
Url: "",
|
||||
})
|
||||
}
|
||||
}
|
||||
} else { // all version
|
||||
err := point.RequestReleases(d.GetRequest, args.Refresh)
|
||||
} else {
|
||||
// all versions mode
|
||||
releases, err := d.getAllReleases(point.Repo)
|
||||
if err != nil {
|
||||
log.Warnf("failed to request releases for %s: %v", point.Repo, err)
|
||||
continue
|
||||
}
|
||||
if len(releases) == 0 {
|
||||
// no releases but may still have repo files (e.g. README)
|
||||
if point.Point == path && d.Addition.ShowReadme {
|
||||
other, err := d.fetchRepoFiles(point.Repo)
|
||||
if err == nil {
|
||||
files = append(files, otherFiles(point.Point, other)...)
|
||||
} else {
|
||||
log.Warnf("failed to get other files for %s: %v", point.Repo, err)
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if point.Point == path { // 与仓库路径相同
|
||||
if point.Releases == nil {
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get releases for %s: %w", point.Repo, err)
|
||||
}
|
||||
return nil, fmt.Errorf("failed to get releases for %s: unknown error", point.Repo)
|
||||
}
|
||||
files = append(files, point.GetAllVersion()...)
|
||||
if point.Point == path {
|
||||
// 当前目录就是仓库挂载点
|
||||
files = append(files, releasesToVersionDirs(point.Point, releases)...)
|
||||
if d.Addition.ShowReadme {
|
||||
otherFiles, err := point.GetOtherFile(d.GetRequest, args.Refresh)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get other files for %s: %w", point.Repo, err)
|
||||
other, err := d.fetchRepoFiles(point.Repo)
|
||||
if err == nil {
|
||||
files = append(files, otherFiles(point.Point, other)...)
|
||||
} else {
|
||||
log.Warnf("failed to get other files for %s: %v", point.Repo, err)
|
||||
}
|
||||
files = append(files, otherFiles...)
|
||||
}
|
||||
} else if strings.HasPrefix(point.Point, path) { // 仓库目录的父目录
|
||||
} else if strings.HasPrefix(point.Point, path) {
|
||||
// 仓库目录的父目录
|
||||
nextDir := GetNextDir(point.Point, path)
|
||||
if nextDir == "" {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get releases for %s: %w", point.Repo, err)
|
||||
}
|
||||
|
||||
hasSameDir := false
|
||||
for index := range files {
|
||||
if files[index].GetName() == nextDir {
|
||||
hasSameDir = true
|
||||
files[index].Size += point.GetAllVersionSize()
|
||||
files[index].Size += releasesTotalSize(releases)
|
||||
break
|
||||
}
|
||||
}
|
||||
if !hasSameDir {
|
||||
var updateAt, createAt string
|
||||
if point.Releases != nil && len(*point.Releases) > 0 {
|
||||
updateAt = (*point.Releases)[0].PublishedAt
|
||||
createAt = (*point.Releases)[0].CreatedAt
|
||||
}
|
||||
files = append(files, File{
|
||||
FileName: nextDir,
|
||||
Path: stdpath.Join(path, nextDir),
|
||||
Size: point.GetAllVersionSize(),
|
||||
UpdateAt: updateAt,
|
||||
CreateAt: createAt,
|
||||
Size: releasesTotalSize(releases),
|
||||
UpdateAt: releases[0].PublishedAt,
|
||||
CreateAt: releases[0].CreatedAt,
|
||||
Type: "dir",
|
||||
Url: "",
|
||||
})
|
||||
}
|
||||
} else if strings.HasPrefix(path, point.Point) { // 仓库目录的子目录
|
||||
} else if strings.HasPrefix(path, point.Point) {
|
||||
// 仓库目录的子目录(某个版本)
|
||||
tagName := GetNextDir(path, point.Point)
|
||||
if tagName == "" {
|
||||
continue
|
||||
}
|
||||
if point.Releases == nil {
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get releases for %s: %w", point.Repo, err)
|
||||
}
|
||||
return nil, fmt.Errorf("failed to get releases for %s: unknown error", point.Repo)
|
||||
}
|
||||
|
||||
files = append(files, point.GetReleaseByTagName(tagName)...)
|
||||
files = append(files, releaseAssetsByTag(point.Point, tagName, releases)...)
|
||||
|
||||
if d.Addition.ShowSourceCode {
|
||||
files = append(files, point.GetSourceCodeByTagName(tagName)...)
|
||||
files = append(files, sourceCodeFilesByTag(point.Point, releases, tagName)...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,9 @@ type Addition struct {
|
||||
Token string `json:"token" type:"string" required:"false" help:"GitHub token, if you want to access private repositories or increase the rate limit"`
|
||||
ShowSourceCode bool `json:"show_source_code" type:"bool" default:"false" help:"show Source code (zip/tar.gz)"`
|
||||
ShowAllVersion bool `json:"show_all_version" type:"bool" default:"false" help:"show all versions"`
|
||||
GitHubProxy string `json:"gh_proxy" type:"string" default:"" help:"GitHub proxy, e.g. https://ghproxy.net/github.com or https://gh-proxy.com/github.com "`
|
||||
PerPage int `json:"per_page" type:"number" default:"30" help:"releases per page (max 100), only works when show all versions"`
|
||||
MaxPage int `json:"max_page" type:"number" default:"0" help:"max pages to fetch (0 = unlimited), only works when show all versions"`
|
||||
GitHubProxy string `json:"gh_proxy" type:"string" default:"" help:"GitHub proxy, e.g. https://ghproxy.net/https://github.com or https://gh-proxy.com/https://github.com"`
|
||||
}
|
||||
|
||||
var config = driver.Config{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,8 @@
|
||||
package github_releases
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/OpenListTeam/OpenList/v4/drivers/base"
|
||||
@@ -49,10 +49,8 @@ func (d *GithubReleases) ParseRepos(text string) ([]MountPoint, error) {
|
||||
}
|
||||
|
||||
points = append(points, MountPoint{
|
||||
Point: path,
|
||||
Repo: repo,
|
||||
Release: nil,
|
||||
Releases: nil,
|
||||
Point: path,
|
||||
Repo: repo,
|
||||
})
|
||||
}
|
||||
d.points = points
|
||||
@@ -76,9 +74,79 @@ func GetNextDir(wholePath string, basePath string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// 判断当前目录是否是目标目录的祖先目录
|
||||
func IsAncestorDir(parentDir string, targetDir string) bool {
|
||||
absTargetDir, _ := filepath.Abs(targetDir)
|
||||
absParentDir, _ := filepath.Abs(parentDir)
|
||||
return strings.HasPrefix(absTargetDir, absParentDir)
|
||||
// getLatestRelease 获取最新 release
|
||||
func (d *GithubReleases) getLatestRelease(repo string) (*Release, error) {
|
||||
resp, err := d.GetRequest("https://api.github.com/repos/" + repo + "/releases/latest")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
release := new(Release)
|
||||
if err := json.Unmarshal(resp.Body(), release); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return release, nil
|
||||
}
|
||||
|
||||
// getAllReleases 获取所有 releases(支持自动翻页)
|
||||
func (d *GithubReleases) getAllReleases(repo string) ([]Release, error) {
|
||||
perPage := d.Addition.PerPage
|
||||
if perPage < 1 {
|
||||
perPage = 30
|
||||
} else if perPage > 100 {
|
||||
perPage = 100
|
||||
}
|
||||
|
||||
maxPage := d.Addition.MaxPage
|
||||
if maxPage < 0 {
|
||||
maxPage = 0
|
||||
}
|
||||
|
||||
allReleases := make([]Release, 0)
|
||||
page := 1
|
||||
|
||||
for {
|
||||
url := fmt.Sprintf("https://api.github.com/repos/%s/releases?per_page=%d&page=%d", repo, perPage, page)
|
||||
resp, err := d.GetRequest(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
releases := make([]Release, 0)
|
||||
if err := json.Unmarshal(resp.Body(), &releases); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(releases) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
allReleases = append(allReleases, releases...)
|
||||
|
||||
// 达到最大页数限制
|
||||
if maxPage > 0 && page >= maxPage {
|
||||
break
|
||||
}
|
||||
|
||||
// 如果返回数量小于 perPage,说明是最后一页
|
||||
if len(releases) < perPage {
|
||||
break
|
||||
}
|
||||
|
||||
page++
|
||||
}
|
||||
|
||||
return allReleases, nil
|
||||
}
|
||||
|
||||
// fetchRepoFiles 获取仓库根目录文件列表
|
||||
func (d *GithubReleases) fetchRepoFiles(repo string) ([]FileInfo, error) {
|
||||
resp, err := d.GetRequest("https://api.github.com/repos/" + repo + "/contents")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
files := make([]FileInfo, 0)
|
||||
if err := json.Unmarshal(resp.Body(), &files); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return files, nil
|
||||
}
|
||||
|
||||
@@ -15,11 +15,12 @@ import (
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/model"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/op"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/stream"
|
||||
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
|
||||
"github.com/OpenListTeam/OpenList/v4/pkg/http_range"
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/s3/s3manager"
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/credentials"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager"
|
||||
"github.com/city404/v6-public-rpc-proto/go/v6/common"
|
||||
pbPublicUser "github.com/city404/v6-public-rpc-proto/go/v6/user"
|
||||
pubUserFile "github.com/city404/v6-public-rpc-proto/go/v6/userfile"
|
||||
@@ -373,24 +374,23 @@ func (d *HalalCloud) put(ctx context.Context, dstDir model.Obj, fileStream model
|
||||
u, _ := url.Parse(result.Endpoint)
|
||||
u.Host = "s3." + u.Host
|
||||
result.Endpoint = u.String()
|
||||
s, err := session.NewSession(&aws.Config{
|
||||
s3Client := s3.NewFromConfig(aws.Config{
|
||||
HTTPClient: base.HttpClient,
|
||||
Credentials: credentials.NewStaticCredentials(result.AccessKey, result.SecretKey, result.Token),
|
||||
Region: aws.String(result.Region),
|
||||
Endpoint: aws.String(result.Endpoint),
|
||||
S3ForcePathStyle: aws.Bool(true),
|
||||
Credentials: credentials.NewStaticCredentialsProvider(result.AccessKey, result.SecretKey, result.Token),
|
||||
Region: result.Region,
|
||||
}, func(o *s3.Options) {
|
||||
o.BaseEndpoint = aws.String(result.Endpoint)
|
||||
o.UsePathStyle = true
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uploader := s3manager.NewUploader(s, func(u *s3manager.Uploader) {
|
||||
u.Concurrency = d.uploadThread
|
||||
tmClient := transfermanager.New(s3Client, func(o *transfermanager.Options) {
|
||||
if fileStream.GetSize() > int64(8*utils.MB)*10000 {
|
||||
o.PartSizeBytes = fileStream.GetSize() / 9999
|
||||
}
|
||||
o.Concurrency = d.uploadThread
|
||||
})
|
||||
if fileStream.GetSize() > s3manager.MaxUploadParts*s3manager.DefaultUploadPartSize {
|
||||
uploader.PartSize = fileStream.GetSize() / (s3manager.MaxUploadParts - 1)
|
||||
}
|
||||
|
||||
reader := driver.NewLimitedUploadStream(ctx, fileStream)
|
||||
_, err = uploader.UploadWithContext(ctx, &s3manager.UploadInput{
|
||||
_, err = tmClient.UploadObject(ctx, &transfermanager.UploadObjectInput{
|
||||
Bucket: aws.String(result.Bucket),
|
||||
Key: aws.String(result.Key),
|
||||
Body: io.TeeReader(reader, driver.NewProgress(fileStream.GetSize(), up)),
|
||||
|
||||
@@ -14,10 +14,10 @@ import (
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/driver"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/model"
|
||||
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/s3/s3manager"
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/credentials"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/aws/aws-sdk-go-v2/feature/s3/transfermanager"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"github.com/google/uuid"
|
||||
log "github.com/sirupsen/logrus"
|
||||
@@ -171,12 +171,12 @@ func (d *MediaTrack) Put(ctx context.Context, dstDir model.Obj, file model.FileS
|
||||
return err
|
||||
}
|
||||
credential := resp.Data.Credentials
|
||||
cfg := &aws.Config{
|
||||
Credentials: credentials.NewStaticCredentials(credential.TmpSecretID, credential.TmpSecretKey, credential.Token),
|
||||
Region: &resp.Data.Region,
|
||||
Endpoint: aws.String("cos.accelerate.myqcloud.com"),
|
||||
}
|
||||
s, err := session.NewSession(cfg)
|
||||
s3Client := s3.NewFromConfig(aws.Config{
|
||||
Credentials: credentials.NewStaticCredentialsProvider(credential.TmpSecretID, credential.TmpSecretKey, credential.Token),
|
||||
Region: resp.Data.Region,
|
||||
}, func(o *s3.Options) {
|
||||
o.BaseEndpoint = aws.String("cos.accelerate.myqcloud.com")
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -184,11 +184,13 @@ func (d *MediaTrack) Put(ctx context.Context, dstDir model.Obj, file model.FileS
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
uploader := s3manager.NewUploader(s)
|
||||
if file.GetSize() > s3manager.MaxUploadParts*s3manager.DefaultUploadPartSize {
|
||||
uploader.PartSize = file.GetSize() / (s3manager.MaxUploadParts - 1)
|
||||
}
|
||||
input := &s3manager.UploadInput{
|
||||
tmClient := transfermanager.New(s3Client, func(o *transfermanager.Options) {
|
||||
if file.GetSize() > int64(8*utils.MB)*10000 {
|
||||
o.PartSizeBytes = file.GetSize() / 9999
|
||||
}
|
||||
})
|
||||
|
||||
_, err = tmClient.UploadObject(ctx, &transfermanager.UploadObjectInput{
|
||||
Bucket: &resp.Data.Bucket,
|
||||
Key: &resp.Data.Object,
|
||||
Body: driver.NewLimitedUploadStream(ctx, &driver.ReaderUpdatingProgress{
|
||||
@@ -198,8 +200,7 @@ func (d *MediaTrack) Put(ctx context.Context, dstDir model.Obj, file model.FileS
|
||||
},
|
||||
UpdateProgress: up,
|
||||
}),
|
||||
}
|
||||
_, err = uploader.UploadWithContext(ctx, input)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+66
-46
File diff suppressed because it is too large
Load Diff
@@ -23,6 +23,7 @@ type Addition struct {
|
||||
AddFilenameToDisposition bool `json:"add_filename_to_disposition" help:"Add filename to Content-Disposition header."`
|
||||
EnableDirectUpload bool `json:"enable_direct_upload" default:"false"`
|
||||
DirectUploadHost string `json:"direct_upload_host" required:"false"`
|
||||
UserAgent string `json:"user_agent" required:"false" default:"" help:"Custom User-Agent for S3 requests."`
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user