Compare commits

...

1207 Commits

Author SHA1 Message Date
55d3827dee add(interface): driver&mamage 2025-08-14 22:16:19 +08:00
1fbc9427df add(interface): driver&mamage 2025-08-14 22:16:01 +08:00
bb3d139a47 add(interface): driver&mamage 2025-08-14 21:59:44 +08:00
d227ab85d6 add(trunk): base interface 2025-08-14 21:44:34 +08:00
5342ae96d0 add(trunk): base interface 2025-08-14 21:39:00 +08:00
273e15a050 add(trunk): base interface 2025-08-14 21:30:18 +08:00
13aad2c2fa add(trunk): base interface 2025-08-14 19:56:43 +08:00
368dc65a6e feat: Implement plugin architecture with gRPC support
- Added driver initialization for gRPC plugins in internal/bootstrap/driver.go.
- Introduced configuration structures and protobuf definitions for driver plugins in proto/driver/config.proto and proto/driver/driver.proto.
- Implemented gRPC server and client interfaces for driver plugins in shared/driver/grpc.go.
- Created common response handling utilities in server/common/common.go and server/common/resp.go.
- Developed plugin registration endpoint in server/handles/plugin.go.
- Added test cases for plugin functionality in shared/driver/plugin_test.go.
- Defined plugin reattachment configuration model in shared/model/plugin.go.
2025-08-13 19:04:38 +08:00
8b4b6ba970 feat(config): enhance configuration management and add CORS support
feat(server): implement server initialization with context and graceful shutdown
feat(utils): add utility functions for file and JSON operations
refactor(conf): restructure configuration types and improve default settings
2025-08-13 10:03:22 +08:00
4d28e838ce feat(cmd): initialize command structure and configuration management 2025-08-12 22:15:25 +08:00
3930d4789a add(trunk): next branch 2025-08-12 21:20:33 +08:00
d0c22a1ecb feat(ci): add the default user for docker image (#1036)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-12 09:51:40 +08:00
57fceabcf4 perf(stream): improve file stream range reading and caching mechanism (#1001)
* perf(stream): improve file stream range reading and caching mechanism

* 。

* add bytes_test.go

* fix(stream): handle EOF and buffer reading more gracefully

* 注释

* refactor: update CacheFullAndWriter to accept pointer for UpdateProgress

* update tests

* Update drivers/google_drive/util.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: j2rong4cn <36783515+j2rong4cn@users.noreply.github.com>

* 更优雅的克隆Link

* 修复stream已缓存但无法重复读取

* 将Bytes类型重命名为Reader

* 修复栈溢出

* update tests

---------

Signed-off-by: j2rong4cn <36783515+j2rong4cn@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-11 23:41:22 +08:00
8c244a984d refactor(assets): migrate to resource domain (#975)
* refactor(assets): migrate to resource domain

* feat(bootstrap): add migration value for logo and favicon settings
2025-08-10 09:57:33 +08:00
df479ba806 fix(aliyundrive_open): limit rate for every request (close #724) (#1011)
* fix(aliyundrive_open): limit rate for `Remove` and `MakeDir`; reduce limit for `List` and `Link` (close #724)

* Update drivers/aliyundrive_open/driver.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: 火星大王 <34576789+huoxingdawang@users.noreply.github.com>

* Update drivers/aliyundrive_open/driver.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: 火星大王 <34576789+huoxingdawang@users.noreply.github.com>

* fix(aliyundrive_open): limit rate for every request

* fix(aliyundrive_open): fix limiter not work on reference driver

* fix(aliyundrive_open): typo

* fix(aliyundrive_open): limiter not set to nil after free

* fix(aliyundrive_share): limit rate for every request

---------

Signed-off-by: 火星大王 <34576789+huoxingdawang@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-10 09:55:20 +08:00
5ae8e96237 feat(123_open): update Put method to return model.Obj (#1008)
* feat(123_open): update Put method to return model.Obj

* fix(123_open): declear time zones

* chore(123_open): fix typo

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: MadDogOwner <xiaoran@xrgzs.top>

* fix(123_open): use fixed timezone

* fix(123_open): implement PutResult interface for Open123 driver

---------

Signed-off-by: MadDogOwner <xiaoran@xrgzs.top>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Suyunmeng <69945917+Suyunmeng@users.noreply.github.com>
2025-08-09 15:09:12 +08:00
aa0ced47b0 fix(webdav): Handle HEAD requests for directories with appropriate headers (#1015)
Implement handling of HEAD requests for directories by setting the correct Content-Type and Content-Length headers.
2025-08-09 13:57:09 +08:00
ab747d9052 feat(config): Add PWA manifest.json endpoint for web app installation (#990)
* feat(config): Add PWA manifest.json endpoint for web app installation

* fix: Update comment to English in manifest handler

* fix: fix EOL

* fix: Remove unused fmt import from manifest handler

* feat: use site settings for manifest name and icon

* fix(manifest): Move manifest.json route to static handler for proper CDN handling

* feat: move manifest.json handler to static package and improve path handling

* feat: Add custom static file handler to prevent manifest.json conflicts

* fix: Integrate manifest.json handling into static file serving routes

* fix: Simplify PWA manifest scope handling and static file serving

- Remove CDN-specific logic for PWA manifest scope and start_url
- Always use base path for PWA scope regardless of CDN configuration
- Replace manual file serving logic with http.FileServer for static assets

* fix: Ensure consistent base path handling in site configuration and manifest path construction

* fix: Refactor trailing slash handling in site configuration

* feat(static): update manifest path handling and add route for manifest.json
2025-08-08 20:07:51 +08:00
93c06213d4 feat(local): add directory size support (#624)
* feat(local): add directory size support

* fix(local): fix and improve directory size calculation

* style(local): fix code style

* style(local): fix code style

* style(local): fix code style

* fix(local): refresh directory size when force refresh

Signed-off-by: 我怎么就不是一只猫呢? <26274059+dezhishen@users.noreply.github.com>

* fix:(local): Avoid traversing the parent's parent, which leads to an endless loop

Signed-off-by: 我怎么就不是一只猫呢? <26274059+dezhishen@users.noreply.github.com>

* fix(local:) refresh dir size only enabled

Signed-off-by: 我怎么就不是一只猫呢? <26274059+dezhishen@users.noreply.github.com>

* fix(local): logical error && add RecalculateDirSize && cleaner code for int64

* feat(local): add Benchmark for CalculateDirSize

* refactor(local): 优化移动中对于错误的判断。

---------

Signed-off-by: 我怎么就不是一只猫呢? <26274059+dezhishen@users.noreply.github.com>
Co-authored-by: 我怎么就不是一只猫呢? <26274059+dezhishen@users.noreply.github.com>
2025-08-08 16:59:16 +08:00
b9b8eed285 [skip ci]feat(ci): add FRONTEND_REPO variable to workflows and build script (#1006) 2025-08-08 16:36:22 +08:00
317d190b77 fix(ftp): create a new connection for each download (#989) 2025-08-06 20:35:01 +08:00
52d7d819ad feat(lenovonas_share): add thumb (#986) 2025-08-06 17:34:43 +08:00
0483e0f868 feat(driver_strm): also shown some files with strm (#969)
* feat(driver_strm): Also shown some files with strm

Allow user set some file types that need to shown with strm, usually subtitles

Most of code was copy and managed from drivers/alias

* 优化

* 优化

* 。

* 添加注释

---------

Co-authored-by: j2rong4cn <j2rong@qq.com>
Co-authored-by: j2rong4cn <36783515+j2rong4cn@users.noreply.github.com>
2025-08-06 15:40:48 +08:00
08dae4f55f feat(123_open): update upload api v2 (#976) 2025-08-06 15:27:13 +08:00
9ac0484bc0 perf(ftp): improve concurrent Link response; fix alias/local driver issues (#974) 2025-08-06 13:32:37 +08:00
8cf15183a0 perf: optimize upload (#554)
* pref(115,123): optimize upload

* chore

* aliyun_open, google_drive

* fix bug

* chore

* cloudreve, cloudreve_v4, onedrive, onedrive_app

* chore(conf): add `max_buffer_limit` option

* 123pan multithread upload

* doubao

* google_drive

* chore

* chore

* chore: 计算分片数量的代码

* MaxBufferLimit自动挡

* MaxBufferLimit自动挡

* 189pc

* errorgroup添加Lifecycle

* 查缺补漏

* Conf.MaxBufferLimit单位为MB

* 。

---------

Co-authored-by: MadDogOwner <xiaoran@xrgzs.top>
2025-08-05 21:42:54 +08:00
c8f2aaaa55 feat(cmd): add delete command for storage (#952) 2025-08-04 17:30:43 +08:00
1208bd0a83 fix(fs): nil interface not equal to nil (#971)
https://go.dev/doc/faq#nil_error
2025-08-03 23:51:11 +08:00
6b096bcad4 fix(fs): deadlock when get link error (#963) 2025-08-02 17:49:53 +08:00
58dbf088f9 fix(fs): forget cache when get link error (#956) 2025-08-02 11:03:34 +08:00
05ff7908f2 fix(strm): encoded path is ineffective (#951) 2025-08-02 00:23:18 +08:00
a703b736c9 feat(offline_download): filter empty URLs in offline download requests (#948) 2025-08-01 16:12:21 +08:00
e458f2ab53 fix(bootstrap): add newline after initial admin password output (#943)
fix(bootstrap): add newline after initial admin  password output
2025-08-01 13:43:41 +08:00
a5a22e7085 fix(local): Treat junction as directory in Windows. (#809)
Treat junction as directory in Windows.
2025-07-31 13:54:56 +08:00
9469c95b14 fix(security): potential XSS vulnerabilities (#896) 2025-07-31 12:57:20 +08:00
cf912dcf7a fix(cmd): output to console (#920)
fix(cmd): output to terminal
2025-07-31 11:44:00 +08:00
ccd4af26e5 feat(patch): add migration from Alist V3 driver to OpenList (#919)
* feat(patch): add migration from Alist V3 driver to OpenList

* chore(patch): improve logging
2025-07-31 11:43:21 +08:00
1682e873d6 feat(search): enhanced meilisearch search experience (#864)
* feat(search): enhanced `meilisearch` search experience
- upgrade `meilisearch` dependency
- support subdirectory search
- optimize searchDocument fields for subdirectory search
- specify full index uid instead of index prefix

* fix(search): more fixes to `meilisearch`
- make use of context where context was not used
- remove code of waiting task in deletion process, as tasks are queued and will be executed orderly (if tasks were submitted to the queue successfully), which can improve `AutoUpdate` performance
2025-07-31 11:24:22 +08:00
54ae7e6d9b feat(115_open): Add GetObjInfo to accelerate getting link (#888)
* feat(115_open): Add GetObjInfo to accelerate getting link

* feat(fs): use cache directly when cache exist
2025-07-31 11:20:02 +08:00
991da7d87f feat(strm): add local mode (#885)
* feat(strm): add local mode

* Update drivers/strm/meta.go

Co-authored-by: MadDogOwner <xiaoran@xrgzs.top>
Signed-off-by: Seven <53081179+Seven66677731@users.noreply.github.com>

* feat(strm): local mode add sign

---------

Signed-off-by: Seven <53081179+Seven66677731@users.noreply.github.com>
Co-authored-by: MadDogOwner <xiaoran@xrgzs.top>
2025-07-31 11:18:59 +08:00
Dgs
a498091aef fix(123&&123_share): fix link request header referer (#915) 2025-07-31 10:10:38 +08:00
976c82bb2b fix(drivers): update time-related fields to int64 (#913)
- In doubao/types.go:
  - Change LastUpdateTime from int to int64
  - Change UserCreateTime from int to int64
- In doubao_share/types.go:
  - Change CreateTime and UpdateTime from int to int64 in ShareInfo and FilePath
- In quark_uc/types.go:
  - Change UpdateTime from int to int64 in TranscodingResp

These changes ensure consistent and accurate representation of timestamp data across the project.
2025-07-31 10:10:32 +08:00
5b41a3bdff feat(ci): Add support for LoongArch64 architecture builds (#907) 2025-07-31 10:10:19 +08:00
19d1a3b785 refactor(ci): Refactor Docker build to use base images and dynamic Dockerfile generation (#904) 2025-07-30 15:04:29 +08:00
3c7b0c4999 fix(qb): Configure HTTP client with connection pooling and fix resource leaks in qBittorrent client. (#898) 2025-07-29 21:56:36 +08:00
d6867b4ab6 fix(user): show admin password on first start (#883)
* fix: fix admin password not shown in first start
* chore: add time dependence

Co-authored-by: Yinan Qin <39023210+elysia-best@users.noreply.github.com>
Signed-off-by: ILoveScratch <ilovescratch@foxmail.com>

* fix: fix log format

Co-authored-by: Yinan Qin <39023210+elysia-best@users.noreply.github.com>
Signed-off-by: ILoveScratch <ilovescratch@foxmail.com>

---------

Signed-off-by: ILoveScratch <ilovescratch@foxmail.com>
Co-authored-by: Yinan Qin <39023210+elysia-best@users.noreply.github.com>
2025-07-29 21:36:27 +08:00
11cf561307 fix(security): potential XSS vulnerabilities (#880)
* fix(security): potential XSS vulnerabilities

* chore: replace alist identifier to openlist identifier

Co-authored-by: MadDogOwner <xiaoran@xrgzs.top>
Signed-off-by: ILoveScratch <ilovescratch@foxmail.com>

---------

Signed-off-by: ILoveScratch <ilovescratch@foxmail.com>
Co-authored-by: ILoveScratch <ilovescratch@foxmail.com>
Co-authored-by: MadDogOwner <xiaoran@xrgzs.top>
2025-07-29 20:17:11 +08:00
239b58f63e fix(ci):Disable linux/s390x Docker builds (#887) 2025-07-29 16:22:50 +08:00
7da06655cb feat(setting): add site version information (#859)
* feat(setting): add site version information

* feat(conf): update conf.WebVersion to rolling

* fix(static): update condition to check conf.Version instead of conf.WebVersion

* fix(build.sh): use rolling release for web frontend in dev and beta builds

* chore(build.sh): update GitAuthor to The OpenList Projects Contributors

* fix(static): update condition to check conf.WebVersion
2025-07-29 09:49:33 +08:00
e0b3a611ba feat(thunderx,pikpak): add offline download support for ThunderX; add ctx to specific PikPak functions (#879)
* feat(thunderx,pikpak): add offline download support for ThunderX; add ctx to specific PikPak functions

* Update internal/offline_download/tool/download.go

Co-authored-by: MadDogOwner <xiaoran@xrgzs.top>
Signed-off-by: 花月喵梦 <152958106+nekohy@users.noreply.github.com>

---------

Signed-off-by: 花月喵梦 <152958106+nekohy@users.noreply.github.com>
Co-authored-by: MadDogOwner <xiaoran@xrgzs.top>
2025-07-29 09:46:28 +08:00
be1ad08a83 feat(ci):Add Windows 7 and LoongArch Release build support (#857)
* feat:Add Windows 7 and LoongArch old world build support (#30)

* feat:Add Windows 7 and Loongson old world build support

- Add BuildWin7() function with patched Go compiler for Windows 7 compatibility
- Add BuildLoongOldWorld() function for linux-loong64-abi1.0 target
- Create Zig-based wrapper scripts for Windows 7 cross-compilation
- Integrate new build functions into existing release workflows

* fix(win7):Add MinGW-w64 toolchain and improve LoongArch ABI isolation

- Install MinGW-w64 cross-compilation toolchain for Win7 compatibility
- Replace Zig compiler wrappers with MinGW-w64 for Windows 7 builds
- Add Go build cache cleaning to prevent LoongArch ABI1.0/ABI2.0 cross-contamination
- Force clean rebuilds (-a flag) for LoongArch builds to ensure ABI compatibility

* feat: add Windows 7 build support to beta release workflow

* feat: add LoongArch ABI2.0 support alongside existing ABI1.0 build (#31)

- Add BuildWin7() function with patched Go compiler for Windows 7 compatibility
- Add BuildLoongOldWorld() function for linux-loong64-abi1.0 target
- Create Zig-based wrapper scripts for Windows 7 cross-compilation
- Integrate new build functions into existing release workflows
- Install MinGW-w64 cross-compilation toolchain for Win7 compatibility
- Replace Zig compiler wrappers with MinGW-w64 for Windows 7 builds
- Add Go build cache cleaning to prevent LoongArch ABI1.0/ABI2.0 cross-contamination
- Force clean rebuilds (-a flag) for LoongArch builds to ensure ABI compatibility

* [skip ci]refactor:Refactor LoongArch builds to separate glibc from musl compilation

* fix(go-cache):Improve error handling for Go module cache cleaning in LoongArch builds

* feat(build): Enhance LoongArch build process with improved toolchain setup and cache management

* fix(build): Update Windows 7 target naming in build scripts and workflows

* refactor(build): Replace MinGW-w64 with Zig for Windows 7 toolchain in build scripts

* chore(cgo): remove cgo-actions subproject
2025-07-27 00:27:31 +08:00
4e9c30f49d feat(fs): full support webdav cross-driver copy and move (#823)
* fix(fs): restore webdav cross-driver copy and move

* fix bug

* webdav支持复制、移动 文件夹

* 优化

* 。
2025-07-26 00:27:46 +08:00
0ee31a3f36 fix(crypt): wrong ContentLength 2025-07-25 19:55:22 +08:00
23bddf991e feat(drivers): enable local sorting for cloudreve, ilanzou (#840)
* feat(cloudreve): enable local sorting

* feat(ilanzou): enable local sorting
2025-07-25 18:01:19 +08:00
da8d6607cf fix(static): support logo replacement (#834 Close #754) 2025-07-25 17:12:51 +08:00
6134574dac fix(fs): rename bug (#832)
* fix(fs): rename bug

* chore

* fix bug

* .

---------

Co-authored-by: j2rong4cn <j2rong@qq.com>
2025-07-25 13:42:39 +08:00
b273232f87 refactor(log): redir utils.Log to logrus after init (#833) 2025-07-25 13:38:45 +08:00
358e4d851e refactor(log): filter (#816) 2025-07-25 11:33:27 +08:00
e8a1ed638a fix(ci):Exclude FreeBSD patch releases from version detection 2025-07-24 22:41:45 +08:00
4106e2a996 fix(static): correct CDN fetch condition for index.html (#814) 2025-07-24 22:28:58 +08:00
c2271df64e fix(ci): update OpenListTeam/cgo-actions to v1.2.2 to fix loongarch64 build (#811)
* Update beta_release.yml

* Update build.yml
2025-07-24 22:20:23 +08:00
d4b8570eb8 fix(docker): Fix the runsvdir permission issue caused by su-exec user switching and resolve the RUN_ARIA2 variable compatibility problem. (#805) 2025-07-24 17:22:49 +08:00
bd297e8ccc fix(deps): update module golang.org/x/image to v0.29.0 (#804)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-24 16:22:19 +08:00
923d282c8a fix(deps): update module github.com/sheltonzhu/115driver to v1.1.0 (#803)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-24 16:21:32 +08:00
4d8c4d7089 fix(deps): update module github.com/coreos/go-oidc to v2.3.0+incompatible (#586)
* fix(deps): update module github.com/coreos/go-oidc to v2.3.0+incompatible

* Update go.mod

Signed-off-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com>

---------

Signed-off-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com>
2025-07-24 16:21:03 +08:00
e93ab76036 feat(task-group): introduce TaskGroupCoordinator for coordinated task execution (#721)
* feat(task): add task hook,batch task
refactor(move): move use CopyTask

* Update internal/task/batch_task/refresh.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Seven <53081179+Seven66677731@users.noreply.github.com>

* fix: upload task allFinish judge

* Update internal/task/batch_task/refresh.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Seven <53081179+Seven66677731@users.noreply.github.com>

* feat: enhance concurrency safety

* 优化代码

* 解压缩

* 修复死锁

* refactor(move): move as task

* 重构,优化

* .

* 优化,修复bug

* .

* 修复bug

* feat: add task retry judge

* 代理Task.SetState函数来判断Task的生命周期

* chore: use OnSucceeded、OnFailed、OnBeforeRetry functions

* 优化

* 优化,去除重复代码

* .

* 优化

* .

* webdav

* Revert "fix(fs):After the file is copied or moved, flush the cache of the directory that was copied or moved to."

This reverts commit 5f03edd683.

---------

Signed-off-by: Seven <53081179+Seven66677731@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: j2rong4cn <j2rong@qq.com>
2025-07-24 16:15:24 +08:00
a9f02ecdac refactor(log):Refactor log filtering to use centralized configuration and add server-specific filtering (#798)
* feat(log):Add configurable log filtering middleware for HTTP requests

Implement a comprehensive log filtering system that allows selective suppression of HTTP request logs based on paths, methods, and prefixes. The system includes environment variable configuration support and filters health checks, WebDAV requests, and HEAD requests by default to reduce log noise.

* fix(log):Replace gin.DefaultLogFormatter with custom implementation

* Remove filtered logger test file

* fix(log):Refactor log filtering to use centralized configuration and add server-specific filtering

* fix(log):Add documentation comments for log filtering configuration
2025-07-24 16:10:47 +08:00
93849a3b5b fix(deps): update module github.com/pquerna/otp to v1.5.0 (#799)
Signed-off-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com>
2025-07-24 16:07:23 +08:00
c2e0d0c9ce fix(deps): update module github.com/protonmail/go-crypto to v1.3.0 (#800)
Signed-off-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com>
2025-07-24 16:06:50 +08:00
4a713363ee fix(deps): update module github.com/azure/azure-sdk-for-go/sdk/storage/azblob to v1.6.2 (#801)
Signed-off-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com>
2025-07-24 16:06:10 +08:00
3da8ccb7a7 fix(deps): update module github.com/rclone/rclone to v1.70.3 (#802)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-24 16:05:20 +08:00
676b8cff0b fix(deps): update azure-sdk-for-go monorepo (#579)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-24 10:27:36 +08:00
57cf28fc90 fix(deps): update github.com/fclairamb/ftpserverlib digest to 4a925d7 (#675)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-24 10:26:39 +08:00
8cf90e074d fix(deps): update module github.com/charmbracelet/bubbletea to v1.3.6 (#585)
Signed-off-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com>
2025-07-24 10:26:23 +08:00
74c2ed8306 fix(deps): update module github.com/charmbracelet/bubbles to v0.21.0 (#583)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-24 10:25:09 +08:00
5f03edd683 fix(fs):After the file is copied or moved, flush the cache of the directory that was copied or moved to. (#592)
* fix(fs):After the file is copied, the cache of the copied directory is refreshed

* fixed randomstring

* fixed EOL and Sync branch

chore(quark_uc): `webdav_policy` default to native_proxy

* fixed uuid and other bugs

* fixed comments

* fixed EOL

* add move refresh

* fixed builds

* fixed batch

* change betch to task.go

---------

Co-authored-by: Sumengjing <146963948+suyunjing-su@users.noreply.github.com>
2025-07-24 10:24:12 +08:00
8b65c918d4 chore(permission): admin enables webdav read-only by default (#726)
chore: admin enables webdav read-only by default
2025-07-24 10:19:49 +08:00
b5f0e3e5ee fix(deps): update module github.com/go-webauthn/webauthn to v0.13.4 (#677)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-24 10:05:44 +08:00
179894ff37 fix(deps): update module github.com/ipfs/go-cid to v0.5.0 (#680)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-24 10:05:05 +08:00
e2fc89c637 chore(deps): update dependency go to v1.24.5 (#783)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-24 10:04:20 +08:00
cacf67b181 fix(deps): update module github.com/yuin/goldmark to v1.7.13 (#794)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-24 10:04:00 +08:00
afb043e1d6 feat(docker): Change keep-alive strategy to runit, add aria2 log support (#791) 2025-07-24 09:19:33 +08:00
d9debb81ad feat(log):Add configurable log filtering middleware for HTTP requests (#782)
* feat(log):Add configurable log filtering middleware for HTTP requests

Implement a comprehensive log filtering system that allows selective suppression of HTTP request logs based on paths, methods, and prefixes. The system includes environment variable configuration support and filters health checks, WebDAV requests, and HEAD requests by default to reduce log noise.
2025-07-24 00:00:26 +08:00
4c069fddd6 fix(terabox): file upload error (#733)
* fix(terabox):fix file upload error failed to create file errno 10

Signed-off-by: yuyamionini <46483865+yuyamionini@users.noreply.github.com>

* fix(terabox):fix file upload error failed to create file errno 10

Signed-off-by: yuyamionini <46483865+yuyamionini@users.noreply.github.com>

* replace the goto statement with the retry-go package

Signed-off-by: yuyamionini <46483865+yuyamionini@users.noreply.github.com>

* Update util.go

Signed-off-by: yuyamionini <46483865+yuyamionini@users.noreply.github.com>

* Update util.go

Signed-off-by: yuyamionini <46483865+yuyamionini@users.noreply.github.com>

* go fmt

---------

Signed-off-by: yuyamionini <46483865+yuyamionini@users.noreply.github.com>
Co-authored-by: MadDogOwner <xiaoran@xrgzs.top>
2025-07-23 23:42:12 +08:00
b450a2104d chore(docs): update domain (#788)
* chore(docs): update domain

* docs(issue): add guide link for bug reporting
2025-07-23 14:26:21 +08:00
7d0de17daf feat(static): fetch index.html from cdn for beta (#372)
* refactor(static): simplify folder iteration in Static function

* feat(static): disable local static when `cdn` is set

* feat(static): fetch index.html from cdn for beta

* refactor(static): use RestyClient for better retrying

* fix(static): add Accept header when fetching index.html from CDN

* refactor(static): optimize HTML replacement

* chore(static): add logging to static file system initialization

* feat(static): ensure static file redirected to CDN
2025-07-22 22:14:07 +08:00
bba4fb2203 fix(security): directory traversal (#744)
* fix(security): Directory traversal

* chore: .

* 优化

---------

Co-authored-by: j2rong4cn <j2rong@qq.com>
2025-07-22 14:45:01 +08:00
a20c2020f8 fix(cmd): optimize parse of command flag --data (#777)
* Fix (cmd): optimize parse of command flag `--data`

* DBFile

* 优化

* os.Getwd()
2025-07-22 10:51:28 +08:00
a92b5eb929 refactor(cloudreve): use retry-go for net/http uploads (#773)
* refactor(cloudreve): use retry-go for uploads

* refactor(cloudreve_v4): use retry-go for uploads

* refactor(onedrive): use retry-go for uploads

* refactor(onedrive_app): use retry-go for uploads

* chore(onedrive_app): remove unnecessary error handling for host retrieval

* feat(cloudreve): move read logic inside retry block

* feat(cloudreve_v4): move read logic inside retry block

* feat(onedrive): move read logic inside retry block

* feat(onedrive_app): move read logic inside retry block
2025-07-22 10:25:04 +08:00
6817494a41 chore(ci): update cgo-actions to 1.2.1 & add patch version define for go (#779)
chore(ci): update cgo-actions to 1.2.1 & fix patch version for go
2025-07-22 09:02:07 +08:00
5a0d8ee1b8 feat(proxy): add disable proxy sign (#764)
* feat(proxy): add disable proxy sign

* Update driver.go

* GenerateDownProxyUrl

* .

* Update internal/op/driver.go

Signed-off-by: j2rong4cn <36783515+j2rong4cn@users.noreply.github.com>

* .

---------

Signed-off-by: j2rong4cn <36783515+j2rong4cn@users.noreply.github.com>
Co-authored-by: j2rong4cn <j2rong@qq.com>
Co-authored-by: j2rong4cn <36783515+j2rong4cn@users.noreply.github.com>
2025-07-21 17:03:08 +08:00
012e51c551 fix(cloudreve_v4): remove deprecated authn check for login (#767)
* fix(cloudreve_v4): disable authn check for login

* chore(cloudreve_v4): update site login config fields
2025-07-21 15:53:10 +08:00
59ec1dbc9b feat(lenovonas_share): add option to not show root directory (#772) 2025-07-21 14:38:10 +08:00
6bb28d13f9 fix(quark): set the transcoding link ContentLength to the correct size 2025-07-20 16:40:32 +08:00
811a862288 feat(archives): add additional accepted archive extensions (#747) 2025-07-20 15:32:46 +08:00
74d32fd4d7 fix(simplehttp): logic bug when unable to parse file name (#761) 2025-07-20 14:13:30 +08:00
cedb3d488d [skip ci] chore(ci): output binary name set to openlist 2025-07-19 23:02:29 +08:00
86324d2d6b fix(net): ensure accurate content-length in response (#749)
* fix(fs): ensure accurate content-length in http2 requests

Chrome browsers were unable to preview thumbnails, reporting an
'ERR_HTTP_2_PROTOCOL_ERROR'. This was caused by an incorrect
content-length header in the server's response for thumbnail images.

This commit corrects the content-length calculation, allowing
Chrome and other compliant clients to render thumbnails correctly.

* fix(net): ensure accurate content-length in response

* 补缺

* .

---------

Co-authored-by: zhiqiang.huang <zhiqiang.tech@gmail.com>
Co-authored-by: j2rong4cn <j2rong@qq.com>
2025-07-19 20:36:27 +08:00
648079ae24 remove upx (#750)
Update build.sh

Signed-off-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com>
2025-07-18 12:38:17 +08:00
Dgs
e8d45398d6 feat(quark_uc_tv): add streaming link api (#728) 2025-07-17 14:24:16 +08:00
0c461991f9 chore: standardize context keys with custom ContextKey type (#697)
* chore: standardize context keys with custom ContextKey type

* fix bug

* 使用Request.Context
2025-07-14 23:55:17 +08:00
2a4c546a8b feat: default settings api (#716)
* feat: default settings api

* fix logic bug

* chore
2025-07-14 23:41:34 +08:00
750d4eb3f6 docs(README): add disclaimer (#705)
add disclaimer
2025-07-13 15:22:25 +08:00
cc01b410a4 perf(link): optimize concurrent response (#641)
* fix(crypt): bug caused by link cache

* perf(crypt,mega,halalcloud,quark,uc): optimize concurrent response link

* chore: 删除无用代码

* ftp

* 修复bug;资源释放

* 添加SyncClosers

* local,sftp,smb

* 重构,优化,增强

* Update internal/stream/util.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: j2rong4cn <36783515+j2rong4cn@users.noreply.github.com>

* chore

* chore

* 优化,修复bug

* .

---------

Signed-off-by: j2rong4cn <36783515+j2rong4cn@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-12 17:57:54 +08:00
e5fbe72581 fix(security): add login count validation for webdav (#693) 2025-07-12 17:03:41 +08:00
283f3723d1 [skip ci] chore(ci): update openwrt hook 2025-07-12 12:06:36 +08:00
ad8c7b37a1 chore(ci):Disable duplicate build process 2025-07-12 11:49:27 +08:00
a84ffb96e9 chore(ci):Simplify the build process (#686)
* refactor(ci):Minify build files
2025-07-11 20:30:31 +08:00
19c6b6f930 feat(115_open): add offline download (#683) 2025-07-11 20:17:54 +08:00
eed3c0533c fix(deps): update module github.com/go-resty/resty/v2 to v2.16.5 (#628)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-11 10:26:44 +08:00
c72ba9828a fix(deps): update module github.com/deckarep/golang-set/v2 to v2.8.0 (#589)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-11 10:25:08 +08:00
4965a1b909 fix(deps): update module github.com/blevesearch/bleve/v2 to v2.5.2 (#582)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-11 10:24:50 +08:00
1bba550469 chore(deps): update dependency go to 1.24 (#578)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-11 10:24:23 +08:00
d678322b18 fix(deps): update module github.com/yuin/goldmark to v1.7.12 (#575)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-11 10:24:09 +08:00
efd8897bdf fix(deps): update module github.com/pkg/sftp to v1.13.9 (#574)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-11 10:23:52 +08:00
7c7cec0993 style(offline_download): add more description in log (#653)
fix(offline_download): add more description in log
2025-07-09 14:16:05 +08:00
3838ef0663 feat(traffic): update progress when caching file (#646)
* feat(traffic): update progress when caching file

* 调整参数位置和命名

---------

Co-authored-by: j2rong4cn <j2rong@qq.com>
2025-07-08 21:41:45 +08:00
9e610af114 fix(115_open): upload progress error (#637) 2025-07-07 18:39:09 +08:00
0177177238 fix(crypt): pass refresh list request (close #609) 2025-07-06 13:20:42 +08:00
a77e515c9b fix(ocr): repair verification code OCR recognition service (#602)
* fix(ocr):Repair verification code OCR recognition service

* 修复对 非新用户 无效的问题

* chore: SettingItem.PreDefault重命名为MigrationValue

---------

Co-authored-by: j2rong4cn <j2rong@qq.com>
2025-07-06 13:09:17 +08:00
4af16ab009 fix(115open):fix limit_rate save (#601) 2025-07-06 12:07:07 +08:00
da35423198 [skip ci] chore: go mod tidy 2025-07-06 00:55:23 +08:00
9612d61e60 chore(pkg): update singleflight 2025-07-05 13:31:47 +08:00
92f396df10 chore(quark_uc): webdav_policy default to native_proxy 2025-07-04 19:06:40 +08:00
9557834342 [skip ci] chore(net): update test 2025-07-04 18:44:52 +08:00
288ba2fcda chore(strm): remove excess parameters (#587) 2025-07-04 17:50:37 +08:00
f3920b02f7 fix(net): goroutine deadlock 2025-07-04 12:52:21 +08:00
2ec9dad3db fix(deps): update module github.com/charmbracelet/lipgloss to v0.13.1 (#449)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-04 12:16:42 +08:00
e11227fe2d fix(deps): update module github.com/otiai10/copy to v1.14.1 (#530)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-04 12:16:25 +08:00
859931b78c fix(deps): update module github.com/nwaples/rardecode/v2 to v2.1.1 (#529)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-04 11:27:14 +08:00
b591524ac3 fix(deps): update module github.com/dlclark/regexp2 to v1.11.5 (#450)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-04 11:26:53 +08:00
dc26b4fce5 fix(deps): update module github.com/aws/aws-sdk-go to v1.55.7 (#439)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-04 11:26:36 +08:00
f8cf02a2da fix(deps): update module github.com/golang-jwt/jwt/v4 to v4.5.2 (#453)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-04 11:26:11 +08:00
a214e794f4 fix(deps): update module github.com/ncw/swift/v2 to v2.0.4 (#525)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-04 11:25:52 +08:00
54d761b371 fix(deps): update module github.com/gin-contrib/cors to v1.7.6 (#451)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-04 11:20:51 +08:00
bea7a9b0e4 chore: remove deprecated trainbit drive (#563)
* chore: remove deprecated trainbit drive

* chore: go mod tidy

---------

Co-authored-by: j2rong4cn <j2rong@qq.com>
2025-07-03 18:30:37 +08:00
a46f4cff18 chore(pr auto reply ci): Update PR title validation and feedback messages (#559)
Update PR title validation and feedback messages

Improves the PR title regex to be non-greedy and adds 'chore' to the allowed prefixes. Enhances feedback comments with clearer instructions in both Chinese and English, including guidance for PRs spanning multiple components.
2025-07-03 15:33:02 +08:00
8eb2d600c7 chore(issues): issue and pr auto reply (#551) 2025-07-03 13:11:39 +08:00
ffb6c2a180 refactor: optimize stream, link, and resource management (#486)
* refactor: optimize stream, link, and resource management

* Link.MFile改为io.ReadSeeker类型

* fix (crypt): read on closed response body

* chore

* chore

* chore
2025-07-03 10:39:34 +08:00
8e19a0fb07 fix(s3): logic bug (close #547 #548) 2025-07-03 10:36:34 +08:00
79f4f96217 feat(strm):add sign and encode path options (#537) 2025-07-02 21:09:57 +08:00
7f53390dce fix(build): version lost 2025-07-02 21:00:43 +08:00
e83f8e197a feat(offline-download): SimpleHttp: download stream direct upload (#523)
* feat(offline-download): stream download to upload

* 重命名stream_put为upload_download_stream

* chore
2025-07-02 18:47:16 +08:00
d707f002eb chore(quark_uc): WebProxy enabled by default 2025-07-02 16:37:56 +08:00
c0f69f7fa7 fix(deps): update module github.com/bodgit/sevenzip to v1.6.1 (#448)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-02 15:36:31 +08:00
adf914115f fix(deps): update module github.com/mholt/archives to v0.1.3 (#456) 2025-07-02 15:35:13 +08:00
c166fe6127 chore: remove exp and go mod tidy (#440) 2025-07-02 15:30:53 +08:00
9725e0fd76 fix(s3): correctly handle URL when RemoveBucket is enabled (#497)
* fix(s3): correctly handle URL when RemoveBucket is enabled

* fix(s3): handle errors
2025-07-02 15:23:22 +08:00
5c4cd1b198 feat(strm): support multiple drivers (#510) 2025-07-02 15:16:46 +08:00
44f4658f37 docs: better error hint for wrong refresh token (#517)
* docs: better error hint for wrong refresh token

* fix: modify punctuation
2025-07-02 10:20:43 +08:00
b4997e7a7e Revert "fix(fs): update objs cache" (close #511)
Revert "fix(fs): update objs cache (#507)"

This reverts commit f26892ac3c.
2025-07-01 20:33:44 +08:00
f26892ac3c fix(fs): update objs cache (#507) 2025-07-01 15:46:34 +08:00
aae3851979 chore(README): various optimizations, reordering, and corrections (#504) 2025-07-01 15:22:37 +08:00
a17b3dc405 feat(strm_driver): add strm driver (#410)
* feat(strm_driver): add strm driver

* chore(strm_driver): get api_url from context

* 优化代码

* chore(strm_driver): update package name

---------

Co-authored-by: j2rong4cn <j2rong@qq.com>
2025-07-01 14:29:28 +08:00
022614f155 chore(readme style): remove line break to prevent visible underline (#501)
style: Remove the line break of the img tag in readme to avoid GitHub's incorrect rendering of the blue underline

Co-authored-by: ShenLin <773933146@qq.com>
2025-07-01 12:15:28 +08:00
874dc292ae fix(gomod): go modules with tagged versions (#499)
fix: go modules with tagged versions
2025-07-01 09:54:50 +08:00
9442013b37 feat(cloudreve_v4): enhance metadata and lock conflict handling (#485)
* feat(cloudreve_v4): add metadata constants

* fix(cloudreve_v4): enhance thumbnail handling

* feat(cloudreve_v4): add HideUploading option

* fix(cloudreve_v4): handle lock conflict during file deletion
2025-07-01 01:06:28 +08:00
862b1c3c53 chore(net): remove unnecessary goroutine 2025-07-01 00:28:26 +08:00
52c93f2046 build:Update old dependencies to new hosting (#495)
* build:Update old dependencies to new hosting
2025-06-30 21:26:42 +08:00
Dgs
3d13d5213b feat(quark): add transcoding link api (#470) 2025-06-30 16:20:45 +08:00
103abc942e refactor: pass api_url through context (#457)
* refactor: pass `api_url` through context

* 移除 LinkArgs.HttpReq

* pref(alias): 减少不必要下载代理

* 修复bug

* net: 支持1并发 分片下载
2025-06-30 15:48:05 +08:00
f0236522f3 fix(115): error getting file sha1 when upload (#482) 2025-06-30 12:58:49 +08:00
6a3b8fab06 feat(driver):add online api user-agent (#483) 2025-06-30 10:35:52 +08:00
5c288dc763 fixed(ua):fixed openlist ua 2025-06-30 09:15:56 +08:00
6d0d3ac612 fix: crypt: file already closed; net: concurrent download deadlock 2025-06-30 01:49:27 +08:00
1ec97733e5 fix(crypt cmd): correctly process encrypted folder names and file nam… (#462)
fix(crypt cmd): correctly process encrypted folder names and file name suffix
2025-06-29 22:22:47 +08:00
ded67b746b fix(115): optimize upload (close #364) 2025-06-29 18:55:57 +08:00
4590795cba fixed(fs):fixed overwrite functions (#469)
* fixed(fs):fixed overwrite functions
2025-06-29 12:17:23 +08:00
060fd36883 feat(ci):Add lite version build and standardize Action naming (#464)
* add lite version

* fixed lite ci

* test

* fixed lite version

* fixed release build md5 and tar

* fixed lite

* fixed release ci

* fixed ci secrets

* fixed ci

* fixed ci

* fixed docker ci

* fixed docker ci

* fixed ci

* fixed docker ci

* fixed docker ci

* fixed docker ci

* ci:delete lite in beta version

* feat(ci):Add Lite Version Build

* Fixed Beta version Docker

* Fixed Web Lite

* fixed EOL

* fixed EOL

---------

Co-authored-by: Sumengjing <146963948+suyunjing-su@users.noreply.github.com>
2025-06-28 22:22:16 +08:00
76a1f99df1 chore(default setting): add avif in default image settings (#458) 2025-06-28 19:18:08 +08:00
38766a4cb7 fix(deps): update github.com/t3rm1n4l/go-mega digest to a19cff0 (#435)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-27 21:31:50 +08:00
bcc518cf96 fix(deps): update github.com/zzzhr1990/go-common-entity digest to 1a20004 (#436)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-27 21:27:02 +08:00
3fdb2c79bf fix(deps): update github.com/fclairamb/ftpserverlib digest to 7accbe1 (#432)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-27 21:17:19 +08:00
18f7a2ba0e fix(s3): fix deleting an empty folder issue and filename encoding (#429) 2025-06-27 20:26:53 +08:00
e32cebb153 fix(deps): resolve go.mod tidy failure (#388)
fix: go.mod tidy failed

Co-authored-by: ShenLin <773933146@qq.com>
Co-authored-by: Suyunjing <69945917+Suyunmeng@users.noreply.github.com>
2025-06-27 15:36:50 +08:00
02031bd835 feat(s3): add Content-Disposition header (#365)
* add(s3): add Content-Disposition header

* Update driver.go

Signed-off-by: XZB-1248 <28593573+XZB-1248@users.noreply.github.com>

* Update driver.go

Signed-off-by: XZB-1248 <28593573+XZB-1248@users.noreply.github.com>

---------

Signed-off-by: XZB-1248 <28593573+XZB-1248@users.noreply.github.com>
Co-authored-by: XZB-1248 <i@1248.ink>
Co-authored-by: Suyunjing <69945917+Suyunmeng@users.noreply.github.com>
2025-06-27 15:29:08 +08:00
7726cb14a0 chore(issue): split Issue templates (#417)
* chore(issue): Update issue templates with improved descriptions and links

Enhanced bug and feature request templates with bilingual descriptions, default titles, and updated documentation links. Added new contact options in config.yml, including a Telegram chat link. Improved clarity and localization for user instructions.

* split

* zh

* test preview

* en

* fix temp preview error

* one line and multiple reproduction links

* fix en

* Revert "fix en"

This reverts commit b3cb48afb4.

* Revert "one line and multiple reproduction links"

This reverts commit cd09ef0d15.

* split fr

* fix temp preview error

* consistency

* fr

* reorder

* split

* fix dup

* consistency

* again due to ai: fix temp preview error

* summary
2025-06-27 15:28:47 +08:00
23cfe8090b pref(net): improve concurrent read and write buffer (#416)
* pref(net): improve concurrent read and write buffer

* chore
2025-06-27 15:18:11 +08:00
Dgs
d89d0a05b4 feat(189tv): add 189cloudTV driver (#418) 2025-06-27 15:09:12 +08:00
Dgs
14d57ae2ec fix(189pc): fix redirect_url format (#420) 2025-06-27 15:00:09 +08:00
d5f4b687bb fix:fixed ci setup web error (#394)
* chore:fixed setup web

* fix(ci):Fixed Setup Web CI
2025-06-26 13:38:37 +08:00
Dgs
bdb880f9f2 feat(quark_open): support rapid upload and thumbnail (#393) 2025-06-26 12:20:05 +08:00
22575a1c61 chore:Add auto-trigger support for OpenWRT builds (#375)
* Fixed webhook

* change repository

* fixed

* hook repo

* fixed makefile

* change repository name

* Limit to a single warehouse token
2025-06-25 21:24:03 +08:00
890297aa27 add(driver): quark 302 test (#367)
* add(driver): quark 302 test

* del(driver): baidu share

* add(driver): revert quark 302 test
2025-06-25 16:38:37 +08:00
0fd602bc1b refactor(fs):Refactor the delete function and fix known issues (#353)
* fix(move):Fix file move logic

* fix(move):fixed move logic

* fix(move):Fixed move logic

* Fixed errs

* fix(move):fixed movetask

* fix(move):fix movetask

* fixed

* fix(move):Refactoring the move structure

* fix(move):Fixed move system

* Fixed

* Fixed

* Fixed

* Fixed

* Fixed

* Rollback

* Fixed and Refactor

* fix(move):fixed

* fix(move):Solve related performance issues

* refacter(move):fixed build bugs
2025-06-24 23:36:37 +08:00
Dgs
f6470af971 fix(123&123open): repair etag format (#349) 2025-06-24 22:14:11 +08:00
Dgs
d695d28e13 feat(thunder&thunder_browser): fix deviceId generation & support offline download and update login interface (#290)
* fix(thunder): fix deviceID generation

* feat(thunder_browser): support offline download and update login interface

* feat(thunder_browser): add fluent_play method for offline download
2025-06-24 21:54:30 +08:00
ffc14ea14c feature:add crypt cmd (#342) 2025-06-24 19:05:46 +08:00
25df3daba5 chore(google_photo): update titles in getFakeRoot (#343)
chore(google_photo): update titles in getFakeRoot to use constants instead of hardcoded strings
2025-06-24 18:18:53 +08:00
Dgs
ce3cb2e31e feat(quark_open): add quark open driver support (#324) 2025-06-24 18:02:15 +08:00
afe23986d2 chore(issue): Update issue templates with improved descriptions and links (#337)
Enhanced bug and feature request templates with bilingual descriptions, default titles, and updated documentation links. Added new contact options in config.yml, including a Telegram chat link. Improved clarity and localization for user instructions.
2025-06-24 11:24:40 +08:00
0026f0c860 fix(ci):Fixed webversion (#333)
* Revert "fix(ci):fixed webversion (#332)"

This reverts commit 9e69b2aaa3.

* Fixed webversion

Signed-off-by: Suyunjing <69945917+Suyunmeng@users.noreply.github.com>

---------

Signed-off-by: Suyunjing <69945917+Suyunmeng@users.noreply.github.com>
2025-06-24 07:12:18 +08:00
9e69b2aaa3 fix(ci):fixed webversion (#332)
fix(ci):fixed webversion bugs

Signed-off-by: Suyunjing <69945917+Suyunmeng@users.noreply.github.com>
2025-06-24 00:26:52 +08:00
af71deb407 fix(cloudreve_v4): reference error in the refreshToken method (#328) 2025-06-24 00:01:19 +08:00
fe079cf0a3 fix(cloudreve_v4): update rename api path to /file/rename (#331) 2025-06-23 23:59:01 +08:00
cf85d49b6c fix(dropbox):Disable Dropbox's default use of the online API 2025-06-23 20:04:40 +08:00
96cf2f7cf9 fix(fs):Repair file loss caused by special reasons when moving files (#321)
* fix(move):Fix file move logic

* fix(move):fixed move logic
2025-06-23 19:48:17 +08:00
b0736d2d02 fix(cloudreve_v4): change upS3 callback method from POST to GET (#323) 2025-06-23 19:35:48 +08:00
49213c1321 fix(setting): update PDF and EPUB viewer URLs (#297)
- Change PDF.js viewer URL from protocol-relative to HTTPS and updates parameter from "url" to "file" for proper document loading
- Also standardize EPUB.js viewer to use HTTPS protocol for consistency
2025-06-23 11:32:22 +08:00
64dd3cb047 fix(ci):fixed changelog ci (#302) 2025-06-22 20:48:10 +08:00
12fd52b6b7 docs(README_cn): format document links as list to sync with other languages. (#279)
Fix #272
2025-06-22 19:06:00 +08:00
27533d0e20 fixed(drive):Delete old Dropbox renewapi (#296)
* add dropbox api

* fixed(api):Delete old dropbox renew api

---------

Signed-off-by: Suyunmeng <69945917+Suyunmeng@users.noreply.github.com>
Co-authored-by: pikachuim <pikachuim@qq.com>
2025-06-22 18:52:55 +08:00
Ray
34a2eeb4a9 删除曲奇云盘驱动 (#294)
* Update all.go 删除quqi

Signed-off-by: Ray <eiauo.ray@gmail.com>

* Delete drivers/quqi directory删除quqi驱动

Signed-off-by: Ray <eiauo.ray@gmail.com>

---------

Signed-off-by: Ray <eiauo.ray@gmail.com>
2025-06-22 18:48:26 +08:00
652e4ba1cb add dropbox api (#295) 2025-06-22 18:28:35 +08:00
639b5cf7c2 fix(net):empty file download error (#282) 2025-06-22 14:21:45 +08:00
b5c1386645 fix: typo and outdated - compose yaml (#263)
* Update docker-compose.yml

Image not exist

Signed-off-by:  Jimmy Alexander <142508054+integer2bit@users.noreply.github.com>

* chore: update docker-compose.yml image to docker hub

Signed-off-by:  Jimmy Alexander <142508054+integer2bit@users.noreply.github.com>

---------

Signed-off-by: Jimmy Alexander <142508054+integer2bit@users.noreply.github.com>
2025-06-22 12:22:21 +08:00
041868dfb8 docs: add channel and update compose config (#272)
* fix:remove-compose-version

Signed-off-by: SenkjM <112735335+SenkjM@users.noreply.github.com>

* mod : add Channel

* docs:update README

---------

Signed-off-by: SenkjM <112735335+SenkjM@users.noreply.github.com>
2025-06-22 00:41:25 +08:00
cfbc157477 chore(ci): remove issue-related automation workflows (#257) 2025-06-21 15:14:24 +08:00
5d44806064 fix(upload): revert #79 (#248) 2025-06-21 00:16:19 +08:00
fc8b99c862 chore:fixed issue translate permissions
Signed-off-by: Suyunmeng <sumengjing@outlook.com>
2025-06-20 23:14:28 +08:00
24560b43c0 chore:fixed issue translate
Signed-off-by: Suyunmeng <sumengjing@outlook.com>
2025-06-20 23:08:50 +08:00
39ca385778 chore:Fixed docker release CI
Update release.yml

Signed-off-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com>

Update release.yml

Signed-off-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com>

chore(ci):Fixed CI bugs

Update release_linux_musl_arm.yml

Signed-off-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com>

Update release_linux_musl.yml

Signed-off-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com>

Update release_freebsd.yml

Signed-off-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com>

Update release_linux_musl_arm.yml

Signed-off-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com>

Update release_linux_musl.yml

Signed-off-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com>

Update release_freebsd.yml

Signed-off-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com>

Update release.yml

Signed-off-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com>

Update release_android.yml

Signed-off-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com>

Update release_docker.yml

Signed-off-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com>

Update release_docker.yml

Signed-off-by: Pikachu Ren <40362270+PIKACHUIM@users.noreply.github.com>

chore:Fixed docker ci
2025-06-20 22:44:39 +08:00
ef0531ad40 feat(ci): add changelog content to release content (#233) 2025-06-20 19:24:29 +08:00
12540a8abc fix: http2 content-length (#224) 2025-06-20 17:57:14 +08:00
0f5ed14fe2 feat(fs): add cross-storage move support (#211)
* feat(fs): add cross-storage move support

* fix(fs): add check before moving files

* fix(fs): changed error detect method

---------

Co-authored-by: ShenLin <773933146@qq.com>
2025-06-20 17:54:24 +08:00
ca55b89322 remove alist from repo (#230)
* remove alist from repo

* remove alist from repo

* remove alist from repo
2025-06-20 17:41:16 +08:00
a3c7cb059d chore:Change Logo URL and fixed aliyundrive open bugs (#208)
* Fix Logo URL

* fixed aliyunpan_open

* fixed aliyundrive bugs

* fixed onlineapi bugs

* fixed onlineapi bugs

* Fixed Bugs

* Rollback

* fixed

* fixed onlineapi

* fixed driver

---------

Signed-off-by: Suyunmeng <sumengjing@outlook.com>
2025-06-19 21:20:29 +08:00
0f8545133b add text output for error message (#210)
* mod rank for AccessToken

* del alist_v2

* add error message from remote

---------

Co-authored-by: Suyunmeng <sumengjing@outlook.com>
2025-06-19 20:25:45 +08:00
72fad1be2e Delete Lark Drive (#201) 2025-06-19 16:38:51 +08:00
b7ce7f172b Dev pika (#202)
* mod rank for AccessToken

* del alist_v2

---------

Co-authored-by: Suyunmeng <sumengjing@outlook.com>
2025-06-19 16:25:07 +08:00
248c041711 fix(setting): update preview url (#198) 2025-06-19 15:05:29 +08:00
70b937e031 Revert "feat(log): add error logging middleware for improved error handling (#182)"
This reverts commit 5e8d8d070a.
2025-06-19 09:56:45 +08:00
79521db8e0 fix(ci): add workflow_dispatch for beta_release and build 2025-06-18 23:27:23 +08:00
015d3ecd00 fix(ci): add auth header when access GitHub CI 2025-06-18 23:27:23 +08:00
89451b6d98 fix(ci): use OpenListTeam/cgo-actions@v1.1.2 2025-06-18 23:27:23 +08:00
681cb6c8a4 fix(ci): freebsd 14.1 is deprecated (#187) 2025-06-18 22:17:21 +08:00
c2d1316f65 fix(115open) fixed rate_limit bugs (#161)
* fixed 115 bugs

Signed-off-by: Suyunmeng <sumengjing@outlook.com>

* Fixed 115 open bugs

* fixed bugs

---------

Signed-off-by: Suyunmeng <sumengjing@outlook.com>
2025-06-18 21:32:23 +08:00
5e8d8d070a feat(log): add error logging middleware for improved error handling (#182) 2025-06-18 20:37:16 +08:00
c7c0bfe810 mod rank for AccessToken (#181) 2025-06-18 18:09:36 +08:00
e9c73b52db fix(Dockerfile): add jq package (#168) 2025-06-18 14:26:42 +08:00
7d24a5d45f feat: add file visibility checks for windows (#39)
* feat: add file visibility checks for windows

* fix: fix build error

* refactor: optimize thie ishidden

---------

Co-authored-by: Hantong Chen <70561268+cxw620@users.noreply.github.com>
2025-06-17 23:25:02 +08:00
3ab309e00e refactor: adjust CI process (#125)
* feat(cmd/lang): allow setting frontend path when generate lang files

* chore(ci): remove ci for auto_lang (done by frontend ci)
2025-06-17 22:35:02 +08:00
8822eef97e chore(api):Add online api refresh method (#143)
* Add Official API Refresh Interface(Baiduyun)

* add UseOnlineAPI & APIAddress
add _refreshToken using APIAddress

* fix return

* Modify the frontend display using the default API refresh method

* Fixed display and operation related issues

* fixed aliyundrive_open old refresh

---------

Co-authored-by: Suyunmeng <sumengjing@outlook.com>
2025-06-17 22:13:28 +08:00
7613f886d0 fix(123open): add rate limit (#144) 2025-06-17 18:49:32 +08:00
fe02a989bd feat(123pan): support 123Open (#93) 2025-06-17 18:38:25 +08:00
2bed40cfce chore(Dockerfile): add jq package (#142)
Add jq package

Signed-off-by: Suyunmeng <sumengjing@outlook.com>
2025-06-17 18:38:22 +08:00
87ca1b96ae fix(189pc): crashes when upload cancelled (#79)
* fix(189pc): crashes when upload cancelled

Signed-off-by: XZB-1248 <28593573+XZB-1248@users.noreply.github.com>

* fix(189pc): replace semaphore with errgroup.Group.SetLimit

---------

Signed-off-by: XZB-1248 <28593573+XZB-1248@users.noreply.github.com>
Co-authored-by: KirCute <951206789@qq.com>
2025-06-17 00:13:31 +08:00
5a4649c929 feat(alias): support parallel write (#69)
* feat(alias): support parallel write

* fix(alias): lack `err` in `errors.Join()`
2025-06-17 00:13:01 +08:00
2e2cec05fd fix(cloudreve): remove unnecessary finish increment in upload functions (#62)
* fix(cloudreve): remove unnecessary finish increment in upload functions

* fix(cloudreve_v4): remove unnecessary finish increment in upload functions
2025-06-17 00:12:45 +08:00
b1afadd129 chore: update project meta (#51)
* chore: update project meta (partial)

* chore: update README

* chore: update pdf preview

* revert: use old hash

* chore: update logo file url
2025-06-16 16:29:45 +08:00
a59ad9a84e fix(lanzou): fix removing JavaScript comments from response data (#37)
* 修复清理js中块注释的bug

移除块注释,目前只将开始“/*”和结束的“*/”移除,未将注释中内容移除

Signed-off-by: 410680876f1 <71364356+410680876f1@users.noreply.github.com>

* 修复清理js中注释的bug

移注释,目前只将注释标识符号清楚,注释中内容被遗留了下来
感谢大佬@Kuingsmile的代码审核

Signed-off-by: 410680876f1 <71364356+410680876f1@users.noreply.github.com>

* 代码格式化

Signed-off-by: 410680876f1 <71364356+410680876f1@users.noreply.github.com>

---------

Signed-off-by: 410680876f1 <71364356+410680876f1@users.noreply.github.com>
Co-authored-by: Hantong Chen <70561268+cxw620@users.noreply.github.com>
2025-06-16 16:28:08 +08:00
2e889fb07d chore(ci): fixed dockerhub ci process (#97)
* add DockerHub

* fixed dockerhub

* Update dockerhub CI

* Update DockerHub

* fixed bugs

* fixed CI Bugs

* Update auto_lang.yml

Signed-off-by: Suyunmeng <sumengjing@outlook.com>

* fixed release

Signed-off-by: Suyunmeng <sumengjing@outlook.com>

* Update test_docker.yml

Signed-off-by: Suyunmeng <sumengjing@outlook.com>

* Delete hub

Signed-off-by: Suyunmeng <sumengjing@outlook.com>

* Delete hub

Signed-off-by: Suyunmeng <sumengjing@outlook.com>

* test build

Signed-off-by: Suyunmeng <sumengjing@outlook.com>

* Simplify actions

Signed-off-by: Suyunmeng <sumengjing@outlook.com>

* Simplify actions test

Signed-off-by: Suyunmeng <sumengjing@outlook.com>

* Simplify actions test Successful ,Rollback Environments

Signed-off-by: Suyunmeng <sumengjing@outlook.com>

* Update release_docker.yml

Signed-off-by: Suyunmeng <sumengjing@outlook.com>

* Update test_docker.yml

Signed-off-by: Suyunmeng <sumengjing@outlook.com>

* Update auto_lang.yml

Signed-off-by: Suyunmeng <sumengjing@outlook.com>

* Update auto_lang.yml

Signed-off-by: Suyunmeng <sumengjing@outlook.com>

* Update auto_lang.yml

Signed-off-by: Suyunmeng <sumengjing@outlook.com>

* Update test_docker.yml

Signed-off-by: Suyunmeng <sumengjing@outlook.com>

* Update release_docker.yml

Signed-off-by: Suyunmeng <sumengjing@outlook.com>

---------

Signed-off-by: Suyunmeng <sumengjing@outlook.com>
2025-06-16 14:16:45 +08:00
d95c4f0127 chore: change the CDN link of the logo and modify the OCR port (#84)
* Change the CDN link of the logo and modify the OCR port

* Update

* Rollback OCR interface
2025-06-15 23:19:25 +08:00
1c58d11d62 chore: update build.sh & add loongarch64 support (#28)
* chore: update build.sh

* chore: update ci build

* chore: update ci build GitAuthor

* feat(build.sh): fix web release download & add loongarch64 build (#63)

chore(ci): fix web download & add loongarch64 & update cgo-actions to v1.1.1

* chore: temporary build test

* revert(build.sh): change to release used url

* feat(build.sh): add set -e for build script

* fix(build.sh): fix web release download logic

* fix(build.sh): remove TODO comment

* feat(build.sh): update GitAuthor to bot@openlist.team

* feat(build.sh): update GitAuthor

* fix: using fsSL in curl & add info of desktop client back

* chore: refine beta release workflow comments

---------

Co-authored-by: Yinan Qin <39023210+elysia-best@users.noreply.github.com>
2025-06-14 23:16:42 +08:00
e11c390c4d fix(cli): Fixed links to documentation in the CLI (#71)
Co-authored-by: reschen <reschen@126.com>
2025-06-14 20:21:14 +08:00
2965915bed chore(deps): switch the dependency from KirCute/sftpd-alist to OpenListTeam/sftpd-openlist (#64) 2025-06-14 16:04:13 +08:00
da1cfd1945 chore(deps): remove dependency KirCute/ftpserverlib-pasvportmap (#61) 2025-06-14 15:56:51 +08:00
8a29790327 chore(ci): using latest musl-compilers (#23)
* chore(ci): using `latest` musl-compilers

https://github.com/OpenListTeam/OpenList/pull/3#pullrequestreview-2921194381

Signed-off-by: YaoSiQian <admin@yaosiqian.cn>

* chore(ci): using `latest` musl-compilers in beta_release CI

---------

Signed-off-by: YaoSiQian <admin@yaosiqian.cn>
Co-authored-by: Hantong Chen <cxwdyx620@gmail.com>
2025-06-13 17:01:24 +08:00
7cd8f648c8 fix: change app name in cmd (#36) 2025-06-13 15:19:25 +08:00
b8e6083e19 chore: remove deprecated vtencent drive (#33) 2025-06-13 12:55:52 +08:00
3f821bdcd1 revert: using old salt value (#29)
Signed-off-by: Yinan Qin <39023210+elysia-best@users.noreply.github.com>
2025-06-13 12:47:51 +08:00
9e05c81d9c chore: update project logo (#26) 2025-06-12 23:29:35 +08:00
f1552b67a0 chore(setting): update repo name in default announcement (#27)
chore(SETTING)/update repo name in default announcement
2025-06-12 23:28:33 +08:00
20d1d5b479 chore(README): update README, add progress intro (#21)
* Update README_cn.md

* Update README_cn.md

* Update README.md

* Update README_ja.md

* Update README_ja.md

* Update README_ja.md

* Update README_ja.md

---------

Co-authored-by: Hantong Chen <70561268+cxw620@users.noreply.github.com>
2025-06-12 22:03:18 +08:00
fdcc2f136e chore: change module name to OpenListTeam/OpenList (#2)
* Enable blank issue

* chore(README.md): update docs (temporally)

* Update FUNDING.yml

* chore: purge README.md

* chore: change module name to OpenListTeam/OpenList

* fix: fix link errors

* chore: remove v3 in module name

* fix: resolve some conficts

* fix: resolve conficts

* docs: update with latest file

---------

Co-authored-by: ShenLin <773933146@qq.com>
Co-authored-by: Hantong Chen <cxwdyx620@gmail.com>
Co-authored-by: joshua <i@joshua.su>
Co-authored-by: Hantong Chen <70561268+cxw620@users.noreply.github.com>
2025-06-12 22:02:46 +08:00
5feb86ceee chore(docs&ci): change links in files & fix github ci and docker ci (#3)
* Enable blank issue

* chore(README.md): update docs (temporally)

* Update FUNDING.yml

* chore: purge README.md

* Update README.md

Alist改为OpenList

* Update README_cn.md

Alist改为OpenList

* Update README.md

漏了一处

* Update README_ja.md

Alist改为OpenList

* Update README_cn.md

漏了一处

* Update CODE_OF_CONDUCT.md

更改链接

* Update README.md

更新tg链接

* Update README_cn.md

更新tg链接

* Update README_ja.md

更新tg链接

* chore(build&docs): use new links in build and github templates

* Update README.md

更新团队名

* chore: disable translation update, change beta release into artifacts

* fix: disable docker build and name the uploaded artifacts

* fix typo

* Update README_cn.md

更新团队名称

* Update README_ja.md

更新

* Update project name in CONTRIBUTING.md

* Update README_cn.md

更新

* Update README.md

更新

* Update README_ja.md

* fix: fix artifact name

* chore(build.sh): use original musl.cc

* fix(ci): fix action artifacts upload

* Update CODE_OF_CONDUCT.md

TG更改为Telegram

* Update README_cn.md

更新论坛链接

* Update README.md

更新论坛链接

* Update README_ja.md

更新论坛链接

* feat: update community based call back for onedrive

* chore(ci): update musl.cc link

* chore: use openlist as name instead of default OpenList

* Update user.go

* chore: fix artifact name

* feat(ci): add docker build test

* fix: add more platforms

* fix: explicitly use docker.io

* fix: fix typo

* fix(docker): fix test build push platform

* chore: change to OpenListTeam

* Update CODE_OF_CONDUCT.md

* doc: update org name

* docs: change repo urls

* feat: release docker image to ghcr.io on tagging

* fix: fix the name of test_docker

* build: update the names in docker-compose and docker file

* chore: rename

---------

Co-authored-by: ShenLin <773933146@qq.com>
Co-authored-by: Hantong Chen <cxwdyx620@gmail.com>
Co-authored-by: joshua <i@joshua.su>
Co-authored-by: 绎泽 <yize@tencent.to>
Co-authored-by: zyk2507 <93830642+zyk2507@users.noreply.github.com>
2025-06-12 21:29:43 +08:00
ee783fa1be chore(CONTRIBUTING): update to new OpenList-Frontend 2025-06-12 17:58:55 +08:00
0bcb4fe16d chore(README): update project name
Update FUNDING.yml

chore: purge README.md

Update project name in CONTRIBUTING.md

Update README.md

Alist改为OpenList

Update README_cn.md

Alist改为OpenList

Update README.md

漏了一处

Update README_ja.md

Alist改为OpenList

Update README_cn.md

漏了一处

Update CODE_OF_CONDUCT.md

更改链接

Update README.md

更新tg链接

Update README_cn.md

更新tg链接

Update README_ja.md

更新tg链接

Update README.md

更新团队名

Update README_cn.md

更新团队名称

Update README_ja.md

更新

Update README_cn.md

更新

Update README.md

更新

Update README_ja.md

Update CODE_OF_CONDUCT.md

TG更改为Telegram

Update README_cn.md

更新论坛链接

Update README.md

更新论坛链接

Update README_ja.md

更新论坛链接
2025-06-12 16:56:22 +08:00
4f57bd3ae6 chore(README.md): update docs (temporally) 2025-06-12 16:56:22 +08:00
cf42fe6a40 chore: allow blank issue 2025-06-12 16:56:18 +08:00
c4775521c6 chore(README.md): reminder of fork
fix: remove `alistgo.com`
2025-06-11 16:14:44 +08:00
ffa03bfda1 feat(cloudreve_v4): add Cloudreve V4 driver (#8470 closes #8328 #8467)
* feat(cloudreve_v4): add Cloudreve V4 driver implementation

* fix(cloudreve_v4): update request handling to prevent token refresh loop

* feat(onedrive): implement retry logic for upload failures

* feat(cloudreve): implement retry logic for upload failures

* feat(cloudreve_v4): support cloud sorting

* fix(cloudreve_v4): improve token handling in Init method

* feat(cloudreve_v4): support share

* feat(cloudreve): support reference

* feat(cloudreve_v4): support version upload

* fix(cloudreve_v4): add SetBody in upLocal

* fix(cloudreve_v4): update URL structure in Link and FileUrlResp
2025-05-24 13:38:43 +08:00
630cf30af5 feat(115_open): implement rate limiting for API requests 2025-05-11 13:39:32 +08:00
bc5117fa4f fix(115_open): add delay in MakeDir function to handle rate limiting 2025-05-02 16:53:39 +08:00
11e7284824 fix: prevent guest user from updating profile (#8447) 2025-04-29 23:14:16 +08:00
b2b91a9281 feat(doubao): add get_download_info API and download_api option (#8428) 2025-04-27 20:00:25 +08:00
f541489d7d fix(netease_music): change ListResp size fields from string to int64 (#8417) 2025-04-27 19:59:30 +08:00
6d9c554f6f feat: add UseLargeThumbnail for 139 (#8424) 2025-04-27 19:58:45 +08:00
Mmx
e532ab31ef fix: remove auth middleware for authn login (#8407) 2025-04-27 19:58:09 +08:00
Mmx
bf0705ec17 fix: shebang of entrypoint.sh (#8408) 2025-04-27 19:56:34 +08:00
17b42b9fa4 fix(mega): use newest file for same filename (#8422 close #8344)
Mega supports duplicate names but alist does not support.
In `List()` method, driver will return multiple files with same name.
That makes alist to use oldest version file for listing/downloading.
So it is necessary to filter old same name files in a folder.
After fixes, all CRUD work normally.

Refs #8344
2025-04-27 19:56:04 +08:00
41bdab49aa fix(139): incorrect host (#8368)
* fix: correct new personal cloud path for 139Driver

* Update drivers/139/driver.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix bug

---------

Co-authored-by: panshaosen <19802021493@139.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: j2rong4cn <253551464@qq.com>
2025-04-19 14:29:12 +08:00
8f89c55aca perf(local): avoid duplicate parsing of VideoThumbPos (#7812)
* feat(local): support percent for video thumbnail

The percentage determines the point in the video (as a percentage of the total duration) at which the thumbnail will be generated.

* feat(local): support both time and percent for video thumbnail

* refactor(local): avoid duplicate parsing of VideoThumbPos
2025-04-19 14:27:13 +08:00
b449312da8 fix(docker_release): avoid duplicate occupation in docker image (#8393 close #8388)
* fix(ci): modify the method of adding permissions

* fix(build): modify the method of adding permissions(to keep up with ci)
2025-04-19 14:26:19 +08:00
52d4e8ec47 fix(lanzou): remove JavaScript comments from response data (#8386)
* feat(lanzou): add RemoveJSComment function to clean JavaScript comments from HTML

* feat(lanzou): remove comments from share page data in getFilesByShareUrl function

* fix(lanzou): optimize RemoveJSComment function to improve comment removal logic
2025-04-19 14:24:43 +08:00
28e5b5759e feat(azure_blob): implement GetRootId interface in Addition struct (#8389)
fix failed get dir
2025-04-19 14:23:48 +08:00
477c43971f feat(doubao_share): support doubao_share link (#8376)
Co-authored-by: anobodys <anobodys@gmail.com>
2025-04-19 14:22:43 +08:00
0a9921fa79 fix(aliyundrive_open): resolve file duplication issues and improve path handling (#8358)
* fix(aliyundrive_open): resolve file duplication issues and improve path handling

1. Fix file duplication by implementing a new removeDuplicateFiles method that cleans up duplicate files after operations
2. Change Move operation to use "ignore" for check_name_mode instead of "refuse" to allow moves when destination has same filename
3. Set Copy operation to handle duplicates by removing them after successful copy
4. Improve path handling for all file operations (Move, Rename, Put, MakeDir) by properly maintaining the full path of objects
5. Implement GetRoot interface for proper root object initialization with correct path
6. Add proper path management in List operation to ensure objects have correct paths
7. Fix path handling in error cases and improve logging of failures

* refactor(aliyundrive_open): change error logging to warnings for duplicate file removal

Updated the Move, Rename, and Copy methods to log warnings instead of errors when duplicate file removal fails, as the primary operations have already completed successfully. This improves the clarity of logs without affecting the functionality.

* Update drivers/aliyundrive_open/util.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-04-19 14:22:12 +08:00
88abb323cb feat(url-tree): implement the Put interface to support adding links directly to the UrlTree on the web side (#8312)
* feat(url-tree)支持PUT

* feat(url-tree) UrlTree更新时,需要将路径和内容分割 #8303

* fix: stdpath.Join call

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Andy Hsu <i@nn.ci>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-04-12 17:27:56 +08:00
f0b1aeaf8d feat(doubao): support upload (#8302 close #8335)
* feat(doubao): support upload

* fix(doubao): fix file list cursor

* fix: handle strconv.Atoi err

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: anobodys <anobodys@gmail.com>
Co-authored-by: Andy Hsu <i@nn.ci>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-04-12 17:12:40 +08:00
c8470b9a2a fix(fs): remove old target object from cache before updating (#8352) 2025-04-12 17:09:46 +08:00
Dgs
d0ee90cd11 fix(thunder): fix login issue (#8342 close #8288) 2025-04-12 17:05:58 +08:00
Dgs
544a7ea022 fix(pikpak&pikpak_share): fix WebPackageName (#8305) 2025-04-12 17:03:58 +08:00
4f5cabc725 feat: add h2c for http server (#8294)
* feat: add h2c for http server

* chore(config): add EnableH2c option
2025-04-12 17:02:51 +08:00
a2f266277c fix(net): unexpected write (#8291 close #8281) 2025-04-12 17:01:52 +08:00
a4bfbf8a83 fix(ipfs): fix problems (#8252)
* fix: 🐛 (ipfs): fix the list error caused by not proper join path function

使用更加规范的路径拼接,修复了有中文或符号的路径无法正常访问的问题

* refactor: 命名规范

* 删除多余的条件判断

* fix: 使用withresult方法重构代码,添加get方法,提高性能

* fix: 允许get方法获取目录

去除多余的判断

* fix: 允许copy,rename,move进行覆写

* fix: 修复move方法导致的目录被删除

* refactor: 整理关于返回Path的代码

* fix: 修复由于get方法导致的ipfs路径无法访问

* fix: 修复path处理错误的get方法

修复get方法,删除意外加入的目录

* fix: fix path join

use path join instead of filepath join to avoid os problem

* fix: rm filepath ref

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2025-04-12 17:01:30 +08:00
ddffacf07b perf: optimize IO read/write usage (#8243)
* perf: optimize IO read/write usage

* .

* Update drivers/139/driver.go

Co-authored-by: MadDogOwner <xiaoran@xrgzs.top>

---------

Co-authored-by: MadDogOwner <xiaoran@xrgzs.top>
2025-04-12 16:55:31 +08:00
3375c26c41 perf(quark_uc&quark_uc_tv): native proxy multithreading (#8287)
* perf(quark_uc): native proxy multithreading

* perf(quark_uc_tv): native proxy multithreading

* chore(fs): file query result add id
2025-04-03 20:50:29 +08:00
ab68faef44 fix(baidu_netdisk): add another video crack api (#8275)
Co-authored-by: anobodys <anobodys@gmail.com>
2025-04-03 20:44:49 +08:00
2e21df0661 feat(driver): add Azure Blob Storage driver (#8261)
* add azure-blob driver

* fix nested folders copy

* feat(driver): add Azure Blob Storage driver

实现 Azure Blob Storage 驱动,支持以下功能:
- 使用共享密钥身份验证初始化连接
- 列出目录和文件
- 生成临时 SAS URL 进行文件访问
- 创建目录
- 移动和重命名文件/文件夹
- 复制文件/文件夹
- 删除文件/文件夹
- 上传文件并支持进度跟踪

此驱动允许用户通过 AList 平台无缝访问和管理 Azure Blob Storage 中的数据。

* feat(driver): update help doc for Azure Blob

* doc(readme): add new driver

* Update drivers/azure_blob/driver.go

fix(azure): fix name check

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update README.md

doc(readme): fix the link

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix(azure): fix log and link

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-04-03 20:43:21 +08:00
af18cb138b feat(139): add option ReportRealSize (#8244 close #8141)
* feat(139): handle family upload errors

* feat(139): add option `ReportRealSize`

* Update drivers/139/driver.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-04-03 20:41:59 +08:00
31c55a2adf fix(archive): unable to preview (#8248)
* fix(archive): unable to preview

* fix bug
2025-04-03 20:41:05 +08:00
465dd1703d feat(cloudreve): s3 policy support (#8245)
* feat(cloudreve): s3 policy support

* fix(cloudreve): correct potential off-by-one error in `etags` initialization
2025-04-03 20:40:19 +08:00
a6304285b6 fix: revert "refactor(net): pass request header" (#8269)
5be50e77d9
2025-04-03 20:35:52 +08:00
affd0cecd1 fix(pikpak&pikpak_share): update algorithms (#8278) 2025-04-03 20:35:14 +08:00
37640221c0 fix(doubao): update file size type to int64 (#8289) 2025-04-03 20:34:27 +08:00
e4bd223d1c fix(deps): update 115-sdk-go to v0.1.5 2025-04-03 20:29:53 +08:00
0cde4e73d6 feat(ipfs): better ipfs support (#8225)
* feat:  better ipfs support

fixed mfs crud, added ipns support

* Update driver.go

clean up
2025-03-27 23:25:23 +08:00
7b62dcb88c fix(baidu_netdisk): deplicate retry (#8210 redo #7972, link #8180) 2025-03-27 23:22:55 +08:00
c38dc6df7c fix(115_open): support multipart upload (#8229)
Co-authored-by: neverlee <neverlea@formail.com>
2025-03-27 23:22:08 +08:00
5668e4a4ea feat(doubao): add Doubao driver (#8232 closes #8020 #8206)
* feat(doubao): implement List()

* feat(doubao): implement Link()

* feat(doubao): implement MakeDir()

* refactor(doubao): add type Object to store key

* feat(doubao): implement Move()

* feat(doubao): implement Rename()

* feat(doubao): implement Remove()
2025-03-27 23:21:42 +08:00
1335f80362 feat(archive): support multipart archives (#8184 close #8015)
* feat(archive): multipart support & sevenzip tool

* feat(archive): rardecode tool

* feat(archive): support decompress multi-selected

* fix(archive): decompress response filter internal

* feat(archive): support multipart zip

* fix: more applicable AcceptedMultipartExtensions interface
2025-03-27 23:20:44 +08:00
704d3854df feat(alist_v3): support forward archive requests (#8230)
* feat(alist_v3): support forward archive requests

* fix: encode all inner path
2025-03-27 23:18:34 +08:00
44cc71d354 fix(cloudreve): enable SetContentLength for uploading to local policy (#8228 close #8174)
* fix(cloudreve): upload failure to return error msg instead of deletion success

* fix(cloudreve): enable SetContentLength for uploading to local policy

* refactor(cloudreve): move local policy upload logic to utils for better error handling

* refactor(cloudreve): unified upload code style

* refactor(cloudreve): improve user agent handling
2025-03-27 23:18:15 +08:00
9a9aee9ac6 feat(alias): support writing to non-ambiguous paths (#8216)
* feat(alias): support writing to non-ambiguous paths

* feat(alias): support extract concurrency

* fix(alias): extract url no pass query
2025-03-27 23:17:45 +08:00
4fcc3a187e fix(traffic): duplicate semaphore release when uploading (#8211 close #8180) 2025-03-27 23:15:47 +08:00
10a76c701d fix(db): support postgres trust/peer mode (#8198 close #8066) 2025-03-27 23:15:04 +08:00
6e13923225 fix(sftp-server): postgre cannot store control characters (#8188 close #8186) 2025-03-27 23:14:36 +08:00
32890da29f fix(115_open): upgrade 115-sdk-go dependency to v0.1.4 2025-03-21 19:06:09 +08:00
758554a40f fix(115_open): upgrade 115-sdk-go dependency to v0.1.3 (close #8169) 2025-03-19 21:47:42 +08:00
4563aea47e fix(115_open): rename delay to take effect (close #8156) 2025-03-18 22:25:04 +08:00
35d6f3b8fc fix(115_open): upgrade sdk (close #8151) 2025-03-18 22:21:50 +08:00
b4e6ab12d9 refactor: FilterReadMeScripts (#8154 close #8150)
* refactor: FilterReadMeScripts

* .
2025-03-18 22:02:33 +08:00
3499c4db87 feat: 115 open driver (#8139)
* wip: 115 open

* chore(go.mod): update 115-sdk-go dependency version

* feat(115_open): implement directory management and file operations

* chore(go.mod): update 115-sdk-go dependency to v0.1.1 and adjust callback handling in driver

* chore: rename driver
2025-03-17 00:52:09 +08:00
d20f41d687 fix: missing handling of RangeReadCloser (#8146) 2025-03-16 22:14:44 +08:00
d16ba65f42 fix(lang): initialize configuration in LangCmd before generating language JSON file 2025-03-16 16:37:33 +08:00
c82e632ee1 fix: potential XSS vulnerabilities (#7923)
* fix: potential XSS vulnerabilities

* feat: support filter and render for readme.md

* chore: set ReadMeAutoRender to true

* fix attachFileName undefined

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2025-03-15 23:28:40 +08:00
04f5525f20 fix(s3): incorrectly added slash before the Bucket name (#8083 close #8001) 2025-03-15 00:21:24 +08:00
28b61a93fd feat(webdav): support oc:checksums (#8064 close #7472)
Ref: #7472
2025-03-15 00:21:07 +08:00
0126af4de0 fix(crypt): premature close of MFile (#8132 close #8119)
* fix(crypt): premature close of MFile

* refactor
2025-03-15 00:13:30 +08:00
7579d44517 fix(onedrive): set req.ContentLength (#8081)
* fix(onedrive): set req.ContentLength

* fix(onedrive_app): set req.ContentLength

* fix(cloudreve): set req.ContentLength
2025-03-15 00:12:37 +08:00
5dfea714d8 fix(cloudreve): use milliseconds timestamp in last_modified (#8133) 2025-03-15 00:12:15 +08:00
370a6c15a9 fix(baidu_netdisk): remove duplicate retry (#7972) 2025-03-01 19:00:36 +08:00
2570707a06 feat(baidu_netdisk): support dynamical slice size for low bandwith upload case (#7965)
* 动态分片尺寸

* 补充严格测试结果
2025-03-01 18:46:05 +08:00
4145734c18 refactor(net): pass request header (#8031 close #8008)
* refactor(net): pass request header

* feat(proxy): add `Etag` to response header

* refactor
2025-03-01 18:35:34 +08:00
646c7bcd21 fix(archive): use another sign for extraction (#7982) 2025-03-01 18:34:33 +08:00
cdc41595bc feat(github): support GPG verification (#7996 close #7986)
* feat(github): support GPG verification

* chore
2025-02-24 23:12:23 +08:00
79bef0be9e chore: fix build failed (#8005) 2025-02-16 15:11:48 +08:00
c230f24ebe fix(archive): decode filename when decompressing zips (#7998 close #7988) 2025-02-16 12:25:01 +08:00
30d8c20756 feat(archive): support deprioritize previewing (#7984) 2025-02-16 12:24:10 +08:00
3b71500f23 feat(traffic): support limit task worker count & file stream rate (#7948)
* feat: set task workers num & client stream rate limit

* feat: server stream rate limit

* upgrade xhofe/tache

* .
2025-02-16 12:22:11 +08:00
399336b33c fix(189pc): transfer rename (#7958)
* fix(189pc): transfer rename

* fix: OverwriteUpload

* fix: change search method

* fix

* fix
2025-02-16 12:21:34 +08:00
36b4204623 feat(github): support github proxy (#7979 close #7963) 2025-02-16 12:21:03 +08:00
f25be154c6 fix(ilanzou): add header X-Forwarded-For to solve IP ban (#7977)
* fix: warning

* feat: ip header

* fix: ip header for fs link
2025-02-16 12:20:28 +08:00
ec3fc945a3 fix(feiji): modify the request header (#7902 close #7890) 2025-02-09 18:35:39 +08:00
3f9bed3d5f feat(bootstrap): add .url to proxy types (#7928) 2025-02-09 18:33:38 +08:00
b9ad18bd0a feat(recursive-move): Advanced conflict policy for preventing unintentional overwriting (#7906) 2025-02-09 18:32:57 +08:00
0219c4e15a fix(index): fix the issue where ignored paths are not updated (#7907) 2025-02-09 18:31:43 +08:00
d983a4ebcb refactor(cmd): use std runtime package to get go version info (#7964)
* refactor(cmd): use std `runtime` package to get go version info

- Remove the `GoVersion` variable.
- Remove overriding `GoVersion` by ldflags in `build.sh`.
- Get go version, OS and arch from the constants in the std `runtime` package instead of compile time.

* chore(ci): remove `GoVersion` flag from workflows

Remove GoVersion flag from beta_release.yml and build.yml workflows.

> Reduce compile-time dependencies.
2025-02-09 18:30:56 +08:00
f795807753 feat(github_releases): support dir size for show all version (#7938)
* refactor

* 修改默认 RepoStructure

* feat: 支持使用 gh-proxy
2025-02-09 18:30:38 +08:00
6164e4577b fix: missing args when using alias driver (#7941 close #7932) 2025-02-05 19:22:10 +08:00
39bde328ee fix(lenovonas_share): the size of the directory (#7914) 2025-02-01 17:32:58 +08:00
779c293f04 fix(driver): implement canceling and updating progress for putting for some drivers (#7847)
* fix(driver): additionally implement canceling and updating progress for putting for some drivers

* refactor: add driver archive api into template

* fix(123): use built-in MD5 to avoid caching full

* .

* fix build failed
2025-02-01 17:29:55 +08:00
b9f397d29f fix(139): restore the Account handling, partially reverts #7850 (#7900 close #7784) 2025-01-30 11:25:41 +08:00
d53eecc229 fix(febbox): panic due to slice out of range (#7898 close #7889) 2025-01-30 11:24:07 +08:00
f88fd83d4a feat(ci): use go-cross/cgo-actions for dev build 2025-01-28 18:57:09 +08:00
226c34929a feat(ci): add build info for beta release 2025-01-27 21:32:59 +08:00
027edcbe53 refactor(patch): execute all patches in dev version (#7807) 2025-01-27 20:49:24 +08:00
fd51f34efa feat(misskey): add misskey driver (#7864) 2025-01-27 20:47:52 +08:00
bdd9774aa7 feat(github_releases): add support for github_releases driver (#7844 close #7842)
* feat(github_releases): 添加对 GitHub Releases 的支持

* feat(github_releases): 增加目录大小和更新时间,增加请求缓存

* Feat(github_releases): 可选填入 GitHub token 来提高速率限制或访问私有仓库

* Fix(github_releases): 修复仓库无权限或不存在时的异常

* feat(github_releases): 支持显示所有版本,开启后不显示文件夹大小

* feat(github_releases): 兼容无子目录
2025-01-27 20:28:44 +08:00
258b8f520f feat(recursive-move): add overwrite option to preventing unintentional overwriting (#7868 closes #7382,#7719)
* feat(recursive-move): add `overwrite` option to preventing unintentional overwriting

* chore: rearrange code order
2025-01-27 20:25:39 +08:00
99f39410f2 fix(s3): escape CopySource request header when copying files (#7860 close #7858) 2025-01-27 20:23:13 +08:00
267120a8c8 fix(115): fix offline download (#7845 close #7794)
* feat(115): use multi url for list files & change download url api

* fix(115): fix offline download. (close #7794)
2025-01-27 20:20:55 +08:00
5eff8cc7bf feat(upload): support rapid upload on web (#7851) 2025-01-27 20:20:09 +08:00
d5ec998699 feat(task): allow retry canceled (#7852) 2025-01-27 20:18:10 +08:00
23f3178f39 chore(README): formatting spacing in README links (#7879) [skip ci] 2025-01-27 20:13:35 +08:00
cafdb4d407 fix(139): correct path handling in groupGetFiles (#7850 closes #7848,#7603)
* fix(139): correct path handling in groupGetFiles

* perf(139): reduce the number of requests in groupGetFiles

* refactor(139): check authorization expiration (#10)

* refactor(139): check authorization expiration

* fix bug

* chore(139): update api version to 7.14.0

---------

Co-authored-by: j2rong4cn <36783515+j2rong4cn@users.noreply.github.com>
2025-01-27 20:11:21 +08:00
0d4c63e9ff feat(fs): display the existing filename in error message (#7877) 2025-01-27 20:09:17 +08:00
5c5d8378e5 fix(archive): unable to preview (#7843)
* fix(archive): unrecognition zip

* feat(archive): add tree for zip meta

* fix bug

* refactor(archive):  meta cache time use Link Expiration first

* feat(archive): return sort policy in meta (#2)

* refactor

* perf(archive): reduce new network requests

---------

Co-authored-by: KirCute_ECT <951206789@qq.com>
2025-01-27 20:08:56 +08:00
2be0c3d1a0 feat(alias): add DownloadConcurrency and DownloadPartSize option (#7829)
* fix(net): goroutine logic bug (AlistGo/alist#7215)

* Fix goroutine logic bug

* Fix bug

---------

Co-authored-by: hpy hs <hshpy.pengyu@gmail.com>

* perf(net): sequential and dynamic concurrency

* fix(net): incorrect error return

* feat(alias):  add `DownloadConcurrency` and `DownloadPartSize` option

* feat(net): add `ConcurrencyLimit`

* pref(net): create `chunk` on demand

* refactor

* refactor

* fix(net): `r.Closers.Add` has no effect

* refactor

---------

Co-authored-by: hpy hs <hshpy.pengyu@gmail.com>
2025-01-27 20:08:39 +08:00
bdcf450203 fix: resolve concurrent read/write issues in WrapObjName (#7865) 2025-01-27 20:06:18 +08:00
c2633dd443 fix(workflow): use the dev version of the web for beta releases (#7862)
* fix(workflow): use dev version of the web for beta releases

* chore(config): check version string by prefix
2025-01-23 22:49:35 +08:00
11b6a6012f fix(copy): use Link and Put when the driver does not support copying (#7834) 2025-01-18 23:52:02 +08:00
59e02287b2 feat(fs): add overwrite option to preventing unintentional overwriting (#7809) 2025-01-18 23:39:07 +08:00
bb40e2e2cd feat(archive): archive manage (#7817)
* feat(archive): archive management

* fix(ftp-server): remove duplicate ReadAtSeeker realization

* fix(archive): bad seeking of SeekableStream

* fix(archive): split internal and driver extraction api

* feat(archive): patch

* fix(shutdown): clear decompress upload tasks

* chore

* feat(archive): support .iso format

* chore
2025-01-18 23:28:12 +08:00
ab22cf8233 feat: add Reference interface to driver (#7805)
* feat: add `Reference` interface to driver

* feat(123_share): support reference 123pan
2025-01-18 23:26:58 +08:00
880cc7abca fix(139): use personal_new by default (#7836) 2025-01-18 23:24:09 +08:00
b60da9732f feat(offline-download): allow using offline download tools in any storage (#7716)
* Feat(offline-download): allow using thunder offline download tool in any storage

* Feat(offline-download): allow using 115 offline download tool in any storage

* Feat(offline-download): allow using pikpak offline download tool in any storage

* style(offline-download): unify offline download tool names

* feat(offline-download): show available offline download tools only

* Fix(offline-download): update unmodified tool names.

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2025-01-10 21:24:44 +08:00
e04114d102 feat(github): add github api driver (#7717)
* feat(github): add github api driver

* fix: filter submodule operation

* feat: rename, copy and move, but with bugs

* fix: move and copy returns 422

* fix: change TargetPath in rename msg from parent path to new self path

* fix: add non-commit mutex

* pref(github): use net/http to put blob

* chore: add a help message to `ref` addition
2025-01-10 20:59:58 +08:00
51bcf83511 feat(url-tree): support url tree driver writing (#7779 close #5166)
* feat: support url tree writing

* fix: meta writable

* feat: disable writable via addition
2025-01-10 20:50:56 +08:00
25b4b55ee1 feat(ftp-server): support resumable downloading (#7792) 2025-01-10 20:50:20 +08:00
6812ec9a6d fix(ilanzou): add accept-encoding request header (#7796 close #7759) 2025-01-10 20:49:50 +08:00
31a7470865 feat(local): support both time and percent for video thumbnail (#7802)
* feat(local): support percent for video thumbnail

The percentage determines the point in the video (as a percentage of the total duration) at which the thumbnail will be generated.

* feat(local): support both time and percent for video thumbnail
2025-01-10 20:48:45 +08:00
Mmx
687124c81d ci(build_docker): merge build_docker into release_docker workflow (#7755)
* feat(ci): merge build_docker workflow into release_docker

* fix(ci): logics of docker meta
2025-01-01 21:29:59 +08:00
e4439e66b9 fix:(baidu_photo): upload erron -6 (#7760 close #7744)
* fix:(baidu_photo): upload erron -6

* fix(baidu_photo):api add bdstoken
2025-01-01 21:13:34 +08:00
7fd4ac7851 fix(139): update familyGetFiles pagination logic (#7748 close #7711) 2024-12-30 22:55:47 +08:00
6745dcc139 feat(task): attach creator to user of the context (#7729) 2024-12-30 22:55:09 +08:00
aa1082a56c feat(sftp-server): do not generate host key until first enabled (#7734) 2024-12-30 22:54:37 +08:00
ed149be84b feat(index): add disable index option for storages (#7730) 2024-12-30 22:52:55 +08:00
040dc14ee6 fix(lenovonas_share): stoken expire (#7727) 2024-12-30 22:51:39 +08:00
Mmx
4dce53d72b feat(docker release): improve aria2 image, add aio image (#7750)
* build: add argument INSTALL_ARIA2 to dockerfile

* feat: run aria2 in main entrypoint

* feat(ci): environment matrix for docker release

* improve(ci): allow overwrite artifacts in docker release

* fix(ci): permission of alist binary in docker; entrypoint logic

* improve(aria2): move aria2 data to /opt/aria2; fix permission issues

References:

https://github.com/AlistGo/with_aria2/pull/13

Co-authored-by: GoodbyeNJN <cc@fuckwall.cc>

* fix(ci): aio image is not taking effect

* fix(build): tar command in aria2 installation process

(cherry picked from commit 647285408354807bae64df6a20fefb696ff787de)

---------

Co-authored-by: GoodbyeNJN <cc@fuckwall.cc>
2024-12-30 22:51:05 +08:00
365fc40dfe fix: static page to limit request method (#7745 close #7667) 2024-12-30 22:49:18 +08:00
5994c17b4e feat(patch): upgrade patch module (#7738)
* feat(patch): upgrade patch module

* chore(patch): add docs

* fix(patch): skip and rewrite invalid last launched version

* fix(patch): turn two functions into patches
2024-12-30 22:48:33 +08:00
42243b1517 feat(thunder): add offline download tool (#7673)
* feat(thunder): add offline download tool

* fix(thunder): improve error handling and parse file size in status response

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2024-12-25 21:23:58 +08:00
48916cdedf fix(permission): enhance the strictness of permissions (#7705 close #7680)
* fix(permission): enhance the strictness of permissions

* fix: add initial permissions to admin
2024-12-25 21:17:58 +08:00
5ecf5e823c fix(webauthn): handle error when removing webauthn credential (#7689) 2024-12-25 21:16:34 +08:00
c218b5701e fix(115): support float QPS (#7677) 2024-12-25 21:16:03 +08:00
77d0c78bfd feat(sftp-server): public key login (#7668) 2024-12-25 21:15:06 +08:00
db5c601cfe fix(crypt): add sign to thumbnail (#6611) 2024-12-25 21:13:54 +08:00
221cdf3611 feat(s3): support custom host presign (#7699 close #7696) 2024-12-25 21:13:23 +08:00
40b0e66efe feat(ftp-server): treat moving across file systems as copying (#7704 close #7701)
* feat(ftp-server): treat moving across file systems as copying

* fix: ensure compatibility across different fs on the same driver
2024-12-25 21:12:30 +08:00
b72e85a73a fix(ftp-server): rewrite download in a more appropriate method (#7656) 2024-12-25 21:11:45 +08:00
6aaf5975c6 fix(ftp-server): work unproperly when base url is not root (#7693)
* fix(ftp-server): work unproperly when base url is not root

* fix: avoid merge conflict
2024-12-25 21:11:36 +08:00
bb2aec20e4 fix(139): handle upload file conflicts (#7692) 2024-12-25 21:11:05 +08:00
d7aa1608ac feat(task): add speed monitor (#7655) 2024-12-25 21:09:54 +08:00
db99224126 perf: Speed ​​of database initialization (#7694)
* perf: 优化非sqlite3数据库时初始化慢的问题

* refactor
2024-12-25 21:08:22 +08:00
b8bd14f99b fix(lanzou): missing parameter (#7678 close #7210) 2024-12-17 22:05:52 +08:00
331885ed64 fix(net): close of closed channel (#7580) 2024-12-17 22:04:27 +08:00
cf58ab3a78 chore(config): disable FTP and SFTP by default 2024-12-12 21:04:14 +08:00
33ba7f1521 feat: sftp server support (#7643)
* feat: sftp server support

* fix(sftp-server): try fix build failed

* fix: sftp download lack
2024-12-12 20:51:43 +08:00
201e25c17f fix(ftp-server): large transfer leads to client timeout (#7639)
* fix(ftp-server): client timeout to wait a large file upload to netdisk

* fix(ftp-server): driver alist v3 upload failed and temp files do not be deleted
2024-12-12 20:50:00 +08:00
ecefa5e0eb ci: fix desktop beta release trigger 2024-12-10 20:21:51 +08:00
650b03aeb1 feat: ftp server support (#7634 close #1898)
* feat: ftp server support

* fix(ftp): incorrect mode for dirs in LIST returns
2024-12-10 20:17:46 +08:00
7341846499 perf(task): merge requests of operating selected (#7637) 2024-12-10 19:30:50 +08:00
a3908fd9a6 fix(139): update APIs (#7591 close #7603)
* fix(139): update family cloud API

* fix(139): update API of familyGetLink

* feat(139): support group (close #7603)

* docs: add `139 group` to Readme

* feat(139): support multipart upload (close: #7444)

* feat(139): add custom upload part size option

* fix: missing right big quote

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2024-12-09 23:54:21 +08:00
2a035302b2 fix(cloudreve): support upload to remote and OneDrive storage (#7632 close #6882)
- Add support for remote and OneDrive storage types
- Implement new upload methods for different storage types
- Update driver to handle various storage policies
- Add error handling and session cleanup for failed uploads
2024-12-09 23:35:44 +08:00
016e169c41 feat(139): support multipart upload (close: #7444) (#7630)
* feat(139): support multipart upload (close: #7444)

* feat(139): add custom upload part size option
2024-12-09 23:34:29 +08:00
088120df82 feat(sso): add custom extra scope support (#7577) 2024-12-09 23:33:46 +08:00
aa45a82914 fix(115): fix login bug (#7626 close #7614 close #7620) 2024-12-09 23:33:07 +08:00
5084d98398 fix(onedrive): fix timeout error (#7551 close #7506) 2024-12-08 17:06:33 +08:00
fa15c576f0 fix(pikpak): remove oauth2 method (#7567 close #7545) 2024-12-07 17:03:46 +08:00
2d3605c684 fix(baidu_photo): cookie login fix download error (#7602) 2024-12-07 17:02:52 +08:00
492b49d77a Update README.md 2024-12-07 01:00:25 +08:00
94915b2148 fix(baidu_netdisk): update fileToObj to use ServerCtime and ServerMtime (#7535) 2024-11-21 22:41:23 +08:00
2dec756f23 fix(pikpak&pikpak_share): captcha_sign error (#7530 close #7481 close #7482) 2024-11-21 22:40:39 +08:00
4c0cffd29b fix(net): close of closed channel (#7529) 2024-11-21 22:39:14 +08:00
25c5e075a9 fix(local): Preserve file owner when copying (#7528) 2024-11-21 22:38:41 +08:00
Mmx
398c04386a feat(sso): generate and verify OAuth state with go-cache (#7527) 2024-11-21 22:38:04 +08:00
Mmx
12b429584e feat(security): generating random string with crypto rand (#7525) 2024-11-21 22:37:19 +08:00
Mmx
150dcc2147 fix(sso): OIDC compatibility mode (#7524) 2024-11-21 22:36:41 +08:00
0ba754fd40 fix(release): missing installation of zig 2024-11-17 23:11:03 +08:00
28d2367a87 fix(ci): no space left on device 2024-11-17 22:24:06 +08:00
a4ad98ee3e fix(pikpak): domain block and change to NET (#7350) 2024-11-17 20:03:04 +08:00
1c01dc6839 fix(storage): delete storage fails if a panic occurred during initialization (#7501)
* fix(storage): store storages map when init storage panic

* fix(drivers): add nil check to drop method
2024-11-16 13:20:49 +08:00
c3c5843dce fix(terabox): panic due to slice out of range (#7499 close #7487) 2024-11-16 13:19:59 +08:00
6c38c5972d fix(terabox): big file upload issue (#7498 close #7490) 2024-11-16 13:18:49 +08:00
0a46979c51 feat(115): enhance cache (#7479) 2024-11-08 22:08:50 +08:00
67c93eed2b feat(baidu_netdisk,baidu_photo): add and fix hashinfo (#7469) 2024-11-08 22:08:25 +08:00
f58de9923a refactor(aliyunopen,config): Modify default properties (#7476) 2024-11-08 22:07:35 +08:00
2671c876f1 revert: "fix(115): enforce 20GB file size limit on uploadev"
This reverts commit 216e3909f3.
2024-11-02 21:08:19 +08:00
e707fa38f1 ci: remove specific tag for freebsd action 2024-11-02 17:05:00 +08:00
b803b0070e fix(115): 20GB file upload restriction (#7452)
* fix(115): multipart upload error

* feat(115): Modify default page size

* fix(115): Replace temporary repair scheme
2024-11-02 16:41:33 +08:00
64ceb5afb6 feat: support general users view and cancel own tasks (#7416 close #7398)
* feat: support general users view and cancel own tasks

Add a creator attribute to the upload, copy and offline download
tasks, so that a GENERAL task creator can view and cancel them.

BREAKING CHANGE:

1. A new internal package `task` including the struct `TaskWithCreator`
   which embeds `tache.Base` is created, and the past dependence on
   `tache.Task` will all be transferred to dependence on this package.
2. The API `/admin/task` can now also be accessed via `/task`, and the
   old endpoint is retained to ensure compatibility with legacy
   automation scripts.

Closes #7398

* fix(deps): update github.com/xhofe/tache to v0.1.3
2024-11-01 23:32:26 +08:00
10c7ebb1c0 fix(local): cross-device file move (#7430) 2024-11-01 23:31:33 +08:00
d0cda62703 ci: add freebsd release build (#7344) 2024-11-01 21:37:53 +08:00
ce0b99a510 fix(cloudreve): path not exist when moving/copying files (#7432)
Co-authored-by: 马建军 <1432318228@qq.com>
2024-11-01 21:12:29 +08:00
Mmx
34a148c83d feat(local): thumbnail token bucket smooth migration (#7425)
* feat(local): allow to migrate static token buckets

* improve(local): token bucket migration boundary handling
2024-11-01 20:58:53 +08:00
Mmx
4955d8cec8 ci(docker): support riscv64 and ppc64le (#7426)
* ci(docker): bump cache key of musl library

* build(docker): add new arches to build script

* ci(docker): add new arches to buildx platforms
2024-11-01 20:53:53 +08:00
216e3909f3 fix(115): enforce 20GB file size limit on uploadev (#7447 close #7413)
- Introduce a file size restriction to handle uploads more securely.
- Provide an informative error for uploads that exceed the new limit.
2024-11-01 20:52:19 +08:00
a701432b8b ci: add freebsd to beta release 2024-10-21 00:05:56 +08:00
a2dc45a80b fix(ilanzou): fix upload failure for small files (#7368 close #7250) 2024-10-20 23:53:56 +08:00
48ac23c8de fix(ilanzou): fix infinite loop when getting file list (#7366 close #7357) 2024-10-20 23:53:40 +08:00
2830575490 perf(123pan): change domain of login (#7325)
* Update driver.go

* 1

* Update util.go

* 123新登录接口

* Revert "Update util.go"

This reverts commit a13a58f8a86c7c36d4fd7d91137229a7667f1fb5.

* Update driver.go

* Update util.go

* Update util.go
2024-10-15 19:45:30 +08:00
e8538bd215 feat: add febbox driver (#7304 close #7293) 2024-10-14 22:44:20 +08:00
c3e43ff605 fix(115): use latest appVer for upload (close #7315) 2024-10-12 00:48:54 +08:00
5f19d73fcc fix: Terabox ( close #6961 close #6983 in #7279) 2024-10-04 15:46:10 +08:00
bdf4b52885 feat(offline_download): add transmission (close #4102 in #7232) 2024-09-28 23:15:58 +08:00
6106a2d4cc fix: dynamic update app version (close #7198 in #7220) 2024-09-18 23:30:28 +08:00
b6451451b1 fix: release version (close #7182) 2024-09-17 01:37:14 +08:00
f06d2c0348 fix(115): change ua (#7196 close #7191) 2024-09-17 01:34:47 +08:00
b7ae56b109 ci: delete beta tag before generating changelog 2024-09-14 00:50:24 +08:00
5d9167d676 fix: recover panic on storage init 2024-09-13 23:50:51 +08:00
1b42b9627c fix(google_photo): fix issue copy videos from google photo (#7160 close #7158)
#7158 During copy from google photo to aliyun, it failed consistently with 404 when copying mp4 file with =m37.

Change =m37 to =dv will fix the issue
2024-09-12 19:08:13 +08:00
bb58b94a10 fix(deps): update module github.com/charmbracelet/bubbles to v0.20.0 (#7142)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-10 00:02:47 +08:00
ffce61d227 ci: add @ to trigger by comment 2024-09-10 00:02:24 +08:00
0310b70d90 fix(deps): update module golang.org/x/crypto to v0.27.0 (#7147)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-10 00:01:51 +08:00
73f0b135b6 ci: split arm and non-arm target on beta release workflow 2024-09-09 00:25:35 +08:00
8316f81e41 ci: update beta tag to newest commit 2024-09-08 23:03:58 +08:00
cdbfda8921 fix(baidu_photo): change download api (#7144 close #7133) 2024-09-08 19:47:11 +08:00
9667832b32 fix(pikpak): fix nil pointer error (#7150) 2024-09-08 19:45:42 +08:00
b36d38f63f chore: go mod tidy 2024-09-08 11:12:53 +08:00
c8317250c1 fix(deps): update golang.org/x/exp digest to e7e105d (#7139)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-08 11:10:07 +08:00
0242f36e1c fix(deps): update module google.golang.org/grpc to v1.66.0 (#7098)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-08 10:58:52 +08:00
40a68bcee6 fix(deps): update module github.com/ncw/swift/v2 to v2.0.3 (#7107)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-08 10:58:04 +08:00
92713ef5c4 fix(deps): update module github.com/charmbracelet/bubbletea to v1 (#7103)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-08 10:57:04 +08:00
716d33fddd feat(pikpak&pikpak_share): add download address delay detection (#7136)
* feat(pikpak): add download address delay detection

* feat(pikpak_share): add download address delay detection
2024-09-08 10:45:43 +08:00
c9fa3d7cd6 fix: broken file with local proxy (#7132 close #7112)
* fix: local proxy download file damage

* fix: temp dir remove
2024-09-08 10:44:34 +08:00
Mmx
4874c9e43b fix(local): thumbnails oom (#7124 close #7082)
* add my_build.sh

* Fix OOM of thumbnail generation of LoaclDrive by using a task queue to control thread count

* remove my_build.sh

* chore(local): allow ThumbConcurrency set to zero

* revert(local): changes to thumbnail generating functions

* feat(local): implement static token bucket

* feat(local): use static token bucket to limit thumbnails generating concurrent

---------

Co-authored-by: KKJas <75424880+Muione@users.noreply.github.com>
2024-09-03 20:03:30 +08:00
Mmx
34ada81582 fix(webdav): memory leak in HttpServer (#7123 close #7088)
* chore(webdav): fix warnings in HttpServe

* fix(webdav): HttpServe memory leak
2024-09-03 20:02:13 +08:00
ba716ae325 fix(pikpak): error when passing the user_id field (#7117 close #7118) 2024-09-01 23:06:51 +08:00
d4f9c4b6af ci: trigger desktop beta version 2024-08-29 23:03:54 +08:00
b910b8917f fix(deps): update golang.org/x/exp digest to 9b4947d (#7065)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-24 22:24:18 +08:00
Mmx
d92744e673 chore(local): decrease mass ffmpeg logs (#7073) 2024-08-24 22:20:20 +08:00
868b0ec25c chore: replace link of zhaoziyuan [skip ci] 2024-08-23 12:27:19 +08:00
e21edf98e2 revert: 34b6785fab 2024-08-21 17:08:03 +00:00
d2514d236f feat(drivers): add kodbox storage (#7059 close #7058)
- kodbox: https://github.com/kalcaddle/kodbox
2024-08-22 00:46:38 +08:00
34b6785fab fix(deps): update module github.com/meilisearch/meilisearch-go to v0.28.0 (#7061)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-22 00:45:31 +08:00
48f50a2ceb fix(search): BuildIndex concurrency error (#7035) 2024-08-22 00:44:55 +08:00
74887922b4 fix(offline_download): os.create failure while the name of downloaded file is empty (#7041) 2024-08-22 00:44:23 +08:00
bcb24d61ea fix(deps): update module github.com/go-resty/resty/v2 to v2.14.0 (#6981)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-22 00:43:35 +08:00
db1494455d fix(deps): update module github.com/charmbracelet/bubbles to v0.19.0 (#7048)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-22 00:43:11 +08:00
d9a1809313 fix(deps): update module github.com/charmbracelet/lipgloss to v0.13.0 (#7049)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-22 00:42:50 +08:00
0715198c7f chore: fix log format typo (#7056)
Signed-off-by: cuishuang <imcusg@gmail.com>
2024-08-22 00:42:19 +08:00
ef5e192c3b fix(pikpak): webdav upload issue (#7050) 2024-08-22 00:35:52 +08:00
489b28bdf7 fix(pikpak_share): add captcha_token generation function (#7045) 2024-08-22 00:35:14 +08:00
18176c659c ci: add beta tag to newest docker image 2024-08-20 21:36:36 +08:00
4c48a816bf fix(deps): update module github.com/charmbracelet/bubbletea to v0.27.0 (#7025)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-19 23:30:26 +08:00
9af7aaab59 fix(deps): update github.com/city404/v6-public-rpc-proto/go digest to 90f8e24 (#7028)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-19 23:30:08 +08:00
a54a09314f fix(deps): update module github.com/aws/aws-sdk-go to v1.55.5 (#6813)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-19 23:29:45 +08:00
e2fcd73720 fix(deps): update module github.com/go-webauthn/webauthn to v0.11.1 (#6901)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-19 23:29:24 +08:00
e238b90836 fix(pikpak): modify the processing logic of CaptchaToken (#7024) 2024-08-18 23:26:29 +08:00
69e5b66b50 ci: use changelogithub to generate changelog 2024-08-18 13:57:44 +08:00
e8e6d71c41 ci: only one beta release action concurrency [skip ci] 2024-08-18 00:38:27 +08:00
4ba476e25c ci: build beta release 2024-08-18 00:25:16 +08:00
e5fe9ea5f6 ci: set changelog for beta release 2024-08-17 23:03:49 +08:00
e1906c9312 ci: only release on tag with v prefix 2024-08-17 22:08:29 +08:00
51c95ee117 fix: decode body if enable gzip (#7003) 2024-08-15 22:25:53 +08:00
Mmx
1f652e2e7d ci(docker): using docker build args instead of extra dockerfile for ffmpeg (#6989)
* build: using docker build arg to determine install ffmpeg or not

* ci: pass build-args to ffmpeg image build step
2024-08-15 21:48:48 +08:00
8e6c1aa78d fix(pikpak): refresh_token cannot be obtained (#7017) 2024-08-15 21:46:55 +08:00
6bff5b6107 fix(deps): update module golang.org/x/image to v0.19.0 (#6982)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-14 19:35:33 +08:00
Mmx
94937db491 feat(s3): using internal download method in proxy (#6988) 2024-08-14 19:34:48 +08:00
3dc250cc37 feat(115): update qrcode source list (#6996)
* remove mac, linux, window (disabled)
* add alipaymini, wechatmini, qandroid
2024-08-14 19:34:11 +08:00
9560799175 fix(189pc): InvalidSessionKey (#6994 close #6992) 2024-08-14 19:33:15 +08:00
8f3c5b1587 fix(deps): update module github.com/meilisearch/meilisearch-go to v0.27.2 (#6907)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-11 11:40:47 +08:00
285125d06a fix(deps): update module github.com/larksuite/oapi-sdk-go/v3 to v3.3.1 (#6978)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-11 11:40:26 +08:00
a26185fe05 fix(deps): update github.com/xhofe/go-cache digest to b1a7192 (#6939)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-11 11:40:05 +08:00
a7efa3a676 fix(deps): update golang.org/x/exp digest to 0cdaa3a (#6977)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-11 11:39:13 +08:00
d596ef5c38 fix(deps): update module github.com/blevesearch/bleve/v2 to v2.4.2 (#6892)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-11 11:38:56 +08:00
34e34ef564 fix(deps): update module golang.org/x/time to v0.6.0 (#6944)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-11 11:38:32 +08:00
8032d0afb6 fix(deps): update module golang.org/x/oauth2 to v0.22.0 (#6943)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-10 21:01:41 +08:00
d3bc8993ee fix(deps): update module github.com/dlclark/regexp2 to v1.11.4 (#6958)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-10 21:01:05 +08:00
62ed169a39 feat: add support for quark tv driver and uc tv driver (#6959) 2024-08-10 21:00:43 +08:00
979d0cfeee fix(chaoxing): upload to ChaoxingxingGroupCloud failed (#6953)
change the data type on deserializing json
2024-08-10 20:59:49 +08:00
29165d8e60 feat(115): add offline download tool (close #6888 in #6954) 2024-08-10 20:59:07 +08:00
2d77db6bc2 fix(halalcloud): fix the timeout issue when logging in (#6960) 2024-08-10 20:58:10 +08:00
74f8295960 feat: persistant Task (#6925 close #5313) 2024-08-07 12:16:21 +08:00
f2727095d9 fix(thunder_browser): fix space parameter not handled correctly in some cases & update some parameters (#6952) 2024-08-06 22:14:36 +08:00
d4285b7c6c fix(halalcloud): fix some custom fields not taking effect & update appID and appSecret (#6938) 2024-08-04 19:03:24 +08:00
2e4265a778 feat: deleting folders is not allowed (close #6933) 2024-08-04 18:28:35 +08:00
81258d3e8a feat: invalidate token on logout (#6923 close #6792) 2024-08-04 12:32:39 +08:00
a6bead90d7 feat: add support for lenovonas_share driver (#6921) 2024-08-04 12:28:19 +08:00
87caaf2459 fix: out of order when database is not sqlite3 (#6560) 2024-08-03 13:11:09 +08:00
af9c6afd25 feat: update alist-org/gofakes3 to v0.0.7 to support create folder in PutObject (#6880) 2024-07-27 20:06:05 +08:00
8b5727a0aa fix(deps): update golang.org/x/exp digest to 8a7402a (#6801)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-26 14:27:56 +08:00
aeae47c9bf fix(deps): update module github.com/larksuite/oapi-sdk-go/v3 to v3.3.0 (#6812)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-25 20:13:01 +08:00
1aff758688 fix(deps): update github.com/alist-org/times digest to efa0c7d (#6840)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-25 20:11:12 +08:00
4a42bc5083 fix(lanzou): not find file page param (#6862 close #6857)
* fix(lanzou):not find file page param

* fix(labzou): change lanzouo.com to lanzoui.com
2024-07-25 20:09:48 +08:00
5fa70e4010 perf(123pan): optimize rate limiting (#6859)
- eliminating fixed 200 ms delay in getFiles to prevent thread starvation
- allowing cancellation via context to mitigate potential DoS attacks by immediately cancelling excessive requests
2024-07-25 20:08:59 +08:00
d4e3355f56 chore: duplicate import typo 2024-07-21 20:50:07 +08:00
94f257e557 fix(local): crush on android
closes #5874
closes #6567
2024-07-21 20:48:48 +08:00
e5f53d6dee chore: go mod tidy 2024-07-21 20:31:52 +08:00
cbd4bef814 fix(123pan): use local sort (close #6820) 2024-07-21 20:29:32 +08:00
2d57529e77 fix(123pan): add warning for mismatched file count when listing files (#6814)
Fixes an issue where using `file_name` order could result in incorrect file counts compared to response fields.
2024-07-20 12:27:18 +08:00
2b74999703 fix(deps): update module github.com/alist-org/gofakes3 to v0.0.6 (#6802)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: David Hao <akang943578@gmail.com>
Co-authored-by: Ke Wang <me@ke.wang>
2024-07-17 14:31:09 +08:00
fe081d0ebc chore(deps): update softprops/action-gh-release action to v2 (#6786)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-17 12:22:54 +08:00
5ef7a27be3 chore(deps): update docker/build-push-action action to v6 (#6785)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-17 12:22:35 +08:00
c9a18f4de6 chore(deps): update benjlevesque/short-sha action to v3 (#6784)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-17 12:22:17 +08:00
f2a24881d0 fix(deps): update module gorm.io/driver/postgres to v1.5.9 (#6783)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-17 12:21:54 +08:00
cee00005ab feat: add support for Onedrive Sharelink driver (#6793)
* feat: add support for Onedrive Sharelink driver

* fix(Onedrive Sharelink): use internal UA
2024-07-17 12:21:06 +08:00
049575b5a5 fix(pikpak): captcha_token not refreshing correctly (#6788) 2024-07-16 16:00:05 +08:00
a93937f80d fix(pikpak): add captcha_token generation function (#6775)
closes #6752 
closes #6760
2024-07-14 21:07:00 +08:00
488ebaa1af fix(deps): update module github.com/aws/aws-sdk-go to v1.54.19 (#6170)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-14 21:04:27 +08:00
8278d3875b fix: ignore os.ErrClosed error on repeated FileStream close operations (#6762)
Also resolves the issue where S3 PutObject returns a 500 status code.
2024-07-14 20:59:24 +08:00
736ba44031 fix(deps): update module github.com/gin-gonic/gin to v1.10.0 (#6771)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-14 20:58:55 +08:00
a6ff6a94df fix(deps): update module golang.org/x/oauth2 to v0.21.0 (#6781)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-14 20:58:41 +08:00
17f78b948a fix(deps): update module gorm.io/driver/mysql to v1.5.7 (#6782)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-14 20:58:20 +08:00
fe1040a367 chore(lark): don't use github.com/ipfs/boxo/path 2024-07-14 20:29:23 +08:00
83048e6c7c fix(deps): update module github.com/charmbracelet/lipgloss to v0.12.1 (#6768)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-14 20:22:50 +08:00
9128647970 fix(deps): update module github.com/rclone/rclone to v1.67.0 (#6780)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-14 19:41:23 +08:00
9629705100 fix(deps): update module gorm.io/gorm to v1.25.11 (#6764)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-14 19:40:46 +08:00
cd663f78af fix(deps): update module github.com/charmbracelet/bubbletea to v0.26.6 (#6766)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-14 19:36:10 +08:00
3c483ace4f fix(deps): update module gorm.io/driver/sqlite to v1.5.6 (#6763)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-14 19:09:38 +08:00
3e949fcf33 fix(deps): update module github.com/charmbracelet/bubbles to v0.18.0 (#6765)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-14 19:08:03 +08:00
81b0afc349 fix(deps): update module github.com/dlclark/regexp2 to v1.11.2 (#6769)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-14 19:07:09 +08:00
a04da3ec50 fix(deps): update module github.com/gin-contrib/cors to v1.7.2 (#6770)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-14 19:06:43 +08:00
9e0482afbb fix(deps): update module github.com/larksuite/oapi-sdk-go/v3 to v3.2.8 (#6756)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-13 19:51:32 +08:00
9de40f8976 fix(deps): update module github.com/spf13/cobra to v1.8.1 (#6757)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-13 19:50:31 +08:00
ba4df55d6e fix(deps): upgrade wopan-sdk-go (close #6663) 2024-07-13 19:49:45 +08:00
de8d2d6dc0 fix(deps): update module github.com/go-resty/resty/v2 to v2.13.1 (#6759)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-13 19:40:57 +08:00
65b423c503 fix(deps): update github.com/city404/v6-public-rpc-proto/go digest to 9a9b82a (#6753)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-13 17:42:25 +08:00
ff20b5a6fb fix(deps): update module github.com/baidubce/bce-sdk-go to v0.9.184 (#6754)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-13 17:29:05 +08:00
37d86ff55c fix(deps): update module github.com/minio/sio to v0.4.0 (#6446)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-13 17:28:25 +08:00
4e1c67617f fix(deps): update module github.com/go-webauthn/webauthn to v0.10.2 (#6310)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-13 17:28:13 +08:00
9bc2d340a2 fix(deps): update golang.org/x/exp digest to 46b0784 (#6486)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-13 17:27:49 +08:00
60fc416d8f fix(deps): update module google.golang.org/grpc to v1.64.1 [security] (#6728)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-13 17:05:55 +08:00
99c9632cdc fix(deps): update module github.com/gin-contrib/cors to v1.6.0 [security] (#6708)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-13 17:05:08 +08:00
2fb772c888 fix(deps): update module github.com/meilisearch/meilisearch-go to v0.27.0 (#6436)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-13 17:04:42 +08:00
87192ad07d fix(deps): update module github.com/blevesearch/bleve/v2 to v2.4.1 (#6542)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-13 17:04:18 +08:00
3746831384 chore(deps): update actions-cool/issues-helper action to v3.6.0 (#6513)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-13 17:03:56 +08:00
80d4fbb870 fix(deps): update module github.com/gorilla/websocket to v1.5.3 (#6653)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-13 17:03:20 +08:00
92c65b450e fix(deps): update module golang.org/x/image to v0.18.0 [security] (#6658)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-13 17:02:52 +08:00
213fc0232e fix(deps): update module github.com/sheltonzhu/115driver to v1.0.25 (#6447)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-13 17:02:31 +08:00
Mmx
33be44adad chore: update polyfill URL due to service unavailability and supply chain attack risk (#6740) 2024-07-11 18:13:22 +08:00
ca0d66bd01 fix: S3 Implementation bug & Support AWS Signature V2 (#6683)
* Fix: when S3 PutObject with objectName contains /, aliyundriveopen failed due to KeyNotFound, make dir to fix this.

(cherry picked from commit eb24f45771d29a3659e75813734b290d6306cfcf)

* Upgrade gofakes3 to v0.0.5, support AWS Signature V2

(cherry picked from commit 3218d7cf2c4e1a8c51fd2414595547fd109a89ac)

---------

Co-authored-by: David Hao <akang943578@gmail.com>
2024-07-07 16:50:40 +08:00
3a3d0adfa0 feat: add pikpak offline download function (#6648)
* add pikpak offline download function

* 完善PikPak离线下载功能

* 删除多余的代码

* add task cache to avoid too many requests about API

* 优化Status函数

* 完善所有功能,目前测试无BUG

* 减少缓存时间,优化添加离线任务的参数
2024-07-07 16:50:05 +08:00
ca30849e24 feat: add support for halalcloud driver (#6696) 2024-07-07 13:20:34 +08:00
316f3569a5 feat(thunderBrowser): add automatically generate UserAgent (#6692) 2024-07-07 13:19:19 +08:00
2705877235 fix(iLanZou): resolve resource access issue (#6673)
* fix(drivers/iLanZou): resolve resource access issue on iLanZou driver mount

The driver failed to mount due to incorrect URL parameter ordering which the backend did not accept

This commit reorders the parameters to meet the backend's expectations

and ensures successful mounting of the iLanZou driver.

Closes #6271, Closes #6415

* fix(drivers/iLanZou): Fixed the error ID number returned when creating a folder

Closes #6610, Closes #6333

---------

Co-authored-by: maye174 <96584640+maye174@users.noreply.github.com>
2024-07-02 15:30:00 +08:00
432901db5a feat(thunderx): generate UserAgent automatically (#6664) 2024-07-02 14:59:07 +08:00
227d034db8 feat(sftp): add suport for passphrase of private key (#6624 close #6592)
Co-authored-by: XZB <i@1248.ink>
2024-06-28 23:50:00 +08:00
453d7da622 docs: change outdated repository link to alist-org (#6007) 2024-06-28 23:47:21 +08:00
29fe49fb87 fix(alias): Support forced refresh of file list (#6562) 2024-06-16 16:59:10 +08:00
fcf2683112 feat(ftp): custom encoding (#6528 close #1260) 2024-06-16 16:58:02 +08:00
Mmx
3a996a1a3a build: update sqlite driver (#6599)
* build: update sqlite driver

* build: remove docker build sqlite-compatible commands
2024-06-16 16:56:45 +08:00
1b14d33b9f fix(alist_v3): use net/http for uploading (#6616 close #6613) 2024-06-16 16:55:49 +08:00
639b7817bf feat: add supports for thunder_browser driver (#6529 close #6526)
* feat: add supports for thunderX driver

* fix: Fix the bug where UserID is not passed correctly

* feat: add support for thunder_browser driver
2024-05-27 21:34:26 +08:00
163af0515f fix(pikpak): refresh_token contention (#6501 close #6511) 2024-05-27 21:31:59 +08:00
8e2b9c681a fix(ilanzou): upgrade devVersion 2024-05-23 20:05:00 +08:00
0a8d710e01 fix(mopan): upgrade version (#6500) 2024-05-23 18:56:17 +08:00
d781f7127a fix: add lark to windows target 2024-05-23 11:52:37 +08:00
85d743c5d2 feat: add support for lark driver (#6475)
* feat: lark storage driver

* feat: external view mode

* limit lark targets

* fix: missing package

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2024-05-22 23:31:58 +08:00
5f60b51cf8 feat: add proxy_range option for 139Yun Alias AList V3 (#6496) 2024-05-22 23:31:42 +08:00
7013d1b7b8 fix: pikpak captcha_required (#6497)
* fix: pikpak captcha_required

* fix(pikpak_share):  video download
2024-05-22 23:29:29 +08:00
9eec872637 feat(mega): add 2FA support (#6473)
* feat(mega): add support for two-factor authentication in Mega driver  #6226

* feat(mega): remove debug print statement in Mega driver Init function

* feat(mega): add help message for new field
2024-05-22 23:28:14 +08:00
037850bbd5 feat(alias): support Rename and Remove (#6478)
* feat(alias): support `Rename` and `Remove`

* fix(alias): `autoFlatten` not updated after editing

* feat(alias): add `protect_same_name` option
2024-05-22 09:27:48 +08:00
bbe3d4e19f feat: add supports for thunderX driver (#6464) 2024-05-21 23:24:28 +08:00
78a9676c7c feat(alist_v3): Optional pass UA to upstream remote (#6443)
* fix(115): Support 115 302 redirect while getting link under (nested) alist_v3 remote

* chore: simplify logic

* chore: simplify logic

* use internal UA

* add option to set if the user want their ua be passed to upstream
2024-05-12 17:34:36 +08:00
8bf93562eb fix(baidu): unknown type for custom upload part size (close #6435) 2024-05-09 14:54:53 +08:00
b57afd0a98 fix(sftp): reconnect to server when connection was broken (#6416 close #6403)
* fix(sftp): reconnect to server when conn was broken (close #6403)

* fix(sftp): fix typo

---------

Co-authored-by: George Chen <gchen@isimarkets.com>
2024-05-09 14:53:25 +08:00
f261ef50cc feat: add supports for netease music driver (#6423 close #5364) 2024-05-09 14:29:35 +08:00
7e7b9b9b48 feat(s3): server support generated url request (#6431) 2024-05-09 14:28:59 +08:00
2313213f59 fix(189pc): FamilyID range overflow (#6427 close #6426) 2024-05-09 14:23:12 +08:00
5f28532423 fix(test): ensure setupStorages is executed once (#6422)
In TestGetStorageVirtualFilesByPath() and TestGetBalancedStorage(), setupStorages() was being called twice, leading to a "UNIQUE constraint failed" error.
2024-05-09 14:22:19 +08:00
4cbbda8832 fix(baidu): custom upload part size (close #5757) 2024-05-02 22:30:00 +08:00
Mmx
7bf5014417 ci: cache musl library in docker build workflow (#6392)
* ci: add musl libs into action cache

* build: update Dockerfile.ci
2024-05-02 22:28:13 +08:00
b704bba444 fix(115): disable NoOverwriteUpload (#6409 close #6251)
closed #6251
2024-05-02 22:27:55 +08:00
eecea3febd fix(onedrive): fix Ctime/Mtime (#6397) 2024-05-02 22:27:31 +08:00
0e246a7b0c chore: replace link of vidhub [skip ci] 2024-04-30 14:22:26 +08:00
Mmx
b95df1d745 perf: use io copy with buffer pool (#6389)
* feat: add io methods with buffer

* chore: move io.Copy calls to utils.CopyWithBuffer
2024-04-25 20:11:15 +08:00
ec08ecdf6c fix(baidu_netdisk): cached Ctime/Mtime (#6373 close #6370)
(cherry picked from commit 23542541e4f343d484de1f83ee5c928d2ab6753c)
2024-04-25 20:08:20 +08:00
479fc6d466 fix(webdav): make sure Mtime after Ctime (#6372 close #6371)
* fix(server/webdav) make sure Mtime >= Ctime

* fix(server/webdav) avoid variable 'stream' collides with imported package name
2024-04-24 17:13:30 +08:00
32ddab9b01 feat(123_share): add access token (#6357) 2024-04-24 14:54:01 +08:00
0c9dcec9cd fix: init storages in order (#6346) 2024-04-19 17:22:16 +08:00
793a4ea6ca fix(cloudreve): add domain to the download url if not exists (#6339 close #6265)
* fix: correct the download url got by Cloudreve driver

* fix: add an condition to the correction
2024-04-12 21:45:16 +08:00
c3c5181847 feat(Seafile): add token login (#6324 close #5302) 2024-04-10 21:50:30 +08:00
Mix
cd5a8a011d fix: typo about env of Meilisearch (#6316) 2024-04-08 18:35:23 +08:00
1756036a21 fix(authn): subfolder api is considered as a wrong origin(closes #6294 in #6301) 2024-04-03 14:33:19 +08:00
58c3cb3cf6 fix(s3): don't bind s3 port if s3 is not enabled (#6291) 2024-04-03 10:09:48 +08:00
d8e190406a feat(189pc): add family transfer upload (#6288)
* feat(189pc): add family transfer upload

* fix(189):family transfer file delete
2024-04-02 16:51:02 +08:00
2880ed70ce fix: some typos (#6283)
Signed-off-by: guoguangwu <guoguangwug@gmail.com>
2024-04-02 16:50:30 +08:00
0e86036874 fix(doge): reget client after refresh session (#6277) 2024-03-29 14:56:49 +08:00
e37465e67e feat(crypt): force stream upload for supported drivers (#6270) 2024-03-29 14:42:01 +08:00
d517adde71 docs: use width instead of height for image in Readme (#6282)
* Update README.md

* Update README_cn.md

* Update README_ja.md
2024-03-29 14:40:43 +08:00
8a18f47e68 fix(doge): the temporary access key is only valid for two hours (#6273)
* feat: add doge driver

* doc: 补充readme文档

* fix: 对齐meta信息

* fix: 调整结构体名字,与driver保持一致

* perf: merge to s3

* Rename goge.go to doge.go

* fix: 解决多吉云临时秘钥两个小时过期的问题

* fix: 定时任务在Drop中Stop

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2024-03-27 14:22:26 +08:00
cf08aa3668 feat: add doge driver (#6201)
* feat: add doge driver

* doc: 补充readme文档

* fix: 对齐meta信息

* fix: 调整结构体名字,与driver保持一致

* perf: merge to s3

* Rename goge.go to doge.go

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2024-03-25 22:53:44 +08:00
9c84b6596f feat: stand-alone port s3 server (#6242)
* feat: single port s3 server

* fix: unable to PUT files if not in root dir
2024-03-24 15:16:00 +08:00
022e0ca292 fix(139): incorrect refreshTokenResp serialization (#6248) 2024-03-24 11:04:55 +08:00
88947f6676 fix(ipfs): url escape filename (#6245 close #6027)
This resolves #6027
2024-03-24 11:03:18 +08:00
Mmx
b07ddfbc13 fix(ci): replace dockerfile tag step may have no effect (#6206) 2024-03-13 15:11:21 +08:00
9a0a63d34c fix(ilanzou): add referer to request header (close #6171) 2024-03-11 20:30:22 +08:00
195c869272 feat(139): refresh token periodically (#6146)
* 139定时刷新token

* fix build fail
2024-03-11 20:10:26 +08:00
bdfc1591bd fix: webauthn logspam (#6181) 2024-03-10 16:48:25 +08:00
82222840fe fix(deps): update golang.org/x/exp digest to 814bf88 (#6144)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-09 14:58:36 +08:00
45e009a22c fix(mopan): upload error (close #6158 in #6166) 2024-03-09 14:54:49 +08:00
ac68079a76 feat(seafile): improve features, support access to encrypted library, etc (#6160) 2024-03-08 15:33:42 +08:00
2a17d0c2cd fix: settings reset to default after restart if set to empty (close #6143) 2024-03-05 16:29:26 +08:00
6f6a8e6dfc fix(deps): update github.com/t3rm1n4l/go-mega digest to d494b6a (#6081)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-04 15:12:22 +08:00
7d9ecba99c fix: add m3u8 to default video types (close #6142) 2024-03-04 14:26:00 +08:00
ae6984714d fix: remove default polyfill (#6130 close #6100)
* refactor(setting): replace `polyfill.io``

* fix: remove default polyfill

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2024-03-02 15:36:28 +08:00
d0f88bd1cb feat: s3 server support (#6088 close #5186)
Currently tested: List, Get, Remove
2024-03-02 15:35:10 +08:00
f8b1f87a5f fix: support for Microsoft WebDAV (#6133 close #6104)
* Add support for Microsoft WebDAV

* add import
2024-03-02 14:59:55 +08:00
71e4e1ab6e fix(chaoxing): json cannot unmarshal content.uploadDate (close #6119 in #6124) 2024-03-01 13:37:09 +08:00
7e6522c81e ci: build ffmpeg image with dev version 2024-02-24 18:10:45 +08:00
94a80bccfe fix(feiji): unable to get link (close #6082) 2024-02-24 18:04:08 +08:00
e66abb3f58 fix(deps): update module github.com/aws/aws-sdk-go to v1.50.24 (#5873)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-23 20:56:14 +08:00
742335f80e fix: don't push docker on pr due to security 2024-02-23 15:42:52 +08:00
f1979a8bbc feat(search): search with meilisearch (#6060)
* feat(search): search with meilisearch.

* feat(search): meilisearch supports auto update.

* chores: remove utils.Log.

* fix(search): the null pointer caused by deleting non-existing file/folder indexes.

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2024-02-23 15:37:40 +08:00
1f835502ba feat: support customize dsn for mysql and pg (#6031)
* support for unixsocket to connect to mysql

* feat: customize dsn for mysql and pg

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2024-02-23 15:28:48 +08:00
424ab2d0c0 ci: remove docker latest tag on dev 2024-02-21 15:50:05 +08:00
858ba19670 ci: also push docker to hub for pr 2024-02-21 14:58:45 +08:00
Mmx
0c7e47a76c feat: add docker image with pre-installed ffmpeg (#6054)
* build: add dockerfile for ffmpeg version

* ci: add docker image with ffmpeg release

* fix: donnot push on docker build test
2024-02-21 14:04:22 +08:00
53926d5cd0 fix(search): duplicate folder on autoupdate (#6063 close #6062)
* fix(search): the problem of not returning in time when index does not support auto update.

* fix(search): the problem of duplicate indexing of folders.
2024-02-20 19:12:07 +08:00
47f4b05517 feat(sftp): allow ignore symlink error (close #6026) 2024-02-15 18:54:19 +08:00
6d85f1b0c0 fix(123): User-Agent and rate limit (#6012)
* 修复标签

* 新增接口限流器。防止云盘云端把Alist当做攻击,封禁Alist客户端

---------

Co-authored-by: 风信子 <fengxinzi@xaidc.com>
2024-02-09 14:45:44 +08:00
e49fda3e2a fix: WebDAV's creation date should use RFC3339 format (#6015 close #5878) 2024-02-08 19:22:29 +08:00
da5e35578a fix: embed all files of dist 2024-02-03 19:44:50 +08:00
812f58ae6d fix(mopan): client version is too low (#5987)
* fix(mopan): download err ` client version is too low`

* feat(mopan):support sms login

* refactor(quqi): upload use s3
2024-02-02 21:04:43 +08:00
9bd3c87bcc fix(ldap): exiting by peer exception occurred during the TLS connection(#5977) 2024-02-01 10:43:08 +08:00
c82866975e fix: error on repeated reading static (#5957)
* Update static.go

* rm initial value of static

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2024-01-30 21:21:53 +08:00
aef952ae68 feat(dropbox): add root_namespace_id to access teams folder (#5929)
* feat(dropbox): add root_namespace_id to access teams folder

* fix(dropbox): get_current_account API request

* feat(dropbox): extract root_namespace_id properly

* style: format code
2024-01-24 17:03:50 +08:00
9222510d8d feat(quqi): add download link with cdn (#5938)
* feat(quqi): add download link by cdn

* fix(quqi): cookie error when login with phone number
2024-01-24 16:47:49 +08:00
d88b54d98a fix(quqi): empty file link for non vip user (#5926)
* fix(quqi): error returned when uploading a file that existed

* fix empty download link for no vip user

* fix cannot parse request result

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2024-01-21 15:28:52 +08:00
85a28d9822 fix(quqi): error on uploading an existing file (#5920) 2024-01-20 21:22:50 +08:00
4f7761fe2c fix: set progress to 100 when it's NaN (close #5906) 2024-01-20 13:06:46 +08:00
a8c900d09e fix(quqi): file extension duplication when rename and some missing form parameters (#5910)
* feat: add `quqi` driver

* change signature of request function

* specific header for every storage

* todo: real upload

* fix upload method

* fix incorrect parameters for some request function calls

* refine some form parameters to avoid potential problems

* fix file extension duplication in rename function

* improve the error message in login function

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2024-01-19 13:57:31 +08:00
8bccb69e8d fix(google_photo): add support for streaming video, range requests (#5905)
* Update util.go

Return mediaMetadata

* Update driver.go

Using width and height
2024-01-19 13:02:05 +08:00
0f29a811bf fix: s3 upload exceeded total allowed configured MaxUploadParts (close #5909) 2024-01-19 12:05:10 +08:00
442c2f77ea feat: add quqi driver (#5899 close #5251)
* feat: add `quqi` driver

* change signature of request function

* specific header for every storage

* todo: real upload

* fix upload method

* fix incorrect parameters for some request function calls

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2024-01-19 10:59:56 +08:00
ce06f394f1 fix: missing salt of guest user (close #5737) 2024-01-17 14:15:34 +08:00
e3e790f461 feat(115): add QR code source selection (#5891)
* feat(115): add QR code source selection

closed #5386

* feat(115_share): add QR code source selection
2024-01-16 15:59:44 +08:00
f0e8c0e886 fix(chaoxing): JSON parsing error in content field (#5877)
* fix(chaoxing):fix JSON parsing error in `content` field

* fix(chaoxing): optimizing `UnmarshalJSON` implementation

* fix(chaoxing): use `objectID` when  is empty
2024-01-14 12:53:31 +08:00
86b35ae5cf fix(deps): update module golang.org/x/oauth2 to v0.16.0 (#5865)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-12 11:54:35 +08:00
4930f85b90 fix(deps): update module golang.org/x/crypto to v0.18.0 (#5863)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-11 20:56:19 +08:00
85fe65951d fix(deps): update golang.org/x/exp digest to 0dcbfd6 (#5862)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-11 20:39:16 +08:00
1381e8fb27 fix(deps): update module github.com/aws/aws-sdk-go to v1.49.18 (#5848)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-11 20:24:20 +08:00
292bbe94ee fix(feijipan): incorrect address of download link (close #5859) 2024-01-11 10:16:14 +08:00
bb6747de4e docs: add feijipan to Readme 2024-01-11 10:15:16 +08:00
555ef0eb1a feat: add feijipan driver (close #5856) 2024-01-10 16:58:10 +08:00
bff56ffd0f ci: add android target to release build (#5844)
* build: build android

Signed-off-by: lateautumn233 <lateautumn233@foxmail.com>

* ci: add `android` target to release build

Signed-off-by: lateautumn233 <lateautumn233@foxmail.com>

---------

Signed-off-by: lateautumn233 <lateautumn233@foxmail.com>
2024-01-09 19:00:11 +08:00
34b73b94f7 feat(local): allow specifying the recycle bin path (close #5832) 2024-01-09 18:51:21 +08:00
434892f135 fix(deps): update module github.com/aliyun/aliyun-oss-go-sdk to v3 (#5800)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-09 17:14:31 +08:00
Mmx
e6e2d03ba1 perf: make docker release 10 times faster (#5803)
* build: improve multistage docker build

* build: add dockerfile for ci

* build: add BuildDockerMultiplatform function in build.sh for ci

* ci: change build method

* build: add missing mod download command to the Dockerfile

* build: revert changes made ffmpeg installed

* build: use musl build for docker release

* ci: apply to dev version

* fix: don't login on pr

* fix: don't build_docker_with_aria2 on pr

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2024-01-05 15:52:30 +08:00
28bb3f6310 fix(deps): update module golang.org/x/image to v0.15.0 (#5825)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-05 15:35:41 +08:00
fb729c1846 fix(deps): update module github.com/aws/aws-sdk-go to v1.49.15 (#5816)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-05 15:34:16 +08:00
4448e08f5b fix(net): Buf use Mutex (#5823)
Co-authored-by: Andy Hsu <i@nn.ci>
2024-01-05 12:20:08 +08:00
8020d42b10 fix: panic due to send on closed channel (close #5729) 2024-01-05 11:41:53 +08:00
9d5fb7f595 feat: add ILanzou driver (#5810 close #5715)
* wip: basic request and login

* feat: impl list

* feat: impl link

* feat: impl mkdir, move, rename, delete

* feat: impl upload

* docs: add iLanzou to readme
2024-01-04 22:03:15 +08:00
126cfe9f93 fix(vtencent): only show 50 files (close #5805) 2024-01-04 21:54:39 +08:00
fd96a7ccf4 fix(deps): update golang.org/x/exp digest to be819d1 [skip ci] (#5807)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-04 21:02:22 +08:00
03b9b9a119 chore(deps): update docker/setup-qemu-action action to v3 (#5798)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-03 14:51:54 +08:00
03dbdfc0dd chore(deps): update docker/setup-buildx-action action to v3 (#5797)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-03 14:46:37 +08:00
2683621ed7 chore(deps): update docker/metadata-action action to v5 [skip ci] (#5795)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-03 14:46:09 +08:00
be537aa49b chore(deps): update docker/login-action action to v3 [skip ci] (#5794)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-03 14:45:53 +08:00
6f742a68cf chore(deps): update docker/build-push-action action to v5 [skip ci] (#5793)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-03 14:45:32 +08:00
97a4b8321d chore(deps): update actions/upload-artifact action to v4 (#5792)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-03 14:44:59 +08:00
8c432d3339 chore(deps): update actions/checkout action to v4 (#5788)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-02 17:43:22 +08:00
ff25e51f80 chore(deps): update actions/setup-go action to v5 (#5789)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-02 17:43:08 +08:00
88831b5d5a fix(deps): update module golang.org/x/oauth2 to v0.15.0 [skip ci] (#5785)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-02 15:44:45 +08:00
b97c9173af fix(deps): update module golang.org/x/image to v0.14.0 [skip ci] (#5784)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-02 15:42:38 +08:00
207c7e05fe fix(deps): update module github.com/spf13/cobra to v1.8.0 [skip ci] (#5783)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-02 15:42:17 +08:00
7db27e6da8 fix(deps): update module golang.org/x/time to v0.5.0 [skip ci] (#5786)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-02 15:41:52 +08:00
b5cc90cb5a fix(115): support null UserAgent (#5787) 2024-01-02 15:41:32 +08:00
8a427ddc49 fix(deps): update module github.com/go-webauthn/webauthn to v0.10.0 [skip ci] (#5782)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-02 14:54:38 +08:00
c36644a172 fix(deps): update module github.com/go-resty/resty/v2 to v2.11.0 (#5781)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-02 14:27:08 +08:00
45b1ff4a24 fix(deps): update module github.com/charmbracelet/bubbles to v0.17.1 [skip ci] (#5775)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-02 14:24:56 +08:00
a4a9675616 fix(deps): update module github.com/charmbracelet/bubbletea to v0.25.0 [skip ci] (#5776)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-02 14:12:54 +08:00
8531b23382 fix(deps): update module github.com/deckarep/golang-set/v2 to v2.6.0 [skip ci] (#5778)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-02 14:12:33 +08:00
2c15349ce4 fix(deps): update module github.com/gin-contrib/cors to v1.5.0 [skip ci] (#5779)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-02 14:12:13 +08:00
5afd65b65c fix(deps): update module github.com/aliyun/aliyun-oss-go-sdk to v2.2.10+incompatible (#5447)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-01 22:19:25 +08:00
e2434029f9 fix(deps): update module github.com/maruel/natural to v1.1.1 [skip ci] (#5771)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-01 22:18:51 +08:00
bdf7abe717 fix(deps): update module github.com/aws/aws-sdk-go to v1.49.13 [skip ci] (#5774)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-01 22:18:13 +08:00
2c8d003c2e fix(deps): update module github.com/djherbis/times to v1.6.0 [skip ci] (#5422)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-01 22:17:44 +08:00
a006f57637 fix(deps): update module google.golang.org/appengine to v1.6.8 [skip ci] (#5772)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-01 21:42:43 +08:00
be5d94cd11 fix(deps): update module golang.org/x/crypto to v0.17.0 [security] (#5768)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-01 21:42:03 +08:00
977b3cf9ab fix(deps): update golang.org/x/exp digest to 02704c9 [skip ci] (#5769)
* fix: missing modified in validate regexp

* fix(deps): update golang.org/x/exp digest to 02704c9

---------

Co-authored-by: Andy Hsu <i@nn.ci>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-01 19:57:04 +08:00
182aacd309 fix(deps): update module github.com/gorilla/websocket to v1.5.1 [skip ci] (#5770)
* fix: missing modified in validate regexp

* fix(deps): update module github.com/gorilla/websocket to v1.5.1

---------

Co-authored-by: Andy Hsu <i@nn.ci>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-01 19:55:31 +08:00
57bac9e0d2 fix: some missing regexp lib modified 2024-01-01 18:44:59 +08:00
478470f609 feat!: replace regex package (close #5755) 2023-12-31 15:03:25 +08:00
6b8f35e7fa feat(alipan): replace domain (#5751 close #5747) 2023-12-31 14:29:14 +08:00
697a0ed2d3 feat: add ldap login support (#5706)
* feat: add ldap login support

* fix: ldap permission config group
2023-12-31 13:46:13 +08:00
299bfb4d7b feat(115): support 302 redirect (#5733) 2023-12-25 11:28:57 +08:00
3eca38e599 feat: add support for client-side discoverable WebAuthn login (#5722)
* Add support for client-side discoverable in begin login

Use `(*webauthn.WebAuthn).BeginDiscoverableLogin()` to handle client-side discoverable login.

* Upgrade github.com/go-webauthn/webauthn to v0.10.0

Upgrade [go-webauthn/webauthn](github.com/go-webauthn/webauthn) library to latest.

The convenient finish login function (as FinishDiscoverableLogin) for discoverable functions has been added in the v0.9.0. [^1]

---

[^1]: https://github.com/go-webauthn/webauthn/releases/tag/v0.9.0

* Add support for client-side discoverable in validating login

Use `(*webauthn.WebAuthn).FinishDiscoverableLogin()` to handle client-side discoverable login.

> **NOTE**:
- The first param `rawID` in this callback function is unnecessary to check, it's handled by the third-party webauthn library later.
- `userHandle` param is equal to the ID returned by (User).WebAuthnID() function.
2023-12-24 15:21:17 +08:00
ab216ed170 fix(onedrive): rename object in root folder (close #5468) 2023-12-17 22:58:26 +08:00
e91c42c9dc fix(alist_v3): timeout on upload (close #5465) 2023-12-17 15:45:27 +08:00
54f7b21a73 fix(123): api sign error (#5689 close #5083)
* fix:123 driver connect error

* feat: calculate sign with pure go

---------

Co-authored-by: tangminghao <tangminghao@hxzn.com>
Co-authored-by: Andy Hsu <i@nn.ci>
2023-12-17 15:21:32 +08:00
de56f926cf feat(139): support new personal cloud api (#5690)
Co-authored-by: Andy Hsu <i@nn.ci>
2023-12-16 16:56:45 +08:00
6d4ab57a0e build: enable cgo for win/arm64 [skip ci] 2023-12-15 18:22:16 +08:00
734d4b0354 ci: add darwin/arm64 target to dev build 2023-12-15 17:07:02 +08:00
74b20dedc3 fix: retry multipart file reset (#5693 close #5628) 2023-12-14 21:31:36 +08:00
83c2269330 fix(qbit): seed time doesn't take effect (close #5663) 2023-12-11 15:20:29 +08:00
296be88b5f fix: incorrect key of oidc username (close #5670) 2023-12-10 13:17:56 +08:00
026e944cbb feat: add task info to resp of add task api (close #5579) 2023-12-03 14:44:20 +08:00
8bdfc7ac8e fix(offline_download): don't wait for transfer task (close #5595) 2023-12-03 14:20:01 +08:00
e4a6b758dc docs: remove jetbrains in special sponsor [skip ci] 2023-12-03 12:57:35 +08:00
66b7fe1e1b fix: task cannot be retried manually (close #5599) 2023-11-30 20:44:05 +08:00
f475eb4401 fix: incorrect go-version on auto-lang 2023-11-30 12:37:25 +08:00
b99e709bdb fix(teambition): international upload (close #5360) 2023-11-29 22:51:03 +08:00
f4dcf4599c fix: add error handling for webdav mkcol according to RFC 4918 (#5581)
* feat: add error handling for mkcol method in webdav.go

* feat: update rfc reference

* fix: fix issue with uncorrect error handling
2023-11-27 18:53:52 +08:00
54e75d7287 feat: enabled sign_all by default 2023-11-25 20:27:23 +08:00
d142fc3449 ci: upgrade golang version 2023-11-25 16:09:38 +08:00
f23567199b chore: go mod tidy 2023-11-25 15:12:25 +08:00
1420492d81 ci: go get after replacing go mod 2023-11-25 15:11:29 +08:00
b88067ea2f ci: fix docker build error: 'pread64' undeclared here 2023-11-25 14:42:33 +08:00
d5f381ef6f chore: upgrade golang version 2023-11-25 14:22:13 +08:00
68af284dad fix: task popped but not execute (close #5565) 2023-11-25 14:15:17 +08:00
d26887d211 fix: content-type conflicts with #5420 2023-11-24 19:22:19 +08:00
3f405de6a9 feat: customize allow origins, headers and methods 2023-11-24 19:18:34 +08:00
6100647310 fix: reflected XSS vulnerability plist api 2023-11-24 16:46:48 +08:00
34746e951c feat(offline_download): add simple http tool (close #4002) 2023-11-24 16:26:05 +08:00
b6134dc515 feat: allow keep files in offline download (close #4678) 2023-11-24 15:02:36 +08:00
d455a232ef fix(vtencent): hack file with size 0 but actual size is not 0
- allow use another proxy for vtencent and chaoxing
2023-11-23 22:35:07 +08:00
fe34d30d17 feat(crypt): add show hidden option (#5554) 2023-11-23 21:50:16 +08:00
0fbb986ba9 fix(aliyundrive_open): mitigation measures for 15-minute limit (#5560 close #5547)
* fix(aliyundrive_open):Mitigation measures for AliOpen's 15-minute limit.

I conducted small-scale tests, which seem to have no significant negative impact. If the 15-minute issue still occurs, further measures will be needed. Methods like local proxy can be attempted.

* chore(aliyundrive_open): change cache of the link to 1 minute

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2023-11-23 21:49:16 +08:00
1280070438 feat: add chaoxing and vtencent driver (#5526 close #3347)
* add chaoxing and vtencent

* add vtencent put file

* add sha1 to transfer files instantly

* simplified upload file code

* setting onlyproxy

* fix get files modifyDate bug
2023-11-23 21:40:16 +08:00
d7f66138eb docs: add sponsor VidHub [skip ci] 2023-11-22 15:09:39 +08:00
b2890f05ab feat: retry all failed task (close #5242) 2023-11-21 15:54:42 +08:00
7583c4d734 feat: customize workers and retry of task (close #5493 fix #5274) 2023-11-21 15:51:57 +08:00
11a30c5044 feat: refactor task module 2023-11-20 18:01:51 +08:00
de9647a5fa chore: remove useless code 2023-11-19 20:05:09 +08:00
8d5283604c ci: add short sha to artifact 2023-11-19 15:21:25 +08:00
867accafd1 fix(local): video file thumbnails not displaying on iOS Safari (#5420)
* perf(webdav): support for cookies on webdav drive

* fix(local): video file thumbnails not displaying on iOS Safari
2023-11-18 22:36:41 +08:00
6fc6751463 feat: support using external dist files (close #5531) 2023-11-18 19:56:22 +08:00
f904596cbc chore: remove refs to deprecated io/ioutil (#5519)
Signed-off-by: guoguangwu <guoguangwu@magic-shield.com>
2023-11-16 05:16:15 -06:00
3d51845f57 feat: invalidate old token after changing the password (close #5515) 2023-11-13 15:22:42 +08:00
a7421d8fc2 fix(deps): update module github.com/aws/aws-sdk-go to v1.46.7 (#5068)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-12 15:14:27 +08:00
55a14bc271 fix(mopan): 302 Redirect (#5505 close #5502)
* fix(mopan):302 Redirect

* fix(mopan): do not forget to close the body

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2023-11-12 15:13:55 +08:00
91f51f17d0 feat(webdav): add tls_insecure_skip_verify field (close #5490) 2023-11-10 15:38:23 +08:00
4355dae491 fix: incorrect content-type of apk files (close #5385) 2023-11-06 18:20:25 +08:00
da1c7a4c23 feat: add 115_share driver (#5481 close #5384)
This update introduces the ability to mount 115 share links.
 Currently, only listing and downloading are supported. Note that login and share link are required for this feature to work.

 Close #5384
2023-11-06 16:58:57 +08:00
769281bd40 feat: refactor offline download (#5408 close #4108)
* wip: refactor offline download (#5331)

* base tool

* working: aria2

* refactor: change type of percentage to float64

* wip: adapt aria2

* wip: use items in offline_download

* wip: use tool manager

* wip: adapt qBittorrent

* chore: fix typo

* Squashed commit of the following:

commit 4fc0a77565
Author: Andy Hsu <i@nn.ci>
Date:   Fri Oct 20 21:06:25 2023 +0800

    fix(baidu_netdisk): upload file > 4GB (close #5392)

commit aaffaee2b5
Author: gmugu <94156510@qq.com>
Date:   Thu Oct 19 19:17:53 2023 +0800

    perf(webdav): support request with cookies (#5391)

commit 8ef8023c20
Author: NewbieOrange <NewbieOrange@users.noreply.github.com>
Date:   Thu Oct 19 19:17:09 2023 +0800

    fix(aliyundrive_open): upload progress for normal upload (#5398)

commit cdfbe6dcf2
Author: foxxorcat <95907542+foxxorcat@users.noreply.github.com>
Date:   Wed Oct 18 16:27:07 2023 +0800

    fix: hash gcid empty file (#5394)

commit 94d028743a
Author: Andy Hsu <i@nn.ci>
Date:   Sat Oct 14 13:17:51 2023 +0800

    ci: remove `pr-welcome` label when close issue [skip ci]

commit 7f7335435c
Author: itsHenry <2671230065@qq.com>
Date:   Sat Oct 14 13:12:46 2023 +0800

    feat(cloudreve): support thumbnail (#5373 close #5348)

    * feat(cloudreve): support thumbnail

    * chore: remove unnecessary code

commit b9e192b29c
Author: foxxorcat <95907542+foxxorcat@users.noreply.github.com>
Date:   Thu Oct 12 20:57:12 2023 +0800

    fix(115): limit request rate (#5367 close #5275)

    * fix(115):limit request rate

    * chore(115): fix unit of `limit_rate`

    ---------

    Co-authored-by: Andy Hsu <i@nn.ci>

commit 69a98eaef6
Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Date:   Wed Oct 11 22:01:55 2023 +0800

    fix(deps): update module github.com/aliyun/aliyun-oss-go-sdk to v2.2.9+incompatible (#5141)

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

commit 1ebc96a4e5
Author: Andy Hsu <i@nn.ci>
Date:   Tue Oct 10 18:32:00 2023 +0800

    fix(wopan): fatal error concurrent map writes (close #5352)

commit 66e2324cac
Author: Andy Hsu <i@nn.ci>
Date:   Tue Oct 10 18:23:11 2023 +0800

    chore(deps): upgrade dependencies

commit 7600dc28df
Author: Andy Hsu <i@nn.ci>
Date:   Tue Oct 10 18:13:58 2023 +0800

    fix(aliyundrive_open): change default api to raw server (close #5358)

commit 8ef89ad0a4
Author: foxxorcat <95907542+foxxorcat@users.noreply.github.com>
Date:   Tue Oct 10 18:08:27 2023 +0800

    fix(baidu_netdisk): hash and `error 2` (#5356)

    * fix(baidu):hash and error:2

    * fix:invalid memory address

commit 35d672217d
Author: jeffmingup <1960588251@qq.com>
Date:   Sun Oct 8 19:29:45 2023 +0800

    fix(onedrive_app): incorrect api on `_accessToken` (#5346)

commit 1a283bb272
Author: foxxorcat <95907542+foxxorcat@users.noreply.github.com>
Date:   Fri Oct 6 16:04:39 2023 +0800

    feat(google_drive): add `hash_info`, `ctime`, `thumbnail` (#5334)

commit a008f54f4d
Author: nkh0472 <67589323+nkh0472@users.noreply.github.com>
Date:   Thu Oct 5 13:10:51 2023 +0800

    docs: minor language improvements (#5329) [skip ci]

* fix: adapt update progress type

* Squashed commit of the following:

commit 65c5ec0c34
Author: itsHenry <2671230065@qq.com>
Date:   Sat Nov 4 13:35:09 2023 +0800

    feat(cloudreve): folder size count and switch (#5457 close #5395)

commit a6325967d0
Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Date:   Mon Oct 30 15:11:20 2023 +0800

    fix(deps): update module github.com/charmbracelet/lipgloss to v0.9.1 (#5234)

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

commit 4dff49470a
Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Date:   Mon Oct 30 15:10:36 2023 +0800

    fix(deps): update golang.org/x/exp digest to 7918f67 (#5366)

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

commit cc86d6f3d1
Author: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Date:   Sun Oct 29 14:45:55 2023 +0800

    fix(deps): update module golang.org/x/net to v0.17.0 [security] (#5370)

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

commit c0f9c8ebaf
Author: Andy Hsu <i@nn.ci>
Date:   Thu Oct 26 19:21:09 2023 +0800

    feat: add ignore direct link params (close #5434)
2023-11-06 16:56:55 +08:00
3bbdd4fa89 fix(115): fix driver package import and variable (#5482)
names
2023-11-06 16:53:57 +08:00
68f440abdb fix(weiyun): unmarshal overflow (#5459) 2023-11-05 22:41:14 +08:00
65c5ec0c34 feat(cloudreve): folder size count and switch (#5457 close #5395) 2023-11-04 13:35:09 +08:00
a6325967d0 fix(deps): update module github.com/charmbracelet/lipgloss to v0.9.1 (#5234)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-30 15:11:20 +08:00
4dff49470a fix(deps): update golang.org/x/exp digest to 7918f67 (#5366)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-30 15:10:36 +08:00
cc86d6f3d1 fix(deps): update module golang.org/x/net to v0.17.0 [security] (#5370)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-29 14:45:55 +08:00
c0f9c8ebaf feat: add ignore direct link params (close #5434) 2023-10-26 19:21:09 +08:00
4fc0a77565 fix(baidu_netdisk): upload file > 4GB (close #5392) 2023-10-20 21:06:25 +08:00
aaffaee2b5 perf(webdav): support request with cookies (#5391) 2023-10-19 19:17:53 +08:00
8ef8023c20 fix(aliyundrive_open): upload progress for normal upload (#5398) 2023-10-19 19:17:09 +08:00
cdfbe6dcf2 fix: hash gcid empty file (#5394) 2023-10-18 16:27:07 +08:00
94d028743a ci: remove pr-welcome label when close issue [skip ci] 2023-10-14 13:17:51 +08:00
7f7335435c feat(cloudreve): support thumbnail (#5373 close #5348)
* feat(cloudreve): support thumbnail

* chore: remove unnecessary code
2023-10-14 13:12:46 +08:00
b9e192b29c fix(115): limit request rate (#5367 close #5275)
* fix(115):limit request rate

* chore(115): fix unit of `limit_rate`

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2023-10-12 20:57:12 +08:00
69a98eaef6 fix(deps): update module github.com/aliyun/aliyun-oss-go-sdk to v2.2.9+incompatible (#5141)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-11 22:01:55 +08:00
1ebc96a4e5 fix(wopan): fatal error concurrent map writes (close #5352) 2023-10-10 18:32:00 +08:00
66e2324cac chore(deps): upgrade dependencies 2023-10-10 18:23:11 +08:00
7600dc28df fix(aliyundrive_open): change default api to raw server (close #5358) 2023-10-10 18:13:58 +08:00
8ef89ad0a4 fix(baidu_netdisk): hash and error 2 (#5356)
* fix(baidu):hash and error:2

* fix:invalid memory address
2023-10-10 18:08:27 +08:00
35d672217d fix(onedrive_app): incorrect api on _accessToken (#5346) 2023-10-08 19:29:45 +08:00
1a283bb272 feat(google_drive): add hash_info, ctime, thumbnail (#5334) 2023-10-06 16:04:39 +08:00
a008f54f4d docs: minor language improvements (#5329) [skip ci] 2023-10-05 13:10:51 +08:00
3d7f79cba8 docs: change domain of contributors image [skip ci] 2023-10-03 17:34:24 +08:00
9ff83a7950 feat: add header to meta (ref #5317) 2023-10-02 16:43:29 +08:00
e719a1a456 feat(sso): custom username key for OIDC (close #5169) 2023-10-02 14:42:40 +08:00
40a6fcbdff ci: do not stale issue with working or pr-welcome label [skip ci] 2023-10-02 14:13:11 +08:00
0fd51646f6 feat(onedrive): custom host for download link (close #5310) 2023-10-02 14:07:47 +08:00
e8958019d9 fix(115): allow use proxy directly (close #5324) 2023-10-02 14:00:13 +08:00
e1ef690784 fix(terabox): encode parameters for filemanager api (#5308) 2023-10-01 16:58:29 +08:00
4024050dd0 chore: fix typo (#5316) 2023-10-01 16:58:00 +08:00
eb918658f0 fix(deps): update module github.com/ipfs/go-ipfs-api to v0.7.0 (#5247)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-30 22:58:19 +08:00
fb13dae136 feat(crypt): optional pre-generated thumbnails (#5284) 2023-09-27 13:57:10 +08:00
6b67a36d63 fix(terabox): auto refresh JsToken (close #5277) 2023-09-25 16:38:05 +08:00
a64dd4885e fix(139): fixed time zone (close #5263) 2023-09-22 16:54:16 +08:00
0f03a747d8 ci: cancel previous workflow run 2023-09-22 16:53:07 +08:00
30977cdc6d feat: sso compatibility mode (#5260) 2023-09-22 16:45:51 +08:00
106cf720c1 fix(baidu_netdisk): retry logic in request (close #5262) 2023-09-22 16:27:44 +08:00
882112ed1c feat: add hash_info field to /fs/get (close #5259) 2023-09-22 15:20:04 +08:00
2a6ab77295 fix(115): data race in Link (#5253) 2023-09-21 13:39:07 +08:00
f0981a0c8d chore(virtual): implement the driver interface with result 2023-09-20 09:02:56 +08:00
57eea4db17 fix(deps): update module github.com/go-resty/resty/v2 to v2.8.0 (#5244)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-20 08:51:34 +08:00
234852ca61 fix(deps): update module github.com/pkg/sftp to v1.13.6 (#5041)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-19 20:02:42 +08:00
809105b67e fix(deps): update module github.com/blevesearch/bleve/v2 to v2.3.10 (#5232)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-17 15:57:29 +08:00
02e8c31506 fix(deps): update golang.org/x/exp digest to 9212866 (#5205)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-16 23:21:42 +08:00
19b39a5c04 fix(onedrive): overwrite upload big file (close #5217 in #5218)
See https://learn.microsoft.com/zh-cn/onedrive/developer/rest-api/api/driveitem_createuploadsession
2023-09-14 13:38:07 +08:00
28e2731594 fix: clear cache recursively on deleting the folder (close #5209) 2023-09-13 16:06:17 +08:00
b1a279cbcc feat(139): implement MoveResult interface (close #5130) 2023-09-13 15:56:13 +08:00
352a6a741a feat(webdav): support copy directly without task (close #5206) 2023-09-13 15:45:57 +08:00
109015567a fix(deps): update module golang.org/x/oauth2 to v0.12.0 (#5058)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-12 12:52:48 +08:00
9e0fa77ca2 feat: add 123 link driver (close #4924) 2023-09-10 16:50:10 +08:00
335b11c698 chore: implement the driver interface with obj return [skip ci] 2023-09-08 15:25:49 +08:00
8e433355e6 fix(terabox): missing JsToken field on request (close #5189) 2023-09-08 15:18:56 +08:00
3504f017b9 fix(upload): memory leak on form upload as task (close #5185) 2023-09-07 15:51:52 +08:00
cd2f8077fa chore: enable all pprof handle on debug 2023-09-07 14:56:50 +08:00
d5b68a91d2 fix(webdav): optimize HEAD request (close #5182) 2023-09-06 16:32:51 +08:00
623c7dcea5 fix(189pc): get real link after redirect 2023-09-06 16:02:28 +08:00
ecbd6d86cd fix(lanzou): sub file in share folder need pwd (#5184) 2023-09-06 14:48:12 +08:00
7200344ace feat: adapt hash feature for some drivers (#5180)
* feat(pikpak,thunder): adaptation gcid hash

* chore(weiyun): add note

* feat(baidu_netdisk): adaptation rapid

* feat(baidu_photo): adaptation hash

* feat(189pc): adaptation rapid

* feat(mopan):adaptation ctime

* feat(139):adaptation hash and ctime

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2023-09-06 14:46:35 +08:00
b313ac4daa fix(crypt): fix 139cloud hack (#5178)
(cherry picked from commit 18bf64af47e58cc69cdd2e598de9c19538a7bf78)
2023-09-06 14:12:01 +08:00
f2f312b43a fix: http response body not close on status >= 400 (close #5163) 2023-09-05 15:46:16 +08:00
6f6d20e1ba fix: force_https not take effect on noRoute (close #5167) 2023-09-05 13:05:46 +08:00
3231c3d930 perf(db): release database before exit 2023-09-05 13:04:27 +08:00
b604e21c69 feat(webdav): support http chunked request (close #5161 in #5162)
But we do not recommend not adding the content-length header when putting files
2023-09-05 13:03:29 +08:00
3c66db9845 ci: split release actions 2023-09-03 22:57:18 +08:00
f6ab1f7f61 perf(ftp): non use SIZE FTP command (close #5150) 2023-09-03 18:47:32 +08:00
8e40465e86 fix(aliyundrive_open): date format on uploading (#5151)
(cherry picked from commit 88f815979ac91caa8bc425a2ff9a18bbd8a2e736)
2023-09-03 18:12:05 +08:00
37dffd0fce feat(crypt): customize filename_encoding (#5148)
close #5109
close #5080
2023-09-03 18:06:44 +08:00
e7c0d94b44 fix: form upload when ticked As A Task (#5145) 2023-09-03 15:40:40 +08:00
8102142007 fix(deps): update github.com/orzogc/fake115uploader digest to 58f9eb7 (#5133)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-02 14:50:06 +08:00
7c6dec5d47 fix(deps): update module 115driver to v1.0.16 (close #5117 in #5120)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-01 14:31:47 +08:00
dd10c0c5d0 chore(aliyundrive_open): print resp content on refresh token (close #5129) 2023-08-31 18:43:25 +08:00
34fadecc2c fix(ftp): dead lock on Read (close #5128) 2023-08-31 15:10:47 +08:00
cb8867fcc1 fix(deps): update module github.com/google/uuid to v1.3.1 (#5066)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-30 19:30:41 +08:00
092ed06833 feat(uss): add AntiTheftChainToken field (#5115)
* feat(uss): add AntiTheftChainToken; fix link func

* feat(uss): optimize _upt generation
2023-08-30 15:16:26 +08:00
6308f1c35d fix: updateTime, createTime and HashInfo (#5111) 2023-08-29 13:31:24 +08:00
ce10c9f120 fix: temp file not close and incorrect WebPutAsTask 2023-08-28 18:18:02 +08:00
6c4736fc8f fix: allow no Last-Modified on upload api 2023-08-28 16:42:03 +08:00
b301b791c7 fix(local): set create and modified time for new file (close #4938) 2023-08-27 23:05:13 +08:00
19d34e2eb8 feat: receive lastModified from upload api 2023-08-27 23:03:09 +08:00
a3748af772 feat: misc improvements about upload/copy/hash (#5045)
general: add createTime/updateTime support in webdav and some drivers
general: add hash support in some drivers
general: cross-storage rapid-upload support
general: enhance upload to avoid local temp file if possible
general: replace readseekcloser with File interface to speed upstream operations
feat(aliyun_open): same as above
feat(crypt): add hack for 139cloud

Close #4934 
Close #4819 

baidu_netdisk needs to improve the upload code to support rapid-upload
2023-08-27 21:14:23 +08:00
9b765ef696 chore: remove README.md executable permission (close #5097 in #5100) 2023-08-27 14:35:03 +08:00
8f493cccc4 fix(mopan): parameter error (#5091) 2023-08-25 14:10:05 +08:00
31a033dff1 fix(lanzou): download cannot find data (#5088) 2023-08-24 21:56:20 +08:00
8c3337b88b fix(deps): update module golang.org/x/image to v0.11.0 (#5044)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-21 15:01:11 +08:00
7238243664 fix(deps): update module golang.org/x/crypto to v0.12.0 [skip ci] (#5043)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-21 14:43:59 +08:00
ba2b15ab24 fix(deps): update module golang.org/x/net to v0.14.0 [skip ci] (#5051)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-21 14:43:07 +08:00
28dc8822b7 fix(deps): update module github.com/u2takey/ffmpeg-go to v0.5.0 [skip ci] (#5042)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-20 13:10:01 +08:00
358c5055e9 fix(lanzou): download not find file sgin (close #5046 in #5048) 2023-08-20 13:08:57 +08:00
b6cd40e6d3 chore(deps): update actions-cool/issues-helper action to v3.5.2 [skip ci] (#5033)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-19 14:20:55 +08:00
7d96d8070d fix(deps): update github.com/winfsp/cgofuse digest to f87f5db [skip ci] (#4908)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-19 14:19:30 +08:00
d482fb5f26 fix(deps): update module github.com/aws/aws-sdk-go to v1.44.327 [skip ci] (#4395)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-19 14:18:08 +08:00
60402ce1fc fix(deps): update module github.com/deckarep/golang-set/v2 to v2.3.1 [skip ci] (#4925)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-19 14:15:22 +08:00
1e3950c847 fix: copy tasks using multi-thread downloader can't be canceled (#5028)
#4981 related
2023-08-19 14:06:59 +08:00
ed550594da fix(deps): update golang.org/x/exp digest to d852ddb (#4910)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-18 19:34:38 +08:00
3bbae29f93 feat(cloudreve): add custom user-agent (close #5020) 2023-08-17 19:41:21 +08:00
3b74f8cd9a fix(deps): update module github.com/sheltonzhu/115driver to v1.0.15 (#4926)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-17 15:33:46 +08:00
e9bdb91e01 fix: ignore salt on marshal model.User 2023-08-16 13:31:15 +08:00
1aa024ed6b feat: support webauthn login (#4945)
* feat: support webauthn login

* manually merge

* fix: clear user cache after updating authn

* decrease db size of Authn

* change authn type to text

* simplify code structure

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2023-08-14 22:54:38 +08:00
13e8d36e1a fix(aliyundrive_open): use RawStdEncoding for base64 2023-08-13 20:52:38 +08:00
5606c23768 perf(copy): use multi-thread downloader (close #5000) 2023-08-13 15:31:49 +08:00
0b675d6c02 chore(deps): bump github.com/libp2p/go-libp2p to 0.27.8 (#4978)
Bumps [github.com/libp2p/go-libp2p](https://github.com/libp2p/go-libp2p) from 0.26.3 to 0.27.8.
- [Release notes](https://github.com/libp2p/go-libp2p/releases)
- [Changelog](https://github.com/libp2p/go-libp2p/blob/master/CHANGELOG.md)
- [Commits](https://github.com/libp2p/go-libp2p/compare/v0.26.3...v0.27.8)

---
updated-dependencies:
- dependency-name: github.com/libp2p/go-libp2p
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-11 22:57:42 +08:00
c1db3a36ad feat: upload progress recovery (#4987)
* feat(189pc):upload progress recovery

* fix:some err

* feat(baidu_netdisk,baidu_photo):upload progress recovery

* feat(mopan):upload progress recovery

* feat(baidu_netdisk):custom upload api
2023-08-11 14:23:30 +08:00
c59dbb4f9e fix(local): files get deleted when copied to other storage (close #4983) 2023-08-10 16:42:09 +08:00
df6b306fce perf(drivers): fs operations and cache (#4965)
* perf(baidu_photo):multi-thread upload

* perf(baidu_netdisk):multi-thread upload and cache optimization

* fix:LimitWriter

* fix(weiyun):only one login is allowed

* feat(189pc):multi threaded upload

* feat(baidu_netdisk):multi threaded upload

* feat(baidu_photo):multi threaded upload

* feat(weiyun):multi threaded upload

* perf(aliyundriver_open):optimize upload code and optimize cache

* fix(weiyun):invalid directory ID

* fix(baidu_netdisk):modified time

* fix(baidu_netdisk,baidu_photo):upload slice error

* perf(baidu_netdisk):cancel unnecessary retries

* fix(limitWriter):must return a non-nil error if it returns n < len(p)

* fix(aliyundrive_open):Name and Filename only use one

* perf(mopan):multi-thread upload
2023-08-09 16:13:09 +08:00
9d45718e5f fix: model.Link marshal error (close #4971)
ignore unsupported filed of `model.Link`
2023-08-09 14:04:31 +08:00
b91ed7a78a fix(aliyundrive_open): retry refresh token if sub not match 2023-08-08 22:08:05 +08:00
95386d777b feat(aliyundrive_open): record token exchange 2023-08-08 20:38:13 +08:00
635809c376 feat(cmd): list all storages command (close #4960) 2023-08-08 16:15:45 +08:00
af6bb2a6aa docs: ignore network reason for bug report [skip ci] 2023-08-08 14:54:32 +08:00
a797494aa3 fix: missed update user's password 2023-08-07 18:51:54 +08:00
353dd7f796 ci: mark non-prerelease when upload assets 2023-08-07 16:23:36 +08:00
1c00d64952 feat: rehash password with a unique salt for each user 2023-08-07 15:46:19 +08:00
ff5cf3f4fa feat: allow use token to access WebDAV 2023-08-07 14:38:50 +08:00
5b6b2f427a feat(cmd): add show token command 2023-08-07 13:49:23 +08:00
7877184bee feat(baidu_netdisk): add retry to most operations (close #4863 in #4939) 2023-08-07 13:44:28 +08:00
e9cb37122e chore(cmd): change come output for admin command 2023-08-06 23:02:22 +08:00
a425392a2b feat(cmd): set or random new password for admin 2023-08-06 22:34:02 +08:00
75acbcc115 perf: sha256 for user's password (close #3552) 2023-08-06 22:09:17 +08:00
30415cefbe perf: delete user cache after cancel 2FA 2023-08-06 20:47:58 +08:00
1d06a0019f feat(search): paging and scope (close #4381 in #4930)
Co-authored-by: Andy Hsu <i@nn.ci>
2023-08-06 15:13:23 +08:00
3686075a7f ci: change auto commit user [skip ci] 2023-08-05 16:32:06 +08:00
6c1c7e5cc0 fix(wopan): missing familyID on mkdir (close #4927) 2023-08-04 22:26:56 +08:00
c4f901b201 fix: undeclared identifier kIOMainPortDefault on darwin/arm64 2023-08-04 21:23:58 +08:00
4b7acb1389 feat(ci): add multiple ARM targets prebuilt (close #4243) 2023-08-04 20:57:56 +08:00
15b7169df4 perf: multi-thread downloader, Content-Disposition (#4921)
general: enhance multi-thread downloader with cancelable context, immediately stop all stream processes when canceled;
feat(crypt): improve stream closing;
general: fix the bug of downloading files becomes previewing stream on modern browsers;

Co-authored-by: Sean He <866155+seanhe26@users.noreply.github.com>
Co-authored-by: Andy Hsu <i@nn.ci>
2023-08-04 15:29:54 +08:00
861948bcf3 revert: "ci: auto gofmt for pull request" [skip ci]
This reverts commit 8b353da0d2.
2023-08-04 13:25:23 +08:00
e5ffd39cf2 feat: add 123Pan Share driver (close #4853 in #4898)
Co-authored-by: Andy Hsu <i@nn.ci>
2023-08-03 15:01:43 +08:00
8b353da0d2 ci: auto gofmt for pull request [skip ci] 2023-08-03 14:49:22 +08:00
49bde82426 perf(189pc): empty file upload and cache optimization (#4913)
- login captcha error
- cache optimization
- upload empty file
2023-08-03 14:08:40 +08:00
3e285aaec4 feat: add weiyun support (close #4802 in #4883)
Co-authored-by: Andy Hsu <i@nn.ci>
2023-08-02 21:39:59 +08:00
355fc576b1 issue: add config to bug report template [skip ci] 2023-08-02 21:05:50 +08:00
a69d72aa20 feat(aliyundrive_open): support resource drive (close #4889) 2023-08-02 15:50:01 +08:00
e5d123c5d3 fix(deps): update module golang.org/x/image to v0.10.0 [skip ci] (#4902)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-02 15:38:10 +08:00
220eb33f88 fix(deps): update module golang.org/x/net to v0.13.0 [skip ci] (#4903)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-02 15:16:39 +08:00
5238850036 docs: sync README [skip ci] 2023-08-02 15:15:48 +08:00
81ac963567 fix(deps): update module github.com/ipfs/go-ipfs-api to v0.6.1 [skip ci] (#4882)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-02 15:01:25 +08:00
3c21a9a520 feat: Crypt driver, improve http/webdav handling (#4884)
this PR has several enhancements, fixes, and features:
- [x] Crypt: a transparent encryption driver. Anyone can easily, and safely store encrypted data on the remote storage provider.  Consider your data is safely stored in the safe, and the storage provider can only see the safe, but not your data.
  - [x] Optional: compatible with [Rclone Crypt](https://rclone.org/crypt/). More ways to manipulate the encrypted data.
  - [x] directory and filename encryption
  - [x] server-side encryption mode (server encrypts & decrypts all data, all data flows thru the server)
- [x] obfuscate sensitive information internally
- [x] introduced a server memory-cached multi-thread downloader.
  - [x] Driver: **Quark** enabled this feature, faster load in any single thread scenario. e.g. media player directly playing from the link, now it's faster.
- [x] general improvement on HTTP/WebDAV stream processing & header handling & response handling
  - [x] Driver: **Mega** driver support ranged http header
  - [x] Driver: **Quark** fix bug of not closing HTTP request to Quark server while user end has closed connection to alist

## Crypt, a transparent Encrypt/Decrypt Driver. (Rclone Crypt compatible)

e.g.  
Crypt mount path ->  /vault 
Crypt remote path -> /ali/encrypted
Aliyun mount paht -> /ali

when the user uploads a.jpg to /vault, the data will be encrypted and saved to /ali/encrypted/xxxxx. And when the user wants to access a.jpg,  it's automatically decrypted, and the user can do anything with it.
Since it's Rclone Crypt compatible, users can download /ali/encrypted/xxxxx  and decrypt it with rclone crypt tool. Or the user can mount this folder using rclone, then mount the decrypted folder in Linux...

NB.  Some breaking changes is made to make it follow global standard, e.g. processing the HTTP header properly.

close #4679 
close #4827 

Co-authored-by: Sean He <866155+seanhe26@users.noreply.github.com>
Co-authored-by: Andy Hsu <i@nn.ci>
2023-08-02 14:40:36 +08:00
1dc1dd1f07 feat(aliyundrive_open): support livp format file download (close #4890) 2023-08-01 21:50:25 +08:00
c9ea9bce81 feat(lanzou): support login with account (close #4880 in #4885) 2023-08-01 19:44:57 +08:00
9f08353d31 feat(baidu_photo): optional delete album origin file (close #4872 in #4875) 2023-07-31 18:29:45 +08:00
ce0c3626c2 ci: remove working label on issue closed 2023-07-31 16:54:00 +08:00
06f46206db fix(baidu_photo): album download (close #4603 in #4871)
Co-authored-by: Andy Hsu <i@nn.ci>
2023-07-31 16:27:16 +08:00
579f0c06af ci: delete file after decompression
fix: no space left on device
2023-07-30 18:25:52 +08:00
b12d92acc9 perf(baidu_netdisk): optimize memory allocate 2023-07-29 17:12:43 +08:00
e700ce15e5 fix: missed progress in upload task 2023-07-29 17:09:26 +08:00
7dbef7d559 chore(deps): update actions-cool/issues-helper action to v3.5.1 (#4855)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-28 16:16:42 +08:00
7e9cdd8b07 fix(aliyundrive_open): fail limit on concurrently call (#4851) 2023-07-28 15:55:39 +08:00
cee6bc6b5d fix(terabox): slice out of range (close #4858 in #4860) 2023-07-28 15:52:20 +08:00
cfd23c05b4 fix(139): upload empty file (close #4711) 2023-07-27 19:26:22 +08:00
0c1acd72ca fix: link cache not deleted after overwriting file (close #4852) 2023-07-27 19:07:53 +08:00
e2ca06dcca docs: update go version 2023-07-27 18:32:33 +08:00
0828fd787d chore: update placeholder of version in bug_report issue template 2023-07-27 18:31:16 +08:00
2e23ea68d4 fix(aliyundrive_open): increase limit interval (close #4851) 2023-07-27 18:26:11 +08:00
4afa822bec fix(123): Use APP-side API (close #4834 in #4856) 2023-07-27 15:51:59 +08:00
f2ca9b40db fix(qbittorrent): incorrect field type (close #4843) 2023-07-25 13:31:41 +08:00
4c2535cb22 fix(115): user-agent lost on upload (close #4831) 2023-07-23 15:18:33 +08:00
d4ea8787c9 fix(123): upload file size that less than 16 MB (close #4816) 2023-07-21 14:35:18 +08:00
a4de04528a fix(123): auth-key verification (close #4811 in #4814)
Co-authored-by: Andy Hsu <i@nn.ci>
2023-07-21 14:33:45 +08:00
f60aae7499 chore(deps): update actions-cool/issues-helper action to v3.5.0 (#4801)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-21 13:55:16 +08:00
de8f9e9eee feat: SSO auto register (close #4692 in #4795)
Co-authored-by: Andy Hsu <i@nn.ci>
2023-07-20 16:30:30 +08:00
cace9db12f docs: add Japanese README [skip ci] (#4798) 2023-07-19 14:05:41 +08:00
ec2fb82836 chore: update special sponsors [skip ci] 2023-07-18 15:26:03 +08:00
afcfbf02ea chore: go mod tidy 2023-07-16 15:12:38 +08:00
cad04e07dd fix(deps): update module github.com/blevesearch/bleve/v2 to v2.3.9 [skip ci] (#4750)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-16 15:06:49 +08:00
30f732138c fix(deps): update module github.com/sirupsen/logrus to v1.9.3 [skip ci] (#4668)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-16 15:06:16 +08:00
04034bd03b fix(deps): update module github.com/jlaffaye/ftp to v0.2.0 [skip ci] (#4455)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-16 15:05:46 +08:00
6ec9a8d4c7 fix(aliyundrive_open): the temp file is not delete (close #4777) 2023-07-16 15:01:22 +08:00
3f7882b467 feat(aliyundrive_open): rapid upload (close #4766) 2023-07-15 19:33:46 +08:00
a4511c1963 refactor: change hash function 2023-07-15 16:29:44 +08:00
9d1f122717 fix(local): thumbnail rotated if exist orientation tag (close #4749) 2023-07-15 14:31:03 +08:00
5dd73d80d8 fix(123): remove stream upload method (close #4772) 2023-07-14 19:12:18 +08:00
fce872bc1b feat(123): thumbnail support (#3953) 2023-07-14 14:43:40 +08:00
df6c4c80c2 fix(123): update app-version (close #4758) 2023-07-14 14:17:29 +08:00
d2ff040cf8 feat(s3): add SessionToken field (close #4761) 2023-07-13 15:58:19 +08:00
a31af209cc fix(pikpak): hash calculation and fast upload judgment (#4745 fix #1081) 2023-07-11 22:19:21 +08:00
3f8b3da52b feat(server): add HEAD method support (close #4740) 2023-07-11 13:47:49 +08:00
6887f14ec6 feat(pikpak): allow disable media link (close #4735) 2023-07-11 13:40:58 +08:00
3e0de5eaac fix(deps): adapt module github.com/caarlos0/env/v9 (#4728) 2023-07-10 22:06:50 +08:00
61101a60f4 fix(s3): unable to copy empty folder (close #4620) 2023-07-10 14:55:19 +08:00
3529023bf9 fix(mopan): size field type(close #4734 in #4736) 2023-07-10 14:25:27 +08:00
d1d1a089a4 fix(deps): update module github.com/caarlos0/env/v7 to v9 (#4728)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-09 18:15:04 +08:00
fa66358b1e fix(sftp): read target obj of symlink file (close #4713) 2023-07-09 14:42:57 +08:00
2b533e4b91 feat: allow customize perm of unix file (close #4709) 2023-07-08 20:17:05 +08:00
d3530a8d80 fix(deps): update module golang.org/x/image to v0.9.0 (#4725)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-08 19:21:15 +08:00
6052eb3512 fix(deps): update module golang.org/x/oauth2 to v0.10.0 (#4522)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-08 15:44:42 +08:00
d17f7f7cad fix(123): judge status on get redirect_url (close #4718) 2023-07-07 19:55:37 +08:00
8bdc67ec3d fix(webdav): return 404 if error happened on handlePropfind 2023-07-05 13:52:21 +08:00
4fabc27366 fix(aliyundrive_open): panic if driver not init 2023-07-05 13:51:46 +08:00
e4c7b0f17c fix: https port is not effective 2023-07-05 13:02:52 +08:00
5e8bfb017e fix(123): add Referer to request (close #4631) 2023-07-04 18:36:46 +08:00
7d20a01dba feat!: support listen to the unix (close #4671)
Starting from this commit, the HTTP server related config all move to the scheme
2023-07-04 17:56:02 +08:00
59dbf4496f feat(offline_download): try to init client if not ready (close #4674) 2023-07-03 22:57:42 +08:00
12f40608e6 fix(oidc): use TOTP as state verification to replace the static 'state' parameter (#4665) 2023-07-03 22:41:08 +08:00
89832c296f fix: judge can proxy with ext (close #4688) 2023-07-03 20:41:37 +08:00
f09bb88846 fix(thunder): upload issues (close #4663 in #4667) 2023-06-29 13:21:30 +08:00
c518f59528 feat: add MoPan driver (close #4325 in #4659)
Co-authored-by: Andy Hsu <i@nn.ci>
2023-06-28 14:53:43 +08:00
e9c74f9959 fix: regexp rename error (close #4644 in #4653)
Co-authored-by: Andy Hsu <i@nn.ci>
2023-06-26 15:15:57 +08:00
21b8e7f6e5 fix(aliyundrive_share): add limit rate and lift rate limit restrictions (#4587) 2023-06-26 14:49:21 +08:00
2ae9cd8634 fix(dropbox): failed get link in #4639
close cfee536b96 (commitcomment-119404554)
2023-06-25 17:07:31 +08:00
cfee536b96 feat: add Dropbox driver (#4639 close #4590)
Co-authored-by: Andy Hsu <i@nn.ci>
2023-06-23 17:36:40 +08:00
1c8fe3b24c fix(aliyundrive_open): adaptive part size adjustment (#4609)
Co-authored-by: Andy Hsu <i@nn.ci>
2023-06-23 14:25:30 +08:00
84e23c397d fix(baidu_netdisk): rollback #3652 (close #4628) 2023-06-21 18:37:25 +08:00
f7baec2e65 feat: add WoPan driver (close #4541) 2023-06-17 20:20:00 +08:00
378bab32f1 chore(aliyundrive_share): increase the limit of the list api (#4588) 2023-06-17 20:10:34 +08:00
6cd8151cad fix(aliyundrive_open): change default oauth_token_url 2023-06-16 15:03:27 +08:00
541449e10f docs: add special sponsor [skip ci] 2023-06-14 05:42:21 +08:00
ca5a53fc24 fix(aliyundrive_open): openFile/list rate limit 2023-06-11 18:18:09 +08:00
f646d2a699 feat!: listen to both http & https (#4536)
Co-authored-by: Andy Hsu <i@nn.ci>
2023-06-11 18:17:37 +08:00
363e036bf0 chore: fix typo [skip ci] 2023-06-10 22:25:35 +08:00
e23f00f349 fix(139): avoid panic due to Authorization for emptiness 2023-06-10 00:12:04 +08:00
9600267bda ci: add linux-musl-amd64/arm64 to dev build 2023-06-09 23:43:52 +08:00
a66b0e0151 feat(139): auto extract account from Authorization 2023-06-09 23:41:41 +08:00
3bfa00d5d2 fix(189pc): add REQID header 2023-06-09 23:33:12 +08:00
6cbd2532cc fix(139): modify the authentication mode 2023-06-09 23:02:02 +08:00
47976af0d3 feat: set ProxyFromEnvironment for default http client (#4546) 2023-06-09 22:08:54 +08:00
4dca52be85 fix(s3): optional add filename to disposition (close #4538) 2023-06-06 22:47:27 +08:00
62bb09300d chore: fix typo [skip ci] 2023-06-06 19:34:10 +08:00
f9e067abec feat: support delayed start (#4532) 2023-06-05 16:00:31 +08:00
1e62666406 feat(baidu_netdisk): allow custom crack ua 2023-06-04 15:57:41 +08:00
0e0cdf15ef chore: change daysUntilClose [skip ci] 2023-06-03 21:15:52 +08:00
b124fdc092 perf(baidu): avoid refreshing the token on every startup 2023-06-02 18:31:42 +08:00
5141b3c165 fix(deps): update module github.com/gin-gonic/gin to v1.9.1 [security] [skip ci] (#4521)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-02 18:31:14 +08:00
881d6e271e feat: add OIDC single sign-on (#4496)
close #3914
close #4315
2023-06-02 18:22:07 +08:00
bd2418c438 feat(deps): update alpine to 3.18 2023-05-28 19:30:42 +08:00
8421c72c5c fix(seafile): driver panic while downloading or uploading file (#4491)
Co-authored-by: Andy Hsu <i@nn.ci>
2023-05-28 16:45:46 +08:00
a80e21997c feat(cloudreve): auto remove trailing slash in address (#4492)
Co-authored-by: Andy Hsu <i@nn.ci>
2023-05-28 16:18:09 +08:00
4369cbbac3 fix(alist_v3): missed Content-Length on upload (close #4457) 2023-05-27 20:23:36 +08:00
89f76d7899 feat: add UC driver (close #1127 in #4459)
Co-authored-by: lj98568 <lj98568@alibaba-inc.com>
Co-authored-by: Andy Hsu <i@nn.ci>
2023-05-27 19:36:14 +08:00
ef68f84787 fix(baidu_photo): legal album title check (close #4479 in #4487) 2023-05-27 17:07:57 +08:00
2c1f70fbe9 fix(189pc): large file upload error (close #4417 in #4438) 2023-05-27 14:28:58 +08:00
b2f5757f8d fix(copy): copy from driver that return writer (close #4291) 2023-05-26 21:57:43 +08:00
6b97b4eb20 feat(s3): set content type from stream when uploading (#4460)
Co-authored-by: guopeilun <guopl@flatincbr.com>
2023-05-24 18:02:49 +08:00
645c10c11f fix(deps): update module github.com/sirupsen/logrus to v1.9.2 (#4402)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-20 22:15:32 +08:00
571bcf07b0 fix(alias): add api prefix for proxy url (close #4392) 2023-05-19 00:12:57 +08:00
63de65be45 fix: increase timeout for http_client (close #4409) 2023-05-18 23:32:05 +08:00
a3446720a2 fix: make TlsInsecureSkipVerify enable for all request (#4386) 2023-05-14 17:05:47 +08:00
3c4c2ad4e0 feat(teambition): support s3 upload method (close #4365) 2023-05-13 23:06:25 +08:00
077a525961 fix(189): adapt new login method (close #4378) 2023-05-13 17:28:40 +08:00
5be79eb26e feat: add robots.txt setting (close #4303) 2023-05-12 16:53:15 +08:00
ddc19ab699 fix(deps): update module github.com/blevesearch/bleve/v2 to v2.3.8 [skip ci] (#4322)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-12 16:34:25 +08:00
ddfca5a29b fix(deps): update module github.com/aws/aws-sdk-go to v1.44.262 (#3285)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-12 16:25:30 +08:00
c19166be1c feat(google_drive): support sa (close #3132 in #4360)
Co-authored-by: Andy Hsu <i@nn.ci>
2023-05-12 14:47:50 +08:00
daad61443c feat(local): support thumbnail cache (close #4216) 2023-05-11 19:57:24 +08:00
4b0c01158d fix: panic on nil pointer 2023-05-11 19:44:44 +08:00
f97f1d532e fix(webdav): don't retry for put if body isn't seeker (close #4149 close #4238) 2023-05-11 18:57:35 +08:00
e15755fef0 fix(189): enable TlsInsecureSkipVerify (close #4355) 2023-05-11 18:48:31 +08:00
ea88998325 docs: add help message for mount path (#4364)
Co-authored-by: Andy Hsu <i@nn.ci>
2023-05-11 18:40:56 +08:00
74d971aa8a docs: fix git address [skip ci] (#4366) 2023-05-11 15:05:33 +08:00
d41d868a8d fix(baidu_photo): change folder name length limit (close #4351 in #4353)
Co-authored-by: Andy Hsu <i@nn.ci>
2023-05-09 20:44:57 +08:00
555cc26cbf fix(deps): update module golang.org/x/crypto to v0.9.0 (#4350)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-09 20:28:52 +08:00
ab4215080b fix(deps): update module golang.org/x/net to v0.10.0 (#4347)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-09 16:31:17 +08:00
9502f5acd7 fix(cloudreve): skip init login when using cookie (#4341) 2023-05-08 19:25:36 +08:00
b03879403f feat(cloudreve): support use cookie to login (close #4324 in #4339)
Co-authored-by: Andy Hsu <i@nn.ci>
2023-05-08 15:19:51 +08:00
ee4ac81677 fix(webdav): can't rename on infini-cloud (close #4333) 2023-05-08 14:21:12 +08:00
b69fc8c306 ci: increase daysUntilClose to avoid use stale-bot [skip ci] 2023-05-07 21:07:31 +08:00
ee6c31332d feat(drivers): ipfs api (#4265)
Co-authored-by: Andy Hsu <i@nn.ci>
2023-05-05 17:42:22 +08:00
9fa16bd5fc ci: use github helper to close stale issue 2023-05-05 16:29:59 +08:00
c77ed5fcb0 feat(aliyundrive_open): limit rate for List and Link (close #4290) 2023-05-02 22:06:03 +08:00
822be17fb9 feat(aliyundrive_open): add expiration for link (close #4061) 2023-05-02 16:12:40 +08:00
7e3b13ea2d fix: fs/list interface conversion from copy alias (close #4279) 2023-05-01 15:45:45 +08:00
f8fb48fb32 fix: cannot connect to Casdoor SSO (close #4266 in #4274) 2023-05-01 15:32:34 +08:00
4bf46268da feat(alias): support thumbnail (close #4256) 2023-04-28 00:17:15 +08:00
b7ea73b3c2 fix(aliyundrive_open): can't refresh token if access_token is empty (#4255) 2023-04-28 00:01:47 +08:00
9fbc54314d chore(aliyundrive_open): change base url 2023-04-27 16:38:40 +08:00
cf8ab29a17 feat: optional allow be mounted (close #4218) 2023-04-27 16:33:01 +08:00
51cadd2d49 fix: ignore handle in json (close #4251 close #4252) 2023-04-27 15:39:32 +08:00
2bae8e129e feat: add Casdoor single sign-on (#4222) 2023-04-26 16:01:40 +08:00
9d55ad3af6 fix(123): get download url (close #4244) 2023-04-26 15:06:24 +08:00
36cd504783 fix(alist_v3): missed meta_password update
fix: adb0739dfe (commitcomment-110328033)
2023-04-24 20:56:46 +08:00
49f13b9b90 fix(baidu_photo): upload file has web prefix (close #4233 in #4235) 2023-04-24 19:13:33 +08:00
adb0739dfe feat!(alist_v3): support username & password login (close #4226)
Breaking changes:
- rename access_token to token
- rename old password to meta_password
2023-04-23 17:48:26 +08:00
340cb940e3 fix(qbittorrent): set autoTMM (#4217) 2023-04-22 13:33:54 +08:00
8711f2a1c5 feat(quark): shard request file (close #4175) 2023-04-17 15:33:38 +08:00
7f35aab071 revert(quark): remove preset range header 2023-04-17 14:39:21 +08:00
ecd167d2f9 feat(quark): add preset range header (close #4166) 2023-04-16 19:26:03 +08:00
220fd30830 fix: the recursive subdirectory moving bug (#4171) 2023-04-16 16:08:12 +08:00
5cba10446e fix(123): adapt new upload method (close #4141) 2023-04-14 15:48:39 +08:00
a9bdb15205 ci: fix golang version in auto_lang [skip ci] 2023-04-14 13:49:13 +08:00
c5f6a90f54 fix(quark): download file size limit (close #4140) 2023-04-14 13:47:05 +08:00
46f9aefb04 feat: empty folder clear API [ckip ci] (#4132)
* 增加清理空文件夹API

* 修复嵌套文件夹删除Bug

 Author:    varg247 <varg247@gmail.com>

---------

Co-authored-by: varg247 <varg247@qq.com>
2023-04-13 15:39:21 +08:00
fdcad9c154 fix(123): incorrect endpoint (close #4046) 2023-04-12 23:04:12 +08:00
027025361a ci: fixed version of alpine 2023-04-12 16:01:49 +08:00
f1245153b9 chore(deps): upgrade to go@1.20 2023-04-12 15:42:27 +08:00
570b8be022 fix(onedrive): error check in upBig 2023-04-11 22:52:42 +08:00
86a773674a feat(task): print stack trace if panic 2023-04-11 15:16:57 +08:00
75fd0ee185 feat(s3): optional remove bucket name from path (close #4069) 2023-04-09 19:25:52 +08:00
cc43238bd1 fix(alias): disable log completely (#4054) 2023-04-09 15:46:26 +08:00
c0a6beecea fix(alias): panic on nil pointer (close #4093) 2023-04-09 14:06:04 +08:00
c77eebb035 fix(deps): update module golang.org/x/image to v0.7.0 (#4065)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-08 21:51:51 +08:00
b1efb86b28 fix(deps): update module golang.org/x/net to v0.9.0 [skip ci] (#4066)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-08 21:20:19 +08:00
0707449c8f fix(deps): update module golang.org/x/crypto to v0.8.0 [skip ci] (#4076)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-08 21:18:39 +08:00
0f8a84f67e perf(alias): disabled log on fs call (close #4054) 2023-04-07 00:02:07 +08:00
a475783b00 fix(deps): update module github.com/spf13/cobra to v1.7.0 [skip ci] (#4041)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-06 21:41:41 +08:00
67413015e8 ci: use non-upx prebuilt for windows by default 2023-04-06 21:38:57 +08:00
3a311a47af fix(deps): update module github.com/upyun/go-sdk/v3 to v3.0.4 (#4039)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-04 17:10:31 +08:00
9ccd802126 fix(123): api prefix changed (close #4038) 2023-04-04 16:39:56 +08:00
0acba7cd22 perf(123): reduce login count 2023-04-03 11:24:29 +08:00
3cdb8e7a81 fix(trainbit): incorrect filename display (#4027) 2023-04-02 21:13:20 +08:00
d3efee2ea1 fix(s3): increase PartSize if filesize > 50000MB (close #4017) 2023-04-02 16:09:27 +08:00
4ec274e748 fix(aliyundrive_open): refresh upload url if expired (#3999 close #3823)
* fix(aliyundrive_open): refresh upload url for large files

* fix(aliyundrive_open): retry upload on url expiry

* fix(aliyundrive_open): ignore 409 error

* feat(aliyundrive): cleanup upload retry logic

* feat(util): add multireadable io utility

* feat(aliyundrive_open): make upload fully stream

* feat(aliyundrive_open): refresh upload url every 20 puts

* fix(aliyundrive_open): part info panic

* chore: change refresh upload url strategy

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2023-04-01 14:54:29 +08:00
3b07c72f88 fix(proxy): ignore Referer if got redirect (close #3996) 2023-03-31 20:29:55 +08:00
0c5820a98f docs(aliyundrive_open): revised the sentence that may cause ambiguity (#3989) 2023-03-29 20:26:21 +08:00
86beadc0ed fix: missed sign with enable sign_all (close #3957) 2023-03-26 16:19:01 +08:00
be62d64dba chore: cancel 2fa succeed tips 2023-03-25 18:36:13 +08:00
112363031a feat: add fine-grained control for link signing (#3924)
* Determine whether the URL requires Sign

* Add File and Mem based KV

NOT TESTED: TokenKV Function

* Change Token KV func to common func.

Add File based KV func

* Remove KV, Remove Token

I found that the original Sign function is enough to complete the link signature, and only need to add simple configuration items to meet the requirements.

* Add IsStorageSigned func to judge if Signing is enabled in the storage settings.

It should be working now.

* Add a SIGN button to the management panel.

* Add enable_sign to the basic storage struct.

Can enable sign for every driver now.

Bug: When sign enabled, in download page, Copy link doesn't contain a sign.

(Not done yet)

* Fix a bug from commit 8f6c25f.

Response of fsread function does not contain sign.

* Optimize code and follow advices.

- Add back public/dist/README.md

- Enable sign when DownProxyUrl is enabled

- Merge needSign() to isEncrypt() in fsread.go

* simplify code

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2023-03-24 22:44:33 +08:00
48dc3552a6 fix(url_tree): incorrect tree structure 2023-03-24 20:34:03 +08:00
663814c9ef fix(url_tree): fix test url [skip ci] (#3940) 2023-03-24 20:26:00 +08:00
bd892e6a63 feat(drivers): new driver UrlTree (close #3268 in #3933)
* feat(drivers): new driver `urls` (close #3268)

* chore: rename

* support customize basic info or get from url

* dfs tree to calculate folder size

* go mod tidy

* add help message
2023-03-24 15:13:54 +08:00
4fd2c09845 fix(115): download issue due to ua (close #3931 in #3932) 2023-03-23 22:57:44 +08:00
0eab31bdf5 fix(local): filename with whitespace issue (#3928)
* fix(local): filename whitespace problem

* fix(deps): remove deprecated package io/ioutil

---------

Co-authored-by: XZB <i@1248.ink>
2023-03-23 15:18:37 +08:00
c6af22b97e feat: add thumbnail to fs/get api (#3927) 2023-03-23 13:59:39 +08:00
b2a5110672 feat(onedrive): support application authorization method (#3906) 2023-03-23 13:26:03 +08:00
c628992ea6 ci: add log required on question label [skip ci] 2023-03-22 14:03:04 +08:00
c65d868e09 fix(baidu_share): large file download (#3887 close #3876)
* fix(baidushare): large file download

* refactor: optimize client
2023-03-20 17:46:15 +08:00
aeb48b2ecc perf(aliyundrive_open): don't refresh token on init if token valid 2023-03-20 15:00:02 +08:00
cefec1a663 style: sort imports 2023-03-20 14:59:01 +08:00
e7ad830aa8 fix(cloudreve): captcha code ocr (#3889 close #3662) 2023-03-19 20:30:39 +08:00
b27eed265a fix(deps): update module github.com/blevesearch/bleve/v2 to v2.3.7 [skip ci] (#3874)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-19 20:26:48 +08:00
3abe26473c fix(trainbit): decode html code (#3883) 2023-03-19 15:25:06 +08:00
023107226c fix(trainbit): remove unnecessary operation (#3881) 2023-03-18 13:52:36 +08:00
8b109cfe40 fix(smb): byte alignment (close #3868) 2023-03-17 16:32:34 +08:00
b48e97d406 chore: fix release name [skip ci] 2023-03-16 22:47:01 +08:00
6c91cfeb90 chore(deps): update actions/setup-go action to v4 (#3858)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-16 18:28:51 +08:00
bfd1f25972 fix(deps): update module github.com/deckarep/golang-set/v2 to v2.3.0 [skip ci] (#3852)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-16 15:58:02 +08:00
8c0defce09 feat(task): add clear succeeded and retry (#3856 close #3776) 2023-03-16 15:56:27 +08:00
a1e88cfa05 fix(teambition): empty token for upload (close #3854) 2023-03-15 14:56:41 +08:00
443f5ffbcc feat(alias): auto flatten if only one root 2023-03-14 20:25:52 +08:00
b8bc94306d fix(alias): check obj exist for every storage (fix d9795ff) 2023-03-14 20:11:25 +08:00
d9795ff22f feat(alias): support proxy and direct together 2023-03-14 13:46:27 +08:00
c4108007cd fix: spaces in filename will be replaced with plus sign (#3841)
Co-authored-by: XZB <i@1248.ink>
2023-03-14 12:27:42 +08:00
f3db23a41e feat(qbittorrent): add offline download seed time (#3842 close #3588) 2023-03-14 12:13:23 +08:00
4741a75c92 feat(115): update upload api to v4.0 add pagesize option (#3840 close #3753) 2023-03-13 20:02:52 +08:00
301756ba03 feat(drivers): alias a new storage with multi path (close #3248) 2023-03-13 15:35:37 +08:00
3b2703a5e5 feat(drivers): add the support for Trainbit (#3813)
* feat: add the support for Trainbit
read only

* feat: add the support for Trainbit
modify the structure of code
allow to create folder, move, rename and remove

* feat: add the support for Trainbit
allow to upload file

* feat: add the support for Trainbit
get token from page

* feat: add the support for Trainbit
display progress of updating

* feat: add the support for Trainbit
fix bug of time zone

* feat: add the support for Trainbit
fix the bug of filename
2023-03-12 22:18:55 +08:00
2a601f06cb feat(drivers): add BaiduYun share link support (#3801)
新增百度网盘分享链接挂载
2023-03-12 14:00:11 +08:00
adc3a56552 feat(aliyundrive): make checksum cancellable (#3814) 2023-03-12 13:59:40 +08:00
4d9a29bddd feat(ftp): support seek/range request (#3811) 2023-03-11 21:02:47 +08:00
666e02f0c3 fix(storage): explicitly set storages' status to disabled (#3810) 2023-03-11 20:45:35 +08:00
6aaec19c1c feat: allow override startup command for Docker image (#3800)
This is to enable the use case where the stock Docker image is used with
different flags. E.g. `docker run xhofe/alist:latest ./alist server --data=mydata`

This was the behavior until PR#2818 changed it. This would make the image more usable.
2023-03-11 15:33:59 +08:00
1091e1b740 feat: file aggregation and regular rename api (#3788)
* 增加文件聚合接口,将给定文件夹下所有文件移动到目标文件夹。

* 增加文件正则重命名接口。

---------

Co-authored-by: varg247 <varg247@qq.com>
2023-03-10 19:01:49 +08:00
d06c605421 fix: smb drive lastConnTime data race (#3787 close #3782) 2023-03-10 15:59:53 +08:00
43de823058 fix: path IsApply check (close #3784) 2023-03-09 21:03:56 +08:00
02d0aef611 feat(aliyundrive_open): add internal upload (aliyun ECS for Beijing area only) (#3775) 2023-03-09 20:48:30 +08:00
5596661ce8 feat(aliyundrive_open): optional delete file directly (close #3769) 2023-03-08 19:19:13 +08:00
2379cb8d67 style: go mod tidy 2023-03-08 19:08:11 +08:00
8c0ebe0841 revert: "fix(deps): update module gorm.io/gorm to v1.24.6 (#3684)" (close #3746)
This reverts commit c595fd7f94.
2023-03-08 19:07:04 +08:00
fd868bac84 fix(deps): update module github.com/caarlos0/env/v7 to v7.1.0 (#3763)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-08 16:21:43 +08:00
ebcbb29a0f feat: ping api (close #3752) 2023-03-07 19:05:52 +08:00
00ff0a43a7 feat(cmd): disable a storage with specific mountPath (close #3564) 2023-03-07 19:01:40 +08:00
3d3f23ec9e fix: upload check if disable sub folder (close #3741) 2023-03-07 14:13:39 +08:00
d484219c48 fix(security): compare auth token in constant time (#3740 close #3739) 2023-03-06 23:41:06 +08:00
dd4c97393e feat: show sso settings at a more reasonable sort (#3735) 2023-03-06 20:59:45 +08:00
07b8ff25a7 ci: auto release desktop 2023-03-06 18:05:57 +08:00
0d5c3c5080 fix(deps): update module github.com/deckarep/golang-set/v2 to v2.2.0 [skip ci] (#3727)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-06 17:54:17 +08:00
75b4429f73 feat(quark): enable NoOverwriteUpload (#3720) 2023-03-05 18:00:00 +08:00
34ef6bd18d feat(115): enable NoOverwriteUpload [skip ci] (close #3669) 2023-03-05 17:59:19 +08:00
c915313ec9 feat: rename then delete if storage doesn't support overwrite upload (close #3643) 2023-03-05 15:36:12 +08:00
12a095a1d6 fix: slice bounds out of range on CanAccess check 2023-03-05 15:29:53 +08:00
dc000f640a feat: optional log to std 2023-03-05 15:07:06 +08:00
aa1c5b2be3 fix(deps): update module golang.org/x/crypto to v0.7.0 [skip ci] (#3717)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-05 14:32:41 +08:00
1d4ec3c50d fix(deps): update module golang.org/x/net to v0.8.0 [skip ci] (#3715)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-05 14:32:26 +08:00
ebfeef52f4 fix(deps): update module golang.org/x/image to v0.6.0 [skip ci] (#3714)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-05 13:52:53 +08:00
c595fd7f94 fix(deps): update module gorm.io/gorm to v1.24.6 (#3684)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-02 19:15:50 +08:00
421052f88a fix(deps): update github.com/t3rm1n4l/go-mega digest to a01a2cd (#3665)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-02 19:03:38 +08:00
603681fbe6 feat: rebuild Single sign-on system (#3649 close #3571)
* rebuild single sign on system

* perf: use cache

* fix: codefactor check

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2023-03-02 17:55:33 +08:00
f442185aa5 perf(123): optimize login error 2023-02-28 21:17:15 +08:00
ca9e739465 fix: hide apply to sub path without enable (close #3661) 2023-02-28 18:43:52 +08:00
53a1c4283b fix(baidu_netdisk): maybe optimize crack api (#3652)
User-Agent to netdisk and remove origin=dlna(is baned)
2023-02-28 18:27:07 +08:00
93dd768234 fix(webdav): disabled is not working in webdav (#3659)
A disabled user with webdav permission can use webdav normally, which is not allowed.
2023-02-28 18:26:13 +08:00
c9c4d6bc7e fix!(local): perm on mkdir (close #3626) 2023-02-26 21:25:32 +08:00
81e10f8939 ci: set prerelease before the build completes 2023-02-25 18:06:35 +08:00
4dd753de52 fix(aliyundrive_open): missed expire_sec while get link (close #3610) 2023-02-25 17:54:36 +08:00
79df63d319 chore(aliyundrive): change alert info 2023-02-25 14:28:27 +08:00
ec54831162 fix: only refresh token while do request (close #3591) 2023-02-24 20:31:12 +08:00
c8f3e8ab4d feat!: skip tls insecure verify by default 2023-02-23 22:33:54 +08:00
4be8524d80 feat: add alert for driver 2023-02-23 22:03:11 +08:00
0d3146b51d fix(webdav): disable put with empty path (close #3569) 2023-02-23 21:19:50 +08:00
f95d843969 feat(aliyundrive): add url_expire_sec for video preview (close #3522) 2023-02-23 20:50:31 +08:00
28aee8c493 feat: add aliyundrive open driver (#3437)
close #3533 
close #3521 
close #3459 
close #3375 

* feat: add aliyundrive open driver

* feat: adapt alist api

* fix: trailing spaces

* feat(aliyundrive_open): video preview api
2023-02-23 20:45:57 +08:00
de3ea82eb9 ci: add closeComment for stale 2023-02-22 22:17:33 +08:00
268ba3d069 fix(deps): update module github.com/gin-gonic/gin to v1.9.0 [skip ci] (#3551)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-22 21:24:35 +08:00
309d6558fb feat(local): add thumbnail for video with ffmpeg (#3556)
* feat(local): add ffmpeg

* fix: missed `+`

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2023-02-22 21:19:42 +08:00
c08fdfc868 fix: missed assignment [skip ci] 2023-02-22 20:20:28 +08:00
1b28e6af3e ci: replace issues-helper with stale for inactive check 2023-02-22 20:07:18 +08:00
8655e33e60 fix: incorrect api if not set site_url (6c2f348) 2023-02-21 19:57:50 +08:00
50579fef84 fix: cancel api replace to avoid missing host 2023-02-21 19:45:09 +08:00
e39299bfe2 fix(local): missed type of MkdirPerm (923937b) 2023-02-21 17:45:15 +08:00
d1ab2443f1 feat(qbittorrent): delete tags when deleting qbittorrent tasks (#3546)
* feat & refactor(qbittorrent/client): support `deleteFiles` arg for `Client.Delete()` method

* feat(qbittorrent/client): also delete tags in `Client.Delete()`
2023-02-21 16:45:41 +08:00
658cf368bb fix(deps): update github.com/t3rm1n4l/go-mega digest to b87ebf5 (#3539)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-21 16:43:37 +08:00
fd36ce59f6 fix(onedrive): either id or path in parentReference must be specified (close #3028) 2023-02-21 16:19:46 +08:00
95b3b87672 feat(sftp): support range header 2023-02-20 16:57:52 +08:00
0d07d81802 feat(smb): support range header (close #3192) 2023-02-20 16:46:38 +08:00
923937b530 feat(local): custom mkdir perm (close #3196) 2023-02-20 16:20:36 +08:00
09492193c4 fix(alist_v3): api error pass (close #3326) 2023-02-20 16:15:52 +08:00
40b26a81a0 fix!: change default epub viewer (close #3519) 2023-02-20 16:08:10 +08:00
4293a0ba8c fix(deps): update module github.com/golang-jwt/jwt/v4 to v4.5.0 [skip ci] (#3525)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-20 16:06:35 +08:00
6c2f3486fc fix!: reverse proxy to sub-directory (#3483)
from this commit, if you want reverse proxy to sub-directory like `alist` with `nginx`, you need config:

```nginx
location /alist/ {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Range $http_range;
    proxy_set_header If-Range $http_if_range;
    proxy_redirect off;
    proxy_pass http://127.0.0.1:5244/alist/;
    # the max size of file to upload
    client_max_body_size 20000m;
}
```
2023-02-18 19:03:07 +08:00
3c7512f64a fix(qbittorrent): fix two file transferring related bugs [skip ci] (#3501)
* fix(qbittorrent): delete qbittorrent task before transferring

* fix(qbittorrent): parse the path correctly when the torrent contains folders
2023-02-18 18:54:51 +08:00
84219d3d70 fix(deps): update module gorm.io/driver/mysql to v1.4.7 [skip ci] (#3495)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-18 18:13:41 +08:00
05d3727335 fix(deps): update module golang.org/x/image to v0.5.0 [security skip ci] (#3489)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-18 18:13:22 +08:00
ee77c3b113 fix: friendly tip for initial logging in [skip ci] (#3406)
* refactor: friendly tip for initial logging in

* fix CodeFactor issue

more info pls refer to: https://segmentfault.com/a/1190000043031147
2023-02-18 17:53:11 +08:00
fcaf485e0b fix(deps): update module gorm.io/driver/postgres to v1.4.8 [skip ci] (#3496)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-18 17:52:03 +08:00
bd83469bb1 fix(deps): update module golang.org/x/net to v0.7.0 [security skip ci] (#3502)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-18 17:51:33 +08:00
90f111b24f docs: translate title [skip ci] (#3498)
* Update README_cn.md

* Update README_cn.md

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2023-02-18 17:50:42 +08:00
7d1034c569 fix(aliyundrive): error occurred when running multiple instances at the same time (#3448)
* fix(aliyundrive):an error occurred when running multiple instances at the same time

* Update util.go

fix(aliyunpan):clear retry count
2023-02-16 22:12:19 +08:00
236c17176c fix(123): adapt new file list api (close #3464) 2023-02-16 22:09:45 +08:00
6ee4c10e8f chore(onedrive)!: change default redirect_uri [skip ci] 2023-02-16 21:37:20 +08:00
3798634028 fix(pikpak_share): change media url to content url (close #3273) (#3441) 2023-02-16 15:42:11 +08:00
567ba5ccd4 feat(aliyundrive_share): aliyun office preview (close #3408) 2023-02-15 16:52:24 +08:00
ae2ee1821a chore: change qBittorrent setting [skip ci] 2023-02-15 16:51:29 +08:00
805b1e4fa3 fix: different url encoding (close #3423) 2023-02-15 16:20:30 +08:00
d92c10da56 fix(qbittorrent): fix multiple bugs for qbittorrent download (close #3413 in #3427)
* fix(qbittorrent): wait for qbittorrent to parse torrent and create task

#3413

* fix(qbittorrent): check task state correctly

* fix(qbittorrent): fix path sent to `op.Put()`
2023-02-15 15:58:31 +08:00
6659f6d367 fix: windows arm64 build [skip ci] 2023-02-14 20:28:05 +08:00
fe416ba15c feat!: close sign_all by default 2023-02-14 19:20:15 +08:00
de66708b24 fix(aliyundrive): device session signature error (#3398)
* fix signature

* fix: indent-error-flow [skip ci]
2023-02-14 19:17:21 +08:00
2ca3e0b8bc fix(123): incorrect download url (close #3385) 2023-02-14 15:47:41 +08:00
ae04a0a760 chore: go mod tidy 2023-02-14 15:30:33 +08:00
c28168c970 feat: support qbittorrent (close #3087 in #3333)
* feat(qbittorrent): authorization and logging in support

* feat(qbittorrent/client): support `AddFromLink`

* refactor(qbittorrent/client): check authorization when getting a new client

* feat(qbittorrent/client): support `GetInfo`

* test(qbittorrent/client): update test cases

* feat(qbittorrent): init qbittorrent client on bootstrap

* feat(qbittorrent): support setting webui url via gin

* feat(qbittorrent/client): support deleting

* feat(qbittorrent/client): parse `TorrentStatus` enum when unmarshalling json in `GetInfo()`

* feat(qbittorrent/client): support getting files by id

* feat(qbittorrent): support adding qbittorrent tasks via gin

* refactor(qbittorrent/client): return a `Client` interface in `New()` instead of `*client`

* refactor: task handle

* chore: fix typo

* chore: change path

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2023-02-14 15:20:45 +08:00
46b2ed2507 fix(aliyundriver):x-device-id error code (#3390)
* fix(aliyundriver):x-drvice-id error code

* fix(aliyunpan):session signature error

* fix typo

---------

Co-authored-by: Andy Hsu <i@nn.ci>
2023-02-14 14:11:07 +08:00
22843ffc70 fix(fs): copy file if symlink failed (#3368) 2023-02-13 14:41:35 +08:00
e1b6368343 feat(aliyundrive): zero copy for local file uploads (#3359) 2023-02-12 16:13:57 +08:00
62dae50d70 feat(fs): create symbolic link instead of copy local files (close #2186 in #3354) 2023-02-12 16:03:11 +08:00
43a8ed472b fix: can't login by github after disable guest (close #3314) 2023-02-09 20:12:04 +08:00
d87878c232 ci: cancel win/arm64 on dev build [skip ci] 2023-02-09 20:05:00 +08:00
ab7dee49b0 feat: add windows/arm64 target (close #3308) 2023-02-09 19:52:40 +08:00
dca115506d fix(deps): update module golang.org/x/crypto to v0.6.0 [skip ci] (#3315)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-09 16:17:10 +08:00
be17fba0c6 fix(deps): update module golang.org/x/net to v0.6.0 [skip ci] (#3316)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-09 16:16:43 +08:00
cd58aa5efe fix(deps): update module gorm.io/driver/mysql to v1.4.6 (#3311) [skip ci]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-09 16:00:08 +08:00
946833d2cc fix(deps): update module golang.org/x/image to v0.4.0 (#3323) [skip ci]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-09 15:59:31 +08:00
eb42d09849 chore(deps): update docker/build-push-action action to v4 (#3200)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-08 22:22:33 +08:00
9d00492750 fix(deps): update module gorm.io/driver/postgres to v1.4.7 (#3312) [skip ci]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-08 22:20:04 +08:00
b6711d6ab9 chore(deps): update actions-cool/issues-helper action to v3.4.0 (#3279) [skip ci]
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-08 22:12:02 +08:00
7bc46de8aa feat: settings for tls insecure skip verify (close #3306 in #3307) 2023-02-08 22:01:26 +08:00
a4f4fb2d73 chore(deps): upgrade github.com/caarlos0/env 2023-02-07 19:55:55 +08:00
a181b56ea7 feat: optional forward direct link params (close #3123) 2023-02-07 16:39:14 +08:00
d0b743d955 fix(onedrive): downloadUrl missed on personal account (close #3276) 2023-02-07 16:16:29 +08:00
a985b748e9 fix: allow_indexed check (close #3291) 2023-02-07 15:14:39 +08:00
847 changed files with 71329 additions and 13648 deletions

View File

@ -1,56 +0,0 @@
name: "Bug report"
description: Bug report
labels: [bug]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report, please **confirm that your issue is not a duplicate issue and not because of your operation or version issues**
感谢您花时间填写此错误报告,请**务必确认您的issue不是重复的且不是因为您的操作或版本问题**
- type: checkboxes
attributes:
label: Please make sure of the following things
description: You may select more than one, even select all.
options:
- label: I have read the [documentation](https://alist.nn.ci).
- label: I'm sure there are no duplicate issues or discussions.
- label: I'm sure it's due to `alist` and not something else(such as `Dependencies` or `Operational`).
- label: I'm sure I'm using the latest version
- type: input
id: version
attributes:
label: Alist Version / Alist 版本
description: What version of our software are you running?
placeholder: v2.0.0
validations:
required: true
- type: input
id: driver
attributes:
label: Driver used / 使用的存储驱动
description: What storage driver are you using?
placeholder: "for example: Onedrive"
validations:
required: true
- type: textarea
id: bug-description
attributes:
label: Describe the bug / 问题描述
validations:
required: true
- type: textarea
id: reproduction
attributes:
label: Reproduction / 复现链接
description: |
Please provide a link to a repo that can reproduce the problem you ran into. Please be aware that your issue may be closed directly if you don't provide it.
请提供能复现此问题的链接请知悉如果不提供它你的issue可能会被直接关闭。
validations:
required: true
- type: textarea
id: logs
attributes:
label: Logs / 日志
description: |
Please copy and paste any relevant log output.
请复制粘贴错误日志,或者截图

View File

@ -1,5 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: Questions & Discussions
url: https://github.com/Xhofe/alist/discussions
about: Use GitHub discussions for message-board style questions and discussions.

View File

@ -1,33 +0,0 @@
name: "Feature request"
description: Feature request
labels: [enhancement]
body:
- type: checkboxes
attributes:
label: Please make sure of the following things
description: You may select more than one, even select all.
options:
- label: I have read the [documentation](https://alist.nn.ci).
- label: I'm sure there are no duplicate issues or discussions.
- label: I'm sure this feature is not implemented.
- label: I'm sure it's a reasonable and popular requirement.
- type: textarea
id: feature-description
attributes:
label: Description of the feature / 需求描述
validations:
required: true
- type: textarea
id: suggested-solution
attributes:
label: Suggested solution / 实现思路
description: |
Solutions to achieve this requirement.
实现此需求的解决思路。
- type: textarea
id: additional-context
attributes:
label: Additional context / 附件
description: |
Any other context or screenshots about the feature request here, or information you find helpful.
相关的任何其他上下文或截图,或者你觉得有帮助的信息

21
.github/config.yml vendored
View File

@ -1,21 +0,0 @@
# Configuration for welcome - https://github.com/behaviorbot/welcome
# Configuration for new-issue-welcome - https://github.com/behaviorbot/new-issue-welcome
# Comment to be posted to on first time issues
newIssueWelcomeComment: >
Thanks for opening your first issue here! Be sure to follow the issue template!
# Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome
# Comment to be posted to on PRs from first time contributors in your repository
newPRWelcomeComment: >
Thanks for opening this pull request! Please check out our contributing guidelines.
# Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge
# Comment to be posted to on pull requests merged by a first time user
firstPRMergeComment: >
Congrats on merging your first pull request! We here at behavior bot are proud of you!
# It is recommend to include as many gifs and emojis as possible

View File

@ -1,67 +0,0 @@
name: auto_lang
on:
push:
branches:
- 'main'
paths:
- 'drivers/**'
- 'internal/bootstrap/data/setting.go'
- 'internal/conf/const.go'
- 'cmd/lang.go'
workflow_dispatch:
jobs:
auto_lang:
strategy:
matrix:
platform: [ ubuntu-latest ]
go-version: [ 1.19 ]
name: auto generate lang.json
runs-on: ${{ matrix.platform }}
steps:
- name: Setup go
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
- name: Checkout alist
uses: actions/checkout@v3
with:
path: alist
- name: Checkout alist-web
uses: actions/checkout@v3
with:
repository: 'alist-org/alist-web'
ref: main
persist-credentials: false
fetch-depth: 0
path: alist-web
- name: Generate lang
run: |
cd alist
go run ./main.go lang
cd ..
- name: Copy lang file
run: |
cp -f ./alist/lang/*.json ./alist-web/src/lang/en/ 2>/dev/null || :
- name: Commit git
run: |
cd alist-web
git add .
git config --local user.email "i@nn.ci"
git config --local user.name "Noah Hsu"
git commit -m "chore: auto update i18n file" -a 2>/dev/null || :
cd ..
- name: Push lang files
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.MY_TOKEN }}
branch: main
directory: alist-web
repository: alist-org/alist-web

View File

@ -1,40 +0,0 @@
name: build
on:
push:
branches: [ 'main' ]
pull_request:
branches: [ 'main' ]
jobs:
build:
strategy:
matrix:
platform: [ubuntu-latest]
go-version: [1.19]
name: Build
runs-on: ${{ matrix.platform }}
steps:
- name: Setup Go
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
- name: Checkout
uses: actions/checkout@v3
- name: Install dependencies
run: |
docker pull crazymax/xgo:latest
go install github.com/crazy-max/xgo@latest
sudo apt install upx
- name: Build
run: |
bash build.sh dev
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: alist
path: dist

View File

@ -1,65 +0,0 @@
name: build_docker
on:
push:
branches: [ main ]
jobs:
build_docker:
name: Build docker
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Docker meta
id: meta
uses: docker/metadata-action@v4
with:
images: xhofe/alist
- name: Replace release with dev
run: |
sed -i 's/release/dev/g' Dockerfile
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: xhofe
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
id: docker_build
uses: docker/build-push-action@v3
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64
build_docker_with_aria2:
needs: build_docker
name: Build docker with aria2
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
repository: alist-org/with_aria2
ref: main
persist-credentials: false
fetch-depth: 0
- name: Commit
run: |
git config --local user.email "i@nn.ci"
git config --local user.name "Noah Hsu"
git commit --allow-empty -m "Trigger build for ${{ github.sha }}"
- name: Push commit
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.MY_TOKEN }}
branch: main
repository: alist-org/with_aria2

View File

@ -1,17 +0,0 @@
name: Check inactive
on:
schedule:
- cron: "0 0 1 * *"
jobs:
check-inactive:
runs-on: ubuntu-latest
steps:
- name: check-inactive
uses: actions-cool/issues-helper@v3
with:
actions: 'check-inactive'
token: ${{ secrets.GITHUB_TOKEN }}
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.

View File

@ -1,21 +0,0 @@
name: Close inactive
on:
schedule:
- cron: "0 0 */7 * *"
workflow_dispatch:
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.

View File

@ -1,22 +0,0 @@
name: Close need info
on:
schedule:
- cron: "0 0 */7 * *"
workflow_dispatch:
jobs:
close-need-info:
runs-on: ubuntu-latest
steps:
- name: close-issues
uses: actions-cool/issues-helper@v3
with:
actions: 'close-issues'
token: ${{ secrets.GITHUB_TOKEN }}
labels: 'question'
inactive-day: 7
close-reason: 'not_planned'
body: |
Hello @${{ github.event.issue.user.login }}, this issue was closed due to no activities in 7 days.
你好 @${{ github.event.issue.user.login }}此issue因超过7天未回复被关闭。

View File

@ -1,25 +0,0 @@
name: Issue Duplicate
on:
issues:
types: [labeled]
jobs:
create-comment:
runs-on: ubuntu-latest
if: github.event.label.name == 'duplicate'
steps:
- name: Create comment
uses: actions-cool/issues-helper@v3
with:
actions: 'create-comment'
token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.issue.number }}
body: |
Hello @${{ github.event.issue.user.login }}, your issue is a duplicate and will be closed.
你好 @${{ github.event.issue.user.login }}你的issue是重复的将被关闭。
- name: Close issue
uses: actions-cool/issues-helper@v3
with:
actions: 'close-issue'
token: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,25 +0,0 @@
name: Issue Invalid
on:
issues:
types: [labeled]
jobs:
create-comment:
runs-on: ubuntu-latest
if: github.event.label.name == 'invalid'
steps:
- name: Create comment
uses: actions-cool/issues-helper@v3
with:
actions: 'create-comment'
token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.issue.number }}
body: |
Hello @${{ github.event.issue.user.login }}, your issue is invalid and will be closed.
你好 @${{ github.event.issue.user.login }}你的issue无效将被关闭。
- name: Close issue
uses: actions-cool/issues-helper@v3
with:
actions: 'close-issue'
token: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,20 +0,0 @@
name: Issue Question
on:
issues:
types: [labeled]
jobs:
create-comment:
runs-on: ubuntu-latest
if: github.event.label.name == 'question'
steps:
- name: Create comment
uses: actions-cool/issues-helper@v3.3.3
with:
actions: 'create-comment'
token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.issue.number }}
body: |
Hello @${{ github.event.issue.user.login }}, please input issue by template and add detail. Issues labeled by `question` will be closed if no activities in 7 days.
你好 @${{ github.event.issue.user.login }}请按照issue模板填写, 并详细说明问题/复现步骤/复现链接/实现思路或提供更多信息等, 7天内未回复issue自动关闭。

View File

@ -1,19 +0,0 @@
name: Issues Similarity Analysis
on:
issues:
types: [opened, edited]
jobs:
similarity-analysis:
runs-on: ubuntu-latest
steps:
- name: analysis
uses: actions-cool/issues-similarity-analysis@v1
with:
filter-threshold: 0.5
comment-title: '### See'
comment-body: '${index}. ${similarity} #${number}'
show-footer: false
show-mentioned: true
since-days: 730

View File

@ -1,13 +0,0 @@
name: Translation Helper
on:
pull_request_target:
types: [opened]
issues:
types: [opened]
jobs:
translate:
runs-on: ubuntu-latest
steps:
- uses: actions-cool/translation-helper@v1.2.0

View File

@ -1,25 +0,0 @@
name: Issue Wontfix
on:
issues:
types: [labeled]
jobs:
lock-issue:
runs-on: ubuntu-latest
if: github.event.label.name == 'wontfix'
steps:
- name: Create comment
uses: actions-cool/issues-helper@v3
with:
actions: 'create-comment'
token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.issue.number }}
body: |
Hello @${{ github.event.issue.user.login }}, this issue will not be worked on and will be closed.
你好 @${{ github.event.issue.user.login }},这不会被处理,将被关闭。
- name: Close issue
uses: actions-cool/issues-helper@v3
with:
actions: 'close-issue'
token: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,52 +0,0 @@
name: release
on:
push:
tags:
- '*'
jobs:
changelog:
name: Create Release
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
- run: npx changelogithub # or changelogithub@0.12 if ensure the stable result
env:
GITHUB_TOKEN: ${{secrets.MY_TOKEN}}
release:
needs: changelog
strategy:
matrix:
platform: [ubuntu-latest]
go-version: [1.19]
name: Release
runs-on: ${{ matrix.platform }}
steps:
- name: Setup Go
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go-version }}
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install dependencies
run: |
docker pull crazymax/xgo:latest
go install github.com/crazy-max/xgo@latest
sudo apt install upx
- name: Build
run: |
bash build.sh release
- name: Release
uses: softprops/action-gh-release@v1
with:
files: build/compress/*

View File

@ -1,68 +0,0 @@
name: release_docker
on:
push:
tags:
- '*'
jobs:
release_docker:
name: Release Docker
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Docker meta
id: meta
uses: docker/metadata-action@v4
with:
images: xhofe/alist
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: xhofe
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
id: docker_build
uses: docker/build-push-action@v3
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/386,linux/arm/v6,linux/s390x
release_docker_with_aria2:
needs: release_docker
name: Release docker with aria2
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
repository: alist-org/with_aria2
ref: main
persist-credentials: false
fetch-depth: 0
- name: Add tag
run: |
git config --local user.email "i@nn.ci"
git config --local user.name "Noah Hsu"
git tag -a ${{ github.ref_name }} -m "release ${{ github.ref_name }}"
- name: Push tags
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.MY_TOKEN }}
branch: main
repository: alist-org/with_aria2

3
.gitignore vendored
View File

@ -24,8 +24,11 @@ output/
*.json
/build
/data/
/tmp/
/log/
/lang/
/daemon/
/public/dist/*
/!public/dist/README.md
.VSCodeCounter

View File

@ -1,18 +0,0 @@
FROM alpine:edge as builder
LABEL stage=go-builder
WORKDIR /app/
COPY ./ ./
RUN apk add --no-cache bash curl gcc git go musl-dev; \
bash build.sh release docker
FROM alpine:edge
LABEL MAINTAINER="i@nn.ci"
VOLUME /opt/alist/data/
WORKDIR /opt/alist/
COPY --from=builder /app/bin/alist ./
COPY entrypoint.sh /entrypoint.sh
RUN apk add --no-cache bash ca-certificates su-exec tzdata; \
chmod +x /entrypoint.sh
ENV PUID=0 PGID=0 UMASK=022
EXPOSE 5244
ENTRYPOINT [ "/entrypoint.sh" ]

135
README.md
View File

@ -1,135 +0,0 @@
<div align="center">
<a href="https://alist.nn.ci"><img height="100px" alt="logo" src="https://cdn.jsdelivr.net/gh/alist-org/logo@main/logo.svg"/></a>
<p><em>🗂A file list program that supports multiple storage, powered by Gin and Solidjs.</em></p>
<div>
<a href="https://goreportcard.com/report/github.com/alist-org/alist/v3">
<img src="https://goreportcard.com/badge/github.com/alist-org/alist/v3" alt="latest version" />
</a>
<a href="https://github.com/Xhofe/alist/blob/main/LICENSE">
<img src="https://img.shields.io/github/license/Xhofe/alist" alt="License" />
</a>
<a href="https://github.com/Xhofe/alist/actions?query=workflow%3ABuild">
<img src="https://img.shields.io/github/actions/workflow/status/Xhofe/alist/build.yml?branch=main" alt="Build status" />
</a>
<a href="https://github.com/Xhofe/alist/releases">
<img src="https://img.shields.io/github/release/Xhofe/alist" alt="latest version" />
</a>
<a title="Crowdin" target="_blank" href="https://crwd.in/alist">
<img src="https://badges.crowdin.net/alist/localized.svg">
</a>
</div>
<div>
<a href="https://github.com/Xhofe/alist/discussions">
<img src="https://img.shields.io/github/discussions/Xhofe/alist?color=%23ED8936" alt="discussions" />
</a>
<a href="https://discord.gg/F4ymsH4xv2">
<img src="https://img.shields.io/discord/1018870125102895134?logo=discord" alt="discussions" />
</a>
<a href="https://github.com/Xhofe/alist/releases">
<img src="https://img.shields.io/github/downloads/Xhofe/alist/total?color=%239F7AEA&logo=github" alt="Downloads" />
</a>
<a href="https://hub.docker.com/r/xhofe/alist">
<img src="https://img.shields.io/docker/pulls/xhofe/alist?color=%2348BB78&logo=docker&label=pulls" alt="Downloads" />
</a>
<a href="https://alist.nn.ci/guide/sponsor.html">
<img src="https://img.shields.io/badge/%24-sponsor-F87171.svg" alt="sponsor" />
</a>
</div>
</div>
---
English | [中文](./README_cn.md) | [Contributing](./CONTRIBUTING.md) | [CODE_OF_CONDUCT](./CODE_OF_CONDUCT.md)
## Features
- [x] Multiple storage
- [x] Local storage
- [x] [Aliyundrive](https://www.aliyundrive.com/)
- [x] OneDrive / Sharepoint ([global](https://www.office.com/), [cn](https://portal.partner.microsoftonline.cn),de,us)
- [x] [189cloud](https://cloud.189.cn) (Personal, Family)
- [x] [GoogleDrive](https://drive.google.com/)
- [x] [123pan](https://www.123pan.com/)
- [x] FTP / SFTP
- [x] [PikPak](https://www.mypikpak.com/)
- [x] [S3](https://aws.amazon.com/s3/)
- [x] [Seafile](https://seafile.com/)
- [x] [UPYUN Storage Service](https://www.upyun.com/products/file-storage)
- [x] WebDav(Support OneDrive/SharePoint without API)
- [x] Teambition([China](https://www.teambition.com/ ),[International](https://us.teambition.com/ ))
- [x] [Mediatrack](https://www.mediatrack.cn/)
- [x] [139yun](https://yun.139.com/) (Personal, Family)
- [x] [YandexDisk](https://disk.yandex.com/)
- [x] [BaiduNetdisk](http://pan.baidu.com/)
- [x] [Terabox](https://www.terabox.com/main)
- [x] [Quark](https://pan.quark.cn)
- [x] [Thunder](https://pan.xunlei.com)
- [x] [Lanzou](https://www.lanzou.com/)
- [x] [Aliyundrive share](https://www.aliyundrive.com/)
- [x] [Google photo](https://photos.google.com/)
- [x] [Mega.nz](https://mega.nz)
- [x] [Baidu photo](https://photo.baidu.com/)
- [x] SMB
- [x] [115](https://115.com/)
- [X] Cloudreve
- [x] Easy to deploy and out-of-the-box
- [x] File preview (PDF, markdown, code, plain text, ...)
- [x] Image preview in gallery mode
- [x] Video and audio preview, support lyrics and subtitles
- [x] Office documents preview (docx, pptx, xlsx, ...)
- [x] `README.md` preview rendering
- [x] File permalink copy and direct file download
- [x] Dark mode
- [x] I18n
- [x] Protected routes (password protection and authentication)
- [x] WebDav (see https://alist.nn.ci/guide/webdav.html for details)
- [x] [Docker Deploy](https://hub.docker.com/r/xhofe/alist)
- [x] Cloudflare workers proxy
- [x] File/Folder package download
- [x] Web upload(Can allow visitors to upload), delete, mkdir, rename, move and copy
- [x] Offline download
- [x] Copy files between two storage
## Document
<https://alist.nn.ci/>
## Demo
<https://al.nn.ci>
## Discussion
Please go to our [discussion forum](https://github.com/Xhofe/alist/discussions) for general questions, **issues are for bug reports and feature request only.**
## Sponsor
AList is an open-source software, if you happen to like this project and want me to keep going, please consider sponsoring me or providing a single donation! Thanks for all the love and support:
https://alist.nn.ci/guide/sponsor.html
### Special sponsors
- [找资源 - 阿里云盘资源搜索引擎](https://zhaoziyuan.la/)
- [KinhDown 百度云盘不限速下载永久免费已稳定运行3年非常可靠Q群 -> 786799372](https://kinhdown.com)
- [JetBrains: Essential tools for software developers and teams](https://www.jetbrains.com/)
## Contributors
Thanks goes to these wonderful people:
[![Contributors](http://contributors.nn.ci/api?repo=alist-org/alist&repo=alist-org/alist-web&repo=alist-org/docs)](https://github.com/alist-org/alist/graphs/contributors)
## License
The `AList` is open-source software licensed under the AGPL-3.0 license.
## Disclaimer
- This program is a free and open source project. It is designed to share files on the network disk, which is convenient for downloading and learning golang. Please abide by relevant laws and regulations when using it, and do not abuse it;
- This program is implemented by calling the official sdk/interface, without destroying the official interface behavior;
- This program only does 302 redirect/traffic forwarding, and does not intercept, store, or tamper with any user data;
- Before using this program, you should understand and bear the corresponding risks, including but not limited to account ban, download speed limit, etc., which is none of this program's business;
- If there is any infringement, please contact me by [email](mailto:i@nn.ci), and it will be dealt with in time.
---
> [@Blog](https://nn.ci/) · [@GitHub](https://github.com/Xhofe) · [@TelegramGroup](https://t.me/alist_chat) · [@Discord](https://discord.gg/F4ymsH4xv2)

View File

@ -1,133 +0,0 @@
<div align="center">
<a href="https://alist.nn.ci"><img height="100px" alt="logo" src="https://cdn.jsdelivr.net/gh/alist-org/logo@main/logo.svg"/></a>
<p><em>🗂一个支持多存储的文件列表程序,使用 Gin 和 Solidjs。</em></p>
<div>
<a href="https://goreportcard.com/report/github.com/alist-org/alist/v3">
<img src="https://goreportcard.com/badge/github.com/alist-org/alist/v3" alt="latest version" />
</a>
<a href="https://github.com/Xhofe/alist/blob/main/LICENSE">
<img src="https://img.shields.io/github/license/Xhofe/alist" alt="License" />
</a>
<a href="https://github.com/Xhofe/alist/actions?query=workflow%3ABuild">
<img src="https://img.shields.io/github/actions/workflow/status/Xhofe/alist/build.yml?branch=main" alt="Build status" />
</a>
<a href="https://github.com/Xhofe/alist/releases">
<img src="https://img.shields.io/github/release/Xhofe/alist" alt="latest version" />
</a>
<a title="Crowdin" target="_blank" href="https://crwd.in/alist">
<img src="https://badges.crowdin.net/alist/localized.svg">
</a>
</div>
<div>
<a href="https://github.com/Xhofe/alist/discussions">
<img src="https://img.shields.io/github/discussions/Xhofe/alist?color=%23ED8936" alt="discussions" />
</a>
<a href="https://discord.gg/F4ymsH4xv2">
<img src="https://img.shields.io/discord/1018870125102895134?logo=discord" alt="discussions" />
</a>
<a href="https://github.com/Xhofe/alist/releases">
<img src="https://img.shields.io/github/downloads/Xhofe/alist/total?color=%239F7AEA&logo=github" alt="Downloads" />
</a>
<a href="https://hub.docker.com/r/xhofe/alist">
<img src="https://img.shields.io/docker/pulls/xhofe/alist?color=%2348BB78&logo=docker&label=pulls" alt="Downloads" />
</a>
<a href="https://alist.nn.ci/zh/guide/sponsor.html">
<img src="https://img.shields.io/badge/%24-sponsor-F87171.svg" alt="sponsor" />
</a>
</div>
</div>
---
[English](./README.md) | 中文 | [Contributing](./CONTRIBUTING.md) | [CODE_OF_CONDUCT](./CODE_OF_CONDUCT.md)
## Features
- [x] 多种存储
- [x] 本地存储
- [x] [阿里云盘](https://www.aliyundrive.com/)
- [x] OneDrive / Sharepoint[国际版](https://www.office.com/), [世纪互联](https://portal.partner.microsoftonline.cn),de,us
- [x] [天翼云盘](https://cloud.189.cn) (个人云, 家庭云)
- [x] [GoogleDrive](https://drive.google.com/)
- [x] [123云盘](https://www.123pan.com/)
- [x] FTP / SFTP
- [x] [PikPak](https://www.mypikpak.com/)
- [x] [S3](https://aws.amazon.com/cn/s3/)
- [x] [Seafile](https://seafile.com/)
- [x] [又拍云对象存储](https://www.upyun.com/products/file-storage)
- [x] WebDav(支持无API的OneDrive/SharePoint)
- [x] Teambition[中国](https://www.teambition.com/ )[国际](https://us.teambition.com/ )
- [x] [分秒帧](https://www.mediatrack.cn/)
- [x] [和彩云](https://yun.139.com/) (个人云, 家庭云)
- [x] [Yandex.Disk](https://disk.yandex.com/)
- [x] [百度网盘](http://pan.baidu.com/)
- [x] [夸克网盘](https://pan.quark.cn)
- [x] [迅雷网盘](https://pan.xunlei.com)
- [x] [蓝奏云](https://www.lanzou.com/)
- [x] [阿里云盘分享](https://www.aliyundrive.com/)
- [x] [谷歌相册](https://photos.google.com/)
- [x] [Mega.nz](https://mega.nz)
- [x] [一刻相册](https://photo.baidu.com/)
- [x] SMB
- [x] [115](https://115.com/)
- [X] Cloudreve
- [x] 部署方便,开箱即用
- [x] 文件预览PDF、markdown、代码、纯文本……
- [x] 画廊模式下的图像预览
- [x] 视频和音频预览,支持歌词和字幕
- [x] Office 文档预览docx、pptx、xlsx、...
- [x] `README.md` 预览渲染
- [x] 文件永久链接复制和直接文件下载
- [x] 黑暗模式
- [x] 国际化
- [x] 受保护的路由(密码保护和身份验证)
- [x] WebDav (具体见 https://alist.nn.ci/zh/guide/webdav.html)
- [x] [Docker 部署](https://hub.docker.com/r/xhofe/alist)
- [x] Cloudflare workers 中转
- [x] 文件/文件夹打包下载
- [x] 网页上传(可以允许访客上传),删除,新建文件夹,重命名,移动,复制
- [x] 离线下载
- [x] 跨存储复制文件
## Document
<https://alist.nn.ci/zh/>
## Demo
<https://al.nn.ci>
## Discussion
一般问题请到[讨论论坛](https://github.com/Xhofe/alist/discussions) **issue仅针对错误报告和功能请求。**
## Sponsor
AList 是一个开源软件如果你碰巧喜欢这个项目并希望我继续下去请考虑赞助我或提供一个单一的捐款感谢所有的爱和支持https://alist.nn.ci/zh/guide/sponsor.html
### Special sponsors
- [找资源 - 阿里云盘资源搜索引擎](https://zhaoziyuan.la/)
- [KinhDown 百度云盘不限速下载永久免费已稳定运行3年非常可靠Q群 -> 786799372](https://kinhdown.com)
- [JetBrains: Essential tools for software developers and teams](https://www.jetbrains.com/)
## Contributors
Thanks goes to these wonderful people:
[![Contributors](http://contributors.nn.ci/api?repo=alist-org/alist&repo=alist-org/alist-web&repo=alist-org/docs)](https://github.com/alist-org/alist/graphs/contributors)
## 许可
`AList` 是在 AGPL-3.0 许可下许可的开源软件。
## 免责声明
- 本程序为免费开源项目旨在分享网盘文件方便下载以及学习golang使用时请遵守相关法律法规请勿滥用
- 本程序通过调用官方sdk/接口实现,无破坏官方接口行为;
- 本程序仅做302重定向/流量转发,不拦截、存储、篡改任何用户数据;
- 在使用本程序之前你应了解并承担相应的风险包括但不限于账号被ban下载限速等与本程序无关
- 如有侵权,请通过[邮件](mailto:i@nn.ci)与我联系,会及时处理。
---
> [@博客](https://nn.ci/) · [@GitHub](https://github.com/Xhofe) · [@Telegram群](https://t.me/alist_chat) · [@Discord](https://discord.gg/F4ymsH4xv2)

11
buf.gen.yaml Normal file
View File

@ -0,0 +1,11 @@
version: v1
plugins:
- plugin: buf.build/protocolbuffers/go:v1.36.7
out: .
opt:
- paths=source_relative
- plugin: buf.build/grpc/go:v1.5.1
out: .
opt:
- paths=source_relative
- require_unimplemented_servers=false

1
buf.yaml Normal file
View File

@ -0,0 +1 @@
version: v1

131
build.sh
View File

@ -1,131 +0,0 @@
appName="alist"
builtAt="$(date +'%F %T %z')"
goVersion=$(go version | sed 's/go version //')
gitAuthor=$(git show -s --format='format:%aN <%ae>' HEAD)
gitCommit=$(git log --pretty=format:"%h" -1)
if [ "$1" = "dev" ]; then
version="dev"
webVersion="dev"
else
version=$(git describe --abbrev=0 --tags)
webVersion=$(wget -qO- -t1 -T2 "https://api.github.com/repos/alist-org/alist-web/releases/latest" | grep "tag_name" | head -n 1 | awk -F ":" '{print $2}' | sed 's/\"//g;s/,//g;s/ //g')
fi
echo "backend version: $version"
echo "frontend version: $webVersion"
ldflags="\
-w -s \
-X 'github.com/alist-org/alist/v3/internal/conf.BuiltAt=$builtAt' \
-X 'github.com/alist-org/alist/v3/internal/conf.GoVersion=$goVersion' \
-X 'github.com/alist-org/alist/v3/internal/conf.GitAuthor=$gitAuthor' \
-X 'github.com/alist-org/alist/v3/internal/conf.GitCommit=$gitCommit' \
-X 'github.com/alist-org/alist/v3/internal/conf.Version=$version' \
-X 'github.com/alist-org/alist/v3/internal/conf.WebVersion=$webVersion' \
"
FetchWebDev() {
curl -L https://codeload.github.com/alist-org/web-dist/tar.gz/refs/heads/dev -o web-dist-dev.tar.gz
tar -zxvf web-dist-dev.tar.gz
rm -rf public/dist
mv -f web-dist-dev/dist public
rm -rf web-dist-dev web-dist-dev.tar.gz
}
FetchWebRelease() {
curl -L https://github.com/alist-org/alist-web/releases/latest/download/dist.tar.gz -o dist.tar.gz
tar -zxvf dist.tar.gz
rm -rf public/dist
mv -f dist public
rm -rf dist.tar.gz
}
BuildDev() {
rm -rf .git/
xgo -targets=linux/amd64,windows/amd64,darwin/amd64 -out "$appName" -ldflags="$ldflags" -tags=jsoniter .
mkdir -p "dist"
mv alist-* dist
cd dist
upx -9 ./alist-linux*
upx -9 ./alist-windows*
find . -type f -print0 | xargs -0 md5sum >md5.txt
cat md5.txt
}
BuildDocker() {
go build -o ./bin/alist -ldflags="$ldflags" -tags=jsoniter .
}
BuildRelease() {
rm -rf .git/
mkdir -p "build"
muslflags="--extldflags '-static -fpic' $ldflags"
BASE="https://musl.nn.ci/"
FILES=(x86_64-linux-musl-cross aarch64-linux-musl-cross arm-linux-musleabihf-cross mips-linux-musl-cross mips64-linux-musl-cross mips64el-linux-musl-cross mipsel-linux-musl-cross powerpc64le-linux-musl-cross s390x-linux-musl-cross)
for i in "${FILES[@]}"; do
url="${BASE}${i}.tgz"
curl -L -o "${i}.tgz" "${url}"
sudo tar xf "${i}.tgz" --strip-components 1 -C /usr/local
done
OS_ARCHES=(linux-musl-amd64 linux-musl-arm64 linux-musl-arm linux-musl-mips linux-musl-mips64 linux-musl-mips64le linux-musl-mipsle linux-musl-ppc64le linux-musl-s390x)
CGO_ARGS=(x86_64-linux-musl-gcc aarch64-linux-musl-gcc arm-linux-musleabihf-gcc mips-linux-musl-gcc mips64-linux-musl-gcc mips64el-linux-musl-gcc mipsel-linux-musl-gcc powerpc64le-linux-musl-gcc s390x-linux-musl-gcc)
for i in "${!OS_ARCHES[@]}"; do
os_arch=${OS_ARCHES[$i]}
cgo_cc=${CGO_ARGS[$i]}
echo building for ${os_arch}
export GOOS=${os_arch%%-*}
export GOARCH=${os_arch##*-}
export CC=${cgo_cc}
export CGO_ENABLED=1
go build -o ./build/$appName-$os_arch -ldflags="$muslflags" -tags=jsoniter .
done
xgo -out "$appName" -ldflags="$ldflags" -tags=jsoniter .
# why? Because some target platforms seem to have issues with upx compression
upx -9 ./alist-linux-amd64
upx -9 ./alist-windows*
mv alist-* build
}
MakeRelease() {
cd build
mkdir compress
for i in $(find . -type f -name "$appName-linux-*"); do
cp "$i" alist
tar -czvf compress/"$i".tar.gz alist
rm -f alist
done
for i in $(find . -type f -name "$appName-darwin-*"); do
cp "$i" alist
tar -czvf compress/"$i".tar.gz alist
rm -f alist
done
for i in $(find . -type f -name "$appName-windows-*"); do
cp "$i" alist.exe
zip compress/$(echo $i | sed 's/\.[^.]*$//').zip alist.exe
rm -f alist.exe
done
cd compress
find . -type f -print0 | xargs -0 md5sum >md5.txt
cat md5.txt
cd ../..
}
if [ "$1" = "dev" ]; then
FetchWebDev
if [ "$2" = "docker" ]; then
BuildDocker
else
BuildDev
fi
elif [ "$1" = "release" ]; then
FetchWebRelease
if [ "$2" = "docker" ]; then
BuildDocker
else
BuildRelease
MakeRelease
fi
else
echo -e "Parameter error"
fi

View File

@ -1,40 +0,0 @@
/*
Copyright © 2022 NAME HERE <EMAIL ADDRESS>
*/
package cmd
import (
"github.com/alist-org/alist/v3/internal/op"
"github.com/alist-org/alist/v3/pkg/utils"
"github.com/spf13/cobra"
)
// PasswordCmd represents the password command
var PasswordCmd = &cobra.Command{
Use: "admin",
Aliases: []string{"password"},
Short: "Show admin user's info",
Run: func(cmd *cobra.Command, args []string) {
Init()
admin, err := op.GetAdmin()
if err != nil {
utils.Log.Errorf("failed get admin user: %+v", err)
} else {
utils.Log.Infof("admin user's info: \nusername: %s\npassword: %s", admin.Username, admin.Password)
}
},
}
func init() {
RootCmd.AddCommand(PasswordCmd)
// Here you will define your flags and configuration settings.
// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// passwordCmd.PersistentFlags().String("foo", "", "A help for foo")
// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// passwordCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

View File

@ -1,44 +1,42 @@
package cmd
import (
"os"
"path/filepath"
"strconv"
"context"
"github.com/alist-org/alist/v3/internal/bootstrap"
"github.com/alist-org/alist/v3/internal/bootstrap/data"
"github.com/alist-org/alist/v3/pkg/utils"
log "github.com/sirupsen/logrus"
"github.com/OpenListTeam/OpenList/v5/cmd/flags"
"github.com/OpenListTeam/OpenList/v5/internal/bootstrap"
"github.com/sirupsen/logrus"
)
func Init() {
func Init(ctx context.Context) {
if flags.Dev {
flags.Debug = true
}
initLogrus()
bootstrap.InitConfig()
bootstrap.Log()
bootstrap.InitDB()
data.InitData()
bootstrap.InitIndex()
bootstrap.InitDriverPlugins()
}
var pid = -1
var pidFile string
func Release() {
func initDaemon() {
ex, err := os.Executable()
if err != nil {
log.Fatal(err)
}
exPath := filepath.Dir(ex)
_ = os.MkdirAll(filepath.Join(exPath, "daemon"), 0700)
pidFile = filepath.Join(exPath, "daemon/pid")
if utils.Exists(pidFile) {
bytes, err := os.ReadFile(pidFile)
if err != nil {
log.Fatal("failed to read pid file", err)
}
id, err := strconv.Atoi(string(bytes))
if err != nil {
log.Fatal("failed to parse pid data", err)
}
pid = id
}
func initLog(l *logrus.Logger) {
if flags.Debug {
l.SetLevel(logrus.DebugLevel)
l.SetReportCaller(true)
} else {
l.SetLevel(logrus.InfoLevel)
l.SetReportCaller(false)
}
}
func initLogrus() {
formatter := logrus.TextFormatter{
ForceColors: true,
EnvironmentOverrideColors: true,
TimestampFormat: "2006-01-02 15:04:05",
FullTimestamp: true,
}
logrus.SetFormatter(&formatter)
initLog(logrus.StandardLogger())
}

View File

@ -1,9 +1,40 @@
package flags
import (
"os"
"path/filepath"
"github.com/sirupsen/logrus"
)
var (
DataDir string
ConfigFile string
Debug bool
NoPrefix bool
Dev bool
ForceBinDir bool
LogStd bool
pwd string
)
// Program working directory
func PWD() string {
if pwd != "" {
return pwd
}
if ForceBinDir {
ex, err := os.Executable()
if err != nil {
logrus.Fatal(err)
}
pwd = filepath.Dir(ex)
return pwd
}
d, err := os.Getwd()
if err != nil {
logrus.Fatal(err)
}
pwd = d
return d
}

View File

@ -4,16 +4,16 @@ import (
"fmt"
"os"
"github.com/alist-org/alist/v3/cmd/flags"
"github.com/OpenListTeam/OpenList/v5/cmd/flags"
"github.com/spf13/cobra"
)
var RootCmd = &cobra.Command{
Use: "alist",
Use: "openlist",
Short: "A file list program that supports multiple storage.",
Long: `A file list program that supports multiple storage,
built with love by Xhofe and friends in Go/Solid.js.
Complete documentation is available at https://alist.nn.ci/`,
built with love by OpenListTeam.
Complete documentation is available at https://doc.oplist.org/`,
}
func Execute() {
@ -24,9 +24,10 @@ func Execute() {
}
func init() {
RootCmd.PersistentFlags().StringVar(&flags.DataDir, "data", "data", "config file")
RootCmd.PersistentFlags().StringVarP(&flags.ConfigFile, "config", "c", "data/config.json", "config file")
RootCmd.PersistentFlags().BoolVar(&flags.Debug, "debug", false, "start with debug mode")
RootCmd.PersistentFlags().BoolVar(&flags.NoPrefix, "no-prefix", false, "disable env prefix")
RootCmd.PersistentFlags().BoolVar(&flags.Dev, "dev", false, "start with dev mode")
RootCmd.PersistentFlags().BoolVar(&flags.ForceBinDir, "force-bin-dir", false, "Force to use the directory where the binary file is located as data directory")
RootCmd.PersistentFlags().BoolVarP(&flags.ForceBinDir, "force-bin-dir", "f", false, "force to use the directory where the binary file is located as data directory")
RootCmd.PersistentFlags().BoolVar(&flags.LogStd, "log-std", false, "force to log to std")
}

View File

@ -2,22 +2,25 @@ package cmd
import (
"context"
"errors"
"fmt"
"net"
"net/http"
"os"
"os/signal"
"strconv"
"sync"
"syscall"
"time"
"github.com/alist-org/alist/v3/cmd/flags"
_ "github.com/alist-org/alist/v3/drivers"
"github.com/alist-org/alist/v3/internal/bootstrap"
"github.com/alist-org/alist/v3/internal/conf"
"github.com/alist-org/alist/v3/pkg/utils"
"github.com/alist-org/alist/v3/server"
"github.com/OpenListTeam/OpenList/v5/cmd/flags"
"github.com/OpenListTeam/OpenList/v5/internal/conf"
"github.com/OpenListTeam/OpenList/v5/server"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
)
// ServerCmd represents the server command
@ -26,71 +29,131 @@ var ServerCmd = &cobra.Command{
Short: "Start the server at the specified address",
Long: `Start the server at the specified address
the address is defined in config file`,
Run: func(cmd *cobra.Command, args []string) {
Init()
bootstrap.InitAria2()
bootstrap.LoadStorages()
if !flags.Debug && !flags.Dev {
Run: func(_ *cobra.Command, args []string) {
serverCtx, serverCancel := context.WithCancel(context.Background())
defer serverCancel()
Init(serverCtx)
if !flags.Debug {
gin.SetMode(gin.ReleaseMode)
}
r := gin.New()
r.Use(gin.LoggerWithWriter(log.StandardLogger().Out), gin.RecoveryWithWriter(log.StandardLogger().Out))
r.Use(gin.LoggerWithWriter(log.StandardLogger().Out))
r.Use(gin.RecoveryWithWriter(log.StandardLogger().Out))
server.Init(r)
base := fmt.Sprintf("%s:%d", conf.Conf.Address, conf.Conf.Port)
utils.Log.Infof("start server @ %s", base)
srv := &http.Server{Addr: base, Handler: r}
go func() {
var err error
if conf.Conf.Scheme.Https {
//err = r.RunTLS(base, conf.Conf.Scheme.CertFile, conf.Conf.Scheme.KeyFile)
err = srv.ListenAndServeTLS(conf.Conf.Scheme.CertFile, conf.Conf.Scheme.KeyFile)
} else {
err = srv.ListenAndServe()
}
if err != nil && err != http.ErrServerClosed {
utils.Log.Fatalf("failed to start: %s", err.Error())
}
}()
// Wait for interrupt signal to gracefully shutdown the server with
// a timeout of 5 seconds.
quit := make(chan os.Signal)
var httpHandler http.Handler = r
if conf.Conf.Scheme.EnableH2c {
httpHandler = h2c.NewHandler(r, &http2.Server{})
}
var httpSrv, httpsSrv, unixSrv *http.Server
if conf.Conf.Scheme.HttpPort > 0 {
httpBase := fmt.Sprintf("%s:%d", conf.Conf.Scheme.Address, conf.Conf.Scheme.HttpPort)
log.Infoln("start HTTP server", "@", httpBase)
httpSrv = &http.Server{Addr: httpBase, Handler: httpHandler}
go func() {
err := httpSrv.ListenAndServe()
if err != nil && !errors.Is(err, http.ErrServerClosed) {
log.Errorln("start HTTP server", ":", err)
serverCancel()
}
}()
}
if conf.Conf.Scheme.HttpsPort > 0 {
httpsBase := fmt.Sprintf("%s:%d", conf.Conf.Scheme.Address, conf.Conf.Scheme.HttpsPort)
log.Infoln("start HTTPS server", "@", httpsBase)
httpsSrv = &http.Server{Addr: httpsBase, Handler: r}
go func() {
err := httpsSrv.ListenAndServeTLS(conf.Conf.Scheme.CertFile, conf.Conf.Scheme.KeyFile)
if err != nil && !errors.Is(err, http.ErrServerClosed) {
log.Errorln("start HTTPS server", ":", err)
serverCancel()
}
}()
}
if conf.Conf.Scheme.UnixFile != "" {
log.Infoln("start Unix server", "@", conf.Conf.Scheme.UnixFile)
unixSrv = &http.Server{Handler: httpHandler}
go func() {
listener, err := net.Listen("unix", conf.Conf.Scheme.UnixFile)
if err != nil {
log.Errorln("start Unix server", ":", err)
serverCancel()
return
}
mode, err := strconv.ParseUint(conf.Conf.Scheme.UnixFilePerm, 8, 32)
if err != nil {
log.Errorln("parse unix_file_perm", ":", err)
} else {
err = os.Chmod(conf.Conf.Scheme.UnixFile, os.FileMode(mode))
if err != nil {
log.Errorln("chmod socket file", ":", err)
}
}
err = unixSrv.Serve(listener)
if err != nil && !errors.Is(err, http.ErrServerClosed) {
log.Errorln("start Unix server", ":", err)
serverCancel()
}
}()
}
quit := make(chan os.Signal, 1)
// kill (no param) default send syscanll.SIGTERM
// kill -2 is syscall.SIGINT
// kill -9 is syscall. SIGKILL but can"t be catch, so don't need add it
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
utils.Log.Println("Shutdown Server ...")
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
utils.Log.Fatal("Server Shutdown:", err)
}
// catching ctx.Done(). timeout of 3 seconds.
select {
case <-ctx.Done():
utils.Log.Println("timeout of 1 seconds.")
case <-quit:
case <-serverCtx.Done():
}
utils.Log.Println("Server exiting")
log.Println("shutdown server...")
Release()
quitCtx, quitCancel := context.WithTimeout(context.Background(), time.Second)
defer quitCancel()
var wg sync.WaitGroup
if httpSrv != nil {
wg.Add(1)
go func() {
defer wg.Done()
if err := httpSrv.Shutdown(quitCtx); err != nil {
log.Errorln("shutdown HTTP server", ":", err)
}
}()
}
if httpsSrv != nil {
wg.Add(1)
go func() {
defer wg.Done()
if err := httpsSrv.Shutdown(quitCtx); err != nil {
log.Errorln("shutdown HTTPS server", ":", err)
}
}()
}
if unixSrv != nil {
wg.Add(1)
go func() {
defer wg.Done()
if err := unixSrv.Shutdown(quitCtx); err != nil {
log.Errorln("shutdown Unix server", ":", err)
}
}()
}
wg.Wait()
log.Println("server exit")
},
}
func init() {
RootCmd.AddCommand(ServerCmd)
// Here you will define your flags and configuration settings.
// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// serverCmd.PersistentFlags().String("foo", "", "A help for foo")
// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// serverCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}
// OutAlistInit 暴露用于外部启动server的函数
func OutAlistInit() {
// OutOpenListInit 暴露用于外部启动server的函数
func OutOpenListInit() {
var (
cmd *cobra.Command
args []string

View File

@ -1,93 +0,0 @@
package _115
import (
"context"
"os"
driver115 "github.com/SheltonZhu/115driver/pkg/driver"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/pkg/utils"
"github.com/pkg/errors"
)
type Pan115 struct {
model.Storage
Addition
client *driver115.Pan115Client
}
func (d *Pan115) Config() driver.Config {
return config
}
func (d *Pan115) GetAddition() driver.Additional {
return &d.Addition
}
func (d *Pan115) Init(ctx context.Context) error {
return d.login()
}
func (d *Pan115) Drop(ctx context.Context) error {
return nil
}
func (d *Pan115) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
files, err := d.getFiles(dir.GetID())
if err != nil && !errors.Is(err, driver115.ErrNotExist) {
return nil, err
}
return utils.SliceConvert(files, func(src driver115.File) (model.Obj, error) {
return src, nil
})
}
func (d *Pan115) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
downloadInfo, err := d.client.Download(file.(driver115.File).PickCode)
if err != nil {
return nil, err
}
link := &model.Link{
URL: downloadInfo.Url.Url,
Header: downloadInfo.Header,
}
return link, nil
}
func (d *Pan115) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
if _, err := d.client.Mkdir(parentDir.GetID(), dirName); err != nil {
return err
}
return nil
}
func (d *Pan115) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
return d.client.Move(dstDir.GetID(), srcObj.GetID())
}
func (d *Pan115) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
return d.client.Rename(srcObj.GetID(), newName)
}
func (d *Pan115) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
return d.client.Copy(dstDir.GetID(), srcObj.GetID())
}
func (d *Pan115) Remove(ctx context.Context, obj model.Obj) error {
return d.client.Delete(obj.GetID())
}
func (d *Pan115) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
tempFile, err := utils.CreateTempFile(stream.GetReadCloser())
if err != nil {
return err
}
defer func() {
_ = tempFile.Close()
_ = os.Remove(tempFile.Name())
}()
return d.client.UploadFastOrByMultipart(dstDir.GetID(), stream.GetName(), stream.GetSize(), tempFile)
}
var _ driver.Driver = (*Pan115)(nil)

View File

@ -1,25 +0,0 @@
package _115
import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)
type Addition struct {
Cookie string `json:"cookie"`
QRCodeToken string `json:"qrcode_token"`
driver.RootID
}
var config = driver.Config{
Name: "115 Cloud",
DefaultRoot: "0",
OnlyProxy: true,
OnlyLocal: true,
}
func init() {
op.RegisterDriver(func() driver.Driver {
return &Pan115{}
})
}

View File

@ -1,8 +0,0 @@
package _115
import (
"github.com/SheltonZhu/115driver/pkg/driver"
"github.com/alist-org/alist/v3/internal/model"
)
var _ model.Obj = (*driver.File)(nil)

View File

@ -1,49 +0,0 @@
package _115
import (
"fmt"
"github.com/SheltonZhu/115driver/pkg/driver"
"github.com/pkg/errors"
)
var UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36 115Browser/23.9.3.2 115disk/30.1.0"
func (d *Pan115) login() error {
var err error
opts := []driver.Option{
driver.UA(UserAgent),
}
d.client = driver.New(opts...)
cr := &driver.Credential{}
if d.Addition.QRCodeToken != "" {
s := &driver.QRCodeSession{
UID: d.Addition.QRCodeToken,
}
if cr, err = d.client.QRCodeLogin(s); err != nil {
return errors.Wrap(err, "failed to login by qrcode")
}
d.Addition.Cookie = fmt.Sprintf("UID=%s;CID=%s;SEID=%s", cr.UID, cr.CID, cr.SEID)
d.Addition.QRCodeToken = ""
} else if d.Addition.Cookie != "" {
if err = cr.FromCookie(d.Addition.Cookie); err != nil {
return errors.Wrap(err, "failed to login by cookies")
}
d.client.ImportCredential(cr)
} else {
return errors.New("missing cookie or qrcode account")
}
return d.client.LoginCheck()
}
func (d *Pan115) getFiles(fileId string) ([]driver.File, error) {
res := make([]driver.File, 0)
files, err := d.client.List(fileId)
if err != nil {
return nil, err
}
for _, file := range *files {
res = append(res, file)
}
return res, nil
}

View File

@ -1,28 +0,0 @@
package _123
import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)
type Addition struct {
Username string `json:"username" required:"true"`
Password string `json:"password" required:"true"`
OrderBy string `json:"order_by" type:"select" options:"file_name,size,update_at" default:"file_name"`
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" default:"asc"`
driver.RootID
// define other
StreamUpload bool `json:"stream_upload"`
//Field string `json:"field" type:"select" required:"true" options:"a,b,c" default:"a"`
}
var config = driver.Config{
Name: "123Pan",
DefaultRoot: "0",
}
func init() {
op.RegisterDriver(func() driver.Driver {
return &Pan123{}
})
}

View File

@ -1,103 +0,0 @@
package _123
import (
"errors"
"fmt"
"net/http"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/pkg/utils"
"github.com/go-resty/resty/v2"
jsoniter "github.com/json-iterator/go"
)
// do others that not defined in Driver interface
func (d *Pan123) login() error {
var body base.Json
url := "https://www.123pan.com/a/api/user/sign_in"
if utils.IsEmailFormat(d.Username) {
body = base.Json{
"mail": d.Username,
"password": d.Password,
"type": 2,
}
} else {
body = base.Json{
"passport": d.Username,
"password": d.Password,
}
}
var resp TokenResp
res, err := base.RestyClient.R().
SetResult(&resp).
SetBody(body).Post(url)
if err != nil {
return err
}
if utils.Json.Get(res.Body(), "code").ToInt() != 200 {
err = fmt.Errorf(utils.Json.Get(res.Body(), "message").ToString())
} else {
d.AccessToken = resp.Data.Token
}
return err
}
func (d *Pan123) request(url string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
req := base.RestyClient.R()
req.SetHeaders(map[string]string{
"origin": "https://www.123pan.com",
"authorization": "Bearer " + d.AccessToken,
"platform": "web",
"app-version": "1.2",
})
if callback != nil {
callback(req)
}
if resp != nil {
req.SetResult(resp)
}
res, err := req.Execute(method, url)
if err != nil {
return nil, err
}
body := res.Body()
code := utils.Json.Get(body, "code").ToInt()
if code != 0 {
if code == 401 {
err := d.login()
if err != nil {
return nil, err
}
return d.request(url, method, callback, resp)
}
return nil, errors.New(jsoniter.Get(body, "message").ToString())
}
return body, nil
}
func (d *Pan123) getFiles(parentId string) ([]File, error) {
next := "0"
res := make([]File, 0)
for next != "-1" {
var resp Files
query := map[string]string{
"driveId": "0",
"limit": "100",
"next": next,
"orderBy": d.OrderBy,
"orderDirection": d.OrderDirection,
"parentFileId": parentId,
"trashed": "false",
}
_, err := d.request("https://www.123pan.com/api/file/list/new", http.MethodGet, func(req *resty.Request) {
req.SetQueryParams(query)
}, &resp)
if err != nil {
return nil, err
}
next = resp.Data.Next
res = append(res, resp.Data.InfoList...)
}
return res, nil
}

View File

@ -1,330 +0,0 @@
package _139
import (
"context"
"fmt"
"io"
"net/http"
"strconv"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/errs"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/pkg/utils"
log "github.com/sirupsen/logrus"
)
type Yun139 struct {
model.Storage
Addition
}
func (d *Yun139) Config() driver.Config {
return config
}
func (d *Yun139) GetAddition() driver.Additional {
return &d.Addition
}
func (d *Yun139) Init(ctx context.Context) error {
_, err := d.post("/orchestration/personalCloud/user/v1.0/qryUserExternInfo", base.Json{
"qryUserExternInfoReq": base.Json{
"commonAccountInfo": base.Json{
"account": d.Account,
"accountType": 1,
},
},
}, nil)
return err
}
func (d *Yun139) Drop(ctx context.Context) error {
return nil
}
func (d *Yun139) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
if d.isFamily() {
return d.familyGetFiles(dir.GetID())
} else {
return d.getFiles(dir.GetID())
}
}
func (d *Yun139) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
u, err := d.getLink(file.GetID())
if err != nil {
return nil, err
}
return &model.Link{URL: u}, nil
}
func (d *Yun139) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
data := base.Json{
"createCatalogExtReq": base.Json{
"parentCatalogID": parentDir.GetID(),
"newCatalogName": dirName,
"commonAccountInfo": base.Json{
"account": d.Account,
"accountType": 1,
},
},
}
pathname := "/orchestration/personalCloud/catalog/v1.0/createCatalogExt"
if d.isFamily() {
data = base.Json{
"cloudID": d.CloudID,
"commonAccountInfo": base.Json{
"account": d.Account,
"accountType": 1,
},
"docLibName": dirName,
}
pathname = "/orchestration/familyCloud/cloudCatalog/v1.0/createCloudDoc"
}
_, err := d.post(pathname, data, nil)
return err
}
func (d *Yun139) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
if d.isFamily() {
return errs.NotImplement
}
var contentInfoList []string
var catalogInfoList []string
if srcObj.IsDir() {
catalogInfoList = append(catalogInfoList, srcObj.GetID())
} else {
contentInfoList = append(contentInfoList, srcObj.GetID())
}
data := base.Json{
"createBatchOprTaskReq": base.Json{
"taskType": 3,
"actionType": "304",
"taskInfo": base.Json{
"contentInfoList": contentInfoList,
"catalogInfoList": catalogInfoList,
"newCatalogID": dstDir.GetID(),
},
"commonAccountInfo": base.Json{
"account": d.Account,
"accountType": 1,
},
},
}
pathname := "/orchestration/personalCloud/batchOprTask/v1.0/createBatchOprTask"
_, err := d.post(pathname, data, nil)
return err
}
func (d *Yun139) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
if d.isFamily() {
return errs.NotImplement
}
var data base.Json
var pathname string
if srcObj.IsDir() {
data = base.Json{
"catalogID": srcObj.GetID(),
"catalogName": newName,
"commonAccountInfo": base.Json{
"account": d.Account,
"accountType": 1,
},
}
pathname = "/orchestration/personalCloud/catalog/v1.0/updateCatalogInfo"
} else {
data = base.Json{
"contentID": srcObj.GetID(),
"contentName": newName,
"commonAccountInfo": base.Json{
"account": d.Account,
"accountType": 1,
},
}
pathname = "/orchestration/personalCloud/content/v1.0/updateContentInfo"
}
_, err := d.post(pathname, data, nil)
return err
}
func (d *Yun139) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
if d.isFamily() {
return errs.NotImplement
}
var contentInfoList []string
var catalogInfoList []string
if srcObj.IsDir() {
catalogInfoList = append(catalogInfoList, srcObj.GetID())
} else {
contentInfoList = append(contentInfoList, srcObj.GetID())
}
data := base.Json{
"createBatchOprTaskReq": base.Json{
"taskType": 3,
"actionType": 309,
"taskInfo": base.Json{
"contentInfoList": contentInfoList,
"catalogInfoList": catalogInfoList,
"newCatalogID": dstDir.GetID(),
},
"commonAccountInfo": base.Json{
"account": d.Account,
"accountType": 1,
},
},
}
pathname := "/orchestration/personalCloud/batchOprTask/v1.0/createBatchOprTask"
_, err := d.post(pathname, data, nil)
return err
}
func (d *Yun139) Remove(ctx context.Context, obj model.Obj) error {
var contentInfoList []string
var catalogInfoList []string
if obj.IsDir() {
catalogInfoList = append(catalogInfoList, obj.GetID())
} else {
contentInfoList = append(contentInfoList, obj.GetID())
}
data := base.Json{
"createBatchOprTaskReq": base.Json{
"taskType": 2,
"actionType": 201,
"taskInfo": base.Json{
"newCatalogID": "",
"contentInfoList": contentInfoList,
"catalogInfoList": catalogInfoList,
},
"commonAccountInfo": base.Json{
"account": d.Account,
"accountType": 1,
},
},
}
pathname := "/orchestration/personalCloud/batchOprTask/v1.0/createBatchOprTask"
if d.isFamily() {
data = base.Json{
"catalogList": catalogInfoList,
"contentList": contentInfoList,
"commonAccountInfo": base.Json{
"account": d.Account,
"accountType": 1,
},
"sourceCatalogType": 1002,
"taskType": 2,
}
pathname = "/orchestration/familyCloud/batchOprTask/v1.0/createBatchOprTask"
}
_, err := d.post(pathname, data, nil)
return err
}
const (
_ = iota //ignore first value by assigning to blank identifier
KB = 1 << (10 * iota)
MB
GB
TB
)
func getPartSize(size int64) int64 {
// 网盘对于分片数量存在上限
if size/GB > 30 {
return 512 * MB
}
return 100 * MB
}
func (d *Yun139) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
data := base.Json{
"manualRename": 2,
"operation": 0,
"fileCount": 1,
"totalSize": 0, // 去除上传大小限制
"uploadContentList": []base.Json{{
"contentName": stream.GetName(),
"contentSize": 0, // 去除上传大小限制
// "digest": "5a3231986ce7a6b46e408612d385bafa"
}},
"parentCatalogID": dstDir.GetID(),
"newCatalogName": "",
"commonAccountInfo": base.Json{
"account": d.Account,
"accountType": 1,
},
}
pathname := "/orchestration/personalCloud/uploadAndDownload/v1.0/pcUploadFileRequest"
if d.isFamily() {
data = d.newJson(base.Json{
"fileCount": 1,
"manualRename": 2,
"operation": 0,
"path": "",
"seqNo": "",
"totalSize": 0,
"uploadContentList": []base.Json{{
"contentName": stream.GetName(),
"contentSize": 0,
// "digest": "5a3231986ce7a6b46e408612d385bafa"
}},
})
pathname = "/orchestration/familyCloud/content/v1.0/getFileUploadURL"
return errs.NotImplement
}
var resp UploadResp
_, err := d.post(pathname, data, &resp)
if err != nil {
return err
}
// Progress
p := driver.NewProgress(stream.GetSize(), up)
var partSize = getPartSize(stream.GetSize())
part := (stream.GetSize() + partSize - 1) / partSize
for i := int64(0); i < part; i++ {
if utils.IsCanceled(ctx) {
return ctx.Err()
}
start := i * partSize
byteSize := stream.GetSize() - start
if byteSize > partSize {
byteSize = partSize
}
limitReader := io.LimitReader(stream, byteSize)
// Update Progress
r := io.TeeReader(limitReader, p)
req, err := http.NewRequest("POST", resp.Data.UploadResult.RedirectionURL, r)
if err != nil {
return err
}
req = req.WithContext(ctx)
req.Header.Set("Content-Type", "text/plain;name="+unicode(stream.GetName()))
req.Header.Set("contentSize", strconv.FormatInt(stream.GetSize(), 10))
req.Header.Set("range", fmt.Sprintf("bytes=%d-%d", start, start+byteSize-1))
req.Header.Set("uploadtaskID", resp.Data.UploadResult.UploadTaskID)
req.Header.Set("rangeType", "0")
req.ContentLength = byteSize
res, err := base.HttpClient.Do(req)
if err != nil {
return err
}
log.Debugf("%+v", res)
if res.StatusCode != http.StatusOK {
return fmt.Errorf("unexpected status code: %d", res.StatusCode)
}
res.Body.Close()
}
return nil
}
var _ driver.Driver = (*Yun139)(nil)

View File

@ -1,25 +0,0 @@
package _139
import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)
type Addition struct {
Account string `json:"account" required:"true"`
Cookie string `json:"cookie" type:"text" required:"true"`
driver.RootID
Type string `json:"type" type:"select" options:"personal,family" default:"personal"`
CloudID string `json:"cloud_id"`
}
var config = driver.Config{
Name: "139Yun",
LocalSort: true,
}
func init() {
op.RegisterDriver(func() driver.Driver {
return &Yun139{}
})
}

View File

@ -1,250 +0,0 @@
package _139
import (
"encoding/base64"
"errors"
"fmt"
"net/http"
"net/url"
"sort"
"strconv"
"strings"
"time"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/pkg/utils"
"github.com/alist-org/alist/v3/pkg/utils/random"
"github.com/go-resty/resty/v2"
jsoniter "github.com/json-iterator/go"
log "github.com/sirupsen/logrus"
)
// do others that not defined in Driver interface
func (d *Yun139) isFamily() bool {
return d.Type == "family"
}
func encodeURIComponent(str string) string {
r := url.QueryEscape(str)
r = strings.Replace(r, "+", "%20", -1)
r = strings.Replace(r, "%21", "!", -1)
r = strings.Replace(r, "%27", "'", -1)
r = strings.Replace(r, "%28", "(", -1)
r = strings.Replace(r, "%29", ")", -1)
r = strings.Replace(r, "%2A", "*", -1)
return r
}
func calSign(body, ts, randStr string) string {
body = encodeURIComponent(body)
strs := strings.Split(body, "")
sort.Strings(strs)
body = strings.Join(strs, "")
body = base64.StdEncoding.EncodeToString([]byte(body))
res := utils.GetMD5Encode(body) + utils.GetMD5Encode(ts+":"+randStr)
res = strings.ToUpper(utils.GetMD5Encode(res))
return res
}
func getTime(t string) time.Time {
stamp, _ := time.ParseInLocation("20060102150405", t, time.Local)
return stamp
}
func (d *Yun139) request(pathname string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
url := "https://yun.139.com" + pathname
req := base.RestyClient.R()
randStr := random.String(16)
ts := time.Now().Format("2006-01-02 15:04:05")
if callback != nil {
callback(req)
}
body, err := utils.Json.Marshal(req.Body)
if err != nil {
return nil, err
}
sign := calSign(string(body), ts, randStr)
svcType := "1"
if d.isFamily() {
svcType = "2"
}
req.SetHeaders(map[string]string{
"Accept": "application/json, text/plain, */*",
"CMS-DEVICE": "default",
"Cookie": d.Cookie,
"mcloud-channel": "1000101",
"mcloud-client": "10701",
//"mcloud-route": "001",
"mcloud-sign": fmt.Sprintf("%s,%s,%s", ts, randStr, sign),
//"mcloud-skey":"",
"mcloud-version": "6.6.0",
"Origin": "https://yun.139.com",
"Referer": "https://yun.139.com/w/",
"x-DeviceInfo": "||9|6.6.0|chrome|95.0.4638.69|uwIy75obnsRPIwlJSd7D9GhUvFwG96ce||macos 10.15.2||zh-CN|||",
"x-huawei-channelSrc": "10000034",
"x-inner-ntwk": "2",
"x-m4c-caller": "PC",
"x-m4c-src": "10002",
"x-SvcType": svcType,
})
var e BaseResp
req.SetResult(&e)
res, err := req.Execute(method, url)
log.Debugln(res.String())
if !e.Success {
return nil, errors.New(e.Message)
}
if resp != nil {
err = utils.Json.Unmarshal(res.Body(), resp)
if err != nil {
return nil, err
}
}
return res.Body(), nil
}
func (d *Yun139) post(pathname string, data interface{}, resp interface{}) ([]byte, error) {
return d.request(pathname, http.MethodPost, func(req *resty.Request) {
req.SetBody(data)
}, resp)
}
func (d *Yun139) getFiles(catalogID string) ([]model.Obj, error) {
start := 0
limit := 100
files := make([]model.Obj, 0)
for {
data := base.Json{
"catalogID": catalogID,
"sortDirection": 1,
"startNumber": start + 1,
"endNumber": start + limit,
"filterType": 0,
"catalogSortType": 0,
"contentSortType": 0,
"commonAccountInfo": base.Json{
"account": d.Account,
"accountType": 1,
},
}
var resp GetDiskResp
_, err := d.post("/orchestration/personalCloud/catalog/v1.0/getDisk", data, &resp)
if err != nil {
return nil, err
}
for _, catalog := range resp.Data.GetDiskResult.CatalogList {
f := model.Object{
ID: catalog.CatalogID,
Name: catalog.CatalogName,
Size: 0,
Modified: getTime(catalog.UpdateTime),
IsFolder: true,
}
files = append(files, &f)
}
for _, content := range resp.Data.GetDiskResult.ContentList {
f := model.ObjThumb{
Object: model.Object{
ID: content.ContentID,
Name: content.ContentName,
Size: content.ContentSize,
Modified: getTime(content.UpdateTime),
},
Thumbnail: model.Thumbnail{Thumbnail: content.ThumbnailURL},
//Thumbnail: content.BigthumbnailURL,
}
files = append(files, &f)
}
if start+limit >= resp.Data.GetDiskResult.NodeCount {
break
}
start += limit
}
return files, nil
}
func (d *Yun139) newJson(data map[string]interface{}) base.Json {
common := map[string]interface{}{
"catalogType": 3,
"cloudID": d.CloudID,
"cloudType": 1,
"commonAccountInfo": base.Json{
"account": d.Account,
"accountType": 1,
},
}
return utils.MergeMap(data, common)
}
func (d *Yun139) familyGetFiles(catalogID string) ([]model.Obj, error) {
pageNum := 1
files := make([]model.Obj, 0)
for {
data := d.newJson(base.Json{
"catalogID": catalogID,
"contentSortType": 0,
"pageInfo": base.Json{
"pageNum": pageNum,
"pageSize": 100,
},
"sortDirection": 1,
})
var resp QueryContentListResp
_, err := d.post("/orchestration/familyCloud/content/v1.0/queryContentList", data, &resp)
if err != nil {
return nil, err
}
for _, catalog := range resp.Data.CloudCatalogList {
f := model.Object{
ID: catalog.CatalogID,
Name: catalog.CatalogName,
Size: 0,
IsFolder: true,
Modified: getTime(catalog.LastUpdateTime),
}
files = append(files, &f)
}
for _, content := range resp.Data.CloudContentList {
f := model.ObjThumb{
Object: model.Object{
ID: content.ContentID,
Name: content.ContentName,
Size: content.ContentSize,
Modified: getTime(content.LastUpdateTime),
},
Thumbnail: model.Thumbnail{Thumbnail: content.ThumbnailURL},
//Thumbnail: content.BigthumbnailURL,
}
files = append(files, &f)
}
if 100*pageNum > resp.Data.TotalCount {
break
}
pageNum++
}
return files, nil
}
func (d *Yun139) getLink(contentId string) (string, error) {
data := base.Json{
"appName": "",
"contentID": contentId,
"commonAccountInfo": base.Json{
"account": d.Account,
"accountType": 1,
},
}
res, err := d.post("/orchestration/personalCloud/uploadAndDownload/v1.0/downloadRequest",
data, nil)
if err != nil {
return "", err
}
return jsoniter.Get(res, "data", "downloadURL").ToString(), nil
}
func unicode(str string) string {
textQuoted := strconv.QuoteToASCII(str)
textUnquoted := textQuoted[1 : len(textQuoted)-1]
return textUnquoted
}

View File

@ -1,273 +0,0 @@
package _189pc
import (
"context"
"net/http"
"strings"
"time"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/pkg/utils"
"github.com/go-resty/resty/v2"
)
type Cloud189PC struct {
model.Storage
Addition
identity string
client *resty.Client
putClient *resty.Client
loginParam *LoginParam
tokenInfo *AppSessionResp
}
func (y *Cloud189PC) Config() driver.Config {
return config
}
func (y *Cloud189PC) GetAddition() driver.Additional {
return &y.Addition
}
func (y *Cloud189PC) Init(ctx context.Context) (err error) {
// 处理个人云和家庭云参数
if y.isFamily() && y.RootFolderID == "-11" {
y.RootFolderID = ""
}
if !y.isFamily() && y.RootFolderID == "" {
y.RootFolderID = "-11"
y.FamilyID = ""
}
// 初始化请求客户端
if y.client == nil {
y.client = base.NewRestyClient().SetHeaders(map[string]string{
"Accept": "application/json;charset=UTF-8",
"Referer": WEB_URL,
})
}
if y.putClient == nil {
y.putClient = base.NewRestyClient().SetTimeout(120 * time.Second)
}
// 避免重复登陆
identity := utils.GetMD5Encode(y.Username + y.Password)
if !y.isLogin() || y.identity != identity {
y.identity = identity
if err = y.login(); err != nil {
return
}
}
// 处理家庭云ID
if y.isFamily() && y.FamilyID == "" {
if y.FamilyID, err = y.getFamilyID(); err != nil {
return err
}
}
return
}
func (y *Cloud189PC) Drop(ctx context.Context) error {
return nil
}
func (y *Cloud189PC) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
return y.getFiles(ctx, dir.GetID())
}
func (y *Cloud189PC) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
var downloadUrl struct {
URL string `json:"fileDownloadUrl"`
}
fullUrl := API_URL
if y.isFamily() {
fullUrl += "/family/file"
}
fullUrl += "/getFileDownloadUrl.action"
_, err := y.get(fullUrl, func(r *resty.Request) {
r.SetContext(ctx)
r.SetQueryParam("fileId", file.GetID())
if y.isFamily() {
r.SetQueryParams(map[string]string{
"familyId": y.FamilyID,
})
} else {
r.SetQueryParams(map[string]string{
"dt": "3",
"flag": "1",
})
}
}, &downloadUrl)
if err != nil {
return nil, err
}
// 重定向获取真实链接
downloadUrl.URL = strings.Replace(strings.ReplaceAll(downloadUrl.URL, "&amp;", "&"), "http://", "https://", 1)
res, err := base.NoRedirectClient.R().SetContext(ctx).Get(downloadUrl.URL)
if err != nil {
return nil, err
}
if res.StatusCode() == 302 {
downloadUrl.URL = res.Header().Get("location")
}
like := &model.Link{
URL: downloadUrl.URL,
Header: http.Header{
"User-Agent": []string{base.UserAgent},
},
}
/*
// 获取链接有效时常
strs := regexp.MustCompile(`(?i)expire[^=]*=([0-9]*)`).FindStringSubmatch(downloadUrl.URL)
if len(strs) == 2 {
timestamp, err := strconv.ParseInt(strs[1], 10, 64)
if err == nil {
expired := time.Duration(timestamp-time.Now().Unix()) * time.Second
like.Expiration = &expired
}
}
*/
return like, nil
}
func (y *Cloud189PC) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
fullUrl := API_URL
if y.isFamily() {
fullUrl += "/family/file"
}
fullUrl += "/createFolder.action"
_, err := y.post(fullUrl, func(req *resty.Request) {
req.SetContext(ctx)
req.SetQueryParams(map[string]string{
"folderName": dirName,
"relativePath": "",
})
if y.isFamily() {
req.SetQueryParams(map[string]string{
"familyId": y.FamilyID,
"parentId": parentDir.GetID(),
})
} else {
req.SetQueryParams(map[string]string{
"parentFolderId": parentDir.GetID(),
})
}
}, nil)
return err
}
func (y *Cloud189PC) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
_, err := y.post(API_URL+"/batch/createBatchTask.action", func(req *resty.Request) {
req.SetContext(ctx)
req.SetFormData(map[string]string{
"type": "MOVE",
"taskInfos": MustString(utils.Json.MarshalToString(
[]BatchTaskInfo{
{
FileId: srcObj.GetID(),
FileName: srcObj.GetName(),
IsFolder: BoolToNumber(srcObj.IsDir()),
},
})),
"targetFolderId": dstDir.GetID(),
})
if y.isFamily() {
req.SetFormData(map[string]string{
"familyId": y.FamilyID,
})
}
}, nil)
return err
}
func (y *Cloud189PC) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
queryParam := make(map[string]string)
fullUrl := API_URL
method := http.MethodPost
if y.isFamily() {
fullUrl += "/family/file"
method = http.MethodGet
queryParam["familyId"] = y.FamilyID
}
if srcObj.IsDir() {
fullUrl += "/renameFolder.action"
queryParam["folderId"] = srcObj.GetID()
queryParam["destFolderName"] = newName
} else {
fullUrl += "/renameFile.action"
queryParam["fileId"] = srcObj.GetID()
queryParam["destFileName"] = newName
}
_, err := y.request(fullUrl, method, func(req *resty.Request) {
req.SetContext(ctx)
req.SetQueryParams(queryParam)
}, nil, nil)
return err
}
func (y *Cloud189PC) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
_, err := y.post(API_URL+"/batch/createBatchTask.action", func(req *resty.Request) {
req.SetContext(ctx)
req.SetFormData(map[string]string{
"type": "COPY",
"taskInfos": MustString(utils.Json.MarshalToString(
[]BatchTaskInfo{
{
FileId: srcObj.GetID(),
FileName: srcObj.GetName(),
IsFolder: BoolToNumber(srcObj.IsDir()),
},
})),
"targetFolderId": dstDir.GetID(),
"targetFileName": dstDir.GetName(),
})
if y.isFamily() {
req.SetFormData(map[string]string{
"familyId": y.FamilyID,
})
}
}, nil)
return err
}
func (y *Cloud189PC) Remove(ctx context.Context, obj model.Obj) error {
_, err := y.post(API_URL+"/batch/createBatchTask.action", func(req *resty.Request) {
req.SetContext(ctx)
req.SetFormData(map[string]string{
"type": "DELETE",
"taskInfos": MustString(utils.Json.MarshalToString(
[]*BatchTaskInfo{
{
FileId: obj.GetID(),
FileName: obj.GetName(),
IsFolder: BoolToNumber(obj.IsDir()),
},
})),
})
if y.isFamily() {
req.SetFormData(map[string]string{
"familyId": y.FamilyID,
})
}
}, nil)
return err
}
func (y *Cloud189PC) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
if y.RapidUpload {
return y.FastUpload(ctx, dstDir, stream, up)
}
return y.CommonUpload(ctx, dstDir, stream, up)
}

View File

@ -1,246 +0,0 @@
package _189pc
import (
"encoding/xml"
"fmt"
"sort"
"strings"
"time"
)
// 居然有四种返回方式
type RespErr struct {
ResCode string `json:"res_code"`
ResMessage string `json:"res_message"`
XMLName xml.Name `xml:"error"`
Code string `json:"code" xml:"code"`
Message string `json:"message" xml:"message"`
// Code string `json:"code"`
Msg string `json:"msg"`
ErrorCode string `json:"errorCode"`
ErrorMsg string `json:"errorMsg"`
}
// 登陆需要的参数
type LoginParam struct {
// 加密后的用户名和密码
RsaUsername string
RsaPassword string
// rsa密钥
jRsaKey string
// 请求头参数
Lt string
ReqId string
// 表单参数
ParamId string
// 验证码
CaptchaToken string
}
// 登陆加密相关
type EncryptConfResp struct {
Result int `json:"result"`
Data struct {
UpSmsOn string `json:"upSmsOn"`
Pre string `json:"pre"`
PreDomain string `json:"preDomain"`
PubKey string `json:"pubKey"`
} `json:"data"`
}
type LoginResp struct {
Msg string `json:"msg"`
Result int `json:"result"`
ToUrl string `json:"toUrl"`
}
// 刷新session返回
type UserSessionResp struct {
ResCode int `json:"res_code"`
ResMessage string `json:"res_message"`
LoginName string `json:"loginName"`
KeepAlive int `json:"keepAlive"`
GetFileDiffSpan int `json:"getFileDiffSpan"`
GetUserInfoSpan int `json:"getUserInfoSpan"`
// 个人云
SessionKey string `json:"sessionKey"`
SessionSecret string `json:"sessionSecret"`
// 家庭云
FamilySessionKey string `json:"familySessionKey"`
FamilySessionSecret string `json:"familySessionSecret"`
}
// 登录返回
type AppSessionResp struct {
UserSessionResp
IsSaveName string `json:"isSaveName"`
// 会话刷新Token
AccessToken string `json:"accessToken"`
//Token刷新
RefreshToken string `json:"refreshToken"`
}
// 家庭云账户
type FamilyInfoListResp struct {
FamilyInfoResp []FamilyInfoResp `json:"familyInfoResp"`
}
type FamilyInfoResp struct {
Count int `json:"count"`
CreateTime string `json:"createTime"`
FamilyID int `json:"familyId"`
RemarkName string `json:"remarkName"`
Type int `json:"type"`
UseFlag int `json:"useFlag"`
UserRole int `json:"userRole"`
}
/*文件部分*/
// 文件
type Cloud189File struct {
CreateDate string `json:"createDate"`
FileCata int64 `json:"fileCata"`
Icon struct {
//iconOption 5
SmallUrl string `json:"smallUrl"`
LargeUrl string `json:"largeUrl"`
// iconOption 10
Max600 string `json:"max600"`
MediumURL string `json:"mediumUrl"`
} `json:"icon"`
ID int64 `json:"id"`
LastOpTime string `json:"lastOpTime"`
Md5 string `json:"md5"`
MediaType int `json:"mediaType"`
Name string `json:"name"`
Orientation int64 `json:"orientation"`
Rev string `json:"rev"`
Size int64 `json:"size"`
StarLabel int64 `json:"starLabel"`
parseTime *time.Time
}
func (c *Cloud189File) GetSize() int64 { return c.Size }
func (c *Cloud189File) GetName() string { return c.Name }
func (c *Cloud189File) ModTime() time.Time {
if c.parseTime == nil {
c.parseTime = MustParseTime(c.LastOpTime)
}
return *c.parseTime
}
func (c *Cloud189File) IsDir() bool { return false }
func (c *Cloud189File) GetID() string { return fmt.Sprint(c.ID) }
func (c *Cloud189File) GetPath() string { return "" }
func (c *Cloud189File) Thumb() string { return c.Icon.SmallUrl }
// 文件夹
type Cloud189Folder struct {
ID int64 `json:"id"`
ParentID int64 `json:"parentId"`
Name string `json:"name"`
FileCata int64 `json:"fileCata"`
FileCount int64 `json:"fileCount"`
LastOpTime string `json:"lastOpTime"`
CreateDate string `json:"createDate"`
FileListSize int64 `json:"fileListSize"`
Rev string `json:"rev"`
StarLabel int64 `json:"starLabel"`
parseTime *time.Time
}
func (c *Cloud189Folder) GetSize() int64 { return 0 }
func (c *Cloud189Folder) GetName() string { return c.Name }
func (c *Cloud189Folder) ModTime() time.Time {
if c.parseTime == nil {
c.parseTime = MustParseTime(c.LastOpTime)
}
return *c.parseTime
}
func (c *Cloud189Folder) IsDir() bool { return true }
func (c *Cloud189Folder) GetID() string { return fmt.Sprint(c.ID) }
func (c *Cloud189Folder) GetPath() string { return "" }
type Cloud189FilesResp struct {
//ResCode int `json:"res_code"`
//ResMessage string `json:"res_message"`
FileListAO struct {
Count int `json:"count"`
FileList []Cloud189File `json:"fileList"`
FolderList []Cloud189Folder `json:"folderList"`
} `json:"fileListAO"`
}
// TaskInfo 任务信息
type BatchTaskInfo struct {
// FileId 文件ID
FileId string `json:"fileId"`
// FileName 文件名
FileName string `json:"fileName"`
// IsFolder 是否是文件夹0-否1-是
IsFolder int `json:"isFolder"`
// SrcParentId 文件所在父目录ID
//SrcParentId string `json:"srcParentId"`
}
/* 上传部分 */
type InitMultiUploadResp struct {
//Code string `json:"code"`
Data struct {
UploadType int `json:"uploadType"`
UploadHost string `json:"uploadHost"`
UploadFileID string `json:"uploadFileId"`
FileDataExists int `json:"fileDataExists"`
} `json:"data"`
}
type UploadUrlsResp struct {
Code string `json:"code"`
UploadUrls map[string]Part `json:"uploadUrls"`
}
type Part struct {
RequestURL string `json:"requestURL"`
RequestHeader string `json:"requestHeader"`
}
type Params map[string]string
func (p Params) Set(k, v string) {
p[k] = v
}
func (p Params) Encode() string {
if p == nil {
return ""
}
var buf strings.Builder
keys := make([]string, 0, len(p))
for k := range p {
keys = append(keys, k)
}
sort.Strings(keys)
for i := range keys {
if buf.Len() > 0 {
buf.WriteByte('&')
}
buf.WriteString(keys[i])
buf.WriteByte('=')
buf.WriteString(p[keys[i]])
}
return buf.String()
}

View File

@ -1,652 +0,0 @@
package _189pc
import (
"bytes"
"context"
"crypto/md5"
"encoding/base64"
"encoding/hex"
"fmt"
"io"
"math"
"net/http"
"net/http/cookiejar"
"net/url"
"os"
"regexp"
"strings"
"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/model"
"github.com/alist-org/alist/v3/internal/op"
"github.com/alist-org/alist/v3/internal/setting"
"github.com/alist-org/alist/v3/pkg/utils"
"github.com/go-resty/resty/v2"
"github.com/google/uuid"
jsoniter "github.com/json-iterator/go"
)
const (
ACCOUNT_TYPE = "02"
APP_ID = "8025431004"
CLIENT_TYPE = "10020"
VERSION = "6.2"
WEB_URL = "https://cloud.189.cn"
AUTH_URL = "https://open.e.189.cn"
API_URL = "https://api.cloud.189.cn"
UPLOAD_URL = "https://upload.cloud.189.cn"
RETURN_URL = "https://m.cloud.189.cn/zhuanti/2020/loginErrorPc/index.html"
PC = "TELEPC"
MAC = "TELEMAC"
CHANNEL_ID = "web_cloud.189.cn"
)
func (y *Cloud189PC) request(url, method string, callback base.ReqCallback, params Params, resp interface{}) ([]byte, error) {
dateOfGmt := getHttpDateStr()
sessionKey := y.tokenInfo.SessionKey
sessionSecret := y.tokenInfo.SessionSecret
if y.isFamily() {
sessionKey = y.tokenInfo.FamilySessionKey
sessionSecret = y.tokenInfo.FamilySessionSecret
}
req := y.client.R().SetQueryParams(clientSuffix()).SetHeaders(map[string]string{
"Date": dateOfGmt,
"SessionKey": sessionKey,
"X-Request-ID": uuid.NewString(),
})
// 设置params
var paramsData string
if params != nil {
paramsData = AesECBEncrypt(params.Encode(), sessionSecret[:16])
req.SetQueryParam("params", paramsData)
}
req.SetHeader("Signature", signatureOfHmac(sessionSecret, sessionKey, method, url, dateOfGmt, paramsData))
if callback != nil {
callback(req)
}
if resp != nil {
req.SetResult(resp)
}
res, err := req.Execute(method, url)
if err != nil {
return nil, err
}
var erron RespErr
utils.Json.Unmarshal(res.Body(), &erron)
if erron.ResCode != "" {
return nil, fmt.Errorf("res_code: %s ,res_msg: %s", erron.ResCode, erron.ResMessage)
}
if erron.Code != "" && erron.Code != "SUCCESS" {
if erron.Msg != "" {
return nil, fmt.Errorf("code: %s ,msg: %s", erron.Code, erron.Msg)
}
if erron.Message != "" {
return nil, fmt.Errorf("code: %s ,msg: %s", erron.Code, erron.Message)
}
return nil, fmt.Errorf(res.String())
}
switch erron.ErrorCode {
case "":
break
case "InvalidSessionKey":
if err = y.refreshSession(); err != nil {
return nil, err
}
return y.request(url, method, callback, params, resp)
default:
return nil, fmt.Errorf("err_code: %s ,err_msg: %s", erron.ErrorCode, erron.ErrorMsg)
}
if strings.Contains(res.String(), "userSessionBO is null") {
if err = y.refreshSession(); err != nil {
return nil, err
}
return y.request(url, method, callback, params, resp)
}
resCode := utils.Json.Get(res.Body(), "res_code").ToInt64()
message := utils.Json.Get(res.Body(), "res_message").ToString()
switch resCode {
case 0:
return res.Body(), nil
default:
return nil, fmt.Errorf("res_code: %d ,res_msg: %s", resCode, message)
}
}
func (y *Cloud189PC) get(url string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
return y.request(url, http.MethodGet, callback, nil, resp)
}
func (y *Cloud189PC) post(url string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
return y.request(url, http.MethodPost, callback, nil, resp)
}
func (y *Cloud189PC) getFiles(ctx context.Context, fileId string) ([]model.Obj, error) {
fullUrl := API_URL
if y.isFamily() {
fullUrl += "/family/file"
}
fullUrl += "/listFiles.action"
res := make([]model.Obj, 0, 130)
for pageNum := 1; ; pageNum++ {
var resp Cloud189FilesResp
_, err := y.get(fullUrl, func(r *resty.Request) {
r.SetContext(ctx)
r.SetQueryParams(map[string]string{
"folderId": fileId,
"fileType": "0",
"mediaAttr": "0",
"iconOption": "5",
"pageNum": fmt.Sprint(pageNum),
"pageSize": "130",
})
if y.isFamily() {
r.SetQueryParams(map[string]string{
"familyId": y.FamilyID,
"orderBy": toFamilyOrderBy(y.OrderBy),
"descending": toDesc(y.OrderDirection),
})
} else {
r.SetQueryParams(map[string]string{
"recursive": "0",
"orderBy": y.OrderBy,
"descending": toDesc(y.OrderDirection),
})
}
}, &resp)
if err != nil {
return nil, err
}
// 获取完毕跳出
if resp.FileListAO.Count == 0 {
break
}
for i := 0; i < len(resp.FileListAO.FolderList); i++ {
res = append(res, &resp.FileListAO.FolderList[i])
}
for i := 0; i < len(resp.FileListAO.FileList); i++ {
res = append(res, &resp.FileListAO.FileList[i])
}
}
return res, nil
}
func (y *Cloud189PC) login() (err error) {
// 初始化登陆所需参数
if y.loginParam == nil || !y.NoUseOcr {
if err = y.initLoginParam(); err != nil {
// 验证码也通过错误返回
return err
}
}
defer func() {
// 销毁验证码
y.VCode = ""
// 销毁登陆参数
y.loginParam = nil
// 遇到错误,重新加载登陆参数
if err != nil && y.NoUseOcr {
if err1 := y.initLoginParam(); err1 != nil {
err = fmt.Errorf("err1: %s \nerr2: %s", err, err1)
}
}
}()
param := y.loginParam
var loginresp LoginResp
_, err = y.client.R().
ForceContentType("application/json;charset=UTF-8").SetResult(&loginresp).
SetHeaders(map[string]string{
"REQID": param.ReqId,
"lt": param.Lt,
}).
SetFormData(map[string]string{
"appKey": APP_ID,
"accountType": ACCOUNT_TYPE,
"userName": param.RsaUsername,
"password": param.RsaPassword,
"validateCode": y.VCode,
"captchaToken": param.CaptchaToken,
"returnUrl": RETURN_URL,
"mailSuffix": "@189.cn",
"dynamicCheck": "FALSE",
"clientType": CLIENT_TYPE,
"cb_SaveName": "1",
"isOauth2": "false",
"state": "",
"paramId": param.ParamId,
}).
Post(AUTH_URL + "/api/logbox/oauth2/loginSubmit.do")
if err != nil {
return err
}
if loginresp.ToUrl == "" {
return fmt.Errorf("login failed,No toUrl obtained, msg: %s", loginresp.Msg)
}
// 获取Session
var erron RespErr
var tokenInfo AppSessionResp
_, err = y.client.R().
SetResult(&tokenInfo).SetError(&erron).
SetQueryParams(clientSuffix()).
SetQueryParam("redirectURL", url.QueryEscape(loginresp.ToUrl)).
Post(API_URL + "/getSessionForPC.action")
if err != nil {
return
}
if erron.ResCode != "" {
err = fmt.Errorf(erron.ResMessage)
return
}
if tokenInfo.ResCode != 0 {
err = fmt.Errorf(tokenInfo.ResMessage)
return
}
y.tokenInfo = &tokenInfo
return
}
/* 初始化登陆需要的参数
* 如果遇到验证码返回错误
*/
func (y *Cloud189PC) initLoginParam() error {
// 清除cookie
jar, _ := cookiejar.New(nil)
y.client.SetCookieJar(jar)
res, err := y.client.R().
SetQueryParams(map[string]string{
"appId": APP_ID,
"clientType": CLIENT_TYPE,
"returnURL": RETURN_URL,
"timeStamp": fmt.Sprint(timestamp()),
}).
Get(WEB_URL + "/api/portal/unifyLoginForPC.action")
if err != nil {
return err
}
param := LoginParam{
CaptchaToken: regexp.MustCompile(`'captchaToken' value='(.+?)'`).FindStringSubmatch(res.String())[1],
Lt: regexp.MustCompile(`lt = "(.+?)"`).FindStringSubmatch(res.String())[1],
ParamId: regexp.MustCompile(`paramId = "(.+?)"`).FindStringSubmatch(res.String())[1],
ReqId: regexp.MustCompile(`reqId = "(.+?)"`).FindStringSubmatch(res.String())[1],
// jRsaKey: regexp.MustCompile(`"j_rsaKey" value="(.+?)"`).FindStringSubmatch(res.String())[1],
}
// 获取rsa公钥
var encryptConf EncryptConfResp
_, err = y.client.R().
ForceContentType("application/json;charset=UTF-8").SetResult(&encryptConf).
SetFormData(map[string]string{"appId": APP_ID}).
Post(AUTH_URL + "/api/logbox/config/encryptConf.do")
if err != nil {
return err
}
param.jRsaKey = fmt.Sprintf("-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----", encryptConf.Data.PubKey)
param.RsaUsername = encryptConf.Data.Pre + RsaEncrypt(param.jRsaKey, y.Username)
param.RsaPassword = encryptConf.Data.Pre + RsaEncrypt(param.jRsaKey, y.Password)
y.loginParam = &param
imgRes, err := y.client.R().
SetQueryParams(map[string]string{
"token": param.CaptchaToken,
"REQID": param.ReqId,
"rnd": fmt.Sprint(timestamp()),
}).
Get(AUTH_URL + "/api/logbox/oauth2/picCaptcha.do")
if err != nil {
return fmt.Errorf("failed to obtain verification code")
}
if imgRes.Size() > 20 {
if setting.GetStr(conf.OcrApi) != "" && !y.NoUseOcr {
vRes, err := base.RestyClient.R().
SetMultipartField("image", "validateCode.png", "image/png", bytes.NewReader(imgRes.Body())).
Post(setting.GetStr(conf.OcrApi))
if err != nil {
return err
}
if jsoniter.Get(vRes.Body(), "status").ToInt() == 200 {
y.VCode = jsoniter.Get(vRes.Body(), "result").ToString()
return nil
}
}
// 返回验证码图片给前端
return fmt.Errorf(`need img validate code: <img src="data:image/png;base64,%s"/>`, base64.StdEncoding.EncodeToString(imgRes.Body()))
}
return nil
}
// 刷新会话
func (y *Cloud189PC) refreshSession() (err error) {
var erron RespErr
var userSessionResp UserSessionResp
_, err = y.client.R().
SetResult(&userSessionResp).SetError(&erron).
SetQueryParams(clientSuffix()).
SetQueryParams(map[string]string{
"appId": APP_ID,
"accessToken": y.tokenInfo.AccessToken,
}).
SetHeader("X-Request-ID", uuid.NewString()).
Get(API_URL + "/getSessionForPC.action")
if err != nil {
return err
}
// 错误影响正常访问,下线该储存
defer func() {
if err != nil {
y.GetStorage().SetStatus(fmt.Sprintf("%+v", err.Error()))
op.MustSaveDriverStorage(y)
}
}()
switch erron.ResCode {
case "":
break
case "UserInvalidOpenToken":
if err = y.login(); err != nil {
return err
}
default:
err = fmt.Errorf("res_code: %s ,res_msg: %s", erron.ResCode, erron.ResMessage)
return
}
switch userSessionResp.ResCode {
case 0:
y.tokenInfo.UserSessionResp = userSessionResp
default:
err = fmt.Errorf("code: %d , msg: %s", userSessionResp.ResCode, userSessionResp.ResMessage)
}
return
}
// 普通上传
func (y *Cloud189PC) CommonUpload(ctx context.Context, dstDir model.Obj, file model.FileStreamer, up driver.UpdateProgress) (err error) {
const DEFAULT int64 = 10485760
var count = int64(math.Ceil(float64(file.GetSize()) / float64(DEFAULT)))
requestID := uuid.NewString()
params := Params{
"parentFolderId": dstDir.GetID(),
"fileName": url.QueryEscape(file.GetName()),
"fileSize": fmt.Sprint(file.GetSize()),
"sliceSize": fmt.Sprint(DEFAULT),
"lazyCheck": "1",
}
fullUrl := UPLOAD_URL
if y.isFamily() {
params.Set("familyId", y.FamilyID)
fullUrl += "/family"
} else {
//params.Set("extend", `{"opScene":"1","relativepath":"","rootfolderid":""}`)
fullUrl += "/person"
}
// 初始化上传
var initMultiUpload InitMultiUploadResp
_, err = y.request(fullUrl+"/initMultiUpload", http.MethodGet, func(req *resty.Request) {
req.SetContext(ctx)
req.SetHeader("X-Request-ID", requestID)
}, params, &initMultiUpload)
if err != nil {
return err
}
fileMd5 := md5.New()
silceMd5 := md5.New()
silceMd5Hexs := make([]string, 0, count)
byteData := bytes.NewBuffer(make([]byte, DEFAULT))
for i := int64(1); i <= count; i++ {
if utils.IsCanceled(ctx) {
return ctx.Err()
}
// 读取块
byteData.Reset()
silceMd5.Reset()
_, err := io.CopyN(io.MultiWriter(fileMd5, silceMd5, byteData), file, DEFAULT)
if err != io.EOF && err != io.ErrUnexpectedEOF && err != nil {
return err
}
// 计算块md5并进行hex和base64编码
md5Bytes := silceMd5.Sum(nil)
silceMd5Hexs = append(silceMd5Hexs, strings.ToUpper(hex.EncodeToString(md5Bytes)))
silceMd5Base64 := base64.StdEncoding.EncodeToString(md5Bytes)
// 获取上传链接
var uploadUrl UploadUrlsResp
_, err = y.request(fullUrl+"/getMultiUploadUrls", http.MethodGet,
func(req *resty.Request) {
req.SetContext(ctx)
req.SetHeader("X-Request-ID", requestID)
}, Params{
"partInfo": fmt.Sprintf("%d-%s", i, silceMd5Base64),
"uploadFileId": initMultiUpload.Data.UploadFileID,
}, &uploadUrl)
if err != nil {
return err
}
// 开始上传
uploadData := uploadUrl.UploadUrls[fmt.Sprint("partNumber_", i)]
res, err := y.putClient.R().
SetContext(ctx).
SetQueryParams(clientSuffix()).
SetHeaders(ParseHttpHeader(uploadData.RequestHeader)).
SetBody(byteData).
Put(uploadData.RequestURL)
if err != nil {
return err
}
if res.StatusCode() != http.StatusOK {
return fmt.Errorf("updload fail,msg: %s", res.String())
}
up(int(i * 100 / count))
}
fileMd5Hex := strings.ToUpper(hex.EncodeToString(fileMd5.Sum(nil)))
sliceMd5Hex := fileMd5Hex
if file.GetSize() > DEFAULT {
sliceMd5Hex = strings.ToUpper(utils.GetMD5Encode(strings.Join(silceMd5Hexs, "\n")))
}
// 提交上传
_, err = y.request(fullUrl+"/commitMultiUploadFile", http.MethodGet,
func(req *resty.Request) {
req.SetContext(ctx)
req.SetHeader("X-Request-ID", requestID)
}, Params{
"uploadFileId": initMultiUpload.Data.UploadFileID,
"fileMd5": fileMd5Hex,
"sliceMd5": sliceMd5Hex,
"lazyCheck": "1",
"isLog": "0",
"opertype": "3",
}, nil)
return err
}
// 快传
func (y *Cloud189PC) FastUpload(ctx context.Context, dstDir model.Obj, file model.FileStreamer, up driver.UpdateProgress) (err error) {
// 需要获取完整文件md5,必须支持 io.Seek
tempFile, err := utils.CreateTempFile(file.GetReadCloser())
if err != nil {
return err
}
defer func() {
_ = tempFile.Close()
_ = os.Remove(tempFile.Name())
}()
const DEFAULT int64 = 10485760
count := int(math.Ceil(float64(file.GetSize()) / float64(DEFAULT)))
// 优先计算所需信息
fileMd5 := md5.New()
silceMd5 := md5.New()
silceMd5Hexs := make([]string, 0, count)
silceMd5Base64s := make([]string, 0, count)
for i := 1; i <= count; i++ {
if utils.IsCanceled(ctx) {
return ctx.Err()
}
silceMd5.Reset()
if _, err := io.CopyN(io.MultiWriter(fileMd5, silceMd5), tempFile, DEFAULT); err != nil && err != io.EOF && err != io.ErrUnexpectedEOF {
return err
}
md5Byte := silceMd5.Sum(nil)
silceMd5Hexs = append(silceMd5Hexs, strings.ToUpper(hex.EncodeToString(md5Byte)))
silceMd5Base64s = append(silceMd5Base64s, fmt.Sprint(i, "-", base64.StdEncoding.EncodeToString(md5Byte)))
}
if _, err = tempFile.Seek(0, io.SeekStart); err != nil {
return err
}
fileMd5Hex := strings.ToUpper(hex.EncodeToString(fileMd5.Sum(nil)))
sliceMd5Hex := fileMd5Hex
if file.GetSize() > DEFAULT {
sliceMd5Hex = strings.ToUpper(utils.GetMD5Encode(strings.Join(silceMd5Hexs, "\n")))
}
requestID := uuid.NewString()
// 检测是否支持快传
params := Params{
"parentFolderId": dstDir.GetID(),
"fileName": url.QueryEscape(file.GetName()),
"fileSize": fmt.Sprint(file.GetSize()),
"fileMd5": fileMd5Hex,
"sliceSize": fmt.Sprint(DEFAULT),
"sliceMd5": sliceMd5Hex,
}
fullUrl := UPLOAD_URL
if y.isFamily() {
params.Set("familyId", y.FamilyID)
fullUrl += "/family"
} else {
//params.Set("extend", `{"opScene":"1","relativepath":"","rootfolderid":""}`)
fullUrl += "/person"
}
var uploadInfo InitMultiUploadResp
_, err = y.request(fullUrl+"/initMultiUpload", http.MethodGet, func(req *resty.Request) {
req.SetContext(ctx)
req.SetHeader("X-Request-ID", requestID)
}, params, &uploadInfo)
if err != nil {
return err
}
// 网盘中不存在该文件,开始上传
if uploadInfo.Data.FileDataExists != 1 {
var uploadUrls UploadUrlsResp
_, err = y.request(fullUrl+"/getMultiUploadUrls", http.MethodGet,
func(req *resty.Request) {
req.SetContext(ctx)
req.SetHeader("X-Request-ID", requestID)
}, Params{
"uploadFileId": uploadInfo.Data.UploadFileID,
"partInfo": strings.Join(silceMd5Base64s, ","),
}, &uploadUrls)
if err != nil {
return err
}
for i := 1; i <= count; i++ {
select {
case <-ctx.Done():
return ctx.Err()
default:
}
uploadData := uploadUrls.UploadUrls[fmt.Sprint("partNumber_", i)]
res, err := y.putClient.R().
SetContext(ctx).
SetQueryParams(clientSuffix()).
SetHeaders(ParseHttpHeader(uploadData.RequestHeader)).
SetBody(io.LimitReader(tempFile, DEFAULT)).
Put(uploadData.RequestURL)
if err != nil {
return err
}
if res.StatusCode() != http.StatusOK {
return fmt.Errorf("updload fail,msg: %s", res.String())
}
up(int(i * 100 / count))
}
}
// 提交
_, err = y.request(fullUrl+"/commitMultiUploadFile", http.MethodGet,
func(req *resty.Request) {
req.SetContext(ctx)
req.SetHeader("X-Request-ID", requestID)
}, Params{
"uploadFileId": uploadInfo.Data.UploadFileID,
"isLog": "0",
"opertype": "3",
}, nil)
return err
}
func (y *Cloud189PC) isFamily() bool {
return y.Type == "family"
}
func (y *Cloud189PC) isLogin() bool {
if y.tokenInfo == nil {
return false
}
_, err := y.get(API_URL+"/getUserInfo.action", nil, nil)
return err == nil
}
// 获取家庭云所有用户信息
func (y *Cloud189PC) getFamilyInfoList() ([]FamilyInfoResp, error) {
var resp FamilyInfoListResp
_, err := y.get(API_URL+"/family/manage/getFamilyList.action", nil, &resp)
if err != nil {
return nil, err
}
return resp.FamilyInfoResp, nil
}
// 抽取家庭云ID
func (y *Cloud189PC) getFamilyID() (string, error) {
infos, err := y.getFamilyInfoList()
if err != nil {
return "", err
}
if len(infos) == 0 {
return "", fmt.Errorf("cannot get automatically,please input family_id")
}
for _, info := range infos {
if strings.Contains(y.tokenInfo.LoginName, info.RemarkName) {
return fmt.Sprint(info.FamilyID), nil
}
}
return fmt.Sprint(infos[0].FamilyID), nil
}

View File

@ -1,118 +0,0 @@
package alist_v2
import (
"context"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/errs"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/server/common"
)
type AListV2 struct {
model.Storage
Addition
}
func (d *AListV2) Config() driver.Config {
return config
}
func (d *AListV2) GetAddition() driver.Additional {
return &d.Addition
}
func (d *AListV2) Init(ctx context.Context) error {
if len(d.Addition.Address) > 0 && string(d.Addition.Address[len(d.Addition.Address)-1]) == "/" {
d.Addition.Address = d.Addition.Address[0 : len(d.Addition.Address)-1]
}
// TODO login / refresh token
//op.MustSaveDriverStorage(d)
return nil
}
func (d *AListV2) Drop(ctx context.Context) error {
return nil
}
func (d *AListV2) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
url := d.Address + "/api/public/path"
var resp common.Resp[PathResp]
_, err := base.RestyClient.R().
SetResult(&resp).
SetHeader("Authorization", d.AccessToken).
SetBody(PathReq{
PageNum: 0,
PageSize: 0,
Path: dir.GetPath(),
Password: d.Password,
}).Post(url)
if err != nil {
return nil, err
}
var files []model.Obj
for _, f := range resp.Data.Files {
file := model.ObjThumb{
Object: model.Object{
Name: f.Name,
Modified: *f.UpdatedAt,
Size: f.Size,
IsFolder: f.Type == 1,
},
Thumbnail: model.Thumbnail{Thumbnail: f.Thumbnail},
}
files = append(files, &file)
}
return files, nil
}
func (d *AListV2) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
url := d.Address + "/api/public/path"
var resp common.Resp[PathResp]
_, err := base.RestyClient.R().
SetResult(&resp).
SetHeader("Authorization", d.AccessToken).
SetBody(PathReq{
PageNum: 0,
PageSize: 0,
Path: file.GetPath(),
Password: d.Password,
}).Post(url)
if err != nil {
return nil, err
}
return &model.Link{
URL: resp.Data.Files[0].Url,
}, nil
}
func (d *AListV2) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
return errs.NotImplement
}
func (d *AListV2) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
return errs.NotImplement
}
func (d *AListV2) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
return errs.NotImplement
}
func (d *AListV2) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
return errs.NotImplement
}
func (d *AListV2) Remove(ctx context.Context, obj model.Obj) error {
return errs.NotImplement
}
func (d *AListV2) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
return errs.NotImplement
}
//func (d *AList) Other(ctx context.Context, args model.OtherArgs) (interface{}, error) {
// return nil, errs.NotSupport
//}
var _ driver.Driver = (*AListV2)(nil)

View File

@ -1,26 +0,0 @@
package alist_v2
import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)
type Addition struct {
driver.RootPath
Address string `json:"url" required:"true"`
Password string `json:"password"`
AccessToken string `json:"access_token"`
}
var config = driver.Config{
Name: "AList V2",
LocalSort: true,
NoUpload: true,
DefaultRoot: "/",
}
func init() {
op.RegisterDriver(func() driver.Driver {
return &AListV2{}
})
}

View File

@ -1,31 +0,0 @@
package alist_v2
import (
"time"
)
type File struct {
Id string `json:"-"`
Name string `json:"name"`
Size int64 `json:"size"`
Type int `json:"type"`
Driver string `json:"driver"`
UpdatedAt *time.Time `json:"updated_at"`
Thumbnail string `json:"thumbnail"`
Url string `json:"url"`
SizeStr string `json:"size_str"`
TimeStr string `json:"time_str"`
}
type PathResp struct {
Type string `json:"type"`
//Meta Meta `json:"meta"`
Files []File `json:"files"`
}
type PathReq struct {
PageNum int `json:"page_num"`
PageSize int `json:"page_size"`
Password string `json:"password"`
Path string `json:"path"`
}

View File

@ -1 +0,0 @@
package alist_v2

View File

@ -1,179 +0,0 @@
package alist_v3
import (
"context"
"io"
"path"
"strconv"
"strings"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/server/common"
)
type AListV3 struct {
model.Storage
Addition
}
func (d *AListV3) Config() driver.Config {
return config
}
func (d *AListV3) GetAddition() driver.Additional {
return &d.Addition
}
func (d *AListV3) Init(ctx context.Context) error {
d.Addition.Address = strings.TrimSuffix(d.Addition.Address, "/")
// TODO login / refresh token
//op.MustSaveDriverStorage(d)
return nil
}
func (d *AListV3) Drop(ctx context.Context) error {
return nil
}
func (d *AListV3) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
url := d.Address + "/api/fs/list"
var resp common.Resp[FsListResp]
_, err := base.RestyClient.R().
SetResult(&resp).
SetHeader("Authorization", d.AccessToken).
SetBody(ListReq{
PageReq: model.PageReq{
Page: 1,
PerPage: 0,
},
Path: dir.GetPath(),
Password: d.Password,
Refresh: false,
}).Post(url)
if err != nil {
return nil, err
}
var files []model.Obj
for _, f := range resp.Data.Content {
file := model.ObjThumb{
Object: model.Object{
Name: f.Name,
Modified: f.Modified,
Size: f.Size,
IsFolder: f.IsDir,
},
Thumbnail: model.Thumbnail{Thumbnail: f.Thumb},
}
files = append(files, &file)
}
return files, nil
}
func (d *AListV3) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
url := d.Address + "/api/fs/get"
var resp common.Resp[FsGetResp]
_, err := base.RestyClient.R().
SetResult(&resp).
SetHeader("Authorization", d.AccessToken).
SetBody(FsGetReq{
Path: file.GetPath(),
Password: d.Password,
}).Post(url)
if err != nil {
return nil, err
}
return &model.Link{
URL: resp.Data.RawURL,
}, nil
}
func (d *AListV3) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
url := d.Address + "/api/fs/mkdir"
var resp common.Resp[interface{}]
_, err := base.RestyClient.R().
SetResult(&resp).
SetHeader("Authorization", d.AccessToken).
SetBody(MkdirOrLinkReq{
Path: path.Join(parentDir.GetPath(), dirName),
}).Post(url)
return checkResp(resp, err)
}
func (d *AListV3) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
url := d.Address + "/api/fs/move"
var resp common.Resp[interface{}]
_, err := base.RestyClient.R().
SetResult(&resp).
SetHeader("Authorization", d.AccessToken).
SetBody(MoveCopyReq{
SrcDir: path.Dir(srcObj.GetPath()),
DstDir: dstDir.GetPath(),
Names: []string{srcObj.GetName()},
}).Post(url)
return checkResp(resp, err)
}
func (d *AListV3) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
url := d.Address + "/api/fs/rename"
var resp common.Resp[interface{}]
_, err := base.RestyClient.R().
SetResult(&resp).
SetHeader("Authorization", d.AccessToken).
SetBody(RenameReq{
Path: srcObj.GetPath(),
Name: newName,
}).Post(url)
return checkResp(resp, err)
}
func (d *AListV3) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
url := d.Address + "/api/fs/copy"
var resp common.Resp[interface{}]
_, err := base.RestyClient.R().
SetResult(&resp).
SetHeader("Authorization", d.AccessToken).
SetBody(MoveCopyReq{
SrcDir: path.Dir(srcObj.GetPath()),
DstDir: dstDir.GetPath(),
Names: []string{srcObj.GetName()},
}).Post(url)
return checkResp(resp, err)
}
func (d *AListV3) Remove(ctx context.Context, obj model.Obj) error {
url := d.Address + "/api/fs/remove"
var resp common.Resp[interface{}]
_, err := base.RestyClient.R().
SetResult(&resp).
SetHeader("Authorization", d.AccessToken).
SetBody(RemoveReq{
Dir: path.Dir(obj.GetPath()),
Names: []string{obj.GetName()},
}).Post(url)
return checkResp(resp, err)
}
func (d *AListV3) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
url := d.Address + "/api/fs/put"
var resp common.Resp[interface{}]
fileBytes, err := io.ReadAll(stream.GetReadCloser())
if err != nil {
return nil
}
_, err = base.RestyClient.R().SetContext(ctx).
SetResult(&resp).
SetHeader("Authorization", d.AccessToken).
SetHeader("File-Path", path.Join(dstDir.GetPath(), stream.GetName())).
SetHeader("Password", d.Password).
SetHeader("Content-Length", strconv.FormatInt(stream.GetSize(), 10)).
SetBody(fileBytes).Put(url)
return checkResp(resp, err)
}
//func (d *AList) Other(ctx context.Context, args model.OtherArgs) (interface{}, error) {
// return nil, errs.NotSupport
//}
var _ driver.Driver = (*AListV3)(nil)

View File

@ -1,25 +0,0 @@
package alist_v3
import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)
type Addition struct {
driver.RootPath
Address string `json:"url" required:"true"`
Password string `json:"password"`
AccessToken string `json:"access_token"`
}
var config = driver.Config{
Name: "AList V3",
LocalSort: true,
DefaultRoot: "/",
}
func init() {
op.RegisterDriver(func() driver.Driver {
return &AListV3{}
})
}

View File

@ -1,65 +0,0 @@
package alist_v3
import (
"time"
"github.com/alist-org/alist/v3/internal/model"
)
type ListReq struct {
model.PageReq
Path string `json:"path" form:"path"`
Password string `json:"password" form:"password"`
Refresh bool `json:"refresh"`
}
type ObjResp struct {
Name string `json:"name"`
Size int64 `json:"size"`
IsDir bool `json:"is_dir"`
Modified time.Time `json:"modified"`
Sign string `json:"sign"`
Thumb string `json:"thumb"`
Type int `json:"type"`
}
type FsListResp struct {
Content []ObjResp `json:"content"`
Total int64 `json:"total"`
Readme string `json:"readme"`
Write bool `json:"write"`
Provider string `json:"provider"`
}
type FsGetReq struct {
Path string `json:"path" form:"path"`
Password string `json:"password" form:"password"`
}
type FsGetResp struct {
ObjResp
RawURL string `json:"raw_url"`
Readme string `json:"readme"`
Provider string `json:"provider"`
Related []ObjResp `json:"related"`
}
type MkdirOrLinkReq struct {
Path string `json:"path" form:"path"`
}
type MoveCopyReq struct {
SrcDir string `json:"src_dir"`
DstDir string `json:"dst_dir"`
Names []string `json:"names"`
}
type RenameReq struct {
Path string `json:"path"`
Name string `json:"name"`
}
type RemoveReq struct {
Dir string `json:"dir"`
Names []string `json:"names"`
}

View File

@ -1,17 +0,0 @@
package alist_v3
import (
"errors"
"github.com/alist-org/alist/v3/server/common"
)
func checkResp(resp common.Resp[interface{}], err error) error {
if err != nil {
return err
}
if resp.Message == "success" {
return nil
}
return errors.New(resp.Message)
}

View File

@ -1,116 +0,0 @@
package aliyundrive_share
import (
"context"
"errors"
"net/http"
"time"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/pkg/cron"
"github.com/alist-org/alist/v3/pkg/utils"
log "github.com/sirupsen/logrus"
)
type AliyundriveShare struct {
model.Storage
Addition
AccessToken string
ShareToken string
DriveId string
cron *cron.Cron
}
func (d *AliyundriveShare) Config() driver.Config {
return config
}
func (d *AliyundriveShare) GetAddition() driver.Additional {
return &d.Addition
}
func (d *AliyundriveShare) Init(ctx context.Context) error {
err := d.refreshToken()
if err != nil {
return err
}
err = d.getShareToken()
if err != nil {
return err
}
d.cron = cron.NewCron(time.Hour * 2)
d.cron.Do(func() {
err := d.refreshToken()
if err != nil {
log.Errorf("%+v", err)
}
})
return nil
}
func (d *AliyundriveShare) Drop(ctx context.Context) error {
if d.cron != nil {
d.cron.Stop()
}
d.DriveId = ""
return nil
}
func (d *AliyundriveShare) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
files, err := d.getFiles(dir.GetID())
if err != nil {
return nil, err
}
return utils.SliceConvert(files, func(src File) (model.Obj, error) {
return fileToObj(src), nil
})
}
func (d *AliyundriveShare) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
data := base.Json{
"drive_id": d.DriveId,
"file_id": file.GetID(),
// // Only ten minutes lifetime
"expire_sec": 600,
"share_id": d.ShareId,
}
var resp ShareLinkResp
var e ErrorResp
_, err := base.RestyClient.R().
SetError(&e).SetBody(data).SetResult(&resp).
SetHeader("content-type", "application/json").
SetHeader("Authorization", "Bearer\t"+d.AccessToken).
SetHeader("x-share-token", d.ShareToken).
Post("https://api.aliyundrive.com/v2/file/get_share_link_download_url")
if err != nil {
return nil, err
}
var u string
if e.Code != "" {
if e.Code == "AccessTokenInvalid" || e.Code == "ShareLinkTokenInvalid" {
if e.Code == "AccessTokenInvalid" {
err = d.refreshToken()
} else {
err = d.getShareToken()
}
if err != nil {
return nil, err
}
return d.Link(ctx, file, args)
} else {
return nil, errors.New(e.Code + ": " + e.Message)
}
} else {
u = resp.DownloadUrl
}
return &model.Link{
Header: http.Header{
"Referer": []string{"https://www.aliyundrive.com/"},
},
URL: u,
}, nil
}
var _ driver.Driver = (*AliyundriveShare)(nil)

View File

@ -1,99 +0,0 @@
package aliyundrive_share
import (
"errors"
"fmt"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/op"
log "github.com/sirupsen/logrus"
)
func (d *AliyundriveShare) refreshToken() error {
url := "https://auth.aliyundrive.com/v2/account/token"
var resp base.TokenResp
var e ErrorResp
_, err := base.RestyClient.R().
SetBody(base.Json{"refresh_token": d.RefreshToken, "grant_type": "refresh_token"}).
SetResult(&resp).
SetError(&e).
Post(url)
if err != nil {
return err
}
if e.Code != "" {
return fmt.Errorf("failed to refresh token: %s", e.Message)
}
d.RefreshToken, d.AccessToken = resp.RefreshToken, resp.AccessToken
op.MustSaveDriverStorage(d)
return nil
}
// do others that not defined in Driver interface
func (d *AliyundriveShare) getShareToken() error {
data := base.Json{
"share_id": d.ShareId,
}
if d.SharePwd != "" {
data["share_pwd"] = d.SharePwd
}
var e ErrorResp
var resp ShareTokenResp
_, err := base.RestyClient.R().
SetResult(&resp).SetError(&e).SetBody(data).
Post("https://api.aliyundrive.com/v2/share_link/get_share_token")
if err != nil {
return err
}
if e.Code != "" {
return errors.New(e.Message)
}
d.ShareToken = resp.ShareToken
return nil
}
func (d *AliyundriveShare) getFiles(fileId string) ([]File, error) {
files := make([]File, 0)
data := base.Json{
"image_thumbnail_process": "image/resize,w_160/format,jpeg",
"image_url_process": "image/resize,w_1920/format,jpeg",
"limit": 100,
"order_by": d.OrderBy,
"order_direction": d.OrderDirection,
"parent_file_id": fileId,
"share_id": d.ShareId,
"video_thumbnail_process": "video/snapshot,t_1000,f_jpg,ar_auto,w_300",
"marker": "first",
}
for data["marker"] != "" {
if data["marker"] == "first" {
data["marker"] = ""
}
var e ErrorResp
var resp ListResp
res, err := base.RestyClient.R().
SetHeader("x-share-token", d.ShareToken).
SetResult(&resp).SetError(&e).SetBody(data).
Post("https://api.aliyundrive.com/adrive/v3/file/list")
if err != nil {
return nil, err
}
log.Debugf("aliyundrive share get files: %s", res.String())
if e.Code != "" {
if e.Code == "AccessTokenInvalid" || e.Code == "ShareLinkTokenInvalid" {
err = d.getShareToken()
if err != nil {
return nil, err
}
return d.getFiles(fileId)
}
return nil, errors.New(e.Message)
}
data["marker"] = resp.NextMarker
files = append(files, resp.Items...)
}
if len(files) > 0 && d.DriveId == "" {
d.DriveId = files[0].DriveId
}
return files, nil
}

View File

@ -1,44 +0,0 @@
package drivers
import (
_ "github.com/alist-org/alist/v3/drivers/115"
_ "github.com/alist-org/alist/v3/drivers/123"
_ "github.com/alist-org/alist/v3/drivers/139"
_ "github.com/alist-org/alist/v3/drivers/189"
_ "github.com/alist-org/alist/v3/drivers/189pc"
_ "github.com/alist-org/alist/v3/drivers/alist_v2"
_ "github.com/alist-org/alist/v3/drivers/alist_v3"
_ "github.com/alist-org/alist/v3/drivers/aliyundrive"
_ "github.com/alist-org/alist/v3/drivers/aliyundrive_share"
_ "github.com/alist-org/alist/v3/drivers/baidu_netdisk"
_ "github.com/alist-org/alist/v3/drivers/baidu_photo"
_ "github.com/alist-org/alist/v3/drivers/cloudreve"
_ "github.com/alist-org/alist/v3/drivers/ftp"
_ "github.com/alist-org/alist/v3/drivers/google_drive"
_ "github.com/alist-org/alist/v3/drivers/google_photo"
_ "github.com/alist-org/alist/v3/drivers/lanzou"
_ "github.com/alist-org/alist/v3/drivers/local"
_ "github.com/alist-org/alist/v3/drivers/mediatrack"
_ "github.com/alist-org/alist/v3/drivers/mega"
_ "github.com/alist-org/alist/v3/drivers/onedrive"
_ "github.com/alist-org/alist/v3/drivers/pikpak"
_ "github.com/alist-org/alist/v3/drivers/pikpak_share"
_ "github.com/alist-org/alist/v3/drivers/quark"
_ "github.com/alist-org/alist/v3/drivers/s3"
_ "github.com/alist-org/alist/v3/drivers/seafile"
_ "github.com/alist-org/alist/v3/drivers/sftp"
_ "github.com/alist-org/alist/v3/drivers/smb"
_ "github.com/alist-org/alist/v3/drivers/teambition"
_ "github.com/alist-org/alist/v3/drivers/terabox"
_ "github.com/alist-org/alist/v3/drivers/thunder"
_ "github.com/alist-org/alist/v3/drivers/uss"
_ "github.com/alist-org/alist/v3/drivers/virtual"
_ "github.com/alist-org/alist/v3/drivers/webdav"
_ "github.com/alist-org/alist/v3/drivers/yandex_disk"
)
// All do nothing,just for import
// same as _ import
func All() {
}

View File

@ -1,230 +0,0 @@
package baidu_netdisk
import (
"bytes"
"context"
"crypto/md5"
"encoding/hex"
"fmt"
"io"
"math"
"os"
stdpath "path"
"strconv"
"strings"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/pkg/utils"
log "github.com/sirupsen/logrus"
)
type BaiduNetdisk struct {
model.Storage
Addition
AccessToken string
}
func (d *BaiduNetdisk) Config() driver.Config {
return config
}
func (d *BaiduNetdisk) GetAddition() driver.Additional {
return &d.Addition
}
func (d *BaiduNetdisk) Init(ctx context.Context) error {
return d.refreshToken()
}
func (d *BaiduNetdisk) Drop(ctx context.Context) error {
return nil
}
func (d *BaiduNetdisk) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
files, err := d.getFiles(dir.GetPath())
if err != nil {
return nil, err
}
return utils.SliceConvert(files, func(src File) (model.Obj, error) {
return fileToObj(src), nil
})
}
func (d *BaiduNetdisk) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
if d.DownloadAPI == "crack" {
return d.linkCrack(file, args)
}
return d.linkOfficial(file, args)
}
func (d *BaiduNetdisk) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
_, err := d.create(stdpath.Join(parentDir.GetPath(), dirName), 0, 1, "", "")
return err
}
func (d *BaiduNetdisk) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
data := []base.Json{
{
"path": srcObj.GetPath(),
"dest": dstDir.GetPath(),
"newname": srcObj.GetName(),
},
}
_, err := d.manage("move", data)
return err
}
func (d *BaiduNetdisk) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
data := []base.Json{
{
"path": srcObj.GetPath(),
"newname": newName,
},
}
_, err := d.manage("rename", data)
return err
}
func (d *BaiduNetdisk) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
data := []base.Json{
{
"path": srcObj.GetPath(),
"dest": dstDir.GetPath(),
"newname": srcObj.GetName(),
},
}
_, err := d.manage("copy", data)
return err
}
func (d *BaiduNetdisk) Remove(ctx context.Context, obj model.Obj) error {
data := []string{obj.GetPath()}
_, err := d.manage("delete", data)
return err
}
func (d *BaiduNetdisk) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
tempFile, err := utils.CreateTempFile(stream.GetReadCloser())
if err != nil {
return err
}
defer func() {
_ = tempFile.Close()
_ = os.Remove(tempFile.Name())
}()
var Default int64 = 4 * 1024 * 1024
defaultByteData := make([]byte, Default)
count := int(math.Ceil(float64(stream.GetSize()) / float64(Default)))
var SliceSize int64 = 256 * 1024
// cal md5
h1 := md5.New()
h2 := md5.New()
block_list := make([]string, 0)
content_md5 := ""
slice_md5 := ""
left := stream.GetSize()
for i := 0; i < count; i++ {
byteSize := Default
var byteData []byte
if left < Default {
byteSize = left
byteData = make([]byte, byteSize)
} else {
byteData = defaultByteData
}
left -= byteSize
_, err = io.ReadFull(tempFile, byteData)
if err != nil {
return err
}
h1.Write(byteData)
h2.Write(byteData)
block_list = append(block_list, fmt.Sprintf("\"%s\"", hex.EncodeToString(h2.Sum(nil))))
h2.Reset()
}
content_md5 = hex.EncodeToString(h1.Sum(nil))
_, err = tempFile.Seek(0, io.SeekStart)
if err != nil {
return err
}
if stream.GetSize() <= SliceSize {
slice_md5 = content_md5
} else {
sliceData := make([]byte, SliceSize)
_, err = io.ReadFull(tempFile, sliceData)
if err != nil {
return err
}
h2.Write(sliceData)
slice_md5 = hex.EncodeToString(h2.Sum(nil))
_, err = tempFile.Seek(0, io.SeekStart)
if err != nil {
return err
}
}
rawPath := stdpath.Join(dstDir.GetPath(), stream.GetName())
path := encodeURIComponent(rawPath)
block_list_str := fmt.Sprintf("[%s]", strings.Join(block_list, ","))
data := fmt.Sprintf("path=%s&size=%d&isdir=0&autoinit=1&block_list=%s&content-md5=%s&slice-md5=%s",
path, stream.GetSize(),
block_list_str,
content_md5, slice_md5)
params := map[string]string{
"method": "precreate",
}
var precreateResp PrecreateResp
_, err = d.post("/xpan/file", params, data, &precreateResp)
if err != nil {
return err
}
log.Debugf("%+v", precreateResp)
if precreateResp.ReturnType == 2 {
return nil
}
params = map[string]string{
"method": "upload",
"access_token": d.AccessToken,
"type": "tmpfile",
"path": path,
"uploadid": precreateResp.Uploadid,
}
left = stream.GetSize()
for i, partseq := range precreateResp.BlockList {
if utils.IsCanceled(ctx) {
return ctx.Err()
}
byteSize := Default
var byteData []byte
if left < Default {
byteSize = left
byteData = make([]byte, byteSize)
} else {
byteData = defaultByteData
}
left -= byteSize
_, err = io.ReadFull(tempFile, byteData)
if err != nil {
return err
}
u := "https://d.pcs.baidu.com/rest/2.0/pcs/superfile2"
params["partseq"] = strconv.Itoa(partseq)
res, err := base.RestyClient.R().
SetContext(ctx).
SetQueryParams(params).
SetFileReader("file", stream.GetName(), bytes.NewReader(byteData)).
Post(u)
if err != nil {
return err
}
log.Debugln(res.String())
if len(precreateResp.BlockList) > 0 {
up(i * 100 / len(precreateResp.BlockList))
}
}
_, err = d.create(rawPath, stream.GetSize(), 0, precreateResp.Uploadid, block_list_str)
return err
}
var _ driver.Driver = (*BaiduNetdisk)(nil)

View File

@ -1,27 +0,0 @@
package baidu_netdisk
import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)
type Addition struct {
RefreshToken string `json:"refresh_token" required:"true"`
driver.RootPath
OrderBy string `json:"order_by" type:"select" options:"name,time,size" default:"name"`
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" default:"asc"`
DownloadAPI string `json:"download_api" type:"select" options:"official,crack" default:"official"`
ClientID string `json:"client_id" required:"true" default:"iYCeC9g08h5vuP9UqvPHKKSVrKFXGa1v"`
ClientSecret string `json:"client_secret" required:"true" default:"jXiFMOPVPCWlO2M5CwWQzffpNPaGTRBG"`
}
var config = driver.Config{
Name: "BaiduNetdisk",
DefaultRoot: "/",
}
func init() {
op.RegisterDriver(func() driver.Driver {
return &BaiduNetdisk{}
})
}

View File

@ -1,201 +0,0 @@
package baidu_netdisk
import (
"fmt"
"net/http"
"net/url"
"strconv"
"strings"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/errs"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/internal/op"
"github.com/alist-org/alist/v3/pkg/utils"
"github.com/go-resty/resty/v2"
)
// do others that not defined in Driver interface
func (d *BaiduNetdisk) refreshToken() error {
err := d._refreshToken()
if err != nil && err == errs.EmptyToken {
err = d._refreshToken()
}
return err
}
func (d *BaiduNetdisk) _refreshToken() error {
u := "https://openapi.baidu.com/oauth/2.0/token"
var resp base.TokenResp
var e TokenErrResp
_, err := base.RestyClient.R().SetResult(&resp).SetError(&e).SetQueryParams(map[string]string{
"grant_type": "refresh_token",
"refresh_token": d.RefreshToken,
"client_id": d.ClientID,
"client_secret": d.ClientSecret,
}).Get(u)
if err != nil {
return err
}
if e.Error != "" {
return fmt.Errorf("%s : %s", e.Error, e.ErrorDescription)
}
if resp.RefreshToken == "" {
return errs.EmptyToken
}
d.AccessToken, d.RefreshToken = resp.AccessToken, resp.RefreshToken
op.MustSaveDriverStorage(d)
return nil
}
func (d *BaiduNetdisk) request(furl string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
req := base.RestyClient.R()
req.SetQueryParam("access_token", d.AccessToken)
if callback != nil {
callback(req)
}
if resp != nil {
req.SetResult(resp)
}
res, err := req.Execute(method, furl)
if err != nil {
return nil, err
}
errno := utils.Json.Get(res.Body(), "errno").ToInt()
if errno != 0 {
if errno == -6 {
err = d.refreshToken()
if err != nil {
return nil, err
}
return d.request(furl, method, callback, resp)
}
return nil, fmt.Errorf("errno: %d, refer to https://pan.baidu.com/union/doc/", errno)
}
return res.Body(), nil
}
func (d *BaiduNetdisk) get(pathname string, params map[string]string, resp interface{}) ([]byte, error) {
return d.request("https://pan.baidu.com/rest/2.0"+pathname, http.MethodGet, func(req *resty.Request) {
req.SetQueryParams(params)
}, resp)
}
func (d *BaiduNetdisk) post(pathname string, params map[string]string, data interface{}, resp interface{}) ([]byte, error) {
return d.request("https://pan.baidu.com/rest/2.0"+pathname, http.MethodPost, func(req *resty.Request) {
req.SetQueryParams(params)
req.SetBody(data)
}, resp)
}
func (d *BaiduNetdisk) getFiles(dir string) ([]File, error) {
start := 0
limit := 200
params := map[string]string{
"method": "list",
"dir": dir,
"web": "web",
}
if d.OrderBy != "" {
params["order"] = d.OrderBy
if d.OrderDirection == "desc" {
params["desc"] = "1"
}
}
res := make([]File, 0)
for {
params["start"] = strconv.Itoa(start)
params["limit"] = strconv.Itoa(limit)
start += limit
var resp ListResp
_, err := d.get("/xpan/file", params, &resp)
if err != nil {
return nil, err
}
if len(resp.List) == 0 {
break
}
res = append(res, resp.List...)
}
return res, nil
}
func (d *BaiduNetdisk) linkOfficial(file model.Obj, args model.LinkArgs) (*model.Link, error) {
var resp DownloadResp
params := map[string]string{
"method": "filemetas",
"fsids": fmt.Sprintf("[%s]", file.GetID()),
"dlink": "1",
}
_, err := d.get("/xpan/multimedia", params, &resp)
if err != nil {
return nil, err
}
u := fmt.Sprintf("%s&access_token=%s", resp.List[0].Dlink, d.AccessToken)
res, err := base.NoRedirectClient.R().SetHeader("User-Agent", "pan.baidu.com").Head(u)
if err != nil {
return nil, err
}
//if res.StatusCode() == 302 {
u = res.Header().Get("location")
//}
return &model.Link{
URL: u,
Header: http.Header{
"User-Agent": []string{"pan.baidu.com"},
},
}, nil
}
func (d *BaiduNetdisk) linkCrack(file model.Obj, args model.LinkArgs) (*model.Link, error) {
var resp DownloadResp2
param := map[string]string{
"target": fmt.Sprintf("[\"%s\"]", file.GetPath()),
"dlink": "1",
"web": "5",
"origin": "dlna",
}
_, err := d.request("https://pan.baidu.com/api/filemetas", http.MethodGet, func(req *resty.Request) {
req.SetQueryParams(param)
}, &resp)
if err != nil {
return nil, err
}
return &model.Link{
URL: resp.Info[0].Dlink,
Header: http.Header{
"User-Agent": []string{"pan.baidu.com"},
},
}, nil
}
func (d *BaiduNetdisk) manage(opera string, filelist interface{}) ([]byte, error) {
params := map[string]string{
"method": "filemanager",
"opera": opera,
}
marshal, err := utils.Json.Marshal(filelist)
if err != nil {
return nil, err
}
data := fmt.Sprintf("async=0&filelist=%s&ondup=newcopy", string(marshal))
return d.post("/xpan/file", params, data, nil)
}
func (d *BaiduNetdisk) create(path string, size int64, isdir int, uploadid, block_list string) ([]byte, error) {
params := map[string]string{
"method": "create",
}
data := fmt.Sprintf("path=%s&size=%d&isdir=%d&rtype=3", encodeURIComponent(path), size, isdir)
if uploadid != "" {
data += fmt.Sprintf("&uploadid=%s&block_list=%s", uploadid, block_list)
}
return d.post("/xpan/file", params, data, nil)
}
func encodeURIComponent(str string) string {
r := url.QueryEscape(str)
r = strings.ReplaceAll(r, "+", "%20")
return r
}

View File

@ -1,26 +0,0 @@
package baiduphoto
import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)
type Addition struct {
RefreshToken string `json:"refresh_token" required:"true"`
ShowType string `json:"show_type" type:"select" options:"root,root_only_album,root_only_file" default:"root"`
AlbumID string `json:"album_id"`
//AlbumPassword string `json:"album_password"`
ClientID string `json:"client_id" required:"true" default:"iYCeC9g08h5vuP9UqvPHKKSVrKFXGa1v"`
ClientSecret string `json:"client_secret" required:"true" default:"jXiFMOPVPCWlO2M5CwWQzffpNPaGTRBG"`
}
var config = driver.Config{
Name: "BaiduPhoto",
LocalSort: true,
}
func init() {
op.RegisterDriver(func() driver.Driver {
return &BaiduPhoto{}
})
}

View File

@ -1,30 +0,0 @@
package base
import (
"net/http"
"time"
"github.com/go-resty/resty/v2"
)
var NoRedirectClient *resty.Client
var RestyClient = NewRestyClient()
var HttpClient = &http.Client{}
var UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"
var DefaultTimeout = time.Second * 30
func init() {
NoRedirectClient = resty.New().SetRedirectPolicy(
resty.RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
}),
)
NoRedirectClient.SetHeader("user-agent", UserAgent)
}
func NewRestyClient() *resty.Client {
return resty.New().
SetHeader("user-agent", UserAgent).
SetRetryCount(3).
SetTimeout(DefaultTimeout)
}

View File

@ -1,26 +0,0 @@
package cloudreve
import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)
type Addition struct {
// Usually one of two
driver.RootPath
// define other
Address string `json:"address" required:"true"`
Username string `json:"username" required:"true"`
Password string `json:"password" required:"true"`
}
var config = driver.Config{
Name: "Cloudreve",
DefaultRoot: "/",
}
func init() {
op.RegisterDriver(func() driver.Driver {
return &Cloudreve{}
})
}

View File

@ -1,96 +0,0 @@
package cloudreve
import (
"errors"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/pkg/cookie"
"github.com/go-resty/resty/v2"
json "github.com/json-iterator/go"
"net/http"
)
// do others that not defined in Driver interface
const loginPath = "/user/session"
func (d *Cloudreve) request(method string, path string, callback base.ReqCallback, out interface{}) error {
u := d.Address + "/api/v3" + path
req := base.RestyClient.R()
req.SetHeaders(map[string]string{
"Cookie": "cloudreve-session=" + d.Cookie,
"Accept": "application/json, text/plain, */*",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
})
var r Resp
req.SetResult(&r)
if callback != nil {
callback(req)
}
resp, err := req.Execute(method, u)
if err != nil {
return err
}
if !resp.IsSuccess() {
return errors.New(resp.String())
}
if r.Code != 0 {
// 刷新 cookie
if r.Code == http.StatusUnauthorized && path != loginPath {
err = d.login()
if err != nil {
return err
}
return d.request(method, path, callback, out)
}
return errors.New(r.Msg)
}
sess := cookie.GetCookie(resp.Cookies(), "cloudreve-session")
if sess != nil {
d.Cookie = sess.Value
}
if out != nil && r.Data != nil {
var marshal []byte
marshal, err = json.Marshal(r.Data)
if err != nil {
return err
}
err = json.Unmarshal(marshal, out)
if err != nil {
return err
}
}
return nil
}
func (d *Cloudreve) login() error {
return d.request(http.MethodPost, loginPath, func(req *resty.Request) {
req.SetBody(base.Json{
"username": d.Addition.Username,
"Password": d.Addition.Password,
"captchaCode": "",
})
}, nil)
}
func convertSrc(obj model.Obj) map[string]interface{} {
m := make(map[string]interface{})
var dirs []string
var items []string
if obj.IsDir() {
dirs = append(dirs, obj.GetID())
} else {
items = append(items, obj.GetID())
}
m["dirs"] = dirs
m["items"] = items
return m
}

View File

@ -1,120 +0,0 @@
package ftp
import (
"context"
stdpath "path"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/errs"
"github.com/alist-org/alist/v3/internal/model"
"github.com/jlaffaye/ftp"
)
type FTP struct {
model.Storage
Addition
conn *ftp.ServerConn
}
func (d *FTP) Config() driver.Config {
return config
}
func (d *FTP) GetAddition() driver.Additional {
return &d.Addition
}
func (d *FTP) Init(ctx context.Context) error {
return d.login()
}
func (d *FTP) Drop(ctx context.Context) error {
if d.conn != nil {
_ = d.conn.Logout()
}
return nil
}
func (d *FTP) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
if err := d.login(); err != nil {
return nil, err
}
entries, err := d.conn.List(dir.GetPath())
if err != nil {
return nil, err
}
res := make([]model.Obj, 0)
for i, _ := range entries {
entry := entries[i]
if entry.Name == "." || entry.Name == ".." {
continue
}
f := model.Object{
Name: entry.Name,
Size: int64(entry.Size),
Modified: entry.Time,
IsFolder: entry.Type == ftp.EntryTypeFolder,
}
res = append(res, &f)
}
return res, nil
}
func (d *FTP) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
if err := d.login(); err != nil {
return nil, err
}
resp, err := d.conn.Retr(file.GetPath())
if err != nil {
return nil, err
}
return &model.Link{
Data: resp,
}, nil
}
func (d *FTP) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
if err := d.login(); err != nil {
return err
}
return d.conn.MakeDir(stdpath.Join(parentDir.GetPath(), dirName))
}
func (d *FTP) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
if err := d.login(); err != nil {
return err
}
return d.conn.Rename(srcObj.GetPath(), stdpath.Join(dstDir.GetPath(), srcObj.GetName()))
}
func (d *FTP) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
if err := d.login(); err != nil {
return err
}
return d.conn.Rename(srcObj.GetPath(), stdpath.Join(stdpath.Dir(srcObj.GetPath()), newName))
}
func (d *FTP) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
return errs.NotSupport
}
func (d *FTP) Remove(ctx context.Context, obj model.Obj) error {
if err := d.login(); err != nil {
return err
}
if obj.IsDir() {
return d.conn.RemoveDirRecur(obj.GetPath())
} else {
return d.conn.Delete(obj.GetPath())
}
}
func (d *FTP) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
if err := d.login(); err != nil {
return err
}
// TODO: support cancel
return d.conn.Stor(stdpath.Join(dstDir.GetPath(), stream.GetName()), stream)
}
var _ driver.Driver = (*FTP)(nil)

View File

@ -1,26 +0,0 @@
package ftp
import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)
type Addition struct {
Address string `json:"address" required:"true"`
Username string `json:"username" required:"true"`
Password string `json:"password" required:"true"`
driver.RootPath
}
var config = driver.Config{
Name: "FTP",
LocalSort: true,
OnlyLocal: true,
DefaultRoot: "/",
}
func init() {
op.RegisterDriver(func() driver.Driver {
return &FTP{}
})
}

View File

@ -1,24 +0,0 @@
package ftp
import "github.com/jlaffaye/ftp"
// do others that not defined in Driver interface
func (d *FTP) login() error {
if d.conn != nil {
_, err := d.conn.CurrentDir()
if err == nil {
return nil
}
}
conn, err := ftp.Dial(d.Address)
if err != nil {
return err
}
err = conn.Login(d.Username, d.Password)
if err != nil {
return err
}
d.conn = conn
return nil
}

View File

@ -1,127 +0,0 @@
package google_drive
import (
"context"
"fmt"
"io"
"net/http"
"strconv"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/pkg/utils"
"github.com/go-resty/resty/v2"
log "github.com/sirupsen/logrus"
)
// do others that not defined in Driver interface
func (d *GoogleDrive) refreshToken() error {
url := "https://www.googleapis.com/oauth2/v4/token"
var resp base.TokenResp
var e TokenError
res, err := base.RestyClient.R().SetResult(&resp).SetError(&e).
SetFormData(map[string]string{
"client_id": d.ClientID,
"client_secret": d.ClientSecret,
"refresh_token": d.RefreshToken,
"grant_type": "refresh_token",
}).Post(url)
if err != nil {
return err
}
log.Debug(res.String())
if e.Error != "" {
return fmt.Errorf(e.Error)
}
d.AccessToken = resp.AccessToken
return nil
}
func (d *GoogleDrive) request(url string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
req := base.RestyClient.R()
req.SetHeader("Authorization", "Bearer "+d.AccessToken)
req.SetQueryParam("includeItemsFromAllDrives", "true")
req.SetQueryParam("supportsAllDrives", "true")
if callback != nil {
callback(req)
}
if resp != nil {
req.SetResult(resp)
}
var e Error
req.SetError(&e)
res, err := req.Execute(method, url)
if err != nil {
return nil, err
}
if e.Error.Code != 0 {
if e.Error.Code == 401 {
err = d.refreshToken()
if err != nil {
return nil, err
}
return d.request(url, method, callback, resp)
}
return nil, fmt.Errorf("%s: %v", e.Error.Message, e.Error.Errors)
}
return res.Body(), nil
}
func (d *GoogleDrive) getFiles(id string) ([]File, error) {
pageToken := "first"
res := make([]File, 0)
for pageToken != "" {
if pageToken == "first" {
pageToken = ""
}
var resp Files
orderBy := "folder,name,modifiedTime desc"
if d.OrderBy != "" {
orderBy = d.OrderBy + " " + d.OrderDirection
}
query := map[string]string{
"orderBy": orderBy,
"fields": "files(id,name,mimeType,size,modifiedTime,thumbnailLink,shortcutDetails),nextPageToken",
"pageSize": "1000",
"q": fmt.Sprintf("'%s' in parents and trashed = false", id),
//"includeItemsFromAllDrives": "true",
//"supportsAllDrives": "true",
"pageToken": pageToken,
}
_, err := d.request("https://www.googleapis.com/drive/v3/files", http.MethodGet, func(req *resty.Request) {
req.SetQueryParams(query)
}, &resp)
if err != nil {
return nil, err
}
pageToken = resp.NextPageToken
res = append(res, resp.Files...)
}
return res, nil
}
func (d *GoogleDrive) chunkUpload(ctx context.Context, stream model.FileStreamer, url string) error {
var defaultChunkSize = d.ChunkSize * 1024 * 1024
var finish int64 = 0
for finish < stream.GetSize() {
if utils.IsCanceled(ctx) {
return ctx.Err()
}
chunkSize := stream.GetSize() - finish
if chunkSize > defaultChunkSize {
chunkSize = defaultChunkSize
}
_, err := d.request(url, http.MethodPut, func(req *resty.Request) {
req.SetHeaders(map[string]string{
"Content-Length": strconv.FormatInt(chunkSize, 10),
"Content-Range": fmt.Sprintf("bytes %d-%d/%d", finish, finish+chunkSize-1, stream.GetSize()),
}).SetBody(io.LimitReader(stream.GetReadCloser(), chunkSize)).SetContext(ctx)
}, nil)
if err != nil {
return err
}
finish += chunkSize
}
return nil
}

View File

@ -1,32 +0,0 @@
package lanzou
import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)
type Addition struct {
Type string `json:"type" type:"select" options:"cookie,url" default:"cookie"`
Cookie string `json:"cookie" required:"true" help:"about 15 days valid, ignore if shareUrl is used"`
driver.RootID
SharePassword string `json:"share_password"`
BaseUrl string `json:"baseUrl" required:"true" default:"https://pc.woozooo.com" help:"basic URL for file operation"`
ShareUrl string `json:"shareUrl" required:"true" default:"https://pan.lanzouo.com" help:"used to get the sharing page"`
RepairFileInfo bool `json:"repair_file_info" help:"To use webdav, you need to enable it"`
}
func (a *Addition) IsCookie() bool {
return a.Type == "cookie"
}
var config = driver.Config{
Name: "Lanzou",
LocalSort: true,
DefaultRoot: "-1",
}
func init() {
op.RegisterDriver(func() driver.Driver {
return &LanZou{}
})
}

View File

@ -1,234 +0,0 @@
package local
import (
"bytes"
"context"
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
stdpath "path"
"path/filepath"
"strconv"
"strings"
"github.com/alist-org/alist/v3/internal/conf"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/errs"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/internal/sign"
"github.com/alist-org/alist/v3/pkg/utils"
"github.com/alist-org/alist/v3/server/common"
"github.com/disintegration/imaging"
_ "golang.org/x/image/webp"
)
type Local struct {
model.Storage
Addition
}
func (d *Local) Config() driver.Config {
return config
}
func (d *Local) Init(ctx context.Context) error {
if !utils.Exists(d.GetRootPath()) {
return fmt.Errorf("root folder %s not exists", d.GetRootPath())
}
if !filepath.IsAbs(d.GetRootPath()) {
abs, err := filepath.Abs(d.GetRootPath())
if err != nil {
return err
}
d.Addition.RootFolderPath = abs
}
return nil
}
func (d *Local) Drop(ctx context.Context) error {
return nil
}
func (d *Local) GetAddition() driver.Additional {
return &d.Addition
}
func (d *Local) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
fullPath := dir.GetPath()
rawFiles, err := ioutil.ReadDir(fullPath)
if err != nil {
return nil, err
}
var files []model.Obj
for _, f := range rawFiles {
if !d.ShowHidden && strings.HasPrefix(f.Name(), ".") {
continue
}
thumb := ""
if d.Thumbnail && utils.GetFileType(f.Name()) == conf.IMAGE {
thumb = common.GetApiUrl(nil) + stdpath.Join("/d", args.ReqPath, f.Name())
thumb = utils.EncodePath(thumb, true)
thumb += "?type=thumb&sign=" + sign.Sign(stdpath.Join(args.ReqPath, f.Name()))
}
isFolder := f.IsDir() || isSymlinkDir(f, fullPath)
var size int64
if !isFolder {
size = f.Size()
}
file := model.ObjThumb{
Object: model.Object{
Path: filepath.Join(dir.GetPath(), f.Name()),
Name: f.Name(),
Modified: f.ModTime(),
Size: size,
IsFolder: isFolder,
},
Thumbnail: model.Thumbnail{
Thumbnail: thumb,
},
}
files = append(files, &file)
}
return files, nil
}
func (d *Local) Get(ctx context.Context, path string) (model.Obj, error) {
path = filepath.Join(d.GetRootPath(), path)
f, err := os.Stat(path)
if err != nil {
if strings.Contains(err.Error(), "cannot find the file") {
return nil, errs.ObjectNotFound
}
return nil, err
}
isFolder := f.IsDir() || isSymlinkDir(f, path)
size := f.Size()
if isFolder {
size = 0
}
file := model.Object{
Path: path,
Name: f.Name(),
Modified: f.ModTime(),
Size: size,
IsFolder: isFolder,
}
return &file, nil
}
func (d *Local) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
fullPath := file.GetPath()
var link model.Link
if args.Type == "thumb" && utils.Ext(file.GetName()) != "svg" {
imgData, err := ioutil.ReadFile(fullPath)
if err != nil {
return nil, err
}
srcBuf := bytes.NewBuffer(imgData)
image, err := imaging.Decode(srcBuf)
if err != nil {
return nil, err
}
thumbImg := imaging.Resize(image, 144, 0, imaging.Lanczos)
var buf bytes.Buffer
err = imaging.Encode(&buf, thumbImg, imaging.PNG)
if err != nil {
return nil, err
}
size := buf.Len()
link.Data = io.NopCloser(&buf)
link.Header = http.Header{
"Content-Length": []string{strconv.Itoa(size)},
}
} else {
link.FilePath = &fullPath
}
return &link, nil
}
func (d *Local) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
fullPath := filepath.Join(parentDir.GetPath(), dirName)
err := os.MkdirAll(fullPath, 0777)
if err != nil {
return err
}
return nil
}
func (d *Local) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
srcPath := srcObj.GetPath()
dstPath := filepath.Join(dstDir.GetPath(), srcObj.GetName())
if utils.IsSubPath(srcPath, dstPath) {
return fmt.Errorf("the destination folder is a subfolder of the source folder")
}
err := os.Rename(srcPath, dstPath)
if err != nil {
return err
}
return nil
}
func (d *Local) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
srcPath := srcObj.GetPath()
dstPath := filepath.Join(filepath.Dir(srcPath), newName)
err := os.Rename(srcPath, dstPath)
if err != nil {
return err
}
return nil
}
func (d *Local) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
srcPath := srcObj.GetPath()
dstPath := filepath.Join(dstDir.GetPath(), srcObj.GetName())
if utils.IsSubPath(srcPath, dstPath) {
return fmt.Errorf("the destination folder is a subfolder of the source folder")
}
var err error
if srcObj.IsDir() {
err = utils.CopyDir(srcPath, dstPath)
} else {
err = utils.CopyFile(srcPath, dstPath)
}
if err != nil {
return err
}
return nil
}
func (d *Local) Remove(ctx context.Context, obj model.Obj) error {
var err error
if obj.IsDir() {
err = os.RemoveAll(obj.GetPath())
} else {
err = os.Remove(obj.GetPath())
}
if err != nil {
return err
}
return nil
}
func (d *Local) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
fullPath := filepath.Join(dstDir.GetPath(), stream.GetName())
out, err := os.Create(fullPath)
if err != nil {
return err
}
defer func() {
_ = out.Close()
if errors.Is(err, context.Canceled) {
_ = os.Remove(fullPath)
}
}()
err = utils.CopyWithCtx(ctx, out, stream, stream.GetSize(), up)
if err != nil {
return err
}
return nil
}
var _ driver.Driver = (*Local)(nil)

View File

@ -1,26 +0,0 @@
package local
import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)
type Addition struct {
driver.RootPath
Thumbnail bool `json:"thumbnail" required:"true" help:"enable thumbnail"`
ShowHidden bool `json:"show_hidden" default:"true" required:"false" help:"show hidden directories and files"`
}
var config = driver.Config{
Name: "Local",
OnlyLocal: true,
LocalSort: true,
NoCache: true,
DefaultRoot: "/",
}
func init() {
op.RegisterDriver(func() driver.Driver {
return &Local{}
})
}

View File

@ -1,25 +0,0 @@
package local
import (
"io/fs"
"os"
"path/filepath"
)
func isSymlinkDir(f fs.FileInfo, path string) bool {
if f.Mode()&os.ModeSymlink == os.ModeSymlink {
dst, err := os.Readlink(filepath.Join(path, f.Name()))
if err != nil {
return false
}
if !filepath.IsAbs(dst) {
dst = filepath.Join(path, dst)
}
stat, err := os.Stat(dst)
if err != nil {
return false
}
return stat.IsDir()
}
return false
}

View File

@ -1,192 +0,0 @@
package mega
import (
"context"
"errors"
"fmt"
"io"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/errs"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/pkg/utils"
log "github.com/sirupsen/logrus"
"github.com/t3rm1n4l/go-mega"
)
type Mega struct {
model.Storage
Addition
c *mega.Mega
}
func (d *Mega) Config() driver.Config {
return config
}
func (d *Mega) GetAddition() driver.Additional {
return &d.Addition
}
func (d *Mega) Init(ctx context.Context) error {
d.c = mega.New()
return d.c.Login(d.Email, d.Password)
}
func (d *Mega) Drop(ctx context.Context) error {
return nil
}
func (d *Mega) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
if node, ok := dir.(*MegaNode); ok {
nodes, err := d.c.FS.GetChildren(node.Node)
if err != nil {
return nil, err
}
res := make([]model.Obj, 0)
for i := range nodes {
n := nodes[i]
if n.GetType() == mega.FILE || n.GetType() == mega.FOLDER {
res = append(res, &MegaNode{n})
}
}
return res, nil
}
log.Errorf("can't convert: %+v", dir)
return nil, fmt.Errorf("unable to convert dir to mega node")
}
func (d *Mega) GetRoot(ctx context.Context) (model.Obj, error) {
n := d.c.FS.GetRoot()
log.Debugf("mega root: %+v", *n)
return &MegaNode{n}, nil
}
func (d *Mega) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
if node, ok := file.(*MegaNode); ok {
//link, err := d.c.Link(node.Node, true)
//if err != nil {
// return nil, err
//}
//return &model.Link{URL: link}, nil
down, err := d.c.NewDownload(node.Node)
if err != nil {
return nil, err
}
//u := down.GetResourceUrl()
//u = strings.Replace(u, "http", "https", 1)
//return &model.Link{URL: u}, nil
r, w := io.Pipe()
go func() {
defer func() {
_ = recover()
}()
log.Debugf("chunk size: %d", down.Chunks())
var (
chunk []byte
err error
)
for id := 0; id < down.Chunks(); id++ {
chunk, err = down.DownloadChunk(id)
if err != nil {
log.Errorf("mega down: %+v", err)
break
}
log.Debugf("id: %d,len: %d", id, len(chunk))
//_, _, err = down.ChunkLocation(id)
//if err != nil {
// log.Errorf("mega down: %+v", err)
// return
//}
//_, err = c.Write(chunk)
if _, err = w.Write(chunk); err != nil {
break
}
}
err = w.CloseWithError(err)
if err != nil {
log.Errorf("mega down: %+v", err)
}
}()
return &model.Link{Data: r}, nil
}
return nil, fmt.Errorf("unable to convert dir to mega node")
}
func (d *Mega) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
if parentNode, ok := parentDir.(*MegaNode); ok {
_, err := d.c.CreateDir(dirName, parentNode.Node)
return err
}
return fmt.Errorf("unable to convert dir to mega node")
}
func (d *Mega) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
if srcNode, ok := srcObj.(*MegaNode); ok {
if dstNode, ok := dstDir.(*MegaNode); ok {
return d.c.Move(srcNode.Node, dstNode.Node)
}
}
return fmt.Errorf("unable to convert dir to mega node")
}
func (d *Mega) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
if srcNode, ok := srcObj.(*MegaNode); ok {
return d.c.Rename(srcNode.Node, newName)
}
return fmt.Errorf("unable to convert dir to mega node")
}
func (d *Mega) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
return errs.NotImplement
}
func (d *Mega) Remove(ctx context.Context, obj model.Obj) error {
if node, ok := obj.(*MegaNode); ok {
return d.c.Delete(node.Node, false)
}
return fmt.Errorf("unable to convert dir to mega node")
}
func (d *Mega) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
if dstNode, ok := dstDir.(*MegaNode); ok {
u, err := d.c.NewUpload(dstNode.Node, stream.GetName(), stream.GetSize())
if err != nil {
return err
}
for id := 0; id < u.Chunks(); id++ {
if utils.IsCanceled(ctx) {
return ctx.Err()
}
_, chkSize, err := u.ChunkLocation(id)
if err != nil {
return err
}
chunk := make([]byte, chkSize)
n, err := io.ReadFull(stream, chunk)
if err != nil && err != io.EOF {
return err
}
if n != len(chunk) {
return errors.New("chunk too short")
}
err = u.UploadChunk(id, chunk)
if err != nil {
return err
}
up(id * 100 / u.Chunks())
}
_, err = u.Finish()
return err
}
return fmt.Errorf("unable to convert dir to mega node")
}
//func (d *Mega) Other(ctx context.Context, args model.OtherArgs) (interface{}, error) {
// return nil, errs.NotSupport
//}
var _ driver.Driver = (*Mega)(nil)

View File

@ -1,26 +0,0 @@
package mega
import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)
type Addition struct {
// Usually one of two
//driver.RootPath
//driver.RootID
Email string `json:"email" required:"true"`
Password string `json:"password" required:"true"`
}
var config = driver.Config{
Name: "Mega_nz",
LocalSort: true,
OnlyLocal: true,
}
func init() {
op.RegisterDriver(func() driver.Driver {
return &Mega{}
})
}

View File

@ -1,40 +0,0 @@
package mega
import (
"time"
"github.com/alist-org/alist/v3/internal/model"
"github.com/t3rm1n4l/go-mega"
)
type MegaNode struct {
*mega.Node
}
//func (m *MegaNode) GetSize() int64 {
// //TODO implement me
// panic("implement me")
//}
//
//func (m *MegaNode) GetName() string {
// //TODO implement me
// panic("implement me")
//}
func (m *MegaNode) ModTime() time.Time {
return m.GetTimeStamp()
}
func (m *MegaNode) IsDir() bool {
return m.GetType() == mega.FOLDER || m.GetType() == mega.ROOT
}
func (m *MegaNode) GetID() string {
return m.GetHash()
}
func (m *MegaNode) GetPath() string {
return ""
}
var _ model.Obj = (*MegaNode)(nil)

View File

@ -1,3 +0,0 @@
package mega
// do others that not defined in Driver interface

View File

@ -1,205 +0,0 @@
package onedrive
import (
"bytes"
"context"
"errors"
"fmt"
"io"
"net/http"
stdpath "path"
"strconv"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/errs"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/internal/op"
"github.com/alist-org/alist/v3/pkg/utils"
"github.com/go-resty/resty/v2"
jsoniter "github.com/json-iterator/go"
log "github.com/sirupsen/logrus"
)
var onedriveHostMap = map[string]Host{
"global": {
Oauth: "https://login.microsoftonline.com",
Api: "https://graph.microsoft.com",
},
"cn": {
Oauth: "https://login.chinacloudapi.cn",
Api: "https://microsoftgraph.chinacloudapi.cn",
},
"us": {
Oauth: "https://login.microsoftonline.us",
Api: "https://graph.microsoft.us",
},
"de": {
Oauth: "https://login.microsoftonline.de",
Api: "https://graph.microsoft.de",
},
}
func (d *Onedrive) GetMetaUrl(auth bool, path string) string {
host, _ := onedriveHostMap[d.Region]
path = utils.EncodePath(path, true)
if auth {
return host.Oauth
}
if d.IsSharepoint {
if path == "/" || path == "\\" {
return fmt.Sprintf("%s/v1.0/sites/%s/drive/root", host.Api, d.SiteId)
} else {
return fmt.Sprintf("%s/v1.0/sites/%s/drive/root:%s:", host.Api, d.SiteId, path)
}
} else {
if path == "/" || path == "\\" {
return fmt.Sprintf("%s/v1.0/me/drive/root", host.Api)
} else {
return fmt.Sprintf("%s/v1.0/me/drive/root:%s:", host.Api, path)
}
}
}
func (d *Onedrive) refreshToken() error {
var err error
for i := 0; i < 3; i++ {
err = d._refreshToken()
if err == nil {
break
}
}
return err
}
func (d *Onedrive) _refreshToken() error {
url := d.GetMetaUrl(true, "") + "/common/oauth2/v2.0/token"
var resp base.TokenResp
var e TokenErr
_, err := base.RestyClient.R().SetResult(&resp).SetError(&e).SetFormData(map[string]string{
"grant_type": "refresh_token",
"client_id": d.ClientID,
"client_secret": d.ClientSecret,
"redirect_uri": d.RedirectUri,
"refresh_token": d.RefreshToken,
}).Post(url)
if err != nil {
return err
}
if e.Error != "" {
return fmt.Errorf("%s", e.ErrorDescription)
}
if resp.RefreshToken == "" {
return errs.EmptyToken
}
d.RefreshToken, d.AccessToken = resp.RefreshToken, resp.AccessToken
op.MustSaveDriverStorage(d)
return nil
}
func (d *Onedrive) Request(url string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
req := base.RestyClient.R()
req.SetHeader("Authorization", "Bearer "+d.AccessToken)
if callback != nil {
callback(req)
}
if resp != nil {
req.SetResult(resp)
}
var e RespErr
req.SetError(&e)
res, err := req.Execute(method, url)
if err != nil {
return nil, err
}
if e.Error.Code != "" {
if e.Error.Code == "InvalidAuthenticationToken" {
err = d.refreshToken()
if err != nil {
return nil, err
}
return d.Request(url, method, callback, resp)
}
return nil, errors.New(e.Error.Message)
}
return res.Body(), nil
}
func (d *Onedrive) getFiles(path string) ([]File, error) {
var res []File
nextLink := d.GetMetaUrl(false, path) + "/children?$top=5000&$expand=thumbnails($select=medium)&$select=id,name,size,lastModifiedDateTime,content.downloadUrl,file,parentReference"
for nextLink != "" {
var files Files
_, err := d.Request(nextLink, http.MethodGet, nil, &files)
if err != nil {
return nil, err
}
res = append(res, files.Value...)
nextLink = files.NextLink
}
return res, nil
}
func (d *Onedrive) GetFile(path string) (*File, error) {
var file File
u := d.GetMetaUrl(false, path)
_, err := d.Request(u, http.MethodGet, nil, &file)
return &file, err
}
func (d *Onedrive) upSmall(ctx context.Context, dstDir model.Obj, stream model.FileStreamer) error {
url := d.GetMetaUrl(false, stdpath.Join(dstDir.GetPath(), stream.GetName())) + "/content"
data, err := io.ReadAll(stream)
if err != nil {
return err
}
_, err = d.Request(url, http.MethodPut, func(req *resty.Request) {
req.SetBody(data).SetContext(ctx)
}, nil)
return err
}
func (d *Onedrive) upBig(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
url := d.GetMetaUrl(false, stdpath.Join(dstDir.GetPath(), stream.GetName())) + "/createUploadSession"
res, err := d.Request(url, http.MethodPost, nil, nil)
if err != nil {
return err
}
uploadUrl := jsoniter.Get(res, "uploadUrl").ToString()
var finish int64 = 0
DEFAULT := d.ChunkSize * 1024 * 1024
for finish < stream.GetSize() {
if utils.IsCanceled(ctx) {
return ctx.Err()
}
log.Debugf("upload: %d", finish)
var byteSize int64 = DEFAULT
left := stream.GetSize() - finish
if left < DEFAULT {
byteSize = left
}
byteData := make([]byte, byteSize)
n, err := io.ReadFull(stream, byteData)
log.Debug(err, n)
if err != nil {
return err
}
req, err := http.NewRequest("PUT", uploadUrl, bytes.NewBuffer(byteData))
if err != nil {
return err
}
req = req.WithContext(ctx)
req.Header.Set("Content-Length", strconv.Itoa(int(byteSize)))
req.Header.Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", finish, finish+byteSize-1, stream.GetSize()))
finish += byteSize
res, err := base.HttpClient.Do(req)
if res.StatusCode != 201 && res.StatusCode != 202 {
data, _ := io.ReadAll(res.Body)
res.Body.Close()
return errors.New(string(data))
}
res.Body.Close()
up(int(finish * 100 / stream.GetSize()))
}
return nil
}

View File

@ -1,196 +0,0 @@
package pikpak
import (
"context"
"crypto/sha1"
"encoding/hex"
"fmt"
"io"
"net/http"
"os"
"strings"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/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/go-resty/resty/v2"
jsoniter "github.com/json-iterator/go"
log "github.com/sirupsen/logrus"
)
type PikPak struct {
model.Storage
Addition
RefreshToken string
AccessToken string
}
func (d *PikPak) Config() driver.Config {
return config
}
func (d *PikPak) GetAddition() driver.Additional {
return &d.Addition
}
func (d *PikPak) Init(ctx context.Context) error {
return d.login()
}
func (d *PikPak) Drop(ctx context.Context) error {
return nil
}
func (d *PikPak) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
files, err := d.getFiles(dir.GetID())
if err != nil {
return nil, err
}
return utils.SliceConvert(files, func(src File) (model.Obj, error) {
return fileToObj(src), nil
})
}
func (d *PikPak) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
var resp File
_, err := d.request(fmt.Sprintf("https://api-drive.mypikpak.com/drive/v1/files/%s?_magic=2021&thumbnail_size=SIZE_LARGE", file.GetID()),
http.MethodGet, nil, &resp)
if err != nil {
return nil, err
}
link := model.Link{
URL: resp.WebContentLink,
}
if len(resp.Medias) > 0 && resp.Medias[0].Link.Url != "" {
log.Debugln("use media link")
link.URL = resp.Medias[0].Link.Url
}
return &link, nil
}
func (d *PikPak) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
_, err := d.request("https://api-drive.mypikpak.com/drive/v1/files", http.MethodPost, func(req *resty.Request) {
req.SetBody(base.Json{
"kind": "drive#folder",
"parent_id": parentDir.GetID(),
"name": dirName,
})
}, nil)
return err
}
func (d *PikPak) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
_, err := d.request("https://api-drive.mypikpak.com/drive/v1/files:batchMove", http.MethodPost, func(req *resty.Request) {
req.SetBody(base.Json{
"ids": []string{srcObj.GetID()},
"to": base.Json{
"parent_id": dstDir.GetID(),
},
})
}, nil)
return err
}
func (d *PikPak) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
_, err := d.request("https://api-drive.mypikpak.com/drive/v1/files/"+srcObj.GetID(), http.MethodPatch, func(req *resty.Request) {
req.SetBody(base.Json{
"name": newName,
})
}, nil)
return err
}
func (d *PikPak) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
_, err := d.request("https://api-drive.mypikpak.com/drive/v1/files:batchCopy", http.MethodPost, func(req *resty.Request) {
req.SetBody(base.Json{
"ids": []string{srcObj.GetID()},
"to": base.Json{
"parent_id": dstDir.GetID(),
},
})
}, nil)
return err
}
func (d *PikPak) Remove(ctx context.Context, obj model.Obj) error {
_, err := d.request("https://api-drive.mypikpak.com/drive/v1/files:batchTrash", http.MethodPost, func(req *resty.Request) {
req.SetBody(base.Json{
"ids": []string{obj.GetID()},
})
}, nil)
return err
}
func (d *PikPak) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
tempFile, err := utils.CreateTempFile(stream.GetReadCloser())
if err != nil {
return err
}
defer func() {
_ = tempFile.Close()
_ = os.Remove(tempFile.Name())
}()
// cal sha1
s := sha1.New()
_, err = io.Copy(s, tempFile)
if err != nil {
return err
}
_, err = tempFile.Seek(0, io.SeekStart)
if err != nil {
return err
}
sha1Str := hex.EncodeToString(s.Sum(nil))
data := base.Json{
"kind": "drive#file",
"name": stream.GetName(),
"size": stream.GetSize(),
"hash": strings.ToUpper(sha1Str),
"upload_type": "UPLOAD_TYPE_RESUMABLE",
"objProvider": base.Json{"provider": "UPLOAD_TYPE_UNKNOWN"},
"parent_id": dstDir.GetID(),
}
res, err := d.request("https://api-drive.mypikpak.com/drive/v1/files", http.MethodPost, func(req *resty.Request) {
req.SetBody(data)
}, nil)
if err != nil {
return err
}
if stream.GetSize() == 0 {
log.Debugln(string(res))
return nil
}
params := jsoniter.Get(res, "resumable").Get("params")
endpoint := params.Get("endpoint").ToString()
endpointS := strings.Split(endpoint, ".")
endpoint = strings.Join(endpointS[1:], ".")
accessKeyId := params.Get("access_key_id").ToString()
accessKeySecret := params.Get("access_key_secret").ToString()
securityToken := params.Get("security_token").ToString()
key := params.Get("key").ToString()
bucket := params.Get("bucket").ToString()
cfg := &aws.Config{
Credentials: credentials.NewStaticCredentials(accessKeyId, accessKeySecret, securityToken),
Region: aws.String("pikpak"),
Endpoint: &endpoint,
}
ss, err := session.NewSession(cfg)
if err != nil {
return err
}
uploader := s3manager.NewUploader(ss)
input := &s3manager.UploadInput{
Bucket: &bucket,
Key: &key,
Body: tempFile,
}
_, err = uploader.UploadWithContext(ctx, input)
return err
}
var _ driver.Driver = (*PikPak)(nil)

View File

@ -1,24 +0,0 @@
package pikpak
import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)
type Addition struct {
driver.RootID
Username string `json:"username" required:"true"`
Password string `json:"password" required:"true"`
}
var config = driver.Config{
Name: "PikPak",
LocalSort: true,
DefaultRoot: "",
}
func init() {
op.RegisterDriver(func() driver.Driver {
return &PikPak{}
})
}

View File

@ -1,75 +0,0 @@
package pikpak
import (
"strconv"
"time"
"github.com/alist-org/alist/v3/internal/model"
)
type RespErr struct {
ErrorCode int `json:"error_code"`
Error string `json:"error"`
}
type Files struct {
Files []File `json:"files"`
NextPageToken string `json:"next_page_token"`
}
type File struct {
Id string `json:"id"`
Kind string `json:"kind"`
Name string `json:"name"`
ModifiedTime time.Time `json:"modified_time"`
Size string `json:"size"`
ThumbnailLink string `json:"thumbnail_link"`
WebContentLink string `json:"web_content_link"`
Medias []Media `json:"medias"`
}
func fileToObj(f File) *model.ObjThumb {
size, _ := strconv.ParseInt(f.Size, 10, 64)
return &model.ObjThumb{
Object: model.Object{
ID: f.Id,
Name: f.Name,
Size: size,
Modified: f.ModifiedTime,
IsFolder: f.Kind == "drive#folder",
},
Thumbnail: model.Thumbnail{
Thumbnail: f.ThumbnailLink,
},
}
}
type Media struct {
MediaId string `json:"media_id"`
MediaName string `json:"media_name"`
Video struct {
Height int `json:"height"`
Width int `json:"width"`
Duration int `json:"duration"`
BitRate int `json:"bit_rate"`
FrameRate int `json:"frame_rate"`
VideoCodec string `json:"video_codec"`
AudioCodec string `json:"audio_codec"`
VideoType string `json:"video_type"`
} `json:"video"`
Link struct {
Url string `json:"url"`
Token string `json:"token"`
Expire time.Time `json:"expire"`
} `json:"link"`
NeedMoreQuota bool `json:"need_more_quota"`
VipTypes []interface{} `json:"vip_types"`
RedirectLink string `json:"redirect_link"`
IconLink string `json:"icon_link"`
IsDefault bool `json:"is_default"`
Priority int `json:"priority"`
IsOrigin bool `json:"is_origin"`
ResolutionName string `json:"resolution_name"`
IsVisible bool `json:"is_visible"`
Category string `json:"category"`
}

View File

@ -1,125 +0,0 @@
package pikpak
import (
"errors"
"net/http"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/op"
"github.com/go-resty/resty/v2"
jsoniter "github.com/json-iterator/go"
)
// do others that not defined in Driver interface
func (d *PikPak) login() error {
url := "https://user.mypikpak.com/v1/auth/signin"
var e RespErr
res, err := base.RestyClient.R().SetError(&e).SetBody(base.Json{
"captcha_token": "",
"client_id": "YNxT9w7GMdWvEOKa",
"client_secret": "dbw2OtmVEeuUvIptb1Coyg",
"username": d.Username,
"password": d.Password,
}).Post(url)
if err != nil {
return err
}
if e.ErrorCode != 0 {
return errors.New(e.Error)
}
data := res.Body()
d.RefreshToken = jsoniter.Get(data, "refresh_token").ToString()
d.AccessToken = jsoniter.Get(data, "access_token").ToString()
return nil
}
func (d *PikPak) refreshToken() error {
url := "https://user.mypikpak.com/v1/auth/token"
var e RespErr
res, err := base.RestyClient.R().SetError(&e).
SetHeader("user-agent", "").SetBody(base.Json{
"client_id": "YNxT9w7GMdWvEOKa",
"client_secret": "dbw2OtmVEeuUvIptb1Coyg",
"grant_type": "refresh_token",
"refresh_token": d.RefreshToken,
}).Post(url)
if err != nil {
d.Status = err.Error()
op.MustSaveDriverStorage(d)
return err
}
if e.ErrorCode != 0 {
if e.ErrorCode == 4126 {
// refresh_token invalid, re-login
return d.login()
}
d.Status = e.Error
op.MustSaveDriverStorage(d)
return errors.New(e.Error)
}
data := res.Body()
d.Status = "work"
d.RefreshToken = jsoniter.Get(data, "refresh_token").ToString()
d.AccessToken = jsoniter.Get(data, "access_token").ToString()
op.MustSaveDriverStorage(d)
return nil
}
func (d *PikPak) request(url string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
req := base.RestyClient.R()
req.SetHeader("Authorization", "Bearer "+d.AccessToken)
if callback != nil {
callback(req)
}
if resp != nil {
req.SetResult(resp)
}
var e RespErr
req.SetError(&e)
res, err := req.Execute(method, url)
if err != nil {
return nil, err
}
if e.ErrorCode != 0 {
if e.ErrorCode == 16 {
// login / refresh token
err = d.refreshToken()
if err != nil {
return nil, err
}
return d.request(url, method, callback, resp)
} else {
return nil, errors.New(e.Error)
}
}
return res.Body(), nil
}
func (d *PikPak) getFiles(id string) ([]File, error) {
res := make([]File, 0)
pageToken := "first"
for pageToken != "" {
if pageToken == "first" {
pageToken = ""
}
query := map[string]string{
"parent_id": id,
"thumbnail_size": "SIZE_LARGE",
"with_audit": "true",
"limit": "100",
"filters": `{"phase":{"eq":"PHASE_TYPE_COMPLETE"},"trashed":{"eq":false}}`,
"page_token": pageToken,
}
var resp Files
_, err := d.request("https://api-drive.mypikpak.com/drive/v1/files", http.MethodGet, func(req *resty.Request) {
req.SetQueryParams(query)
}, &resp)
if err != nil {
return nil, err
}
pageToken = resp.NextPageToken
res = append(res, resp.Files...)
}
return res, nil
}

View File

@ -1,81 +0,0 @@
package pikpak_share
import (
"context"
"net/http"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/pkg/utils"
"github.com/go-resty/resty/v2"
log "github.com/sirupsen/logrus"
)
type PikPakShare struct {
model.Storage
Addition
RefreshToken string
AccessToken string
PassCodeToken string
}
func (d *PikPakShare) Config() driver.Config {
return config
}
func (d *PikPakShare) GetAddition() driver.Additional {
return &d.Addition
}
func (d *PikPakShare) Init(ctx context.Context) error {
err := d.login()
if err != nil {
return err
}
if d.SharePwd != "" {
err = d.getSharePassToken()
if err != nil {
return err
}
}
return nil
}
func (d *PikPakShare) Drop(ctx context.Context) error {
return nil
}
func (d *PikPakShare) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
files, err := d.getFiles(dir.GetID())
if err != nil {
return nil, err
}
return utils.SliceConvert(files, func(src File) (model.Obj, error) {
return fileToObj(src), nil
})
}
func (d *PikPakShare) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
var resp ShareResp
query := map[string]string{
"share_id": d.ShareId,
"file_id": file.GetID(),
"pass_code_token": d.PassCodeToken,
}
_, err := d.request("https://api-drive.mypikpak.com/drive/v1/share/file_info", http.MethodGet, func(req *resty.Request) {
req.SetQueryParams(query)
}, &resp)
if err != nil {
return nil, err
}
link := model.Link{
URL: resp.FileInfo.WebContentLink,
}
if len(resp.FileInfo.Medias) > 0 && resp.FileInfo.Medias[0].Link.Url != "" {
log.Debugln("use media link")
link.URL = resp.FileInfo.Medias[0].Link.Url
}
return &link, nil
}
var _ driver.Driver = (*PikPakShare)(nil)

View File

@ -1,27 +0,0 @@
package pikpak_share
import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)
type Addition struct {
driver.RootID
Username string `json:"username" required:"true"`
Password string `json:"password" required:"true"`
ShareId string `json:"share_id" required:"true"`
SharePwd string `json:"share_pwd"`
}
var config = driver.Config{
Name: "PikPakShare",
LocalSort: true,
NoUpload: true,
DefaultRoot: "",
}
func init() {
op.RegisterDriver(func() driver.Driver {
return &PikPakShare{}
})
}

View File

@ -1,154 +0,0 @@
package pikpak_share
import (
"errors"
"net/http"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/op"
"github.com/go-resty/resty/v2"
jsoniter "github.com/json-iterator/go"
)
// do others that not defined in Driver interface
func (d *PikPakShare) login() error {
url := "https://user.mypikpak.com/v1/auth/signin"
var e RespErr
res, err := base.RestyClient.R().SetError(&e).SetBody(base.Json{
"captcha_token": "",
"client_id": "YNxT9w7GMdWvEOKa",
"client_secret": "dbw2OtmVEeuUvIptb1Coyg",
"username": d.Username,
"password": d.Password,
}).Post(url)
if err != nil {
return err
}
if e.ErrorCode != 0 {
return errors.New(e.Error)
}
data := res.Body()
d.RefreshToken = jsoniter.Get(data, "refresh_token").ToString()
d.AccessToken = jsoniter.Get(data, "access_token").ToString()
return nil
}
func (d *PikPakShare) refreshToken() error {
url := "https://user.mypikpak.com/v1/auth/token"
var e RespErr
res, err := base.RestyClient.R().SetError(&e).
SetHeader("user-agent", "").SetBody(base.Json{
"client_id": "YNxT9w7GMdWvEOKa",
"client_secret": "dbw2OtmVEeuUvIptb1Coyg",
"grant_type": "refresh_token",
"refresh_token": d.RefreshToken,
}).Post(url)
if err != nil {
d.Status = err.Error()
op.MustSaveDriverStorage(d)
return err
}
if e.ErrorCode != 0 {
if e.ErrorCode == 4126 {
// refresh_token invalid, re-login
return d.login()
}
d.Status = e.Error
op.MustSaveDriverStorage(d)
return errors.New(e.Error)
}
data := res.Body()
d.Status = "work"
d.RefreshToken = jsoniter.Get(data, "refresh_token").ToString()
d.AccessToken = jsoniter.Get(data, "access_token").ToString()
op.MustSaveDriverStorage(d)
return nil
}
func (d *PikPakShare) request(url string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
req := base.RestyClient.R()
req.SetHeader("Authorization", "Bearer "+d.AccessToken)
if callback != nil {
callback(req)
}
if resp != nil {
req.SetResult(resp)
}
var e RespErr
req.SetError(&e)
res, err := req.Execute(method, url)
if err != nil {
return nil, err
}
if e.ErrorCode != 0 {
if e.ErrorCode == 16 {
// login / refresh token
err = d.refreshToken()
if err != nil {
return nil, err
}
return d.request(url, method, callback, resp)
}
return nil, errors.New(e.Error)
}
return res.Body(), nil
}
func (d *PikPakShare) getSharePassToken() error {
query := map[string]string{
"share_id": d.ShareId,
"pass_code": d.SharePwd,
"thumbnail_size": "SIZE_LARGE",
"limit": "100",
}
var resp ShareResp
_, err := d.request("https://api-drive.mypikpak.com/drive/v1/share", http.MethodGet, func(req *resty.Request) {
req.SetQueryParams(query)
}, &resp)
if err != nil {
return err
}
d.PassCodeToken = resp.PassCodeToken
return nil
}
func (d *PikPakShare) getFiles(id string) ([]File, error) {
res := make([]File, 0)
pageToken := "first"
for pageToken != "" {
if pageToken == "first" {
pageToken = ""
}
query := map[string]string{
"parent_id": id,
"share_id": d.ShareId,
"thumbnail_size": "SIZE_LARGE",
"with_audit": "true",
"limit": "100",
"filters": `{"phase":{"eq":"PHASE_TYPE_COMPLETE"},"trashed":{"eq":false}}`,
"page_token": pageToken,
"pass_code_token": d.PassCodeToken,
}
var resp ShareResp
_, err := d.request("https://api-drive.mypikpak.com/drive/v1/share/detail", http.MethodGet, func(req *resty.Request) {
req.SetQueryParams(query)
}, &resp)
if err != nil {
return nil, err
}
if resp.ShareStatus != "OK" {
if resp.ShareStatus == "PASS_CODE_EMPTY" || resp.ShareStatus == "PASS_CODE_ERROR" {
err = d.getSharePassToken()
if err != nil {
return nil, err
}
return d.getFiles(id)
}
return nil, errors.New(resp.ShareStatusText)
}
pageToken = resp.NextPageToken
res = append(res, resp.Files...)
}
return res, nil
}

View File

@ -1,215 +0,0 @@
package quark
import (
"context"
"crypto/md5"
"crypto/sha1"
"encoding/hex"
"io"
"net/http"
"os"
"time"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/errs"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/pkg/utils"
"github.com/go-resty/resty/v2"
log "github.com/sirupsen/logrus"
)
type Quark struct {
model.Storage
Addition
}
func (d *Quark) Config() driver.Config {
return config
}
func (d *Quark) GetAddition() driver.Additional {
return &d.Addition
}
func (d *Quark) Init(ctx context.Context) error {
_, err := d.request("/config", http.MethodGet, nil, nil)
return err
}
func (d *Quark) Drop(ctx context.Context) error {
return nil
}
func (d *Quark) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
files, err := d.GetFiles(dir.GetID())
if err != nil {
return nil, err
}
return utils.SliceConvert(files, func(src File) (model.Obj, error) {
return fileToObj(src), nil
})
}
func (d *Quark) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
data := base.Json{
"fids": []string{file.GetID()},
}
var resp DownResp
_, err := d.request("/file/download", http.MethodPost, func(req *resty.Request) {
req.SetBody(data)
}, &resp)
if err != nil {
return nil, err
}
return &model.Link{
URL: resp.Data[0].DownloadUrl,
Header: http.Header{
"Cookie": []string{d.Cookie},
"Referer": []string{"https://pan.quark.cn"},
},
}, nil
}
func (d *Quark) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
data := base.Json{
"dir_init_lock": false,
"dir_path": "",
"file_name": dirName,
"pdir_fid": parentDir.GetID(),
}
_, err := d.request("/file", http.MethodPost, func(req *resty.Request) {
req.SetBody(data)
}, nil)
if err == nil {
time.Sleep(time.Second)
}
return err
}
func (d *Quark) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
data := base.Json{
"action_type": 1,
"exclude_fids": []string{},
"filelist": []string{srcObj.GetID()},
"to_pdir_fid": dstDir.GetID(),
}
_, err := d.request("/file/move", http.MethodPost, func(req *resty.Request) {
req.SetBody(data)
}, nil)
return err
}
func (d *Quark) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
data := base.Json{
"fid": srcObj.GetID(),
"file_name": newName,
}
_, err := d.request("/file/rename", http.MethodPost, func(req *resty.Request) {
req.SetBody(data)
}, nil)
return err
}
func (d *Quark) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
return errs.NotSupport
}
func (d *Quark) Remove(ctx context.Context, obj model.Obj) error {
data := base.Json{
"action_type": 1,
"exclude_fids": []string{},
"filelist": []string{obj.GetID()},
}
_, err := d.request("/file/delete", http.MethodPost, func(req *resty.Request) {
req.SetBody(data)
}, nil)
return err
}
func (d *Quark) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
tempFile, err := utils.CreateTempFile(stream.GetReadCloser())
if err != nil {
return err
}
defer func() {
_ = tempFile.Close()
_ = os.Remove(tempFile.Name())
}()
m := md5.New()
_, err = io.Copy(m, tempFile)
if err != nil {
return err
}
_, err = tempFile.Seek(0, io.SeekStart)
if err != nil {
return err
}
md5Str := hex.EncodeToString(m.Sum(nil))
s := sha1.New()
_, err = io.Copy(s, tempFile)
if err != nil {
return err
}
_, err = tempFile.Seek(0, io.SeekStart)
if err != nil {
return err
}
sha1Str := hex.EncodeToString(s.Sum(nil))
// pre
pre, err := d.upPre(stream, dstDir.GetID())
if err != nil {
return err
}
log.Debugln("hash: ", md5Str, sha1Str)
// hash
finish, err := d.upHash(md5Str, sha1Str, pre.Data.TaskId)
if err != nil {
return err
}
if finish {
return nil
}
// part up
partSize := pre.Metadata.PartSize
var bytes []byte
md5s := make([]string, 0)
defaultBytes := make([]byte, partSize)
total := stream.GetSize()
left := total
partNumber := 1
for left > 0 {
if utils.IsCanceled(ctx) {
return ctx.Err()
}
if left > int64(partSize) {
bytes = defaultBytes
} else {
bytes = make([]byte, left)
}
_, err := io.ReadFull(tempFile, bytes)
if err != nil {
return err
}
left -= int64(len(bytes))
log.Debugf("left: %d", left)
m, err := d.upPart(ctx, pre, stream.GetMimetype(), partNumber, bytes)
//m, err := driver.UpPart(pre, file.GetMIMEType(), partNumber, bytes, account, md5Str, sha1Str)
if err != nil {
return err
}
if m == "finish" {
return nil
}
md5s = append(md5s, m)
partNumber++
up(int(100 * (total - left) / total))
}
err = d.upCommit(pre, md5s)
if err != nil {
return err
}
return d.upFinish(pre)
}
var _ driver.Driver = (*Quark)(nil)

View File

@ -1,25 +0,0 @@
package quark
import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)
type Addition struct {
Cookie string `json:"cookie" required:"true"`
driver.RootID
OrderBy string `json:"order_by" type:"select" options:"none,file_type,file_name,updated_at" default:"none"`
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" default:"asc"`
}
var config = driver.Config{
Name: "Quark",
OnlyProxy: true,
DefaultRoot: "0",
}
func init() {
op.RegisterDriver(func() driver.Driver {
return &Quark{}
})
}

View File

@ -1,141 +0,0 @@
package s3
import (
"bytes"
"context"
"fmt"
"io"
"net/url"
stdpath "path"
"time"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/model"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/s3/s3manager"
log "github.com/sirupsen/logrus"
)
type S3 struct {
model.Storage
Addition
Session *session.Session
client *s3.S3
linkClient *s3.S3
}
func (d *S3) Config() driver.Config {
return config
}
func (d *S3) GetAddition() driver.Additional {
return &d.Addition
}
func (d *S3) Init(ctx context.Context) error {
if d.Region == "" {
d.Region = "alist"
}
err := d.initSession()
if err != nil {
return err
}
d.client = d.getClient(false)
d.linkClient = d.getClient(true)
return nil
}
func (d *S3) Drop(ctx context.Context) error {
return nil
}
func (d *S3) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
if d.ListObjectVersion == "v2" {
return d.listV2(dir.GetPath())
}
return d.listV1(dir.GetPath())
}
func (d *S3) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
path := getKey(file.GetPath(), false)
disposition := fmt.Sprintf(`attachment;filename="%s"`, url.QueryEscape(stdpath.Base(path)))
input := &s3.GetObjectInput{
Bucket: &d.Bucket,
Key: &path,
//ResponseContentDisposition: &disposition,
}
if d.CustomHost == "" {
input.ResponseContentDisposition = &disposition
}
req, _ := d.linkClient.GetObjectRequest(input)
var link string
var err error
if d.CustomHost != "" {
err = req.Build()
link = req.HTTPRequest.URL.String()
} else {
link, err = req.Presign(time.Hour * time.Duration(d.SignURLExpire))
}
if err != nil {
return nil, err
}
return &model.Link{
URL: link,
}, nil
}
func (d *S3) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
return d.Put(ctx, &model.Object{
Path: stdpath.Join(parentDir.GetPath(), dirName),
}, &model.FileStream{
Obj: &model.Object{
Name: getPlaceholderName(d.Placeholder),
Modified: time.Now(),
},
ReadCloser: io.NopCloser(bytes.NewReader([]byte{})),
Mimetype: "application/octet-stream",
}, func(int) {})
}
func (d *S3) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
err := d.Copy(ctx, srcObj, dstDir)
if err != nil {
return err
}
return d.Remove(ctx, srcObj)
}
func (d *S3) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
err := d.copy(ctx, srcObj.GetPath(), stdpath.Join(stdpath.Dir(srcObj.GetPath()), newName), srcObj.IsDir())
if err != nil {
return err
}
return d.Remove(ctx, srcObj)
}
func (d *S3) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
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 {
if obj.IsDir() {
return d.removeDir(ctx, obj.GetPath())
}
return d.removeFile(obj.GetPath())
}
func (d *S3) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
uploader := s3manager.NewUploader(d.Session)
key := getKey(stdpath.Join(dstDir.GetPath(), stream.GetName()), false)
log.Debugln("key:", key)
input := &s3manager.UploadInput{
Bucket: &d.Bucket,
Key: &key,
Body: stream,
}
_, err := uploader.UploadWithContext(ctx, input)
return err
}
var _ driver.Driver = (*S3)(nil)

View File

@ -1,33 +0,0 @@
package s3
import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)
type Addition struct {
driver.RootPath
Bucket string `json:"bucket" required:"true"`
Endpoint string `json:"endpoint" required:"true"`
Region string `json:"region"`
AccessKeyID string `json:"access_key_id" required:"true"`
SecretAccessKey string `json:"secret_access_key" required:"true"`
CustomHost string `json:"custom_host"`
SignURLExpire int `json:"sign_url_expire" type:"number" default:"4"`
Placeholder string `json:"placeholder"`
ForcePathStyle bool `json:"force_path_style"`
ListObjectVersion string `json:"list_object_version" type:"select" options:"v1,v2" default:"v1"`
}
var config = driver.Config{
Name: "S3",
DefaultRoot: "/",
LocalSort: true,
CheckStatus: true,
}
func init() {
op.RegisterDriver(func() driver.Driver {
return &S3{}
})
}

View File

@ -1,160 +0,0 @@
package seafile
import (
"context"
"fmt"
"net/http"
"path/filepath"
"strings"
"time"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/pkg/utils"
"github.com/go-resty/resty/v2"
)
type Seafile struct {
model.Storage
Addition
authorization string
}
func (d *Seafile) Config() driver.Config {
return config
}
func (d *Seafile) GetAddition() driver.Additional {
return &d.Addition
}
func (d *Seafile) Init(ctx context.Context) error {
d.Address = strings.TrimSuffix(d.Address, "/")
return d.getToken()
}
func (d *Seafile) Drop(ctx context.Context) error {
return nil
}
func (d *Seafile) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
path := dir.GetPath()
var resp []RepoDirItemResp
_, err := d.request(http.MethodGet, fmt.Sprintf("/api2/repos/%s/dir/", d.Addition.RepoId), func(req *resty.Request) {
req.SetResult(&resp).SetQueryParams(map[string]string{
"p": path,
})
})
if err != nil {
return nil, err
}
return utils.SliceConvert(resp, func(f RepoDirItemResp) (model.Obj, error) {
return &model.ObjThumb{
Object: model.Object{
Name: f.Name,
Modified: time.Unix(f.Modified, 0),
Size: f.Size,
IsFolder: f.Type == "dir",
},
// Thumbnail: model.Thumbnail{Thumbnail: f.Thumb},
}, nil
})
}
func (d *Seafile) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
res, err := d.request(http.MethodGet, fmt.Sprintf("/api2/repos/%s/file/", d.Addition.RepoId), func(req *resty.Request) {
req.SetQueryParams(map[string]string{
"p": file.GetPath(),
"reuse": "1",
})
})
if err != nil {
return nil, err
}
u := string(res)
u = u[1 : len(u)-1] // remove quotes
return &model.Link{URL: u}, nil
}
func (d *Seafile) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
_, err := d.request(http.MethodPost, fmt.Sprintf("/api2/repos/%s/dir/", d.Addition.RepoId), func(req *resty.Request) {
req.SetQueryParams(map[string]string{
"p": filepath.Join(parentDir.GetPath(), dirName),
}).SetFormData(map[string]string{
"operation": "mkdir",
})
})
return err
}
func (d *Seafile) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
_, err := d.request(http.MethodPost, fmt.Sprintf("/api2/repos/%s/file/", d.Addition.RepoId), func(req *resty.Request) {
req.SetQueryParams(map[string]string{
"p": srcObj.GetPath(),
}).SetFormData(map[string]string{
"operation": "move",
"dst_repo": d.Addition.RepoId,
"dst_dir": dstDir.GetPath(),
})
}, true)
return err
}
func (d *Seafile) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
_, err := d.request(http.MethodPost, fmt.Sprintf("/api2/repos/%s/file/", d.Addition.RepoId), func(req *resty.Request) {
req.SetQueryParams(map[string]string{
"p": srcObj.GetPath(),
}).SetFormData(map[string]string{
"operation": "rename",
"newname": newName,
})
}, true)
return err
}
func (d *Seafile) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
_, err := d.request(http.MethodPost, fmt.Sprintf("/api2/repos/%s/file/", d.Addition.RepoId), func(req *resty.Request) {
req.SetQueryParams(map[string]string{
"p": srcObj.GetPath(),
}).SetFormData(map[string]string{
"operation": "copy",
"dst_repo": d.Addition.RepoId,
"dst_dir": dstDir.GetPath(),
})
})
return err
}
func (d *Seafile) Remove(ctx context.Context, obj model.Obj) error {
_, err := d.request(http.MethodDelete, fmt.Sprintf("/api2/repos/%s/file/", d.Addition.RepoId), func(req *resty.Request) {
req.SetQueryParams(map[string]string{
"p": obj.GetPath(),
})
})
return err
}
func (d *Seafile) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
res, err := d.request(http.MethodGet, fmt.Sprintf("/api2/repos/%s/upload-link/", d.Addition.RepoId), func(req *resty.Request) {
req.SetQueryParams(map[string]string{
"p": dstDir.GetPath(),
})
})
if err != nil {
return err
}
u := string(res)
u = u[1 : len(u)-1] // remove quotes
_, err = d.request(http.MethodPost, u, func(req *resty.Request) {
req.SetFileReader("file", stream.GetName(), stream).
SetFormData(map[string]string{
"parent_dir": dstDir.GetPath(),
"replace": "1",
})
})
return err
}
var _ driver.Driver = (*Seafile)(nil)

View File

@ -1,26 +0,0 @@
package seafile
import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)
type Addition struct {
driver.RootPath
Address string `json:"address" required:"true"`
UserName string `json:"username" required:"true"`
Password string `json:"password" required:"true"`
RepoId string `json:"repoId" required:"true"`
}
var config = driver.Config{
Name: "Seafile",
DefaultRoot: "/",
}
func init() {
op.RegisterDriver(func() driver.Driver {
return &Seafile{}
})
}

View File

@ -1,14 +0,0 @@
package seafile
type AuthTokenResp struct {
Token string `json:"token"`
}
type RepoDirItemResp struct {
Id string `json:"id"`
Type string `json:"type"` // dir, file
Name string `json:"name"`
Size int64 `json:"size"`
Modified int64 `json:"mtime"`
Permission string `json:"permission"`
}

View File

@ -1,59 +0,0 @@
package seafile
import (
"fmt"
"strings"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/go-resty/resty/v2"
)
func (d *Seafile) getToken() error {
var authResp AuthTokenResp
res, err := base.RestyClient.R().
SetResult(&authResp).
SetFormData(map[string]string{
"username": d.UserName,
"password": d.Password,
}).
Post(d.Address + "/api2/auth-token/")
if err != nil {
return err
}
if res.StatusCode() >= 400 {
return fmt.Errorf("get token failed: %s", res.String())
}
d.authorization = fmt.Sprintf("Token %s", authResp.Token)
return nil
}
func (d *Seafile) request(method string, pathname string, callback base.ReqCallback, noRedirect ...bool) ([]byte, error) {
full := pathname
if !strings.HasPrefix(pathname, "http") {
full = d.Address + pathname
}
req := base.RestyClient.R()
if len(noRedirect) > 0 && noRedirect[0] {
req = base.NoRedirectClient.R()
}
var res resty.Response
for i := 0; i < 2; i++ {
req.SetHeader("Authorization", d.authorization)
callback(req)
res, err := req.Execute(method, full)
if err != nil {
return nil, err
}
if res.StatusCode() != 401 { // Unauthorized
break
}
err = d.getToken()
if err != nil {
return nil, err
}
}
if res.StatusCode() >= 400 {
return nil, fmt.Errorf("request failed: %s", res.String())
}
return res.Body(), nil
}

View File

@ -1,28 +0,0 @@
package sftp
import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)
type Addition struct {
Address string `json:"address" required:"true"`
Username string `json:"username" required:"true"`
PrivateKey string `json:"private_key" type:"text"`
Password string `json:"password"`
driver.RootPath
}
var config = driver.Config{
Name: "SFTP",
LocalSort: true,
OnlyLocal: true,
DefaultRoot: "/",
CheckStatus: true,
}
func init() {
op.RegisterDriver(func() driver.Driver {
return &SFTP{}
})
}

View File

@ -1,16 +0,0 @@
package sftp
import (
"os"
"github.com/alist-org/alist/v3/internal/model"
)
func fileToObj(f os.FileInfo) model.Obj {
return &model.Object{
Name: f.Name(),
Size: f.Size(),
Modified: f.ModTime(),
IsFolder: f.IsDir(),
}
}

View File

@ -1,78 +0,0 @@
package template
import (
"context"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/errs"
"github.com/alist-org/alist/v3/internal/model"
)
type Template struct {
model.Storage
Addition
}
func (d *Template) Config() driver.Config {
return config
}
func (d *Template) GetAddition() driver.Additional {
return &d.Addition
}
func (d *Template) Init(ctx context.Context) error {
// TODO login / refresh token
//op.MustSaveDriverStorage(d)
return nil
}
func (d *Template) Drop(ctx context.Context) error {
return nil
}
func (d *Template) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
// TODO return the files list
return nil, errs.NotImplement
}
func (d *Template) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
// TODO return link of file
return nil, errs.NotImplement
}
func (d *Template) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
// TODO create folder
return errs.NotImplement
}
func (d *Template) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
// TODO move obj
return errs.NotImplement
}
func (d *Template) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
// TODO rename obj
return errs.NotImplement
}
func (d *Template) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
// TODO copy obj
return errs.NotImplement
}
func (d *Template) Remove(ctx context.Context, obj model.Obj) error {
// TODO remove obj
return errs.NotImplement
}
func (d *Template) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
// TODO upload file
return errs.NotImplement
}
//func (d *Template) Other(ctx context.Context, args model.OtherArgs) (interface{}, error) {
// return nil, errs.NotSupport
//}
var _ driver.Driver = (*Template)(nil)

View File

@ -1,31 +0,0 @@
package template
import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)
type Addition struct {
// Usually one of two
driver.RootPath
driver.RootID
// define other
Field string `json:"field" type:"select" required:"true" options:"a,b,c" default:"a"`
}
var config = driver.Config{
Name: "Template",
LocalSort: false,
OnlyLocal: false,
OnlyProxy: false,
NoCache: false,
NoUpload: false,
NeedMs: false,
DefaultRoot: "root, / or other",
}
func init() {
op.RegisterDriver(func() driver.Driver {
return &Template{}
})
}

View File

@ -1,223 +0,0 @@
package terbox
import (
"bytes"
"context"
"crypto/md5"
"encoding/hex"
"fmt"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/pkg/utils"
log "github.com/sirupsen/logrus"
"io"
"math"
"os"
stdpath "path"
"strconv"
"strings"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/model"
)
type Terabox struct {
model.Storage
Addition
}
func (d *Terabox) Config() driver.Config {
return config
}
func (d *Terabox) GetAddition() driver.Additional {
return &d.Addition
}
func (d *Terabox) Init(ctx context.Context) error {
var resp CheckLoginResp
_, err := d.get("/api/check/login", nil, &resp)
if err != nil {
return err
}
if resp.Errno != 0 {
if resp.Errno == 9000 {
return fmt.Errorf("terabox is not yet available in this area")
}
return fmt.Errorf("failed to check login status according to cookie")
}
return err
}
func (d *Terabox) Drop(ctx context.Context) error {
return nil
}
func (d *Terabox) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
files, err := d.getFiles(dir.GetPath())
if err != nil {
return nil, err
}
return utils.SliceConvert(files, func(src File) (model.Obj, error) {
return fileToObj(src), nil
})
}
func (d *Terabox) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
if d.DownloadAPI == "crack" {
return d.linkCrack(file, args)
}
return d.linkOfficial(file, args)
}
func (d *Terabox) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
_, err := d.create(stdpath.Join(parentDir.GetPath(), dirName), 0, 1, "", "")
return err
}
func (d *Terabox) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
data := []base.Json{
{
"path": srcObj.GetPath(),
"dest": dstDir.GetPath(),
"newname": srcObj.GetName(),
},
}
_, err := d.manage("move", data)
return err
}
func (d *Terabox) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
data := []base.Json{
{
"path": srcObj.GetPath(),
"newname": newName,
},
}
_, err := d.manage("rename", data)
return err
}
func (d *Terabox) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
data := []base.Json{
{
"path": srcObj.GetPath(),
"dest": dstDir.GetPath(),
"newname": srcObj.GetName(),
},
}
_, err := d.manage("copy", data)
return err
}
func (d *Terabox) Remove(ctx context.Context, obj model.Obj) error {
data := []string{obj.GetPath()}
_, err := d.manage("delete", data)
return err
}
func (d *Terabox) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
tempFile, err := utils.CreateTempFile(stream.GetReadCloser())
if err != nil {
return err
}
defer func() {
_ = tempFile.Close()
_ = os.Remove(tempFile.Name())
}()
var Default int64 = 4 * 1024 * 1024
defaultByteData := make([]byte, Default)
count := int(math.Ceil(float64(stream.GetSize()) / float64(Default)))
// cal md5
h1 := md5.New()
h2 := md5.New()
block_list := make([]string, 0)
left := stream.GetSize()
for i := 0; i < count; i++ {
byteSize := Default
var byteData []byte
if left < Default {
byteSize = left
byteData = make([]byte, byteSize)
} else {
byteData = defaultByteData
}
left -= byteSize
_, err = io.ReadFull(tempFile, byteData)
if err != nil {
return err
}
h1.Write(byteData)
h2.Write(byteData)
block_list = append(block_list, fmt.Sprintf("\"%s\"", hex.EncodeToString(h2.Sum(nil))))
h2.Reset()
}
_, err = tempFile.Seek(0, io.SeekStart)
if err != nil {
return err
}
rawPath := stdpath.Join(dstDir.GetPath(), stream.GetName())
path := encodeURIComponent(rawPath)
block_list_str := fmt.Sprintf("[%s]", strings.Join(block_list, ","))
data := fmt.Sprintf("path=%s&size=%d&isdir=0&autoinit=1&block_list=%s",
path, stream.GetSize(),
block_list_str)
params := map[string]string{}
var precreateResp PrecreateResp
_, err = d.post("/api/precreate", params, data, &precreateResp)
if err != nil {
return err
}
log.Debugf("%+v", precreateResp)
if precreateResp.ReturnType == 2 {
return nil
}
params = map[string]string{
"method": "upload",
"path": path,
"uploadid": precreateResp.Uploadid,
"app_id": "250528",
"web": "1",
"channel": "dubox",
"clienttype": "0",
}
left = stream.GetSize()
for i, partseq := range precreateResp.BlockList {
if utils.IsCanceled(ctx) {
return ctx.Err()
}
byteSize := Default
var byteData []byte
if left < Default {
byteSize = left
byteData = make([]byte, byteSize)
} else {
byteData = defaultByteData
}
left -= byteSize
_, err = io.ReadFull(tempFile, byteData)
if err != nil {
return err
}
u := "https://c-jp.terabox.com/rest/2.0/pcs/superfile2"
params["partseq"] = strconv.Itoa(partseq)
res, err := base.RestyClient.R().
SetContext(ctx).
SetQueryParams(params).
SetFileReader("file", stream.GetName(), bytes.NewReader(byteData)).
SetHeader("Cookie", d.Cookie).
Post(u)
if err != nil {
return err
}
log.Debugln(res.String())
if len(precreateResp.BlockList) > 0 {
up(i * 100 / len(precreateResp.BlockList))
}
}
_, err = d.create(rawPath, stream.GetSize(), 0, precreateResp.Uploadid, block_list_str)
return err
}
var _ driver.Driver = (*Terabox)(nil)

View File

@ -1,200 +0,0 @@
package terbox
import (
"encoding/base64"
"fmt"
"github.com/alist-org/alist/v3/drivers/base"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/pkg/utils"
"github.com/go-resty/resty/v2"
"net/http"
"net/url"
"strconv"
"strings"
"time"
)
func (d *Terabox) request(furl string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
req := base.RestyClient.R()
req.SetHeaders(map[string]string{
"Cookie": d.Cookie,
"Accept": "application/json, text/plain, */*",
"Referer": "https://www.terabox.com/",
"User-Agent": base.UserAgent,
"X-Requested-With": "XMLHttpRequest",
})
req.SetQueryParam("app_id", "250528")
req.SetQueryParam("web", "1")
req.SetQueryParam("channel", "dubox")
req.SetQueryParam("clienttype", "0")
if callback != nil {
callback(req)
}
if resp != nil {
req.SetResult(resp)
}
res, err := req.Execute(method, furl)
if err != nil {
return nil, err
}
return res.Body(), nil
}
func (d *Terabox) get(pathname string, params map[string]string, resp interface{}) ([]byte, error) {
return d.request("https://www.terabox.com"+pathname, http.MethodGet, func(req *resty.Request) {
if params != nil {
req.SetQueryParams(params)
}
}, resp)
}
func (d *Terabox) post(pathname string, params map[string]string, data interface{}, resp interface{}) ([]byte, error) {
return d.request("https://www.terabox.com"+pathname, http.MethodPost, func(req *resty.Request) {
if params != nil {
req.SetQueryParams(params)
}
req.SetBody(data)
}, resp)
}
func (d *Terabox) getFiles(dir string) ([]File, error) {
page := 1
num := 100
params := map[string]string{
"dir": dir,
}
if d.OrderBy != "" {
params["order"] = d.OrderBy
if d.OrderDirection == "desc" {
params["desc"] = "1"
}
}
res := make([]File, 0)
for {
params["page"] = strconv.Itoa(page)
params["num"] = strconv.Itoa(num)
var resp ListResp
_, err := d.get("/api/list", params, &resp)
if err != nil {
return nil, err
}
if resp.Errno == 9000 {
return nil, fmt.Errorf("terabox is not yet available in this area")
}
if len(resp.List) == 0 {
break
}
res = append(res, resp.List...)
page++
}
return res, nil
}
func sign(s1, s2 string) string {
var a = make([]int, 256)
var p = make([]int, 256)
var o []byte
var v = len(s1)
for q := 0; q < 256; q++ {
a[q] = int(s1[(q % v) : (q%v)+1][0])
p[q] = q
}
for u, q := 0, 0; q < 256; q++ {
u = (u + p[q] + a[q]) % 256
p[q], p[u] = p[u], p[q]
}
for i, u, q := 0, 0, 0; q < len(s2); q++ {
i = (i + 1) % 256
u = (u + p[i]) % 256
p[i], p[u] = p[u], p[i]
k := p[((p[i] + p[u]) % 256)]
o = append(o, byte(int(s2[q])^k))
}
return base64.StdEncoding.EncodeToString(o)
}
func (d *Terabox) genSign() (string, error) {
var resp HomeInfoResp
_, err := d.get("/api/home/info", map[string]string{}, &resp)
if err != nil {
return "", err
}
return sign(resp.Data.Sign3, resp.Data.Sign1), nil
}
func (d *Terabox) linkOfficial(file model.Obj, args model.LinkArgs) (*model.Link, error) {
var resp DownloadResp
signString, err := d.genSign()
if err != nil {
return nil, err
}
params := map[string]string{
"type": "dlink",
"fidlist": fmt.Sprintf("[%s]", file.GetID()),
"sign": signString,
"vip": "2",
"timestamp": strconv.FormatInt(time.Now().Unix(), 10),
}
_, err = d.get("/api/download", params, &resp)
if err != nil {
return nil, err
}
res, err := base.NoRedirectClient.R().SetHeader("Cookie", d.Cookie).SetHeader("User-Agent", base.UserAgent).Get(resp.Dlink[0].Dlink)
if err != nil {
return nil, err
}
u := res.Header().Get("location")
return &model.Link{
URL: u,
Header: http.Header{
"User-Agent": []string{base.UserAgent},
},
}, nil
}
func (d *Terabox) linkCrack(file model.Obj, args model.LinkArgs) (*model.Link, error) {
var resp DownloadResp2
param := map[string]string{
"target": fmt.Sprintf("[\"%s\"]", file.GetPath()),
"dlink": "1",
"origin": "dlna",
}
_, err := d.get("/api/filemetas", param, &resp)
if err != nil {
return nil, err
}
return &model.Link{
URL: resp.Info[0].Dlink,
Header: http.Header{
"User-Agent": []string{base.UserAgent},
},
}, nil
}
func (d *Terabox) manage(opera string, filelist interface{}) ([]byte, error) {
params := map[string]string{
"onnest": "fail",
"opera": opera,
}
marshal, err := utils.Json.Marshal(filelist)
if err != nil {
return nil, err
}
data := fmt.Sprintf("async=0&filelist=%s&ondup=newcopy", string(marshal))
return d.post("/api/filemanager", params, data, nil)
}
func (d *Terabox) create(path string, size int64, isdir int, uploadid, block_list string) ([]byte, error) {
params := map[string]string{}
data := fmt.Sprintf("path=%s&size=%d&isdir=%d", encodeURIComponent(path), size, isdir)
if uploadid != "" {
data += fmt.Sprintf("&uploadid=%s&block_list=%s", uploadid, block_list)
}
return d.post("/api/create", params, data, nil)
}
func encodeURIComponent(str string) string {
r := url.QueryEscape(str)
r = strings.ReplaceAll(r, "+", "%20")
return r
}

View File

@ -1,195 +0,0 @@
package thunder
import (
"fmt"
"strconv"
"time"
)
type ErrResp struct {
ErrorCode int64 `json:"error_code"`
ErrorMsg string `json:"error"`
ErrorDescription string `json:"error_description"`
// ErrorDetails interface{} `json:"error_details"`
}
func (e *ErrResp) IsError() bool {
return e.ErrorCode != 0 || e.ErrorMsg != "" || e.ErrorDescription != ""
}
func (e *ErrResp) Error() string {
return fmt.Sprintf("ErrorCode: %d ,Error: %s ,ErrorDescription: %s ", e.ErrorCode, e.ErrorMsg, e.ErrorDescription)
}
/*
* 验证码Token
**/
type CaptchaTokenRequest struct {
Action string `json:"action"`
CaptchaToken string `json:"captcha_token"`
ClientID string `json:"client_id"`
DeviceID string `json:"device_id"`
Meta map[string]string `json:"meta"`
RedirectUri string `json:"redirect_uri"`
}
type CaptchaTokenResponse struct {
CaptchaToken string `json:"captcha_token"`
ExpiresIn int64 `json:"expires_in"`
Url string `json:"url"`
}
/*
* 登录
**/
type TokenResp struct {
TokenType string `json:"token_type"`
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
ExpiresIn int64 `json:"expires_in"`
Sub string `json:"sub"`
UserID string `json:"user_id"`
}
func (t *TokenResp) Token() string {
return fmt.Sprint(t.TokenType, " ", t.AccessToken)
}
type SignInRequest struct {
CaptchaToken string `json:"captcha_token"`
ClientID string `json:"client_id"`
ClientSecret string `json:"client_secret"`
Username string `json:"username"`
Password string `json:"password"`
}
/*
* 文件
**/
type FileList struct {
Kind string `json:"kind"`
NextPageToken string `json:"next_page_token"`
Files []Files `json:"files"`
Version string `json:"version"`
VersionOutdated bool `json:"version_outdated"`
}
type Link struct {
URL string `json:"url"`
Token string `json:"token"`
Expire time.Time `json:"expire"`
Type string `json:"type"`
}
type Files struct {
Kind string `json:"kind"`
ID string `json:"id"`
ParentID string `json:"parent_id"`
Name string `json:"name"`
//UserID string `json:"user_id"`
Size string `json:"size"`
//Revision string `json:"revision"`
//FileExtension string `json:"file_extension"`
//MimeType string `json:"mime_type"`
//Starred bool `json:"starred"`
WebContentLink string `json:"web_content_link"`
CreatedTime time.Time `json:"created_time"`
ModifiedTime time.Time `json:"modified_time"`
IconLink string `json:"icon_link"`
ThumbnailLink string `json:"thumbnail_link"`
//Md5Checksum string `json:"md5_checksum"`
//Hash string `json:"hash"`
Links map[string]Link `json:"links"`
Phase string `json:"phase"`
Audit struct {
Status string `json:"status"`
Message string `json:"message"`
Title string `json:"title"`
} `json:"audit"`
Medias []struct {
Category string `json:"category"`
IconLink string `json:"icon_link"`
IsDefault bool `json:"is_default"`
IsOrigin bool `json:"is_origin"`
IsVisible bool `json:"is_visible"`
Link Link `json:"link"`
MediaID string `json:"media_id"`
MediaName string `json:"media_name"`
NeedMoreQuota bool `json:"need_more_quota"`
Priority int `json:"priority"`
RedirectLink string `json:"redirect_link"`
ResolutionName string `json:"resolution_name"`
Video struct {
AudioCodec string `json:"audio_codec"`
BitRate int `json:"bit_rate"`
Duration int `json:"duration"`
FrameRate int `json:"frame_rate"`
Height int `json:"height"`
VideoCodec string `json:"video_codec"`
VideoType string `json:"video_type"`
Width int `json:"width"`
} `json:"video"`
VipTypes []string `json:"vip_types"`
} `json:"medias"`
Trashed bool `json:"trashed"`
DeleteTime string `json:"delete_time"`
OriginalURL string `json:"original_url"`
//Params struct{} `json:"params"`
//OriginalFileIndex int `json:"original_file_index"`
//Space string `json:"space"`
//Apps []interface{} `json:"apps"`
//Writable bool `json:"writable"`
//FolderType string `json:"folder_type"`
//Collection interface{} `json:"collection"`
}
func (c *Files) GetSize() int64 { size, _ := strconv.ParseInt(c.Size, 10, 64); return size }
func (c *Files) GetName() string { return c.Name }
func (c *Files) ModTime() time.Time { return c.ModifiedTime }
func (c *Files) IsDir() bool { return c.Kind == FOLDER }
func (c *Files) GetID() string { return c.ID }
func (c *Files) GetPath() string { return "" }
func (c *Files) Thumb() string { return c.ThumbnailLink }
/*
* 上传
**/
type UploadTaskResponse struct {
UploadType string `json:"upload_type"`
/*//UPLOAD_TYPE_FORM
Form struct {
//Headers struct{} `json:"headers"`
Kind string `json:"kind"`
Method string `json:"method"`
MultiParts struct {
OSSAccessKeyID string `json:"OSSAccessKeyId"`
Signature string `json:"Signature"`
Callback string `json:"callback"`
Key string `json:"key"`
Policy string `json:"policy"`
XUserData string `json:"x:user_data"`
} `json:"multi_parts"`
URL string `json:"url"`
} `json:"form"`*/
//UPLOAD_TYPE_RESUMABLE
Resumable struct {
Kind string `json:"kind"`
Params struct {
AccessKeyID string `json:"access_key_id"`
AccessKeySecret string `json:"access_key_secret"`
Bucket string `json:"bucket"`
Endpoint string `json:"endpoint"`
Expiration time.Time `json:"expiration"`
Key string `json:"key"`
SecurityToken string `json:"security_token"`
} `json:"params"`
Provider string `json:"provider"`
} `json:"resumable"`
File Files `json:"file"`
}

View File

@ -1,28 +0,0 @@
package uss
import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)
type Addition struct {
driver.RootPath
Bucket string `json:"bucket" required:"true"`
Endpoint string `json:"endpoint" required:"true"`
OperatorName string `json:"operator_name" required:"true"`
OperatorPassword string `json:"operator_password" required:"true"`
//CustomHost string `json:"custom_host"` //Endpoint与CustomHost作用相同去除
SignURLExpire int `json:"sign_url_expire" type:"number" default:"4"`
}
var config = driver.Config{
Name: "USS",
LocalSort: true,
DefaultRoot: "/",
}
func init() {
op.RegisterDriver(func() driver.Driver {
return &USS{}
})
}

View File

@ -1,85 +0,0 @@
package virtual
import (
"context"
"io"
"time"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/pkg/utils/random"
)
type Virtual struct {
model.Storage
Addition
}
func (d *Virtual) Config() driver.Config {
return config
}
func (d *Virtual) Init(ctx context.Context) error {
return nil
}
func (d *Virtual) Drop(ctx context.Context) error {
return nil
}
func (d *Virtual) GetAddition() driver.Additional {
return &d.Addition
}
func (d *Virtual) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
var res []model.Obj
for i := 0; i < d.NumFile; i++ {
res = append(res, &model.Object{
Name: random.String(10),
Size: random.RangeInt64(d.MinFileSize, d.MaxFileSize),
IsFolder: false,
Modified: time.Now(),
})
}
for i := 0; i < d.NumFolder; i++ {
res = append(res, &model.Object{
Name: random.String(10),
Size: 0,
IsFolder: true,
Modified: time.Now(),
})
}
return res, nil
}
func (d *Virtual) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
return &model.Link{
Data: io.NopCloser(io.LimitReader(random.Rand, file.GetSize())),
}, nil
}
func (d *Virtual) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
return nil
}
func (d *Virtual) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
return nil
}
func (d *Virtual) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
return nil
}
func (d *Virtual) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
return nil
}
func (d *Virtual) Remove(ctx context.Context, obj model.Obj) error {
return nil
}
func (d *Virtual) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
return nil
}
var _ driver.Driver = (*Virtual)(nil)

View File

@ -1,31 +0,0 @@
package webdav
import (
"net/http"
"github.com/alist-org/alist/v3/drivers/webdav/odrvcookie"
"github.com/alist-org/alist/v3/pkg/gowebdav"
)
// do others that not defined in Driver interface
func (d *WebDav) isSharepoint() bool {
return d.Vendor == "sharepoint"
}
func (d *WebDav) setClient() error {
c := gowebdav.NewClient(d.Address, d.Username, d.Password)
if d.isSharepoint() {
cookie, err := odrvcookie.GetCookie(d.Username, d.Password, d.Address)
if err == nil {
c.SetInterceptor(func(method string, rq *http.Request) {
rq.Header.Del("Authorization")
rq.Header.Set("Cookie", cookie)
})
} else {
return err
}
}
d.client = c
return nil
}

View File

@ -1,7 +0,0 @@
#!/bin/bash
chown -R ${PUID}:${PGID} /opt/alist/
umask ${UMASK}
exec su-exec ${PUID}:${PGID} ./alist server --no-prefix

137
go.mod
View File

@ -1,107 +1,50 @@
module github.com/alist-org/alist/v3
module github.com/OpenListTeam/OpenList/v5
go 1.19
go 1.24
require (
github.com/SheltonZhu/115driver v1.0.13
github.com/Xhofe/go-cache v0.0.0-20220723083548-714439c8af9a
github.com/aws/aws-sdk-go v1.44.194
github.com/blevesearch/bleve/v2 v2.3.6
github.com/caarlos0/env/v6 v6.10.1
github.com/caarlos0/env/v7 v7.0.0
github.com/deckarep/golang-set/v2 v2.1.0
github.com/disintegration/imaging v1.6.2
github.com/gin-contrib/cors v1.4.0
github.com/gin-gonic/gin v1.8.2
github.com/go-resty/resty/v2 v2.7.0
github.com/golang-jwt/jwt/v4 v4.4.3
github.com/google/uuid v1.3.0
github.com/gorilla/websocket v1.5.0
github.com/hirochachacha/go-smb2 v1.1.0
github.com/jlaffaye/ftp v0.1.0
github.com/gin-contrib/cors v1.7.6
github.com/gin-gonic/gin v1.10.1
github.com/hashicorp/go-plugin v1.7.0
github.com/json-iterator/go v1.1.12
github.com/maruel/natural v1.1.0
github.com/natefinch/lumberjack v2.0.0+incompatible
github.com/pkg/errors v0.9.1
github.com/pkg/sftp v1.13.5
github.com/pquerna/otp v1.4.0
github.com/sirupsen/logrus v1.9.0
github.com/spf13/cobra v1.6.1
github.com/t3rm1n4l/go-mega v0.0.0-20220725095014-c4e0c2b5debf
github.com/upyun/go-sdk/v3 v3.0.3
github.com/winfsp/cgofuse v1.5.0
golang.org/x/crypto v0.5.0
golang.org/x/image v0.3.0
golang.org/x/net v0.5.0
gorm.io/driver/mysql v1.4.5
gorm.io/driver/postgres v1.4.6
gorm.io/driver/sqlite v1.4.4
gorm.io/gorm v1.24.5
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.9.1
golang.org/x/net v0.43.0
google.golang.org/grpc v1.74.2
google.golang.org/protobuf v1.36.7
)
require (
github.com/BurntSushi/toml v0.3.1 // indirect
github.com/RoaringBitmap/roaring v0.9.4 // indirect
github.com/aead/ecdh v0.2.0 // indirect
github.com/aliyun/aliyun-oss-go-sdk v2.2.5+incompatible // indirect
github.com/andreburgaud/crypt2go v1.1.0 // indirect
github.com/bits-and-blooms/bitset v1.2.0 // indirect
github.com/blevesearch/bleve_index_api v1.0.5 // indirect
github.com/blevesearch/geo v0.1.16 // indirect
github.com/blevesearch/go-porterstemmer v1.0.3 // indirect
github.com/blevesearch/gtreap v0.1.1 // indirect
github.com/blevesearch/mmap-go v1.0.4 // indirect
github.com/blevesearch/scorch_segment_api/v2 v2.1.4 // indirect
github.com/blevesearch/segment v0.9.0 // indirect
github.com/blevesearch/snowballstem v0.9.0 // indirect
github.com/blevesearch/upsidedown_store_api v1.0.1 // indirect
github.com/blevesearch/vellum v1.0.9 // indirect
github.com/blevesearch/zapx/v11 v11.3.7 // indirect
github.com/blevesearch/zapx/v12 v12.3.7 // indirect
github.com/blevesearch/zapx/v13 v13.3.7 // indirect
github.com/blevesearch/zapx/v14 v14.3.7 // indirect
github.com/blevesearch/zapx/v15 v15.3.8 // indirect
github.com/bluele/gcache v0.0.2 // indirect
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
github.com/gaoyb7/115drive-webdav v0.1.8 // indirect
github.com/geoffgarside/ber v1.1.0 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.0 // indirect
github.com/go-playground/universal-translator v0.18.0 // indirect
github.com/go-playground/validator/v10 v10.11.1 // indirect
github.com/go-sql-driver/mysql v1.7.0 // indirect
github.com/goccy/go-json v0.9.11 // indirect
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 // indirect
github.com/golang/protobuf v1.5.0 // indirect
github.com/golang/snappy v0.0.1 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/pgx/v5 v5.2.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/mattn/go-sqlite3 v1.14.15 // indirect
github.com/bytedance/sonic v1.14.0 // indirect
github.com/bytedance/sonic/loader v0.3.0 // indirect
github.com/cloudwego/base64x v0.1.6 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.9 // indirect
github.com/gin-contrib/sse v1.1.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.27.0 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/hashicorp/go-hclog v1.6.3 // indirect
github.com/hashicorp/yamux v0.1.2 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mschoch/smat v0.2.0 // indirect
github.com/orzogc/fake115uploader v0.3.3-0.20221009101310-08b764073b77 // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/pierrec/lz4/v4 v4.1.17 // indirect
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/ugorji/go/codec v1.2.7 // indirect
go.etcd.io/bbolt v1.3.5 // indirect
golang.org/x/sys v0.4.0 // indirect
golang.org/x/text v0.6.0 // indirect
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
github.com/oklog/run v1.2.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/spf13/pflag v1.0.7 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.3.0 // indirect
golang.org/x/arch v0.20.0 // indirect
golang.org/x/crypto v0.41.0 // indirect
golang.org/x/sys v0.35.0 // indirect
golang.org/x/text v0.28.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250811230008-5f3141c8851a // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

Some files were not shown because too many files have changed in this diff Show More