Full Code of AlistGo/alist for AI

main 6bde813ef14c cached
727 files
2.9 MB
802.3k tokens
6244 symbols
1 requests
Download .txt
Showing preview only (3,193K chars total). Download the full file or copy to clipboard to get everything.
Repository: AlistGo/alist
Branch: main
Commit: 6bde813ef14c
Files: 727
Total size: 2.9 MB

Directory structure:
gitextract_zld5nmnw/

├── .air.toml
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.yml
│   │   ├── config.yml
│   │   └── feature_request.yml
│   ├── config.yml
│   ├── stale.yml
│   └── workflows/
│       ├── auto_lang.yml
│       ├── beta_release.yml
│       ├── build.yml
│       ├── changelog.yml
│       ├── issue_close_question.yml
│       ├── issue_close_stale.yml
│       ├── issue_duplicate.yml
│       ├── issue_invalid.yml
│       ├── issue_on_close.yml
│       ├── issue_question.yml
│       ├── issue_similarity.yml
│       ├── issue_translate.yml
│       ├── issue_wontfix.yml
│       ├── release.yml
│       ├── release_android.yml
│       ├── release_docker.yml
│       ├── release_freebsd.yml
│       ├── release_linux_musl.yml
│       └── release_linux_musl_arm.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── Dockerfile.ci
├── LICENSE
├── README.md
├── README_cn.md
├── README_ja.md
├── build.sh
├── cmd/
│   ├── admin.go
│   ├── cancel2FA.go
│   ├── common.go
│   ├── flags/
│   │   └── config.go
│   ├── kill.go
│   ├── lang.go
│   ├── restart.go
│   ├── root.go
│   ├── server.go
│   ├── start.go
│   ├── stop_default.go
│   ├── stop_windows.go
│   ├── storage.go
│   ├── user.go
│   └── version.go
├── docker-compose.yml
├── drivers/
│   ├── 115/
│   │   ├── appver.go
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── 115_open/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   ├── upload.go
│   │   └── util.go
│   ├── 115_share/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   └── utils.go
│   ├── 123/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   ├── upload.go
│   │   └── util.go
│   ├── 123_link/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── parse.go
│   │   ├── types.go
│   │   └── util.go
│   ├── 123_open/
│   │   ├── api.go
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── sign.go
│   │   ├── token.go
│   │   ├── types.go
│   │   ├── upload.go
│   │   └── util.go
│   ├── 123_share/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── 139/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── 189/
│   │   ├── driver.go
│   │   ├── help.go
│   │   ├── login.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── 189pc/
│   │   ├── driver.go
│   │   ├── help.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── utils.go
│   ├── alias/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── alist_v2/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── alist_v3/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── aliyundrive/
│   │   ├── driver.go
│   │   ├── global.go
│   │   ├── help.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── aliyundrive_open/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   ├── upload.go
│   │   └── util.go
│   ├── aliyundrive_share/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── all.go
│   ├── azure_blob/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── baidu_netdisk/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── baidu_photo/
│   │   ├── driver.go
│   │   ├── help.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── utils.go
│   ├── baidu_share/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── base/
│   │   ├── client.go
│   │   ├── types.go
│   │   ├── upload.go
│   │   └── util.go
│   ├── bitqiu/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── chaoxing/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── cloudreve/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── cloudreve_v4/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── crypt/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── doubao/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── doubao_new/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── doubao_share/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── dropbox/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── febbox/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── oauth2.go
│   │   ├── types.go
│   │   └── util.go
│   ├── ftp/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── ftps/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── gitee/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── github/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── github_releases/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── models.go
│   │   ├── types.go
│   │   └── util.go
│   ├── gofile/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── google_drive/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── google_photo/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── halalcloud/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── options.go
│   │   ├── types.go
│   │   └── util.go
│   ├── ilanzou/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── ipfs_api/
│   │   ├── driver.go
│   │   └── meta.go
│   ├── kodbox/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── lanzou/
│   │   ├── driver.go
│   │   ├── help.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── lark/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── lark.go
│   ├── lenovonas_share/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── local/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── token_bucket.go
│   │   └── util.go
│   ├── mediafire/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── mediatrack/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── mega/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── misskey/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── mopan/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── netease_music/
│   │   ├── crypto.go
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   ├── upload.go
│   │   └── util.go
│   ├── onedrive/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── onedrive_app/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── onedrive_sharelink/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── pcloud/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── pikpak/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── pikpak_share/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── proton_drive/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── quark_uc/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── quark_uc_tv/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── quqi/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── s3/
│   │   ├── doge.go
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── other.go
│   │   ├── types.go
│   │   └── util.go
│   ├── seafile/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── sftp/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── smb/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── streamtape/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── strm/
│   │   ├── driver.go
│   │   ├── hook.go
│   │   ├── meta.go
│   │   └── util.go
│   ├── teambition/
│   │   ├── driver.go
│   │   ├── help.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── template/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── terabox/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── thunder/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── thunder_browser/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── thunderx/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── trainbit/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── url_tree/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   ├── urls_test.go
│   │   └── util.go
│   ├── uss/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── virtual/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   └── util.go
│   ├── vtencent/
│   │   ├── drive.go
│   │   ├── meta.go
│   │   ├── signature.go
│   │   ├── types.go
│   │   └── util.go
│   ├── webdav/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── odrvcookie/
│   │   │   ├── cookie.go
│   │   │   └── fetch.go
│   │   ├── types.go
│   │   └── util.go
│   ├── weiyun/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   └── types.go
│   ├── wopan/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── wukong/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   └── types.go
│   └── yandex_disk/
│       ├── driver.go
│       ├── meta.go
│       ├── types.go
│       └── util.go
├── entrypoint.sh
├── go.mod
├── go.sum
├── internal/
│   ├── archive/
│   │   ├── all.go
│   │   ├── archives/
│   │   │   ├── archives.go
│   │   │   └── utils.go
│   │   ├── iso9660/
│   │   │   ├── iso9660.go
│   │   │   └── utils.go
│   │   ├── rardecode/
│   │   │   ├── rardecode.go
│   │   │   └── utils.go
│   │   ├── sevenzip/
│   │   │   ├── sevenzip.go
│   │   │   └── utils.go
│   │   ├── tool/
│   │   │   ├── base.go
│   │   │   ├── helper.go
│   │   │   ├── securepath.go
│   │   │   ├── securepath_test.go
│   │   │   └── utils.go
│   │   └── zip/
│   │       ├── utils.go
│   │       └── zip.go
│   ├── authn/
│   │   └── authn.go
│   ├── bootstrap/
│   │   ├── config.go
│   │   ├── data/
│   │   │   ├── data.go
│   │   │   ├── dev.go
│   │   │   ├── role.go
│   │   │   ├── setting.go
│   │   │   ├── task.go
│   │   │   └── user.go
│   │   ├── db.go
│   │   ├── index.go
│   │   ├── log.go
│   │   ├── offline_download.go
│   │   ├── patch/
│   │   │   ├── all.go
│   │   │   ├── v3_24_0/
│   │   │   │   └── hash_password.go
│   │   │   ├── v3_32_0/
│   │   │   │   └── update_authn.go
│   │   │   ├── v3_41_0/
│   │   │   │   └── grant_permission.go
│   │   │   └── v3_46_0/
│   │   │       └── convert_role.go
│   │   ├── patch.go
│   │   ├── storage.go
│   │   ├── stream_limit.go
│   │   └── task.go
│   ├── conf/
│   │   ├── config.go
│   │   ├── const.go
│   │   └── var.go
│   ├── db/
│   │   ├── db.go
│   │   ├── label.go
│   │   ├── label_file_binding.go
│   │   ├── meta.go
│   │   ├── obj_file.go
│   │   ├── role.go
│   │   ├── searchnode.go
│   │   ├── session.go
│   │   ├── settingitem.go
│   │   ├── sshkey.go
│   │   ├── storage.go
│   │   ├── tasks.go
│   │   ├── user.go
│   │   └── util.go
│   ├── device/
│   │   └── session.go
│   ├── driver/
│   │   ├── config.go
│   │   ├── driver.go
│   │   ├── item.go
│   │   └── utils.go
│   ├── errs/
│   │   ├── device.go
│   │   ├── driver.go
│   │   ├── errors.go
│   │   ├── errors_test.go
│   │   ├── object.go
│   │   ├── operate.go
│   │   ├── role.go
│   │   ├── search.go
│   │   └── user.go
│   ├── fs/
│   │   ├── archive.go
│   │   ├── copy.go
│   │   ├── fs.go
│   │   ├── get.go
│   │   ├── link.go
│   │   ├── list.go
│   │   ├── other.go
│   │   ├── put.go
│   │   ├── s3_transition.go
│   │   └── walk.go
│   ├── fuse/
│   │   ├── fs.go
│   │   └── mount.go
│   ├── message/
│   │   ├── http.go
│   │   ├── message.go
│   │   └── ws.go
│   ├── model/
│   │   ├── archive.go
│   │   ├── args.go
│   │   ├── file.go
│   │   ├── label.go
│   │   ├── label_file_binding.go
│   │   ├── meta.go
│   │   ├── obj.go
│   │   ├── obj_file.go
│   │   ├── object.go
│   │   ├── paths.go
│   │   ├── req.go
│   │   ├── role.go
│   │   ├── roles.go
│   │   ├── search.go
│   │   ├── session.go
│   │   ├── setting.go
│   │   ├── sshkey.go
│   │   ├── storage.go
│   │   ├── task.go
│   │   └── user.go
│   ├── net/
│   │   ├── request.go
│   │   ├── request_test.go
│   │   ├── serve.go
│   │   └── util.go
│   ├── offline_download/
│   │   ├── 115/
│   │   │   └── client.go
│   │   ├── all.go
│   │   ├── aria2/
│   │   │   ├── aria2.go
│   │   │   └── notify.go
│   │   ├── http/
│   │   │   ├── client.go
│   │   │   └── util.go
│   │   ├── pikpak/
│   │   │   ├── pikpak.go
│   │   │   └── util.go
│   │   ├── qbit/
│   │   │   └── qbit.go
│   │   ├── thunder/
│   │   │   ├── thunder.go
│   │   │   └── util.go
│   │   ├── tool/
│   │   │   ├── add.go
│   │   │   ├── base.go
│   │   │   ├── download.go
│   │   │   ├── tools.go
│   │   │   └── transfer.go
│   │   └── transmission/
│   │       └── client.go
│   ├── op/
│   │   ├── archive.go
│   │   ├── const.go
│   │   ├── driver.go
│   │   ├── driver_test.go
│   │   ├── fs.go
│   │   ├── hook.go
│   │   ├── label.go
│   │   ├── label_file_binding.go
│   │   ├── meta.go
│   │   ├── path.go
│   │   ├── role.go
│   │   ├── setting.go
│   │   ├── sshkey.go
│   │   ├── storage.go
│   │   ├── storage_test.go
│   │   └── user.go
│   ├── search/
│   │   ├── bleve/
│   │   │   ├── init.go
│   │   │   └── search.go
│   │   ├── build.go
│   │   ├── db/
│   │   │   ├── init.go
│   │   │   └── search.go
│   │   ├── db_non_full_text/
│   │   │   ├── init.go
│   │   │   └── search.go
│   │   ├── import.go
│   │   ├── meilisearch/
│   │   │   ├── init.go
│   │   │   └── search.go
│   │   ├── search.go
│   │   ├── searcher/
│   │   │   ├── manage.go
│   │   │   └── searcher.go
│   │   └── util.go
│   ├── session/
│   │   └── session.go
│   ├── setting/
│   │   └── setting.go
│   ├── sign/
│   │   ├── archive.go
│   │   └── sign.go
│   ├── stream/
│   │   ├── limit.go
│   │   ├── stream.go
│   │   └── util.go
│   └── task/
│       ├── base.go
│       └── manager.go
├── main.go
├── pkg/
│   ├── aria2/
│   │   └── rpc/
│   │       ├── README.md
│   │       ├── call.go
│   │       ├── call_test.go
│   │       ├── client.go
│   │       ├── client_test.go
│   │       ├── const.go
│   │       ├── json2.go
│   │       ├── notification.go
│   │       ├── proc.go
│   │       ├── proto.go
│   │       └── resp.go
│   ├── chanio/
│   │   └── chanio.go
│   ├── cookie/
│   │   └── cookie.go
│   ├── cron/
│   │   ├── cron.go
│   │   └── cron_test.go
│   ├── errgroup/
│   │   └── errgroup.go
│   ├── generic/
│   │   └── queue.go
│   ├── generic_sync/
│   │   ├── map.go
│   │   └── map_test.go
│   ├── http_range/
│   │   └── range.go
│   ├── mq/
│   │   └── mq.go
│   ├── qbittorrent/
│   │   └── client.go
│   ├── sign/
│   │   ├── hmac.go
│   │   └── sign.go
│   ├── singleflight/
│   │   ├── signleflight_test.go
│   │   └── singleflight.go
│   ├── task/
│   │   ├── errors.go
│   │   ├── manager.go
│   │   ├── task.go
│   │   └── task_test.go
│   └── utils/
│       ├── balance.go
│       ├── bool.go
│       ├── ctx.go
│       ├── email.go
│       ├── file.go
│       ├── hash/
│       │   └── gcid.go
│       ├── hash.go
│       ├── hash_test.go
│       ├── io.go
│       ├── ip.go
│       ├── json.go
│       ├── log.go
│       ├── map.go
│       ├── mask.go
│       ├── oauth2.go
│       ├── path.go
│       ├── path_test.go
│       ├── random/
│       │   └── random.go
│       ├── slice.go
│       ├── str.go
│       ├── time.go
│       └── url.go
├── public/
│   └── public.go
├── server/
│   ├── common/
│   │   ├── auth.go
│   │   ├── base.go
│   │   ├── check.go
│   │   ├── check_test.go
│   │   ├── common.go
│   │   ├── hide_privacy_test.go
│   │   ├── proxy.go
│   │   ├── resp.go
│   │   ├── role_perm.go
│   │   └── sign.go
│   ├── debug.go
│   ├── ftp/
│   │   ├── afero.go
│   │   ├── fsmanage.go
│   │   ├── fsread.go
│   │   ├── fsup.go
│   │   └── site.go
│   ├── ftp.go
│   ├── handles/
│   │   ├── archive.go
│   │   ├── auth.go
│   │   ├── const.go
│   │   ├── down.go
│   │   ├── driver.go
│   │   ├── fsbatch.go
│   │   ├── fsmanage.go
│   │   ├── fsread.go
│   │   ├── fsup.go
│   │   ├── helper.go
│   │   ├── index.go
│   │   ├── label.go
│   │   ├── label_file_binding.go
│   │   ├── ldap_login.go
│   │   ├── meta.go
│   │   ├── offline_download.go
│   │   ├── role.go
│   │   ├── search.go
│   │   ├── session.go
│   │   ├── setting.go
│   │   ├── sshkey.go
│   │   ├── ssologin.go
│   │   ├── storage.go
│   │   ├── task.go
│   │   ├── user.go
│   │   └── webauthn.go
│   ├── middlewares/
│   │   ├── auth.go
│   │   ├── check.go
│   │   ├── down.go
│   │   ├── fsup.go
│   │   ├── https.go
│   │   ├── limit.go
│   │   ├── search.go
│   │   └── session_refresh.go
│   ├── router.go
│   ├── s3/
│   │   ├── backend.go
│   │   ├── ioutils.go
│   │   ├── list.go
│   │   ├── logger.go
│   │   ├── pager.go
│   │   ├── server.go
│   │   └── utils.go
│   ├── s3.go
│   ├── sftp/
│   │   ├── const.go
│   │   ├── hostkey.go
│   │   └── sftp.go
│   ├── sftp.go
│   ├── static/
│   │   ├── config.go
│   │   └── static.go
│   ├── webdav/
│   │   ├── buffered_response_writer.go
│   │   ├── file.go
│   │   ├── if.go
│   │   ├── internal/
│   │   │   └── xml/
│   │   │       ├── README
│   │   │       ├── atom_test.go
│   │   │       ├── example_test.go
│   │   │       ├── marshal.go
│   │   │       ├── marshal_test.go
│   │   │       ├── read.go
│   │   │       ├── read_test.go
│   │   │       ├── typeinfo.go
│   │   │       ├── xml.go
│   │   │       └── xml_test.go
│   │   ├── litmus_test_server.go
│   │   ├── lock.go
│   │   ├── lock_test.go
│   │   ├── path.go
│   │   ├── prop.go
│   │   ├── util.go
│   │   ├── webdav.go
│   │   ├── xml.go
│   │   └── xml_test.go
│   └── webdav.go
└── wrapper/
    ├── zcc-arm64
    └── zcxx-arm64

================================================
FILE CONTENTS
================================================

================================================
FILE: .air.toml
================================================
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"

[build]
args_bin = ["server"]
bin = "./tmp/main"
cmd = "go build -o ./tmp/main ."
delay = 0
exclude_dir = ["assets", "tmp", "vendor", "testdata"]
exclude_file = []
exclude_regex = ["_test.go"]
exclude_unchanged = false
follow_symlink = false
full_bin = ""
include_dir = []
include_ext = ["go", "tpl", "tmpl", "html"]
include_file = []
kill_delay = "0s"
log = "build-errors.log"
poll = false
poll_interval = 0
rerun = false
rerun_delay = 500
send_interrupt = false
stop_on_error = false

[color]
app = ""
build = "yellow"
main = "magenta"
runner = "green"
watcher = "cyan"

[log]
main_only = false
time = false

[misc]
clean_on_exit = false

[screen]
clear_on_rebuild = false
keep_scroll = true


================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms

github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: xhofe # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
custom: ['https://alistgo.com/guide/sponsor.html']


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yml
================================================
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 must check all the following, otherwise your issue may be closed directly. Or you can go to the [discussions](https://github.com/alist-org/alist/discussions)
        您必须勾选以下所有内容,否则您的issue可能会被直接关闭。或者您可以去[讨论区](https://github.com/alist-org/alist/discussions)
      options:
        - label: |
            I have read the [documentation](https://alistgo.com).
            我已经阅读了[文档](https://alistgo.com)。
        - label: |
            I'm sure there are no duplicate issues or discussions.
            我确定没有重复的issue或讨论。
        - label: |
            I'm sure it's due to `AList` and not something else(such as [Network](https://alistgo.com/faq/howto.html#tls-handshake-timeout-read-connection-reset-by-peer-dns-lookup-failed-connect-connection-refused-client-timeout-exceeded-while-awaiting-headers-no-such-host) ,`Dependencies` or `Operational`).
            我确定是`AList`的问题,而不是其他原因(例如[网络](https://alistgo.com/zh/faq/howto.html#tls-handshake-timeout-read-connection-reset-by-peer-dns-lookup-failed-connect-connection-refused-client-timeout-exceeded-while-awaiting-headers-no-such-host),`依赖`或`操作`)。
        - label: |
            I'm sure this issue is not fixed in the latest version.
            我确定这个问题在最新版本中没有被修复。

  - type: input
    id: version
    attributes:
      label: AList Version / AList 版本
      description: |
        What version of our software are you running? Do not use `latest` or `master` as an answer.
        您使用的是哪个版本的软件?请不要使用`latest`或`master`作为答案。
      placeholder: v3.xx.xx
    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: config
    attributes:
      label: Config / 配置
      description: |
        Please provide the configuration file of your `AList` application and take a screenshot of the relevant storage configuration. (hide privacy field)
        请提供您的`AList`应用的配置文件,并截图相关存储配置。(隐藏隐私字段)
    validations:
      required: true
  - type: textarea
    id: logs
    attributes:
      label: Logs / 日志
      description: |
        Please copy and paste any relevant log output.
        请复制粘贴错误日志,或者截图


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
  - name: Questions & Discussions
    url: https://github.com/alist-org/alist/discussions
    about: Use GitHub discussions for message-board style questions and discussions.

================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.yml
================================================
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://alistgo.com).
        - 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.
        相关的任何其他上下文或截图,或者你觉得有帮助的信息

================================================
FILE: .github/config.yml
================================================
# 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

================================================
FILE: .github/stale.yml
================================================
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 44
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 20
# Issues with these labels will never be considered stale
exemptLabels:
  - accepted
  - security
  - working
  - pr-welcome
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
  This issue has been automatically marked as stale because it has not had
  recent activity. It will be closed if no further activity occurs. Thank you
  for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: >
  This issue was closed due to inactive more than 52 days. You can reopen or
  recreate it if you think it should continue. Thank you for your contributions again.


================================================
FILE: .github/workflows/auto_lang.yml
================================================
name: auto_lang

on:
  push:
    branches:
      - 'main'
    paths:
      - 'drivers/**'
      - 'internal/bootstrap/data/setting.go'
      - 'internal/conf/const.go'
      - 'cmd/lang.go'
  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  auto_lang:
    strategy:
      matrix:
        platform: [ ubuntu-latest ]
        go-version: [ '1.21' ]
    name: auto generate lang.json
    runs-on: ${{ matrix.platform }}
    steps:
      - name: Setup go
        uses: actions/setup-go@v5
        with:
          go-version: ${{ matrix.go-version }}

      - name: Checkout alist
        uses: actions/checkout@v4
        with:
          path: alist

      - name: Checkout alist-web
        uses: actions/checkout@v4
        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 "bot@nn.ci"
          git config --local user.name "IlaBot"
          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


================================================
FILE: .github/workflows/beta_release.yml
================================================
name: beta release

on:
  push:
    branches: [ 'main' ]

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

permissions:
  contents: write

jobs:
  changelog:
    strategy:
      matrix:
        platform: [ ubuntu-latest ]
        go-version: [ '1.21' ]
    name: Beta Release Changelog
    runs-on: ${{ matrix.platform }}
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Create or update ref
        id: create-or-update-ref
        uses: ovsds/create-or-update-ref-action@v1
        with:
          ref: tags/beta
          sha: ${{ github.sha }}

      - name: Delete beta tag
        run: git tag -d beta
        continue-on-error: true

      - name: changelog # or changelogithub@0.12 if ensure the stable result
        id: changelog
        run: |
          git tag -l
          npx changelogithub --output CHANGELOG.md
#          npx changelogen@latest --output CHANGELOG.md

      - name: Upload assets
        uses: softprops/action-gh-release@v2
        with:
          body_path: CHANGELOG.md
          files: CHANGELOG.md
          prerelease: true
          tag_name: beta

  release:
    needs:
      - changelog
    strategy:
      matrix:
        include:
          - target: '!(*musl*|*windows-arm64*|*android*|*freebsd*)' # xgo
            hash: "md5"
          - target: 'linux-!(arm*)-musl*' #musl-not-arm
            hash: "md5-linux-musl"
          - target: 'linux-arm*-musl*' #musl-arm
            hash: "md5-linux-musl-arm"
          - target: 'windows-arm64' #win-arm64
            hash: "md5-windows-arm64"
          - target: 'android-*' #android
            hash: "md5-android"
          - target: 'freebsd-*' #freebsd
            hash: "md5-freebsd"

    name: Beta Release
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: '1.22'

      - name: Setup web
        run: bash build.sh dev web

      - name: Build
        uses: go-cross/cgo-actions@v1
        with:
          targets: ${{ matrix.target }}
          musl-target-format: $os-$musl-$arch
          out-dir: build
          x-flags: |
            github.com/alist-org/alist/v3/internal/conf.BuiltAt=$built_at
            github.com/alist-org/alist/v3/internal/conf.GitAuthor=Xhofe
            github.com/alist-org/alist/v3/internal/conf.GitCommit=$git_commit
            github.com/alist-org/alist/v3/internal/conf.Version=$tag
            github.com/alist-org/alist/v3/internal/conf.WebVersion=dev

      - name: Compress
        run: |
          bash build.sh zip ${{ matrix.hash }}
          
      - name: Upload assets
        uses: softprops/action-gh-release@v2
        with:
          files: build/compress/*
          prerelease: true
          tag_name: beta
          
  desktop:
    needs:
      - release
    name: Beta Release Desktop
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v4
        with:
          repository: AlistGo/desktop-release
          ref: main
          persist-credentials: false
          fetch-depth: 0

      - name: Commit
        run: |
          git config --local user.email "bot@nn.ci"
          git config --local user.name "IlaBot"
          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: AlistGo/desktop-release

================================================
FILE: .github/workflows/build.yml
================================================
name: build

on:
  push:
    branches: [ 'main' ]
  pull_request:
    branches: [ 'main' ]

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  build:
    strategy:
      matrix:
        platform: [ubuntu-latest]
        target: 
          - darwin-amd64
          - darwin-arm64
          - windows-amd64
          - linux-arm64-musl
          - linux-amd64-musl
          - windows-arm64
          - android-arm64
    name: Build
    runs-on: ${{ matrix.platform }}
    env:
      GOPROXY: https://proxy.golang.org,direct
    steps:

      - name: Checkout
        uses: actions/checkout@v4

      - uses: benjlevesque/short-sha@v3.0
        id: short-sha

      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: '1.22'

      - name: Setup web
        run: bash build.sh dev web

      - name: Build
        uses: go-cross/cgo-actions@v1
        with:
          targets: ${{ matrix.target }}
          musl-target-format: $os-$musl-$arch
          out-dir: build
          x-flags: |
            github.com/alist-org/alist/v3/internal/conf.BuiltAt=$built_at
            github.com/alist-org/alist/v3/internal/conf.GitAuthor=Xhofe
            github.com/alist-org/alist/v3/internal/conf.GitCommit=$git_commit
            github.com/alist-org/alist/v3/internal/conf.Version=$tag
            github.com/alist-org/alist/v3/internal/conf.WebVersion=dev

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: alist_${{ env.SHA }}_${{ matrix.target }}
          path: build/*

================================================
FILE: .github/workflows/changelog.yml
================================================
name: auto changelog

on:
  push:
    tags:
      - 'v*'

jobs:
  changelog:
    name: Create Release
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Delete beta tag
        run: git tag -d beta
        continue-on-error: true

      - run: npx changelogithub # or changelogithub@0.12 if ensure the stable result
        env:
          GITHUB_TOKEN: ${{secrets.MY_TOKEN}}


================================================
FILE: .github/workflows/issue_close_question.yml
================================================
name: Close need info

on:
  schedule:
    - cron: "0 0 */1 * *"
  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: 3
          close-reason: 'not_planned'
          body: |
            Hello @${{ github.event.issue.user.login }}, this issue was closed due to no activities in 3 days.
            你好 @${{ github.event.issue.user.login }},此issue因超过3天未回复被关闭。

================================================
FILE: .github/workflows/issue_close_stale.yml
================================================
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: 'stale'
          inactive-day: 8
          close-reason: 'not_planned'
          body: |
            Hello @${{ github.event.issue.user.login }}, this issue was closed due to inactive more than 52 days. You can reopen or recreate it if you think it should continue. Thank you for your contributions again.

================================================
FILE: .github/workflows/issue_duplicate.yml
================================================
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 }}

================================================
FILE: .github/workflows/issue_invalid.yml
================================================
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 }}

================================================
FILE: .github/workflows/issue_on_close.yml
================================================
name: Remove working label when issue closed

on:
  issues:
    types: [closed]

jobs:
  rm-working:
    runs-on: ubuntu-latest
    steps:
      - name: Remove working label
        uses: actions-cool/issues-helper@v3
        with:
          actions: 'remove-labels'
          token: ${{ secrets.GITHUB_TOKEN }}
          issue-number: ${{ github.event.issue.number }}
          labels: 'working,pr-welcome'


================================================
FILE: .github/workflows/issue_question.yml
================================================
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.6.0
        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 3 days.
            你好 @${{ github.event.issue.user.login }},请按照issue模板填写, 并详细说明问题/日志记录/复现步骤/复现链接/实现思路或提供更多信息等, 3天内未回复issue自动关闭。

================================================
FILE: .github/workflows/issue_similarity.yml
================================================
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

================================================
FILE: .github/workflows/issue_translate.yml
================================================
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

================================================
FILE: .github/workflows/issue_wontfix.yml
================================================
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 }}

================================================
FILE: .github/workflows/release.yml
================================================
name: release

on:
  release:
    types: [ published ]

jobs:
  release:
    strategy:
      matrix:
        platform: [ ubuntu-latest ]
        go-version: [ '1.21' ]
    name: Release
    runs-on: ${{ matrix.platform }}
    steps:

      - name: Free Disk Space (Ubuntu)
        uses: jlumbroso/free-disk-space@main
        with:
          # this might remove tools that are actually needed,
          # if set to "true" but frees about 6 GB
          tool-cache: false
          
          # all of these default to true, but feel free to set to
          # "false" if necessary for your workflow
          android: true
          dotnet: true
          haskell: true
          large-packages: true
          docker-images: true
          swap-storage: true

      - name: Prerelease
        uses: irongut/EditRelease@v1.2.0
        with:
          token: ${{ secrets.MY_TOKEN }}
          id: ${{ github.event.release.id }}
          prerelease: true

      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: ${{ matrix.go-version }}

      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Install dependencies
        run: |
          sudo snap install zig --classic --beta
          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: Upload assets
        uses: softprops/action-gh-release@v2
        with:
          files: build/compress/*
          prerelease: false

  release_desktop:
    needs: release
    name: Release desktop
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v4
        with:
          repository: AlistGo/desktop-release
          ref: main
          persist-credentials: false
          fetch-depth: 0

      - name: Add tag
        run: |
          git config --local user.email "bot@nn.ci"
          git config --local user.name "IlaBot"
          version=$(wget -qO- -t1 -T2 "https://api.github.com/repos/alist-org/alist/releases/latest" | grep "tag_name" | head -n 1 | awk -F ":" '{print $2}' | sed 's/\"//g;s/,//g;s/ //g')
          git tag -a $version -m "release $version"

      - name: Push tags
        uses: ad-m/github-push-action@master
        with:
          github_token: ${{ secrets.MY_TOKEN }}
          branch: main
          repository: AlistGo/desktop-release

================================================
FILE: .github/workflows/release_android.yml
================================================
name: release_android

on:
  release:
    types: [ published ]

jobs:
  release_android:
    strategy:
      matrix:
        platform: [ ubuntu-latest ]
        go-version: [ '1.21' ]
    name: Release
    runs-on: ${{ matrix.platform }}
    steps:

      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: ${{ matrix.go-version }}

      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Build
        run: |
          bash build.sh release android

      - name: Upload assets
        uses: softprops/action-gh-release@v2
        with:
          files: build/compress/*


================================================
FILE: .github/workflows/release_docker.yml
================================================
name: release_docker

on:
  push:
    tags:
      - 'v*'
    branches:
      - main
  pull_request:
    branches:
      - main

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

env:
  REGISTRY: 'xhofe/alist'
  REGISTRY_USERNAME: 'xhofe'
  REGISTRY_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
  GITHUB_CR_REPO: ghcr.io/${{ github.repository }}
  ARTIFACT_NAME: 'binaries_docker_release'
  RELEASE_PLATFORMS: 'linux/amd64,linux/arm64,linux/arm/v7,linux/386,linux/arm/v6,linux/s390x,linux/ppc64le,linux/riscv64'
  IMAGE_PUSH: ${{ github.event_name == 'push' }}
  IMAGE_IS_PROD: ${{ github.ref_type == 'tag' }}
  IMAGE_TAGS_BETA: |
    type=schedule
    type=ref,event=branch
    type=ref,event=tag
    type=ref,event=pr
    type=raw,value=beta,enable={{is_default_branch}}

jobs:
  build_binary:
    name: Build Binaries for Docker Release
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - uses: actions/setup-go@v5
        with:
          go-version: 'stable'

      - name: Cache Musl
        id: cache-musl
        uses: actions/cache@v4
        with:
          path: build/musl-libs
          key: docker-musl-libs-v2

      - name: Download Musl Library
        if: steps.cache-musl.outputs.cache-hit != 'true'
        run: bash build.sh prepare docker-multiplatform

      - name: Build go binary (beta)
        if: env.IMAGE_IS_PROD != 'true'
        run: bash build.sh beta docker-multiplatform

      - name: Build go binary (release)
        if: env.IMAGE_IS_PROD == 'true'
        run: bash build.sh release docker-multiplatform

      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: ${{ env.ARTIFACT_NAME }}
          overwrite: true
          path: |
            build/
            !build/*.tgz
            !build/musl-libs/**

  release_docker:
    needs: build_binary
    name: Release Docker image
    runs-on: ubuntu-latest
    strategy:
      matrix:
        image: ["latest", "ffmpeg", "aria2", "aio"]
        include:
          - image: "latest"
            build_arg: ""
            tag_favor: ""
          - image: "ffmpeg"
            build_arg: INSTALL_FFMPEG=true
            tag_favor: "suffix=-ffmpeg,onlatest=true"
          - image: "aria2"
            build_arg: INSTALL_ARIA2=true
            tag_favor: "suffix=-aria2,onlatest=true"
          - image: "aio"
            build_arg: |
              INSTALL_FFMPEG=true
              INSTALL_ARIA2=true
            tag_favor: "suffix=-aio,onlatest=true"
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
        with:
          name: ${{ env.ARTIFACT_NAME }}
          path: 'build/'

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to DockerHub
        if: env.IMAGE_PUSH == 'true'
        uses: docker/login-action@v3
        with:
          logout: true
          username: ${{ env.REGISTRY_USERNAME }}
          password: ${{ env.REGISTRY_PASSWORD }}

      - name: Login to GHCR
        uses: docker/login-action@v3
        with:
          logout: true
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Docker meta
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: |
            ${{ env.REGISTRY }}
            ${{ env.GITHUB_CR_REPO }}
          tags: ${{ env.IMAGE_IS_PROD == 'true' && '' || env.IMAGE_TAGS_BETA }}
          flavor: |
            ${{ env.IMAGE_IS_PROD == 'true' && 'latest=true' || '' }}
            ${{ matrix.tag_favor }}

      - name: Build and push
        id: docker_build
        uses: docker/build-push-action@v6
        with:
          context: .
          file: Dockerfile.ci
          push: ${{ env.IMAGE_PUSH == 'true' }}
          build-args: ${{ matrix.build_arg }}
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          platforms: ${{ env.RELEASE_PLATFORMS }}

================================================
FILE: .github/workflows/release_freebsd.yml
================================================
name: release_freebsd

on:
  release:
    types: [ published ]

jobs:
  release_freebsd:
    strategy:
      matrix:
        platform: [ ubuntu-latest ]
        go-version: [ '1.21' ]
    name: Release
    runs-on: ${{ matrix.platform }}
    steps:

      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: ${{ matrix.go-version }}

      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Build
        run: |
          bash build.sh release freebsd

      - name: Upload assets
        uses: softprops/action-gh-release@v2
        with:
          files: build/compress/*


================================================
FILE: .github/workflows/release_linux_musl.yml
================================================
name: release_linux_musl

on:
  release:
    types: [ published ]

jobs:
  release_linux_musl:
    strategy:
      matrix:
        platform: [ ubuntu-latest ]
        go-version: [ '1.21' ]
    name: Release
    runs-on: ${{ matrix.platform }}
    steps:

      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: ${{ matrix.go-version }}

      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Build
        run: |
          bash build.sh release linux_musl

      - name: Upload assets
        uses: softprops/action-gh-release@v2
        with:
          files: build/compress/*


================================================
FILE: .github/workflows/release_linux_musl_arm.yml
================================================
name: release_linux_musl_arm

on:
  release:
    types: [ published ]

jobs:
  release_linux_musl_arm:
    strategy:
      matrix:
        platform: [ ubuntu-latest ]
        go-version: [ '1.21' ]
    name: Release
    runs-on: ${{ matrix.platform }}
    steps:

      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: ${{ matrix.go-version }}

      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Build
        run: |
          bash build.sh release linux_musl_arm

      - name: Upload assets
        uses: softprops/action-gh-release@v2
        with:
          files: build/compress/*


================================================
FILE: .gitignore
================================================
.idea/
.DS_Store
output/
/dist/

# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
*.db
*.bin

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/
/bin/*
*.json
/build
/data/
/tmp/
/log/
/lang/
/daemon/
/public/dist/*
/!public/dist/README.md

.VSCodeCounter

================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.

## Our Standards

Examples of behavior that contributes to a positive environment for our
community include:

* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
  and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
  overall community

Examples of unacceptable behavior include:

* The use of sexualized language or imagery, and sexual attention or
  advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
  address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.

Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.

## Scope

This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
i@nn.ci.
All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the
reporter of any incident.

## Enforcement Guidelines

Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:

### 1. Correction

**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.

**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.

### 2. Warning

**Community Impact**: A violation through a single incident or series
of actions.

**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.

### 3. Temporary Ban

**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.

**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.

### 4. Permanent Ban

**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior,  harassment of an
individual, or aggression toward or disparagement of classes of individuals.

**Consequence**: A permanent ban from any sort of public interaction within
the community.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.

Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing

## Setup your machine

`alist` is written in [Go](https://golang.org/) and [React](https://reactjs.org/).

Prerequisites:

- [git](https://git-scm.com)
- [Go 1.20+](https://golang.org/doc/install)
- [gcc](https://gcc.gnu.org/)
- [nodejs](https://nodejs.org/)

Clone `alist` and `alist-web` anywhere:

```shell
$ git clone https://github.com/alist-org/alist.git
$ git clone --recurse-submodules https://github.com/alist-org/alist-web.git
```
You should switch to the `main` branch for development.

## Preview your change
### backend
```shell
$ go run main.go
```
### frontend
```shell
$ pnpm dev
```

## Add a new driver
Copy `drivers/template` folder and rename it, and follow the comments in it.

## Create a commit

Commit messages should be well formatted, and to make that "standardized".

### Commit Message Format
Each commit message consists of a **header**, a **body** and a **footer**.  The header has a special
format that includes a **type**, a **scope** and a **subject**:

```
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
```

The **header** is mandatory and the **scope** of the header is optional.

Any line of the commit message cannot be longer than 100 characters! This allows the message to be easier
to read on GitHub as well as in various git tools.

### Revert
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header
of the reverted commit.
In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit
being reverted.

### Type
Must be one of the following:

* **feat**: A new feature
* **fix**: A bug fix
* **docs**: Documentation only changes
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing
  semi-colons, etc)
* **refactor**: A code change that neither fixes a bug nor adds a feature
* **perf**: A code change that improves performance
* **test**: Adding missing or correcting existing tests
* **build**: Affects project builds or dependency modifications
* **revert**: Restore the previous commit
* **ci**: Continuous integration of related file modifications
* **chore**: Changes to the build process or auxiliary tools and libraries such as documentation
  generation
* **release**: Release a new version

### Scope
The scope could be anything specifying place of the commit change. For example `$location`,
`$browser`, `$compile`, `$rootScope`, `ngHref`, `ngClick`, `ngView`, etc...

You can use `*` when the change affects more than a single scope.

### Subject
The subject contains succinct description of the change:

* use the imperative, present tense: "change" not "changed" nor "changes"
* don't capitalize first letter
* no dot (.) at the end

### Body
Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes".
The body should include the motivation for the change and contrast this with previous behavior.

### Footer
The footer should contain any information about **Breaking Changes** and is also the place to
[reference GitHub issues that this commit closes](https://help.github.com/articles/closing-issues-via-commit-messages/).

**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines.
The rest of the commit message is then used for this.

## Submit a pull request

Push your branch to your `alist` fork and open a pull request against the
`main` branch.


================================================
FILE: Dockerfile
================================================
FROM alpine:edge as builder
LABEL stage=go-builder
WORKDIR /app/
RUN apk add --no-cache bash curl gcc git go musl-dev
COPY go.mod go.sum ./
RUN go mod download
COPY ./ ./
RUN bash build.sh release docker

FROM alpine:edge

ARG INSTALL_FFMPEG=false
ARG INSTALL_ARIA2=false
LABEL MAINTAINER="i@nn.ci"

WORKDIR /opt/alist/

RUN apk update && \
    apk upgrade --no-cache && \
    apk add --no-cache bash ca-certificates su-exec tzdata; \
    [ "$INSTALL_FFMPEG" = "true" ] && apk add --no-cache ffmpeg; \
    [ "$INSTALL_ARIA2" = "true" ] && apk add --no-cache curl aria2 && \
        mkdir -p /opt/aria2/.aria2 && \
        wget https://github.com/P3TERX/aria2.conf/archive/refs/heads/master.tar.gz -O /tmp/aria-conf.tar.gz && \
        tar -zxvf /tmp/aria-conf.tar.gz -C /opt/aria2/.aria2 --strip-components=1 && rm -f /tmp/aria-conf.tar.gz && \
        sed -i 's|rpc-secret|#rpc-secret|g' /opt/aria2/.aria2/aria2.conf && \
        sed -i 's|/root/.aria2|/opt/aria2/.aria2|g' /opt/aria2/.aria2/aria2.conf && \
        sed -i 's|/root/.aria2|/opt/aria2/.aria2|g' /opt/aria2/.aria2/script.conf && \
        sed -i 's|/root|/opt/aria2|g' /opt/aria2/.aria2/aria2.conf && \
        sed -i 's|/root|/opt/aria2|g' /opt/aria2/.aria2/script.conf && \
        touch /opt/aria2/.aria2/aria2.session && \
        /opt/aria2/.aria2/tracker.sh ; \
    rm -rf /var/cache/apk/*

COPY --chmod=755 --from=builder /app/bin/alist ./
COPY --chmod=755 entrypoint.sh /entrypoint.sh
RUN /entrypoint.sh version

ENV PUID=0 PGID=0 UMASK=022 RUN_ARIA2=${INSTALL_ARIA2}
VOLUME /opt/alist/data/
EXPOSE 5244 5245
CMD [ "/entrypoint.sh" ]

================================================
FILE: Dockerfile.ci
================================================
FROM alpine:3.20.7

ARG TARGETPLATFORM
ARG INSTALL_FFMPEG=false
ARG INSTALL_ARIA2=false
LABEL MAINTAINER="i@nn.ci"

WORKDIR /opt/alist/

RUN apk update && \
    apk upgrade --no-cache && \
    apk add --no-cache bash ca-certificates su-exec tzdata; \
    [ "$INSTALL_FFMPEG" = "true" ] && apk add --no-cache ffmpeg; \
    [ "$INSTALL_ARIA2" = "true" ] && apk add --no-cache curl aria2 && \
        mkdir -p /opt/aria2/.aria2 && \
        wget https://github.com/P3TERX/aria2.conf/archive/refs/heads/master.tar.gz -O /tmp/aria-conf.tar.gz && \
        tar -zxvf /tmp/aria-conf.tar.gz -C /opt/aria2/.aria2 --strip-components=1 && rm -f /tmp/aria-conf.tar.gz && \
        sed -i 's|rpc-secret|#rpc-secret|g' /opt/aria2/.aria2/aria2.conf && \
        sed -i 's|/root/.aria2|/opt/aria2/.aria2|g' /opt/aria2/.aria2/aria2.conf && \
        sed -i 's|/root/.aria2|/opt/aria2/.aria2|g' /opt/aria2/.aria2/script.conf && \
        sed -i 's|/root|/opt/aria2|g' /opt/aria2/.aria2/aria2.conf && \
        sed -i 's|/root|/opt/aria2|g' /opt/aria2/.aria2/script.conf && \
        touch /opt/aria2/.aria2/aria2.session && \
        /opt/aria2/.aria2/tracker.sh ; \
    rm -rf /var/cache/apk/*

COPY --chmod=755 /build/${TARGETPLATFORM}/alist ./
COPY --chmod=755 entrypoint.sh /entrypoint.sh
RUN /entrypoint.sh version

ENV PUID=0 PGID=0 UMASK=022 RUN_ARIA2=${INSTALL_ARIA2}
VOLUME /opt/alist/data/
EXPOSE 5244 5245
CMD [ "/entrypoint.sh" ]


================================================
FILE: LICENSE
================================================
                    GNU AFFERO GENERAL PUBLIC LICENSE
                       Version 3, 19 November 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.

  A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate.  Many developers of free software are heartened and
encouraged by the resulting cooperation.  However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.

  The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community.  It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server.  Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.

  An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals.  This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU Affero General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Remote Network Interaction; Use with the GNU General Public License.

  Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software.  This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time.  Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

  If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source.  For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code.  There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.

  You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<https://www.gnu.org/licenses/>.


================================================
FILE: README.md
================================================
<div align="center">
  <a href="https://alistgo.com"><img width="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 storages, 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/alist-org/alist/blob/main/LICENSE">
    <img src="https://img.shields.io/github/license/Xhofe/alist" alt="License" />
  </a>
  <a href="https://github.com/alist-org/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/alist-org/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/alist-org/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/alist-org/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://alistgo.com/guide/sponsor.html">
    <img src="https://img.shields.io/badge/%24-sponsor-F87171.svg" alt="sponsor" />
  </a>
</div>
</div>

---

English | [中文](./README_cn.md) | [日本語](./README_ja.md) | [Contributing](./CONTRIBUTING.md) | [CODE_OF_CONDUCT](./CODE_OF_CONDUCT.md)

## Features

- [x] Multiple storages
    - [x] Local storage
    - [x] [Aliyundrive](https://www.alipan.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] [MediaFire](https://www.mediafire.com)
    - [x] [Mediatrack](https://www.mediatrack.cn/)
    - [x] [ProtonDrive](https://proton.me/drive)
    - [x] [139yun](https://yun.139.com/) (Personal, Family, Group)
    - [x] [YandexDisk](https://disk.yandex.com/)
    - [x] [BaiduNetdisk](http://pan.baidu.com/)
    - [x] [Terabox](https://www.terabox.com/main)
    - [x] [UC](https://drive.uc.cn)
    - [x] [Quark](https://pan.quark.cn)
    - [x] [Thunder](https://pan.xunlei.com)
    - [x] [Lanzou](https://www.lanzou.com/)
    - [x] [ILanzou](https://www.ilanzou.com/)
    - [x] [Aliyundrive share](https://www.alipan.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] [Dropbox](https://www.dropbox.com/)
    - [x] [FeijiPan](https://www.feijipan.com/)
    - [x] [dogecloud](https://www.dogecloud.com/product/oss)
    - [x] [Azure Blob Storage](https://azure.microsoft.com/products/storage/blobs)
- [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://alistgo.com/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
- [x] Multi-thread downloading acceleration for single-thread download/stream

## Document

<https://alistgo.com/>

## API Documentation (via Apifox):

<https://alist-public.apifox.cn/>

## Demo

<https://al.nn.ci>

## Discussion

Please go to our [discussion forum](https://github.com/alist-org/alist/discussions) for general questions, **issues are for bug reports and feature requests 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://alistgo.com/guide/sponsor.html

### Special sponsors

- [VidHub](https://apps.apple.com/app/apple-store/id1659622164?pt=118612019&ct=alist&mt=8) - An elegant cloud video player within the Apple ecosystem. Support for iPhone, iPad, Mac, and Apple TV.

## Contributors

Thanks goes to these wonderful people:

[![Contributors](http://contrib.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.

---

> [@GitHub](https://github.com/alist-org) · [@TelegramGroup](https://t.me/alist_chat) · [@Discord](https://discord.gg/F4ymsH4xv2)


================================================
FILE: README_cn.md
================================================
<div align="center">
  <a href="https://alistgo.com"><img width="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/alist-org/alist/blob/main/LICENSE">
    <img src="https://img.shields.io/github/license/Xhofe/alist" alt="License" />
  </a>
  <a href="https://github.com/alist-org/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/alist-org/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/alist-org/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/alist-org/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://alistgo.com/zh/guide/sponsor.html">
    <img src="https://img.shields.io/badge/%24-sponsor-F87171.svg" alt="sponsor" />
  </a>
</div>
</div>

---

[English](./README.md) | 中文 | [日本語](./README_ja.md) | [Contributing](./CONTRIBUTING.md) | [CODE_OF_CONDUCT](./CODE_OF_CONDUCT.md)

## 功能

- [x] 多种存储
    - [x] 本地存储
    - [x] [阿里云盘](https://www.alipan.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] [MediaFire](https://www.mediafire.com)
    - [x] [分秒帧](https://www.mediatrack.cn/)
    - [x] [ProtonDrive](https://proton.me/drive)
    - [x] [和彩云](https://yun.139.com/) (个人云, 家庭云,共享群组)
    - [x] [Yandex.Disk](https://disk.yandex.com/)
    - [x] [百度网盘](http://pan.baidu.com/)
    - [x] [UC网盘](https://drive.uc.cn)
    - [x] [夸克网盘](https://pan.quark.cn)
    - [x] [迅雷网盘](https://pan.xunlei.com)
    - [x] [蓝奏云](https://www.lanzou.com/)
    - [x] [蓝奏云优享版](https://www.ilanzou.com/)
    - [x] [阿里云盘分享](https://www.alipan.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] [Dropbox](https://www.dropbox.com/)
    - [x] [飞机盘](https://www.feijipan.com/)
    - [x] [多吉云](https://www.dogecloud.com/product/oss)
- [x] 部署方便,开箱即用
- [x] 文件预览(PDF、markdown、代码、纯文本……)
- [x] 画廊模式下的图像预览
- [x] 视频和音频预览,支持歌词和字幕
- [x] Office 文档预览(docx、pptx、xlsx、...)
- [x] `README.md` 预览渲染
- [x] 文件永久链接复制和直接文件下载
- [x] 黑暗模式
- [x] 国际化
- [x] 受保护的路由(密码保护和身份验证)
- [x] WebDav (具体见 https://alistgo.com/zh/guide/webdav.html)
- [x] [Docker 部署](https://hub.docker.com/r/xhofe/alist)
- [x] Cloudflare workers 中转
- [x] 文件/文件夹打包下载
- [x] 网页上传(可以允许访客上传),删除,新建文件夹,重命名,移动,复制
- [x] 离线下载
- [x] 跨存储复制文件
- [x] 单线程下载/串流的多线程下载加速

## 文档

<https://alistgo.com/zh/>

## API 文档(通过 Apifox 提供)

<https://alist-public.apifox.cn/>

## Demo

<https://al.nn.ci>

## 讨论

一般问题请到[讨论论坛](https://github.com/alist-org/alist/discussions) ,**issue仅针对错误报告和功能请求。**

## 赞助

AList 是一个开源软件,如果你碰巧喜欢这个项目,并希望我继续下去,请考虑赞助我或提供一个单一的捐款!感谢所有的爱和支持:https://alistgo.com/zh/guide/sponsor.html

### 特别赞助

- [VidHub](https://apps.apple.com/app/apple-store/id1659622164?pt=118612019&ct=alist&mt=8) - 苹果生态下优雅的网盘视频播放器,iPhone,iPad,Mac,Apple TV全平台支持。

## 贡献者

Thanks goes to these wonderful people:

[![Contributors](http://contrib.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/alist-org) · [@Telegram群](https://t.me/alist_chat) · [@Discord](https://discord.gg/F4ymsH4xv2)


================================================
FILE: README_ja.md
================================================
<div align="center">
  <a href="https://alistgo.com"><img width="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/alist-org/alist/blob/main/LICENSE">
    <img src="https://img.shields.io/github/license/Xhofe/alist" alt="License" />
  </a>
  <a href="https://github.com/alist-org/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/alist-org/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/alist-org/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/alist-org/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://alistgo.com/guide/sponsor.html">
    <img src="https://img.shields.io/badge/%24-sponsor-F87171.svg" alt="sponsor" />
  </a>
</div>
</div>

---

[English](./README.md) | [中文](./README_cn.md) | 日本語 | [Contributing](./CONTRIBUTING.md) | [CODE_OF_CONDUCT](./CODE_OF_CONDUCT.md)

## 特徴

- [x] マルチストレージ
    - [x] ローカルストレージ
    - [x] [Aliyundrive](https://www.alipan.com/)
    - [x] OneDrive / Sharepoint ([グローバル](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] [MediaFire](https://www.mediafire.com)
    - [x] [Mediatrack](https://www.mediatrack.cn/)
    - [x] [ProtonDrive](https://proton.me/drive)
    - [x] [139yun](https://yun.139.com/) (Personal, Family, Group)
    - [x] [YandexDisk](https://disk.yandex.com/)
    - [x] [BaiduNetdisk](http://pan.baidu.com/)
    - [x] [Terabox](https://www.terabox.com/main)
    - [x] [UC](https://drive.uc.cn)
    - [x] [Quark](https://pan.quark.cn)
    - [x] [Thunder](https://pan.xunlei.com)
    - [x] [Lanzou](https://www.lanzou.com/)
    - [x] [ILanzou](https://www.ilanzou.com/)
    - [x] [Aliyundrive share](https://www.alipan.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] [Dropbox](https://www.dropbox.com/)
    - [x] [FeijiPan](https://www.feijipan.com/)
    - [x] [dogecloud](https://www.dogecloud.com/product/oss)
- [x] デプロイが簡単で、すぐに使える
- [x] ファイルプレビュー (PDF, マークダウン, コード, プレーンテキスト, ...)
- [x] ギャラリーモードでの画像プレビュー
- [x] ビデオとオーディオのプレビュー、歌詞と字幕のサポート
- [x] Office ドキュメントのプレビュー (docx, pptx, xlsx, ...)
- [x] `README.md` のプレビューレンダリング
- [x] ファイルのパーマリンクコピーと直接ダウンロード
- [x] ダークモード
- [x] 国際化
- [x] 保護されたルート (パスワード保護と認証)
- [x] WebDav (詳細は https://alistgo.com/guide/webdav.html を参照)
- [x] [Docker デプロイ](https://hub.docker.com/r/xhofe/alist)
- [x] Cloudflare ワーカープロキシ
- [x] ファイル/フォルダパッケージのダウンロード
- [x] ウェブアップロード(訪問者にアップロードを許可できる), 削除, mkdir, 名前変更, 移動, コピー
- [x] オフラインダウンロード
- [x] 二つのストレージ間でファイルをコピー
- [x] シングルスレッドのダウンロード/ストリーム向けのマルチスレッド ダウンロード アクセラレーション

## ドキュメント

<https://alistgo.com/>

## APIドキュメント(Apifox 提供)

<https://alist-public.apifox.cn/>

## デモ

<https://al.nn.ci>

## ディスカッション

一般的なご質問は[ディスカッションフォーラム](https://github.com/alist-org/alist/discussions)をご利用ください。**問題はバグレポートと機能リクエストのみです。**

## スポンサー

AList はオープンソースのソフトウェアです。もしあなたがこのプロジェクトを気に入ってくださり、続けて欲しいと思ってくださるなら、ぜひスポンサーになってくださるか、1口でも寄付をしてくださるようご検討ください!すべての愛とサポートに感謝します:
https://alistgo.com/guide/sponsor.html

### スペシャルスポンサー

- [VidHub](https://apps.apple.com/app/apple-store/id1659622164?pt=118612019&ct=alist&mt=8) - An elegant cloud video player within the Apple ecosystem. Support for iPhone, iPad, Mac, and Apple TV.

## コントリビューター

これらの素晴らしい人々に感謝します:

[![Contributors](http://contrib.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リダイレクト/トラフィック転送のみを行い、いかなるユーザーデータも傍受、保存、改ざんしません;
- このプログラムを使用する前に、アカウントの禁止、ダウンロード速度の制限など、対応するリスクを理解し、負担する必要があります;
- もし侵害があれば、[メール](mailto:i@nn.ci)で私に連絡してください。

---

> [@Blog](https://nn.ci/) · [@GitHub](https://github.com/alist-org) · [@TelegramGroup](https://t.me/alist_chat) · [@Discord](https://discord.gg/F4ymsH4xv2)


================================================
FILE: build.sh
================================================
appName="alist"
builtAt="$(date +'%F %T %z')"
gitAuthor="Xhofe <i@nn.ci>"
gitCommit=$(git log --pretty=format:"%h" -1)

if [ "$1" = "dev" ]; then
  version="dev"
  webVersion="dev"
elif [ "$1" = "beta" ]; then
  version="beta"
  webVersion="dev"
else
  git tag -d beta
  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.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
}

BuildWinArm64() {
  echo building for windows-arm64
  chmod +x ./wrapper/zcc-arm64
  chmod +x ./wrapper/zcxx-arm64
  export GOOS=windows
  export GOARCH=arm64
  export CC=$(pwd)/wrapper/zcc-arm64
  export CXX=$(pwd)/wrapper/zcxx-arm64
  export CGO_ENABLED=1
  go build -o "$1" -ldflags="$ldflags" -tags=jsoniter .
}

BuildDev() {
  rm -rf .git/
  mkdir -p "dist"
  muslflags="--extldflags '-static -fpic' $ldflags"
  BASE="https://musl.nn.ci/"
  FILES=(x86_64-linux-musl-cross aarch64-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)
  CGO_ARGS=(x86_64-linux-musl-gcc aarch64-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 ./dist/$appName-$os_arch -ldflags="$muslflags" -tags=jsoniter .
  done
  xgo -targets=windows/amd64,darwin/amd64,darwin/arm64 -out "$appName" -ldflags="$ldflags" -tags=jsoniter .
  mv alist-* dist
  cd dist
  cp ./alist-windows-amd64.exe ./alist-windows-amd64-upx.exe
  upx -9 ./alist-windows-amd64-upx.exe
  find . -type f -print0 | xargs -0 md5sum >md5.txt
  cat md5.txt
}

BuildDocker() {
  go build -o ./bin/alist -ldflags="$ldflags" -tags=jsoniter .
}

PrepareBuildDockerMusl() {
  mkdir -p build/musl-libs
  BASE="https://github.com/go-cross/musl-toolchain-archive/releases/latest/download/"
  FILES=(x86_64-linux-musl-cross aarch64-linux-musl-cross i486-linux-musl-cross s390x-linux-musl-cross armv6-linux-musleabihf-cross armv7l-linux-musleabihf-cross riscv64-linux-musl-cross powerpc64le-linux-musl-cross)
  for i in "${FILES[@]}"; do
    url="${BASE}${i}.tgz"
    lib_tgz="build/${i}.tgz"
    curl -L -o "${lib_tgz}" "${url}"
    tar xf "${lib_tgz}" --strip-components 1 -C build/musl-libs
    rm -f "${lib_tgz}"
  done
}

BuildDockerMultiplatform() {
  go mod download

  # run PrepareBuildDockerMusl before build
  export PATH=$PATH:$PWD/build/musl-libs/bin

  docker_lflags="--extldflags '-static -fpic' $ldflags"
  export CGO_ENABLED=1

  OS_ARCHES=(linux-amd64 linux-arm64 linux-386 linux-s390x linux-riscv64 linux-ppc64le)
  CGO_ARGS=(x86_64-linux-musl-gcc aarch64-linux-musl-gcc i486-linux-musl-gcc s390x-linux-musl-gcc riscv64-linux-musl-gcc powerpc64le-linux-musl-gcc)
  for i in "${!OS_ARCHES[@]}"; do
    os_arch=${OS_ARCHES[$i]}
    cgo_cc=${CGO_ARGS[$i]}
    os=${os_arch%%-*}
    arch=${os_arch##*-}
    export GOOS=$os
    export GOARCH=$arch
    export CC=${cgo_cc}
    echo "building for $os_arch"
    go build -o build/$os/$arch/alist -ldflags="$docker_lflags" -tags=jsoniter .
  done

  DOCKER_ARM_ARCHES=(linux-arm/v6 linux-arm/v7)
  CGO_ARGS=(armv6-linux-musleabihf-gcc armv7l-linux-musleabihf-gcc)
  GO_ARM=(6 7)
  export GOOS=linux
  export GOARCH=arm
  for i in "${!DOCKER_ARM_ARCHES[@]}"; do
    docker_arch=${DOCKER_ARM_ARCHES[$i]}
    cgo_cc=${CGO_ARGS[$i]}
    export GOARM=${GO_ARM[$i]}
    export CC=${cgo_cc}
    echo "building for $docker_arch"
    go build -o build/${docker_arch%%-*}/${docker_arch##*-}/alist -ldflags="$docker_lflags" -tags=jsoniter .
  done
}

BuildRelease() {
  rm -rf .git/
  mkdir -p "build"
  BuildWinArm64 ./build/alist-windows-arm64.exe
  xgo -out "$appName" -ldflags="$ldflags" -tags=jsoniter .
  # why? Because some target platforms seem to have issues with upx compression
  upx -9 ./alist-linux-amd64
  cp ./alist-windows-amd64.exe ./alist-windows-amd64-upx.exe
  upx -9 ./alist-windows-amd64-upx.exe
  mv alist-* build
}

BuildReleaseLinuxMusl() {
  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 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
    rm -f "${i}.tgz"
  done
  OS_ARCHES=(linux-musl-amd64 linux-musl-arm64 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 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
}

BuildReleaseLinuxMuslArm() {
  rm -rf .git/
  mkdir -p "build"
  muslflags="--extldflags '-static -fpic' $ldflags"
  BASE="https://musl.nn.ci/"
#  FILES=(arm-linux-musleabi-cross arm-linux-musleabihf-cross armeb-linux-musleabi-cross armeb-linux-musleabihf-cross armel-linux-musleabi-cross armel-linux-musleabihf-cross armv5l-linux-musleabi-cross armv5l-linux-musleabihf-cross armv6-linux-musleabi-cross armv6-linux-musleabihf-cross armv7l-linux-musleabihf-cross armv7m-linux-musleabi-cross armv7r-linux-musleabihf-cross)
  FILES=(arm-linux-musleabi-cross arm-linux-musleabihf-cross armel-linux-musleabi-cross armel-linux-musleabihf-cross armv5l-linux-musleabi-cross armv5l-linux-musleabihf-cross armv6-linux-musleabi-cross armv6-linux-musleabihf-cross armv7l-linux-musleabihf-cross armv7m-linux-musleabi-cross armv7r-linux-musleabihf-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
    rm -f "${i}.tgz"
  done
#  OS_ARCHES=(linux-musleabi-arm linux-musleabihf-arm linux-musleabi-armeb linux-musleabihf-armeb linux-musleabi-armel linux-musleabihf-armel linux-musleabi-armv5l linux-musleabihf-armv5l linux-musleabi-armv6 linux-musleabihf-armv6 linux-musleabihf-armv7l linux-musleabi-armv7m linux-musleabihf-armv7r)
#  CGO_ARGS=(arm-linux-musleabi-gcc arm-linux-musleabihf-gcc armeb-linux-musleabi-gcc armeb-linux-musleabihf-gcc armel-linux-musleabi-gcc armel-linux-musleabihf-gcc armv5l-linux-musleabi-gcc armv5l-linux-musleabihf-gcc armv6-linux-musleabi-gcc armv6-linux-musleabihf-gcc armv7l-linux-musleabihf-gcc armv7m-linux-musleabi-gcc armv7r-linux-musleabihf-gcc)
#  GOARMS=('' '' '' '' '' '' '5' '5' '6' '6' '7' '7' '7')
  OS_ARCHES=(linux-musleabi-arm linux-musleabihf-arm linux-musleabi-armel linux-musleabihf-armel linux-musleabi-armv5l linux-musleabihf-armv5l linux-musleabi-armv6 linux-musleabihf-armv6 linux-musleabihf-armv7l linux-musleabi-armv7m linux-musleabihf-armv7r)
  CGO_ARGS=(arm-linux-musleabi-gcc arm-linux-musleabihf-gcc armel-linux-musleabi-gcc armel-linux-musleabihf-gcc armv5l-linux-musleabi-gcc armv5l-linux-musleabihf-gcc armv6-linux-musleabi-gcc armv6-linux-musleabihf-gcc armv7l-linux-musleabihf-gcc armv7m-linux-musleabi-gcc armv7r-linux-musleabihf-gcc)
  GOARMS=('' '' '' '' '5' '5' '6' '6' '7' '7' '7')
  for i in "${!OS_ARCHES[@]}"; do
    os_arch=${OS_ARCHES[$i]}
    cgo_cc=${CGO_ARGS[$i]}
    arm=${GOARMS[$i]}
    echo building for ${os_arch}
    export GOOS=linux
    export GOARCH=arm
    export CC=${cgo_cc}
    export CGO_ENABLED=1
    export GOARM=${arm}
    go build -o ./build/$appName-$os_arch -ldflags="$muslflags" -tags=jsoniter .
  done
}

BuildReleaseAndroid() {
  rm -rf .git/
  mkdir -p "build"
  wget https://dl.google.com/android/repository/android-ndk-r26b-linux.zip
  unzip android-ndk-r26b-linux.zip
  rm android-ndk-r26b-linux.zip
  OS_ARCHES=(amd64 arm64 386 arm)
  CGO_ARGS=(x86_64-linux-android24-clang aarch64-linux-android24-clang i686-linux-android24-clang armv7a-linux-androideabi24-clang)
  for i in "${!OS_ARCHES[@]}"; do
    os_arch=${OS_ARCHES[$i]}
    cgo_cc=$(realpath android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/${CGO_ARGS[$i]})
    echo building for android-${os_arch}
    export GOOS=android
    export GOARCH=${os_arch##*-}
    export CC=${cgo_cc}
    export CGO_ENABLED=1
    go build -o ./build/$appName-android-$os_arch -ldflags="$ldflags" -tags=jsoniter .
    android-ndk-r26b/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip ./build/$appName-android-$os_arch
  done
}

BuildReleaseFreeBSD() {
  rm -rf .git/
  mkdir -p "build/freebsd"
  OS_ARCHES=(amd64 arm64 i386)
  GO_ARCHES=(amd64 arm64 386)
  CGO_ARGS=(x86_64-unknown-freebsd14.1 aarch64-unknown-freebsd14.1 i386-unknown-freebsd14.1)
  for i in "${!OS_ARCHES[@]}"; do
    os_arch=${OS_ARCHES[$i]}
    cgo_cc="clang --target=${CGO_ARGS[$i]} --sysroot=/opt/freebsd/${os_arch}"
    echo building for freebsd-${os_arch}
    sudo mkdir -p "/opt/freebsd/${os_arch}"
    wget -q https://download.freebsd.org/releases/${os_arch}/14.3-RELEASE/base.txz
    sudo tar -xf ./base.txz -C /opt/freebsd/${os_arch}
    rm base.txz
    export GOOS=freebsd
    export GOARCH=${GO_ARCHES[$i]}
    export CC=${cgo_cc}
    export CGO_ENABLED=1
    export CGO_LDFLAGS="-fuse-ld=lld"
    go build -o ./build/$appName-freebsd-$os_arch -ldflags="$ldflags" -tags=jsoniter .
  done
}

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-android-*"); 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-freebsd-*"); 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 >"$1"
  cat "$1"
  cd ../..
}

if [ "$1" = "dev" ]; then
  FetchWebDev
  if [ "$2" = "docker" ]; then
    BuildDocker
  elif [ "$2" = "docker-multiplatform" ]; then
      BuildDockerMultiplatform
  elif [ "$2" = "web" ]; then
    echo "web only"
  else
    BuildDev
  fi
elif [ "$1" = "release" -o "$1" = "beta" ]; then
  if [ "$1" = "beta" ]; then
    FetchWebDev
  else
    FetchWebRelease
  fi
  if [ "$2" = "docker" ]; then
    BuildDocker
  elif [ "$2" = "docker-multiplatform" ]; then
    BuildDockerMultiplatform
  elif [ "$2" = "linux_musl_arm" ]; then
    BuildReleaseLinuxMuslArm
    MakeRelease "md5-linux-musl-arm.txt"
  elif [ "$2" = "linux_musl" ]; then
    BuildReleaseLinuxMusl
    MakeRelease "md5-linux-musl.txt"
  elif [ "$2" = "android" ]; then
    BuildReleaseAndroid
    MakeRelease "md5-android.txt"
  elif [ "$2" = "freebsd" ]; then
    BuildReleaseFreeBSD
    MakeRelease "md5-freebsd.txt"
  elif [ "$2" = "web" ]; then
    echo "web only"
  else
    BuildRelease
    MakeRelease "md5.txt"
  fi
elif [ "$1" = "prepare" ]; then
  if [ "$2" = "docker-multiplatform" ]; then
    PrepareBuildDockerMusl
  fi
elif [ "$1" = "zip" ]; then
  MakeRelease "$2".txt
else
  echo -e "Parameter error"
fi


================================================
FILE: cmd/admin.go
================================================
/*
Copyright © 2022 NAME HERE <EMAIL ADDRESS>
*/
package cmd

import (
	"github.com/alist-org/alist/v3/internal/conf"
	"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/alist-org/alist/v3/pkg/utils/random"
	"github.com/spf13/cobra"
)

// AdminCmd represents the password command
var AdminCmd = &cobra.Command{
	Use:     "admin",
	Aliases: []string{"password"},
	Short:   "Show admin user's info and some operations about admin user's password",
	Run: func(cmd *cobra.Command, args []string) {
		Init()
		defer Release()
		admin, err := op.GetAdmin()
		if err != nil {
			utils.Log.Errorf("failed get admin user: %+v", err)
		} else {
			utils.Log.Infof("Admin user's username: %s", admin.Username)
			utils.Log.Infof("The password can only be output at the first startup, and then stored as a hash value, which cannot be reversed")
			utils.Log.Infof("You can reset the password with a random string by running [alist admin random]")
			utils.Log.Infof("You can also set a new password by running [alist admin set NEW_PASSWORD]")
		}
	},
}

var RandomPasswordCmd = &cobra.Command{
	Use:   "random",
	Short: "Reset admin user's password to a random string",
	Run: func(cmd *cobra.Command, args []string) {
		newPwd := random.String(8)
		setAdminPassword(newPwd)
	},
}

var SetPasswordCmd = &cobra.Command{
	Use:   "set",
	Short: "Set admin user's password",
	Run: func(cmd *cobra.Command, args []string) {
		if len(args) == 0 {
			utils.Log.Errorf("Please enter the new password")
			return
		}
		setAdminPassword(args[0])
	},
}

var ShowTokenCmd = &cobra.Command{
	Use:   "token",
	Short: "Show admin token",
	Run: func(cmd *cobra.Command, args []string) {
		Init()
		defer Release()
		token := setting.GetStr(conf.Token)
		utils.Log.Infof("Admin token: %s", token)
	},
}

func setAdminPassword(pwd string) {
	Init()
	defer Release()
	admin, err := op.GetAdmin()
	if err != nil {
		utils.Log.Errorf("failed get admin user: %+v", err)
		return
	}
	admin.SetPassword(pwd)
	if err := op.UpdateUser(admin); err != nil {
		utils.Log.Errorf("failed update admin user: %+v", err)
		return
	}
	utils.Log.Infof("admin user has been updated:")
	utils.Log.Infof("username: %s", admin.Username)
	utils.Log.Infof("password: %s", pwd)
	DelAdminCacheOnline()
}

func init() {
	RootCmd.AddCommand(AdminCmd)
	AdminCmd.AddCommand(RandomPasswordCmd)
	AdminCmd.AddCommand(SetPasswordCmd)
	AdminCmd.AddCommand(ShowTokenCmd)
	// 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")
}


================================================
FILE: cmd/cancel2FA.go
================================================
/*
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"
)

// Cancel2FACmd represents the delete2fa command
var Cancel2FACmd = &cobra.Command{
	Use:   "cancel2fa",
	Short: "Delete 2FA of admin user",
	Run: func(cmd *cobra.Command, args []string) {
		Init()
		defer Release()
		admin, err := op.GetAdmin()
		if err != nil {
			utils.Log.Errorf("failed to get admin user: %+v", err)
		} else {
			err := op.Cancel2FAByUser(admin)
			if err != nil {
				utils.Log.Errorf("failed to cancel 2FA: %+v", err)
			} else {
				utils.Log.Info("2FA canceled")
				DelAdminCacheOnline()
			}
		}
	},
}

func init() {
	RootCmd.AddCommand(Cancel2FACmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// cancel2FACmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// cancel2FACmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}


================================================
FILE: cmd/common.go
================================================
package cmd

import (
	"github.com/alist-org/alist/v3/internal/bootstrap/patch/v3_46_0"
	"os"
	"path/filepath"
	"strconv"

	"github.com/alist-org/alist/v3/internal/bootstrap"
	"github.com/alist-org/alist/v3/internal/bootstrap/data"
	"github.com/alist-org/alist/v3/internal/db"
	"github.com/alist-org/alist/v3/pkg/utils"
	log "github.com/sirupsen/logrus"
)

func Init() {
	bootstrap.InitConfig()
	bootstrap.Log()
	bootstrap.InitDB()

	if v3_46_0.IsLegacyRoleDetected() {
		utils.Log.Warnf("Detected legacy role format, executing ConvertLegacyRoles patch early...")
		v3_46_0.ConvertLegacyRoles()
	}

	data.InitData()
	bootstrap.InitStreamLimit()
	bootstrap.InitIndex()
	bootstrap.InitUpgradePatch()
}

func Release() {
	db.Close()
}

var pid = -1
var pidFile string

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
	}
}


================================================
FILE: cmd/flags/config.go
================================================
package flags

var (
	DataDir     string
	Debug       bool
	NoPrefix    bool
	Dev         bool
	ForceBinDir bool
	LogStd      bool
)


================================================
FILE: cmd/kill.go
================================================
package cmd

import (
	log "github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
	"os"
)

// KillCmd represents the kill command
var KillCmd = &cobra.Command{
	Use:   "kill",
	Short: "Force kill alist server process by daemon/pid file",
	Run: func(cmd *cobra.Command, args []string) {
		kill()
	},
}

func kill() {
	initDaemon()
	if pid == -1 {
		log.Info("Seems not have been started. Try use `alist start` to start server.")
		return
	}
	process, err := os.FindProcess(pid)
	if err != nil {
		log.Errorf("failed to find process by pid: %d, reason: %v", pid, process)
		return
	}
	err = process.Kill()
	if err != nil {
		log.Errorf("failed to kill process %d: %v", pid, err)
	} else {
		log.Info("killed process: ", pid)
	}
	err = os.Remove(pidFile)
	if err != nil {
		log.Errorf("failed to remove pid file")
	}
	pid = -1
}

func init() {
	RootCmd.AddCommand(KillCmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// stopCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// stopCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}


================================================
FILE: cmd/lang.go
================================================
/*
Package cmd
Copyright © 2022 Noah Hsu<i@nn.ci>
*/
package cmd

import (
	"fmt"
	"io"
	"os"
	"reflect"
	"strings"

	_ "github.com/alist-org/alist/v3/drivers"
	"github.com/alist-org/alist/v3/internal/bootstrap"
	"github.com/alist-org/alist/v3/internal/bootstrap/data"
	"github.com/alist-org/alist/v3/internal/conf"
	"github.com/alist-org/alist/v3/internal/op"
	"github.com/alist-org/alist/v3/pkg/utils"
	log "github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
)

type KV[V any] map[string]V

type Drivers KV[KV[interface{}]]

func firstUpper(s string) string {
	if s == "" {
		return ""
	}
	return strings.ToUpper(s[:1]) + s[1:]
}

func convert(s string) string {
	ss := strings.Split(s, "_")
	ans := strings.Join(ss, " ")
	return firstUpper(ans)
}

func writeFile(name string, data interface{}) {
	f, err := os.Open(fmt.Sprintf("../alist-web/src/lang/en/%s.json", name))
	if err != nil {
		log.Errorf("failed to open %s.json: %+v", name, err)
		return
	}
	defer f.Close()
	content, err := io.ReadAll(f)
	if err != nil {
		log.Errorf("failed to read %s.json: %+v", name, err)
		return
	}
	oldData := make(map[string]interface{})
	newData := make(map[string]interface{})
	err = utils.Json.Unmarshal(content, &oldData)
	if err != nil {
		log.Errorf("failed to unmarshal %s.json: %+v", name, err)
		return
	}
	content, err = utils.Json.Marshal(data)
	if err != nil {
		log.Errorf("failed to marshal json: %+v", err)
		return
	}
	err = utils.Json.Unmarshal(content, &newData)
	if err != nil {
		log.Errorf("failed to unmarshal json: %+v", err)
		return
	}
	if reflect.DeepEqual(oldData, newData) {
		log.Infof("%s.json no changed, skip", name)
	} else {
		log.Infof("%s.json changed, update file", name)
		//log.Infof("old: %+v\nnew:%+v", oldData, data)
		utils.WriteJsonToFile(fmt.Sprintf("lang/%s.json", name), newData, true)
	}
}

func generateDriversJson() {
	drivers := make(Drivers)
	drivers["drivers"] = make(KV[interface{}])
	drivers["config"] = make(KV[interface{}])
	driverInfoMap := op.GetDriverInfoMap()
	for k, v := range driverInfoMap {
		drivers["drivers"][k] = convert(k)
		items := make(KV[interface{}])
		config := map[string]string{}
		if v.Config.Alert != "" {
			alert := strings.SplitN(v.Config.Alert, "|", 2)
			if len(alert) > 1 {
				config["alert"] = alert[1]
			}
		}
		drivers["config"][k] = config
		for i := range v.Additional {
			item := v.Additional[i]
			items[item.Name] = convert(item.Name)
			if item.Help != "" {
				items[fmt.Sprintf("%s-tips", item.Name)] = item.Help
			}
			if item.Type == conf.TypeSelect && len(item.Options) > 0 {
				options := make(KV[string])
				_options := strings.Split(item.Options, ",")
				for _, o := range _options {
					options[o] = convert(o)
				}
				items[fmt.Sprintf("%ss", item.Name)] = options
			}
		}
		drivers[k] = items
	}
	writeFile("drivers", drivers)
}

func generateSettingsJson() {
	settings := data.InitialSettings()
	settingsLang := make(KV[any])
	for _, setting := range settings {
		settingsLang[setting.Key] = convert(setting.Key)
		if setting.Help != "" {
			settingsLang[fmt.Sprintf("%s-tips", setting.Key)] = setting.Help
		}
		if setting.Type == conf.TypeSelect && len(setting.Options) > 0 {
			options := make(KV[string])
			_options := strings.Split(setting.Options, ",")
			for _, o := range _options {
				options[o] = convert(o)
			}
			settingsLang[fmt.Sprintf("%ss", setting.Key)] = options
		}
	}
	writeFile("settings", settingsLang)
	//utils.WriteJsonToFile("lang/settings.json", settingsLang)
}

// LangCmd represents the lang command
var LangCmd = &cobra.Command{
	Use:   "lang",
	Short: "Generate language json file",
	Run: func(cmd *cobra.Command, args []string) {
		bootstrap.InitConfig()
		err := os.MkdirAll("lang", 0777)
		if err != nil {
			utils.Log.Fatalf("failed create folder: %s", err.Error())
		}
		generateDriversJson()
		generateSettingsJson()
	},
}

func init() {
	RootCmd.AddCommand(LangCmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// langCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// langCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}


================================================
FILE: cmd/restart.go
================================================
/*
Copyright © 2022 NAME HERE <EMAIL ADDRESS>
*/
package cmd

import (
	"github.com/spf13/cobra"
)

// RestartCmd represents the restart command
var RestartCmd = &cobra.Command{
	Use:   "restart",
	Short: "Restart alist server by daemon/pid file",
	Run: func(cmd *cobra.Command, args []string) {
		stop()
		start()
	},
}

func init() {
	RootCmd.AddCommand(RestartCmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// restartCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// restartCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}


================================================
FILE: cmd/root.go
================================================
package cmd

import (
	"fmt"
	"os"

	"github.com/alist-org/alist/v3/cmd/flags"
	_ "github.com/alist-org/alist/v3/drivers"
	_ "github.com/alist-org/alist/v3/internal/archive"
	_ "github.com/alist-org/alist/v3/internal/offline_download"
	"github.com/spf13/cobra"
)

var RootCmd = &cobra.Command{
	Use:   "alist",
	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://alistgo.com/`,
}

func Execute() {
	if err := RootCmd.Execute(); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}

func init() {
	RootCmd.PersistentFlags().StringVar(&flags.DataDir, "data", "data", "data folder")
	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().BoolVar(&flags.LogStd, "log-std", false, "Force to log to std")
}


================================================
FILE: cmd/server.go
================================================
package cmd

import (
	"context"
	"errors"
	"fmt"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strconv"
	"sync"
	"syscall"
	"time"

	ftpserver "github.com/KirCute/ftpserverlib-pasvportmap"
	"github.com/KirCute/sftpd-alist"
	"github.com/alist-org/alist/v3/cmd/flags"
	"github.com/alist-org/alist/v3/internal/bootstrap"
	"github.com/alist-org/alist/v3/internal/conf"
	"github.com/alist-org/alist/v3/internal/fs"
	"github.com/alist-org/alist/v3/pkg/utils"
	"github.com/alist-org/alist/v3/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
var ServerCmd = &cobra.Command{
	Use:   "server",
	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()
		if conf.Conf.DelayedStart != 0 {
			utils.Log.Infof("delayed start for %d seconds", conf.Conf.DelayedStart)
			time.Sleep(time.Duration(conf.Conf.DelayedStart) * time.Second)
		}
		bootstrap.InitOfflineDownloadTools()
		bootstrap.LoadStorages()
		bootstrap.InitTaskManager()
		if !flags.Debug && !flags.Dev {
			gin.SetMode(gin.ReleaseMode)
		}
		r := gin.New()
		r.Use(gin.LoggerWithWriter(log.StandardLogger().Out), gin.RecoveryWithWriter(log.StandardLogger().Out))
		server.Init(r)
		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 != -1 {
			httpBase := fmt.Sprintf("%s:%d", conf.Conf.Scheme.Address, conf.Conf.Scheme.HttpPort)
			utils.Log.Infof("start HTTP server @ %s", httpBase)
			httpSrv = &http.Server{Addr: httpBase, Handler: httpHandler}
			go func() {
				err := httpSrv.ListenAndServe()
				if err != nil && !errors.Is(err, http.ErrServerClosed) {
					utils.Log.Fatalf("failed to start http: %s", err.Error())
				}
			}()
		}
		if conf.Conf.Scheme.HttpsPort != -1 {
			httpsBase := fmt.Sprintf("%s:%d", conf.Conf.Scheme.Address, conf.Conf.Scheme.HttpsPort)
			utils.Log.Infof("start HTTPS server @ %s", 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) {
					utils.Log.Fatalf("failed to start https: %s", err.Error())
				}
			}()
		}
		if conf.Conf.Scheme.UnixFile != "" {
			utils.Log.Infof("start unix server @ %s", conf.Conf.Scheme.UnixFile)
			unixSrv = &http.Server{Handler: httpHandler}
			go func() {
				listener, err := net.Listen("unix", conf.Conf.Scheme.UnixFile)
				if err != nil {
					utils.Log.Fatalf("failed to listen unix: %+v", err)
				}
				// set socket file permission
				mode, err := strconv.ParseUint(conf.Conf.Scheme.UnixFilePerm, 8, 32)
				if err != nil {
					utils.Log.Errorf("failed to parse socket file permission: %+v", err)
				} else {
					err = os.Chmod(conf.Conf.Scheme.UnixFile, os.FileMode(mode))
					if err != nil {
						utils.Log.Errorf("failed to chmod socket file: %+v", err)
					}
				}
				err = unixSrv.Serve(listener)
				if err != nil && !errors.Is(err, http.ErrServerClosed) {
					utils.Log.Fatalf("failed to start unix: %s", err.Error())
				}
			}()
		}
		if conf.Conf.S3.Port != -1 && conf.Conf.S3.Enable {
			s3r := gin.New()
			s3r.Use(gin.LoggerWithWriter(log.StandardLogger().Out), gin.RecoveryWithWriter(log.StandardLogger().Out))
			server.InitS3(s3r)
			s3Base := fmt.Sprintf("%s:%d", conf.Conf.Scheme.Address, conf.Conf.S3.Port)
			utils.Log.Infof("start S3 server @ %s", s3Base)
			go func() {
				var err error
				if conf.Conf.S3.SSL {
					httpsSrv = &http.Server{Addr: s3Base, Handler: s3r}
					err = httpsSrv.ListenAndServeTLS(conf.Conf.Scheme.CertFile, conf.Conf.Scheme.KeyFile)
				}
				if !conf.Conf.S3.SSL {
					httpSrv = &http.Server{Addr: s3Base, Handler: s3r}
					err = httpSrv.ListenAndServe()
				}
				if err != nil && !errors.Is(err, http.ErrServerClosed) {
					utils.Log.Fatalf("failed to start s3 server: %s", err.Error())
				}
			}()
		}
		var ftpDriver *server.FtpMainDriver
		var ftpServer *ftpserver.FtpServer
		if conf.Conf.FTP.Listen != "" && conf.Conf.FTP.Enable {
			var err error
			ftpDriver, err = server.NewMainDriver()
			if err != nil {
				utils.Log.Fatalf("failed to start ftp driver: %s", err.Error())
			} else {
				utils.Log.Infof("start ftp server on %s", conf.Conf.FTP.Listen)
				go func() {
					ftpServer = ftpserver.NewFtpServer(ftpDriver)
					err = ftpServer.ListenAndServe()
					if err != nil {
						utils.Log.Fatalf("problem ftp server listening: %s", err.Error())
					}
				}()
			}
		}
		var sftpDriver *server.SftpDriver
		var sftpServer *sftpd.SftpServer
		if conf.Conf.SFTP.Listen != "" && conf.Conf.SFTP.Enable {
			var err error
			sftpDriver, err = server.NewSftpDriver()
			if err != nil {
				utils.Log.Fatalf("failed to start sftp driver: %s", err.Error())
			} else {
				utils.Log.Infof("start sftp server on %s", conf.Conf.SFTP.Listen)
				go func() {
					sftpServer = sftpd.NewSftpServer(sftpDriver)
					err = sftpServer.RunServer()
					if err != nil {
						utils.Log.Fatalf("problem sftp server listening: %s", err.Error())
					}
				}()
			}
		}
		// Wait for interrupt signal to gracefully shutdown the server with
		// a timeout of 1 second.
		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...")
		fs.ArchiveContentUploadTaskManager.RemoveAll()
		Release()
		ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
		defer cancel()
		var wg sync.WaitGroup
		if conf.Conf.Scheme.HttpPort != -1 {
			wg.Add(1)
			go func() {
				defer wg.Done()
				if err := httpSrv.Shutdown(ctx); err != nil {
					utils.Log.Fatal("HTTP server shutdown err: ", err)
				}
			}()
		}
		if conf.Conf.Scheme.HttpsPort != -1 {
			wg.Add(1)
			go func() {
				defer wg.Done()
				if err := httpsSrv.Shutdown(ctx); err != nil {
					utils.Log.Fatal("HTTPS server shutdown err: ", err)
				}
			}()
		}
		if conf.Conf.Scheme.UnixFile != "" {
			wg.Add(1)
			go func() {
				defer wg.Done()
				if err := unixSrv.Shutdown(ctx); err != nil {
					utils.Log.Fatal("Unix server shutdown err: ", err)
				}
			}()
		}
		if conf.Conf.FTP.Listen != "" && conf.Conf.FTP.Enable && ftpServer != nil && ftpDriver != nil {
			wg.Add(1)
			go func() {
				defer wg.Done()
				ftpDriver.Stop()
				if err := ftpServer.Stop(); err != nil {
					utils.Log.Fatal("FTP server shutdown err: ", err)
				}
			}()
		}
		if conf.Conf.SFTP.Listen != "" && conf.Conf.SFTP.Enable && sftpServer != nil && sftpDriver != nil {
			wg.Add(1)
			go func() {
				defer wg.Done()
				if err := sftpServer.Close(); err != nil {
					utils.Log.Fatal("SFTP server shutdown err: ", err)
				}
			}()
		}
		wg.Wait()
		utils.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() {
	var (
		cmd  *cobra.Command
		args []string
	)
	ServerCmd.Run(cmd, args)
}


================================================
FILE: cmd/start.go
================================================
/*
Copyright © 2022 NAME HERE <EMAIL ADDRESS>
*/
package cmd

import (
	"os"
	"os/exec"
	"path/filepath"
	"strconv"

	log "github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
)

// StartCmd represents the start command
var StartCmd = &cobra.Command{
	Use:   "start",
	Short: "Silent start alist server with `--force-bin-dir`",
	Run: func(cmd *cobra.Command, args []string) {
		start()
	},
}

func start() {
	initDaemon()
	if pid != -1 {
		_, err := os.FindProcess(pid)
		if err == nil {
			log.Info("alist already started, pid ", pid)
			return
		}
	}
	args := os.Args
	args[1] = "server"
	args = append(args, "--force-bin-dir")
	cmd := &exec.Cmd{
		Path: args[0],
		Args: args,
		Env:  os.Environ(),
	}
	stdout, err := os.OpenFile(filepath.Join(filepath.Dir(pidFile), "start.log"), os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
	if err != nil {
		log.Fatal(os.Getpid(), ": failed to open start log file:", err)
	}
	cmd.Stderr = stdout
	cmd.Stdout = stdout
	err = cmd.Start()
	if err != nil {
		log.Fatal("failed to start children process: ", err)
	}
	log.Infof("success start pid: %d", cmd.Process.Pid)
	err = os.WriteFile(pidFile, []byte(strconv.Itoa(cmd.Process.Pid)), 0666)
	if err != nil {
		log.Warn("failed to record pid, you may not be able to stop the program with `./alist stop`")
	}
}

func init() {
	RootCmd.AddCommand(StartCmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// startCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// startCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}


================================================
FILE: cmd/stop_default.go
================================================
//go:build !windows

package cmd

import (
	"os"
	"syscall"

	log "github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
)

// StopCmd represents the stop command
var StopCmd = &cobra.Command{
	Use:   "stop",
	Short: "Stop alist server by daemon/pid file",
	Run: func(cmd *cobra.Command, args []string) {
		stop()
	},
}

func stop() {
	initDaemon()
	if pid == -1 {
		log.Info("Seems not have been started. Try use `alist start` to start server.")
		return
	}
	process, err := os.FindProcess(pid)
	if err != nil {
		log.Errorf("failed to find process by pid: %d, reason: %v", pid, process)
		return
	}
	err = process.Signal(syscall.SIGTERM)
	if err != nil {
		log.Errorf("failed to terminate process %d: %v", pid, err)
	} else {
		log.Info("terminated process: ", pid)
	}
	err = os.Remove(pidFile)
	if err != nil {
		log.Errorf("failed to remove pid file")
	}
	pid = -1
}

func init() {
	RootCmd.AddCommand(StopCmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// stopCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// stopCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}


================================================
FILE: cmd/stop_windows.go
================================================
//go:build windows

package cmd

import (
	"github.com/spf13/cobra"
)

// StopCmd represents the stop command
var StopCmd = &cobra.Command{
	Use:   "stop",
	Short: "Same as the kill command",
	Run: func(cmd *cobra.Command, args []string) {
		stop()
	},
}

func stop() {
	kill()
}

func init() {
	RootCmd.AddCommand(StopCmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// stopCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// stopCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}


================================================
FILE: cmd/storage.go
================================================
/*
Copyright © 2023 NAME HERE <EMAIL ADDRESS>
*/
package cmd

import (
	"os"
	"strconv"

	"github.com/alist-org/alist/v3/internal/db"
	"github.com/alist-org/alist/v3/pkg/utils"
	"github.com/charmbracelet/bubbles/table"
	tea "github.com/charmbracelet/bubbletea"
	"github.com/charmbracelet/lipgloss"
	"github.com/spf13/cobra"
)

// storageCmd represents the storage command
var storageCmd = &cobra.Command{
	Use:   "storage",
	Short: "Manage storage",
}

var disableStorageCmd = &cobra.Command{
	Use:   "disable",
	Short: "Disable a storage",
	Run: func(cmd *cobra.Command, args []string) {
		if len(args) < 1 {
			utils.Log.Errorf("mount path is required")
			return
		}
		mountPath := args[0]
		Init()
		defer Release()
		storage, err := db.GetStorageByMountPath(mountPath)
		if err != nil {
			utils.Log.Errorf("failed to query storage: %+v", err)
		} else {
			storage.Disabled = true
			err = db.UpdateStorage(storage)
			if err != nil {
				utils.Log.Errorf("failed to update storage: %+v", err)
			} else {
				utils.Log.Infof("Storage with mount path [%s] have been disabled", mountPath)
			}
		}
	},
}

var baseStyle = lipgloss.NewStyle().
	BorderStyle(lipgloss.NormalBorder()).
	BorderForeground(lipgloss.Color("240"))

type model struct {
	table table.Model
}

func (m model) Init() tea.Cmd { return nil }

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
	var cmd tea.Cmd
	switch msg := msg.(type) {
	case tea.KeyMsg:
		switch msg.String() {
		case "esc":
			if m.table.Focused() {
				m.table.Blur()
			} else {
				m.table.Focus()
			}
		case "q", "ctrl+c":
			return m, tea.Quit
			//case "enter":
			//	return m, tea.Batch(
			//		tea.Printf("Let's go to %s!", m.table.SelectedRow()[1]),
			//	)
		}
	}
	m.table, cmd = m.table.Update(msg)
	return m, cmd
}

func (m model) View() string {
	return baseStyle.Render(m.table.View()) + "\n"
}

var storageTableHeight int
var listStorageCmd = &cobra.Command{
	Use:   "list",
	Short: "List all storages",
	Run: func(cmd *cobra.Command, args []string) {
		Init()
		defer Release()
		storages, _, err := db.GetStorages(1, -1)
		if err != nil {
			utils.Log.Errorf("failed to query storages: %+v", err)
		} else {
			utils.Log.Infof("Found %d storages", len(storages))
			columns := []table.Column{
				{Title: "ID", Width: 4},
				{Title: "Driver", Width: 16},
				{Title: "Mount Path", Width: 30},
				{Title: "Enabled", Width: 7},
			}

			var rows []table.Row
			for i := range storages {
				storage := storages[i]
				enabled := "true"
				if storage.Disabled {
					enabled = "false"
				}
				rows = append(rows, table.Row{
					strconv.Itoa(int(storage.ID)),
					storage.Driver,
					storage.MountPath,
					enabled,
				})
			}
			t := table.New(
				table.WithColumns(columns),
				table.WithRows(rows),
				table.WithFocused(true),
				table.WithHeight(storageTableHeight),
			)

			s := table.DefaultStyles()
			s.Header = s.Header.
				BorderStyle(lipgloss.NormalBorder()).
				BorderForeground(lipgloss.Color("240")).
				BorderBottom(true).
				Bold(false)
			s.Selected = s.Selected.
				Foreground(lipgloss.Color("229")).
				Background(lipgloss.Color("57")).
				Bold(false)
			t.SetStyles(s)

			m := model{t}
			if _, err := tea.NewProgram(m).Run(); err != nil {
				utils.Log.Errorf("failed to run program: %+v", err)
				os.Exit(1)
			}
		}
	},
}

func init() {

	RootCmd.AddCommand(storageCmd)
	storageCmd.AddCommand(disableStorageCmd)
	storageCmd.AddCommand(listStorageCmd)
	storageCmd.PersistentFlags().IntVarP(&storageTableHeight, "height", "H", 10, "Table height")
	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// storageCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// storageCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}


================================================
FILE: cmd/user.go
================================================
package cmd

import (
	"crypto/tls"
	"fmt"
	"time"

	"github.com/alist-org/alist/v3/internal/conf"
	"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"
)

func DelAdminCacheOnline() {
	admin, err := op.GetAdmin()
	if err != nil {
		utils.Log.Errorf("[del_admin_cache] get admin error: %+v", err)
		return
	}
	DelUserCacheOnline(admin.Username)
}

func DelUserCacheOnline(username string) {
	client := resty.New().SetTimeout(1 * time.Second).SetTLSClientConfig(&tls.Config{InsecureSkipVerify: conf.Conf.TlsInsecureSkipVerify})
	token := setting.GetStr(conf.Token)
	port := conf.Conf.Scheme.HttpPort
	u := fmt.Sprintf("http://localhost:%d/api/admin/user/del_cache", port)
	if port == -1 {
		if conf.Conf.Scheme.HttpsPort == -1 {
			utils.Log.Warnf("[del_user_cache] no open port")
			return
		}
		u = fmt.Sprintf("https://localhost:%d/api/admin/user/del_cache", conf.Conf.Scheme.HttpsPort)
	}
	res, err := client.R().SetHeader("Authorization", token).SetQueryParam("username", username).Post(u)
	if err != nil {
		utils.Log.Warnf("[del_user_cache_online] failed: %+v", err)
		return
	}
	if res.StatusCode() != 200 {
		utils.Log.Warnf("[del_user_cache_online] failed: %+v", res.String())
		return
	}
	code := utils.Json.Get(res.Body(), "code").ToInt()
	msg := utils.Json.Get(res.Body(), "message").ToString()
	if code != 200 {
		utils.Log.Errorf("[del_user_cache_online] error: %s", msg)
		return
	}
	utils.Log.Debugf("[del_user_cache_online] del user [%s] cache success", username)
}


================================================
FILE: cmd/version.go
================================================
/*
Copyright © 2022 NAME HERE <EMAIL ADDRESS>
*/
package cmd

import (
	"fmt"
	"os"
	"runtime"

	"github.com/alist-org/alist/v3/internal/conf"
	"github.com/spf13/cobra"
)

// VersionCmd represents the version command
var VersionCmd = &cobra.Command{
	Use:   "version",
	Short: "Show current version of AList",
	Run: func(cmd *cobra.Command, args []string) {
		goVersion := fmt.Sprintf("%s %s/%s", runtime.Version(), runtime.GOOS, runtime.GOARCH)

		fmt.Printf(`Built At: %s
Go Version: %s
Author: %s
Commit ID: %s
Version: %s
WebVersion: %s
`, conf.BuiltAt, goVersion, conf.GitAuthor, conf.GitCommit, conf.Version, conf.WebVersion)
		os.Exit(0)
	},
}

func init() {
	RootCmd.AddCommand(VersionCmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// versionCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// versionCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}


================================================
FILE: docker-compose.yml
================================================
version: '3.3'
services:
  alist:
    restart: always
    volumes:
      - '/etc/alist:/opt/alist/data'
    ports:
      - '5244:5244'
      - '5245:5245'
    environment:
      - PUID=0
      - PGID=0
      - UMASK=022
      - TZ=UTC
    container_name: alist
    image: 'xhofe/alist:latest'


================================================
FILE: drivers/115/appver.go
================================================
package _115

import (
	driver115 "github.com/SheltonZhu/115driver/pkg/driver"
	"github.com/alist-org/alist/v3/drivers/base"
	log "github.com/sirupsen/logrus"
)

var (
	md5Salt = "Qclm8MGWUv59TnrR0XPg"
	appVer  = "27.0.5.7"
)

func (d *Pan115) getAppVersion() ([]driver115.AppVersion, error) {
	result := driver115.VersionResp{}
	resp, err := base.RestyClient.R().Get(driver115.ApiGetVersion)

	err = driver115.CheckErr(err, &result, resp)
	if err != nil {
		return nil, err
	}

	return result.Data.GetAppVersions(), nil
}

func (d *Pan115) getAppVer() string {
	// todo add some cache?
	vers, err := d.getAppVersion()
	if err != nil {
		log.Warnf("[115] get app version failed: %v", err)
		return appVer
	}
	for _, ver := range vers {
		if ver.AppName == "win" {
			return ver.Version
		}
	}
	return appVer
}

func (d *Pan115) initAppVer() {
	appVer = d.getAppVer()
}


================================================
FILE: drivers/115/driver.go
================================================
package _115

import (
	"context"
	"strings"
	"sync"

	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/http_range"
	"github.com/alist-org/alist/v3/pkg/utils"
	"github.com/pkg/errors"
	"golang.org/x/time/rate"
)

type Pan115 struct {
	model.Storage
	Addition
	client     *driver115.Pan115Client
	limiter    *rate.Limiter
	appVerOnce sync.Once
}

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 {
	d.appVerOnce.Do(d.initAppVer)
	if d.LimitRate > 0 {
		d.limiter = rate.NewLimiter(rate.Limit(d.LimitRate), 1)
	}
	return d.login()
}

func (d *Pan115) WaitLimit(ctx context.Context) error {
	if d.limiter != nil {
		return d.limiter.Wait(ctx)
	}
	return nil
}

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) {
	if err := d.WaitLimit(ctx); err != nil {
		return nil, err
	}
	files, err := d.getFiles(dir.GetID())
	if err != nil && !errors.Is(err, driver115.ErrNotExist) {
		return nil, err
	}
	return utils.SliceConvert(files, func(src FileObj) (model.Obj, error) {
		return &src, nil
	})
}

func (d *Pan115) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
	if err := d.WaitLimit(ctx); err != nil {
		return nil, err
	}
	userAgent := ""
	if args.Header != nil {
		userAgent = args.Header.Get("User-Agent")
	}
	downloadInfo, err := d.client.DownloadWithUA(file.(*FileObj).PickCode, userAgent)
	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) (model.Obj, error) {
	if err := d.WaitLimit(ctx); err != nil {
		return nil, err
	}

	result := driver115.MkdirResp{}
	form := map[string]string{
		"pid":   parentDir.GetID(),
		"cname": dirName,
	}
	req := d.client.NewRequest().
		SetFormData(form).
		SetResult(&result).
		ForceContentType("application/json;charset=UTF-8")

	resp, err := req.Post(driver115.ApiDirAdd)

	err = driver115.CheckErr(err, &result, resp)
	if err != nil {
		return nil, err
	}
	f, err := d.getNewFile(result.FileID)
	if err != nil {
		return nil, nil
	}
	return f, nil
}

func (d *Pan115) Move(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) {
	if err := d.WaitLimit(ctx); err != nil {
		return nil, err
	}
	if err := d.client.Move(dstDir.GetID(), srcObj.GetID()); err != nil {
		return nil, err
	}
	f, err := d.getNewFile(srcObj.GetID())
	if err != nil {
		return nil, nil
	}
	return f, nil
}

func (d *Pan115) Rename(ctx context.Context, srcObj model.Obj, newName string) (model.Obj, error) {
	if err := d.WaitLimit(ctx); err != nil {
		return nil, err
	}
	if err := d.client.Rename(srcObj.GetID(), newName); err != nil {
		return nil, err
	}
	f, err := d.getNewFile((srcObj.GetID()))
	if err != nil {
		return nil, nil
	}
	return f, nil
}

func (d *Pan115) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
	if err := d.WaitLimit(ctx); err != nil {
		return err
	}
	return d.client.Copy(dstDir.GetID(), srcObj.GetID())
}

func (d *Pan115) Remove(ctx context.Context, obj model.Obj) error {
	if err := d.WaitLimit(ctx); err != nil {
		return err
	}
	return d.client.Delete(obj.GetID())
}

func (d *Pan115) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) (model.Obj, error) {
	if err := d.WaitLimit(ctx); err != nil {
		return nil, err
	}

	var (
		fastInfo *driver115.UploadInitResp
		dirID    = dstDir.GetID()
	)

	if ok, err := d.client.UploadAvailable(); err != nil || !ok {
		return nil, err
	}
	if stream.GetSize() > d.client.UploadMetaInfo.SizeLimit {
		return nil, driver115.ErrUploadTooLarge
	}
	//if digest, err = d.client.GetDigestResult(stream); err != nil {
	//	return err
	//}

	const PreHashSize int64 = 128 * utils.KB
	hashSize := PreHashSize
	if stream.GetSize() < PreHashSize {
		hashSize = stream.GetSize()
	}
	reader, err := stream.RangeRead(http_range.Range{Start: 0, Length: hashSize})
	if err != nil {
		return nil, err
	}
	preHash, err := utils.HashReader(utils.SHA1, reader)
	if err != nil {
		return nil, err
	}
	preHash = strings.ToUpper(preHash)
	fullHash := stream.GetHash().GetHash(utils.SHA1)
	if len(fullHash) <= 0 {
		tmpF, err := stream.CacheFullInTempFile()
		if err != nil {
			return nil, err
		}
		fullHash, err = utils.HashFile(utils.SHA1, tmpF)
		if err != nil {
			return nil, err
		}
	}
	fullHash = strings.ToUpper(fullHash)

	// rapid-upload
	// note that 115 add timeout for rapid-upload,
	// and "sig invalid" err is thrown even when the hash is correct after timeout.
	if fastInfo, err = d.rapidUpload(stream.GetSize(), stream.GetName(), dirID, preHash, fullHash, stream); err != nil {
		return nil, err
	}
	if matched, err := fastInfo.Ok(); err != nil {
		return nil, err
	} else if matched {
		f, err := d.getNewFileByPickCode(fastInfo.PickCode)
		if err != nil {
			return nil, nil
		}
		return f, nil
	}

	var uploadResult *UploadResult
	// 闪传失败,上传
	if stream.GetSize() <= 10*utils.MB { // 文件大小小于10MB,改用普通模式上传
		if uploadResult, err = d.UploadByOSS(ctx, &fastInfo.UploadOSSParams, stream, dirID, up); err != nil {
			return nil, err
		}
	} else {
		// 分片上传
		if uploadResult, err = d.UploadByMultipart(ctx, &fastInfo.UploadOSSParams, stream.GetSize(), stream, dirID, up); err != nil {
			return nil, err
		}
	}

	file, err := d.getNewFile(uploadResult.Data.FileID)
	if err != nil {
		return nil, nil
	}
	return file, nil
}

func (d *Pan115) OfflineList(ctx context.Context) ([]*driver115.OfflineTask, error) {
	resp, err := d.client.ListOfflineTask(0)
	if err != nil {
		return nil, err
	}
	return resp.Tasks, nil
}

func (d *Pan115) OfflineDownload(ctx context.Context, uris []string, dstDir model.Obj) ([]string, error) {
	return d.client.AddOfflineTaskURIs(uris, dstDir.GetID(), driver115.WithAppVer(appVer))
}

func (d *Pan115) DeleteOfflineTasks(ctx context.Context, hashes []string, deleteFiles bool) error {
	return d.client.DeleteOfflineTasks(hashes, deleteFiles)
}

var _ driver.Driver = (*Pan115)(nil)


================================================
FILE: drivers/115/meta.go
================================================
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" type:"text" help:"one of QR code token and cookie required"`
	QRCodeToken  string  `json:"qrcode_token" type:"text" help:"one of QR code token and cookie required"`
	QRCodeSource string  `json:"qrcode_source" type:"select" options:"web,android,ios,tv,alipaymini,wechatmini,qandroid" default:"linux" help:"select the QR code device, default linux"`
	PageSize     int64   `json:"page_size" type:"number" default:"1000" help:"list api per page size of 115 driver"`
	LimitRate    float64 `json:"limit_rate" type:"float" default:"2" help:"limit all api request rate ([limit]r/1s)"`
	driver.RootID
}

var config = driver.Config{
	Name:        "115 Cloud",
	DefaultRoot: "0",
	// OnlyProxy:   true,
	// OnlyLocal:         true,
	// NoOverwriteUpload: true,
}

func init() {
	op.RegisterDriver(func() driver.Driver {
		return &Pan115{}
	})
}


================================================
FILE: drivers/115/types.go
================================================
package _115

import (
	"time"

	"github.com/SheltonZhu/115driver/pkg/driver"
	"github.com/alist-org/alist/v3/internal/model"
	"github.com/alist-org/alist/v3/pkg/utils"
)

var _ model.Obj = (*FileObj)(nil)

type FileObj struct {
	driver.File
	ThumbURL string
}

func (f *FileObj) CreateTime() time.Time {
	return f.File.CreateTime
}

func (f *FileObj) GetHash() utils.HashInfo {
	return utils.NewHashInfo(utils.SHA1, f.Sha1)
}

func (f *FileObj) Thumb() string {
	return f.ThumbURL
}

type UploadResult struct {
	driver.BasicResp
	Data struct {
		PickCode string `json:"pick_code"`
		FileSize int    `json:"file_size"`
		FileID   string `json:"file_id"`
		ThumbURL string `json:"thumb_url"`
		Sha1     string `json:"sha1"`
		Aid      int    `json:"aid"`
		FileName string `json:"file_name"`
		Cid      string `json:"cid"`
		IsVideo  int    `json:"is_video"`
	} `json:"data"`
}


================================================
FILE: drivers/115/util.go
================================================
package _115

import (
	"bytes"
	"context"
	"crypto/md5"
	"crypto/tls"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io"
	"net/url"
	"strconv"
	"strings"
	"sync"
	"sync/atomic"
	"time"

	"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/pkg/http_range"
	"github.com/alist-org/alist/v3/pkg/utils"
	"github.com/aliyun/aliyun-oss-go-sdk/oss"

	cipher "github.com/SheltonZhu/115driver/pkg/crypto/ec115"
	driver115 "github.com/SheltonZhu/115driver/pkg/driver"
	"github.com/pkg/errors"
)

type fileInfoWithThumb struct {
	driver115.FileInfo
	ThumbURL string `json:"u"`
}

type fileListRespWithThumb struct {
	driver115.BasicResp
	CategoryID driver115.IntString `json:"cid"`
	Count      int                 `json:"count"`
	Offset     int                 `json:"offset"`
	Files      []fileInfoWithThumb `json:"data"`
}

type getFileInfoResponseWithThumb struct {
	driver115.BasicResp
	Files []*fileInfoWithThumb `json:"data"`
}

// var UserAgent = driver115.UA115Browser
func (d *Pan115) login() error {
	var err error
	opts := []driver115.Option{
		driver115.UA(d.getUA()),
		func(c *driver115.Pan115Client) {
			c.Client.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: conf.Conf.TlsInsecureSkipVerify})
		},
	}
	d.client = driver115.New(opts...)
	cr := &driver115.Credential{}
	if d.QRCodeToken != "" {
		s := &driver115.QRCodeSession{
			UID: d.QRCodeToken,
		}
		if cr, err = d.client.QRCodeLoginWithApp(s, driver115.LoginApp(d.QRCodeSource)); err != nil {
			return errors.Wrap(err, "failed to login by qrcode")
		}
		d.Cookie = fmt.Sprintf("UID=%s;CID=%s;SEID=%s;KID=%s", cr.UID, cr.CID, cr.SEID, cr.KID)
		d.QRCodeToken = ""
	} else if d.Cookie != "" {
		if err = cr.FromCookie(d.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) ([]FileObj, error) {
	res := make([]FileObj, 0)
	if d.PageSize <= 0 {
		d.PageSize = driver115.FileListLimit
	}
	limit := d.PageSize
	if limit > driver115.MaxDirPageLimit {
		limit = driver115.MaxDirPageLimit
	}

	opts := driver115.DefaultListOptions()
	driver115.WithMultiUrls()(opts)
	if len(opts.ApiURLs) == 0 {
		opts.ApiURLs = []string{driver115.ApiFileList}
	}

	offset := int64(0)
	for i := 0; ; i++ {
		result, err := d.getFilesPageWithThumb(fileId, opts.ApiURLs[i%len(opts.ApiURLs)], limit, offset)
		if err != nil {
			return nil, err
		}
		for _, fileInfo := range result.Files {
			res = append(res, fileObjFromInfo(&fileInfo))
		}
		offset = int64(result.Offset) + limit
		if offset >= int64(result.Count) {
			break
		}
	}

	return res, nil
}

func (d *Pan115) getNewFile(fileId string) (*FileObj, error) {
	fileInfo, err := d.getFileInfoWithThumb("file_id", fileId)
	if err != nil {
		return nil, err
	}
	file := fileObjFromInfo(fileInfo)
	return &file, nil
}

func (d *Pan115) getNewFileByPickCode(pickCode string) (*FileObj, error) {
	fileInfo, err := d.getFileInfoWithThumb("pick_code", pickCode)
	if err != nil {
		return nil, err
	}
	file := fileObjFromInfo(fileInfo)
	return &file, nil
}

func (d *Pan115) getUA() string {
	return fmt.Sprintf("Mozilla/5.0 115Browser/%s", appVer)
}

func fileObjFromInfo(fileInfo *fileInfoWithThumb) FileObj {
	file := &driver115.File{}
	file.From(&fileInfo.FileInfo)
	return FileObj{
		File:     *file,
		ThumbURL: fileInfo.ThumbURL,
	}
}

func (d *Pan115) getFileInfoWithThumb(queryKey, queryVal string) (*fileInfoWithThumb, error) {
	result := getFileInfoResponseWithThumb{}
	req := d.client.NewRequest().
		SetQueryParam(queryKey, queryVal).
		ForceContentType("application/json;charset=UTF-8").
		SetResult(&result)
	resp, err := req.Get(driver115.ApiFileInfo)
	if err := driver115.CheckErr(err, &result, resp); err != nil {
		return nil, err
	}
	if len(result.Files) == 0 {
		return nil, errors.New("not get file info")
	}
	return result.Files[0], nil
}

func (d *Pan115) getFilesPageWithThumb(dirID, apiURL string, limit, offset int64) (*fileListRespWithThumb, error) {
	if dirID == "" {
		dirID = "0"
	}
	result := fileListRespWithThumb{}
	params := map[string]string{
		"aid":              "1",
		"cid":              dirID,
		"o":                driver115.FileOrderByTime,
		"asc":              "1",
		"offset":           strconv.FormatInt(offset, 10),
		"show_dir":         "1",
		"limit":            strconv.FormatInt(limit, 10),
		"snap":             "0",
		"natsort":          "0",
		"record_open_time": "1",
		"format":           "json",
		"fc_mix":           "0",
	}
	req := d.client.NewRequest().
		ForceContentType("application/json;charset=UTF-8").
		SetQueryParams(params).
		SetResult(&result)
	resp, err := req.Get(apiURL)
	if err := driver115.CheckErr(err, &result, resp); err != nil {
		return nil, err
	}
	if dirID != string(result.CategoryID) {
		return nil, driver115.ErrUnexpected
	}
	return &result, nil
}

func (c *Pan115) GenerateToken(fileID, preID, timeStamp, fileSize, signKey, signVal string) string {
	userID := strconv.FormatInt(c.client.UserID, 10)
	userIDMd5 := md5.Sum([]byte(userID))
	tokenMd5 := md5.Sum([]byte(md5Salt + fileID + fileSize + signKey + signVal + userID + timeStamp + hex.EncodeToString(userIDMd5[:]) + appVer))
	return hex.EncodeToString(tokenMd5[:])
}

func (d *Pan115) rapidUpload(fileSize int64, fileName, dirID, preID, fileID string, stream model.FileStreamer) (*driver115.UploadInitResp, error) {
	var (
		ecdhCipher   *cipher.EcdhCipher
		encrypted    []byte
		decrypted    []byte
		encodedToken string
		err          error
		target       = "U_1_" + dirID
		bodyBytes    []byte
		result       = driver115.UploadInitResp{}
		fileSizeStr  = strconv.FormatInt(fileSize, 10)
	)
	if ecdhCipher, err = cipher.NewEcdhCipher(); err != nil {
		return nil, err
	}

	userID := strconv.FormatInt(d.client.UserID, 10)
	form := url.Values{}
	form.Set("appid", "0")
	form.Set("appversion", appVer)
	form.Set("userid", userID)
	form.Set("filename", fileName)
	form.Set("filesize", fileSizeStr)
	form.Set("fileid", fileID)
	form.Set("target", target)
	form.Set("sig", d.client.GenerateSignature(fileID, target))

	signKey, signVal := "", ""
	for retry := true; retry; {
		t := driver115.NowMilli()

		if encodedToken, err = ecdhCipher.EncodeToken(t.ToInt64()); err != nil {
			return nil, err
		}

		params := map[string]string{
			"k_ec": encodedToken,
		}

		form.Set("t", t.String())
		form.Set("token", d.GenerateToken(fileID, preID, t.String(), fileSizeStr, signKey, signVal))
		if signKey != "" && signVal != "" {
			form.Set("sign_key", signKey)
			form.Set("sign_val", signVal)
		}
		if encrypted, err = ecdhCipher.Encrypt([]byte(form.Encode())); err != nil {
			return nil, err
		}

		req := d.client.NewRequest().
			SetQueryParams(params).
			SetBody(encrypted).
			SetHeaderVerbatim("Content-Type", "application/x-www-form-urlencoded").
			SetDoNotParseResponse(true)
		resp, err := req.Post(driver115.ApiUploadInit)
		if err != nil {
			return nil, err
		}
		data := resp.RawBody()
		defer data.Close()
		if bodyBytes, err = io.ReadAll(data); err != nil {
			return nil, err
		}
		if decrypted, err = ecdhCipher.Decrypt(bodyBytes); err != nil {
			return nil, err
		}
		if err = driver115.CheckErr(json.Unmarshal(decrypted, &result), &result, resp); err != nil {
			return nil, err
		}
		if result.Status == 7 {
			// Update signKey & signVal
			signKey = result.SignKey
			signVal, err = UploadDigestRange(stream, result.SignCheck)
			if err != nil {
				return nil, err
			}
		} else {
			retry = false
		}
		result.SHA1 = fileID
	}

	return &result, nil
}

func UploadDigestRange(stream model.FileStreamer, rangeSpec string) (result string, err error) {
	var start, end int64
	if _, err = fmt.Sscanf(rangeSpec, "%d-%d", &start, &end); err != nil {
		return
	}

	length := end - start + 1
	reader, err := stream.RangeRead(http_range.Range{Start: start, Length: length})
	if err != nil {
		return "", err
	}
	hashStr, err := utils.HashReader(utils.SHA1, reader)
	if err != nil {
		return "", err
	}
	result = strings.ToUpper(hashStr)
	return
}

// UploadByOSS use aliyun sdk to upload
func (c *Pan115) UploadByOSS(ctx context.Context, params *driver115.UploadOSSParams, s model.FileStreamer, dirID string, up driver.UpdateProgress) (*UploadResult, error) {
	ossToken, err := c.client.GetOSSToken()
	if err != nil {
		return nil, err
	}
	ossClient, err := oss.New(driver115.OSSEndpoint, ossToken.AccessKeyID, ossToken.AccessKeySecret)
	if err != nil {
		return nil, err
	}
	bucket, err := ossClient.Bucket(params.Bucket)
	if err != nil {
		return nil, err
	}

	var bodyBytes []byte
	r := driver.NewLimitedUploadStream(ctx, &driver.ReaderUpdatingProgress{
		Reader:         s,
		UpdateProgress: up,
	})
	if err = bucket.PutObject(params.Object, r, append(
		driver115.OssOption(params, ossToken),
		oss.CallbackResult(&bodyBytes),
	)...); err != nil {
		return nil, err
	}

	var uploadResult UploadResult
	if err = json.Unmarshal(bodyBytes, &uploadResult); err != nil {
		return nil, err
	}
	return &uploadResult, uploadResult.Err(string(bodyBytes))
}

// UploadByMultipart upload by mutipart blocks
func (d *Pan115) UploadByMultipart(ctx context.Context, params *driver115.UploadOSSParams, fileSize int64, s model.FileStreamer,
	dirID string, up driver.UpdateProgress, opts ...driver115.UploadMultipartOption) (*UploadResult, error) {
	var (
		chunks    []oss.FileChunk
		parts     []oss.UploadPart
		imur      oss.InitiateMultipartUploadResult
		ossClient *oss.Client
		bucket    *oss.Bucket
		ossToken  *driver115.UploadOSSTokenResp
		bodyBytes []byte
		err       error
	)

	tmpF, err := s.CacheFullInTempFile()
	if err != nil {
		return nil, err
	}

	options := driver115.DefalutUploadMultipartOptions()
	if len(opts) > 0 {
		for _, f := range opts {
			f(options)
		}
	}
	// oss 启用Sequential必须按顺序上传
	options.ThreadsNum = 1

	if ossToken, err = d.client.GetOSSToken(); err != nil {
		return nil, err
	}

	if ossClient, err = oss.New(driver115.OSSEndpoint, ossToken.AccessKeyID, ossToken.AccessKeySecret, oss.EnableMD5(true), oss.EnableCRC(true)); err != nil {
		return nil, err
	}

	if bucket, err = ossClient.Bucket(params.Bucket); err != nil {
		return nil, err
	}

	// ossToken一小时后就会失效,所以每50分钟重新获取一次
	ticker := time.NewTicker(options.TokenRefreshTime)
	defer ticker.Stop()
	// 设置超时
	timeout := time.NewTimer(options.Timeout)

	if chunks, err = SplitFile(fileSize); err != nil {
		return nil, err
	}

	if imur, err = bucket.InitiateMultipartUpload(params.Object,
		oss.SetHeader(driver115.OssSecurityTokenHeaderName, ossToken.SecurityToken),
		oss.UserAgentHeader(driver115.OSSUserAgent),
		oss.EnableSha1(), oss.Sequential(),
	); err != nil {
		return nil, err
	}

	wg := sync.WaitGroup{}
	wg.Add(len(chunks))

	chunksCh := make(chan oss.FileChunk)
	errCh := make(chan error)
	UploadedPartsCh := make(chan oss.UploadPart)
	quit := make(chan struct{})

	// producer
	go chunksProducer(chunksCh, chunks)
	go func() {
		wg.Wait()
		quit <- struct{}{}
	}()

	completedNum := atomic.Int32{}
	// consumers
	for i := 0; i < options.ThreadsNum; i++ {
		go func(threadId int) {
			defer func() {
				if r := recover(); r != nil {
					errCh <- fmt.Errorf("recovered in %v", r)
				}
			}()
			for chunk := range chunksCh {
				var part oss.UploadPart // 出现错误就继续尝试,共尝试3次
				for retry := 0; retry < 3; retry++ {
					select {
					case <-ctx.Done():
						break
					case <-ticker.C:
						if ossToken, err = d.client.GetOSSToken(); err != nil { // 到时重新获取ossToken
							errCh <- errors.Wrap(err, "刷新token时出现错误")
						}
					default:
					}
					buf := make([]byte, chunk.Size)
					if _, err = tmpF.ReadAt(buf, chunk.Offset); err != nil && !errors.Is(err, io.EOF) {
						continue
					}
					if part, err = bucket.UploadPart(imur, driver.NewLimitedUploadStream(ctx, bytes.NewReader(buf)),
						chunk.Size, chunk.Number, driver115.OssOption(params, ossToken)...); err == nil {
						break
					}
				}
				if err != nil {
					errCh <- errors.Wrap(err, fmt.Sprintf("上传 %s 的第%d个分片时出现错误:%v", s.GetName(), chunk.Number, err))
				} else {
					num := completedNum.Add(1)
					up(float64(num) * 100.0 / float64(len(chunks)))
				}
				UploadedPartsCh <- part
			}
		}(i)
	}

	go func() {
		for part := range UploadedPartsCh {
			parts = append(parts, part)
			wg.Done()
		}
	}()
LOOP:
	for {
		select {
		case <-ticker.C:
			// 到时重新获取ossToken
			if ossToken, err = d.client.GetOSSToken(); err != nil {
				return nil, err
			}
		case <-quit:
			break LOOP
		case <-errCh:
			return nil, err
		case <-timeout.C:
			return nil, fmt.Errorf("time out")
		}
	}

	// 不知道啥原因,oss那边分片上传不计算sha1,导致115服务器校验错误
	// params.Callback.Callback = strings.ReplaceAll(params.Callback.Callback, "${sha1}", params.SHA1)
	if _, err := bucket.CompleteMultipartUpload(imur, parts, append(
		driver115.OssOption(params, ossToken),
		oss.CallbackResult(&bodyBytes),
	)...); err != nil {
		return nil, err
	}

	var uploadResult UploadResult
	if err = json.Unmarshal(bodyBytes, &uploadResult); err != nil {
		return nil, err
	}
	return &uploadResult, uploadResult.Err(string(bodyBytes))
}

func chunksProducer(ch chan oss.FileChunk, chunks []oss.FileChunk) {
	for _, chunk := range chunks {
		ch <- chunk
	}
}

func SplitFile(fileSize int64) (chunks []oss.FileChunk, err error) {
	for i := int64(1); i < 10; i++ {
		if fileSize < i*utils.GB { // 文件大小小于iGB时分为i*1000片
			if chunks, err = SplitFileByPartNum(fileSize, int(i*1000)); err != nil {
				return
			}
			break
		}
	}
	if fileSize > 9*utils.GB { // 文件大小大于9GB时分为10000片
		if chunks, err = SplitFileByPartNum(fileSize, 10000); err != nil {
			return
		}
	}
	// 单个分片大小不能小于100KB
	if chunks[0].Size < 100*utils.KB {
		if chunks, err = SplitFileByPartSize(fileSize, 100*utils.KB); err != nil {
			return
		}
	}
	return
}

// SplitFileByPartNum splits big file into parts by the num of parts.
// Split the file with specified parts count, returns the split result when error is nil.
func SplitFileByPartNum(fileSize int64, chunkNum int) ([]oss.FileChunk, error) {
	if chunkNum <= 0 || chunkNum > 10000 {
		return nil, errors.New("chunkNum invalid")
	}

	if int64(chunkNum) > fileSize {
		return nil, errors.New("oss: chunkNum invalid")
	}

	var chunks []oss.FileChunk
	chunk := oss.FileChunk{}
	chunkN := (int64)(chunkNum)
	for i := int64(0); i < chunkN; i++ {
		chunk.Number = int(i + 1)
		chunk.Offset = i * (fileSize / chunkN)
		if i == chunkN-1 {
			chunk.Size = fileSize/chunkN + fileSize%chunkN
		} else {
			chunk.Size = fileSize / chunkN
		}
		chunks = append(chunks, chunk)
	}

	return chunks, nil
}

// SplitFileByPartSize splits big file into parts by the size of parts.
// Splits the file by the part size. Returns the FileChunk when error is nil.
func SplitFileByPartSize(fileSize int64, chunkSize int64) ([]oss.FileChunk, error) {
	if chunkSize <= 0 {
		return nil, errors.New("chunkSize invalid")
	}

	chunkN := fileSize / chunkSize
	if chunkN >= 10000 {
		return nil, errors.New("Too many parts, please increase part size")
	}

	var chunks []oss.FileChunk
	chunk := oss.FileChunk{}
	for i := int64(0); i < chunkN; i++ {
		chunk.Number = int(i + 1)
		chunk.Offset = i * chunkSize
		chunk.Size = chunkSize
		chunks = append(chunks, chunk)
	}

	if fileSize%chunkSize > 0 {
		chunk.Number = len(chunks) + 1
		chunk.Offset = int64(len(chunks)) * chunkSize
		chunk.Size = fileSize % chunkSize
		chunks = append(chunks, chunk)
	}

	return chunks, nil
}


================================================
FILE: drivers/115_open/driver.go
================================================
package _115_open

import (
	"context"
	"fmt"
	"io"
	"net/http"
	"strconv"
	"strings"
	"time"

	"github.com/alist-org/alist/v3/cmd/flags"
	"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/internal/op"
	"github.com/alist-org/alist/v3/pkg/utils"
	sdk "github.com/xhofe/115-sdk-go"
	"golang.org/x/time/rate"
)

type Open115 struct {
	model.Storage
	Addition
	client  *sdk.Client
	limiter *rate.Limiter
}

func (d *Open115) Config() driver.Config {
	return config
}

func (d *Open115) GetAddition() driver.Additional {
	return &d.Addition
}

func (d *Open115) Init(ctx context.Context) error {
	d.client = sdk.New(sdk.WithRefreshToken(d.Addition.RefreshToken),
		sdk.WithAccessToken(d.Addition.AccessToken),
		sdk.WithOnRefreshToken(func(s1, s2 string) {
			d.Addition.AccessToken = s1
			d.Addition.RefreshToken = s2
			op.MustSaveDriverStorage(d)
		}))
	if flags.Debug || flags.Dev {
		d.client.SetDebug(true)
	}
	_, err := d.client.UserInfo(ctx)
	if err != nil {
		return err
	}
	if d.Addition.LimitRate > 0 {
		d.limiter = rate.NewLimiter(rate.Limit(d.Addition.LimitRate), 1)
	}
	return nil
}

func (d *Open115) WaitLimit(ctx context.Context) error {
	if d.limiter != nil {
		return d.limiter.Wait(ctx)
	}
	return nil
}

func (d *Open115) Drop(ctx context.Context) error {
	return nil
}

func (d *Open115) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
	var res []model.Obj
	pageSize := int64(200)
	offset := int64(0)
	for {
		if err := d.WaitLimit(ctx); err != nil {
			return nil, err
		}
		resp, err := d.client.GetFiles(ctx, &sdk.GetFilesReq{
			CID:    dir.GetID(),
			Limit:  pageSize,
			Offset: offset,
			ASC:    d.Addition.OrderDirection == "asc",
			O:      d.Addition.OrderBy,
			// Cur:     1,
			ShowDir: true,
		})
		if err != nil {
			return nil, err
		}
		res = append(res, utils.MustSliceConvert(resp.Data, func(src sdk.GetFilesResp_File) model.Obj {
			obj := Obj(src)
			return &obj
		})...)
		if len(res) >= int(resp.Count) {
			break
		}
		offset += pageSize
	}
	return res, nil
}

func (d *Open115) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
	if err := d.WaitLimit(ctx); err != nil {
		return nil, err
	}
	var ua string
	if args.Header != nil {
		ua = args.Header.Get("User-Agent")
	}
	if ua == "" {
		ua = base.UserAgent
	}
	obj, ok := file.(*Obj)
	if !ok {
		return nil, fmt.Errorf("can't convert obj")
	}
	pc := obj.Pc
	resp, err := d.client.DownURL(ctx, pc, ua)
	if err != nil {
		return nil, err
	}
	u, ok := resp[obj.GetID()]
	if !ok {
		return nil, fmt.Errorf("can't get link")
	}
	return &model.Link{
		URL: u.URL.URL,
		Header: http.Header{
			"User-Agent": []string{ua},
		},
	}, nil
}

func (d *Open115) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) (model.Obj, error) {
	if err := d.WaitLimit(ctx); err != nil {
		return nil, err
	}
	resp, err := d.client.Mkdir(ctx, parentDir.GetID(), dirName)
	if err != nil {
		return nil, err
	}
	return &Obj{
		Fid:  resp.FileID,
		Pid:  parentDir.GetID(),
		Fn:   dirName,
		Fc:   "0",
		Upt:  time.Now().Unix(),
		Uet:  time.Now().Unix(),
		UpPt: time.Now().Unix(),
	}, nil
}

func (d *Open115) Move(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) {
	if err := d.WaitLimit(ctx); err != nil {
		return nil, err
	}
	_, err := d.client.Move(ctx, &sdk.MoveReq{
		FileIDs: srcObj.GetID(),
		ToCid:   dstDir.GetID(),
	})
	if err != nil {
		return nil, err
	}
	return srcObj, nil
}

func (d *Open115) Rename(ctx context.Context, srcObj model.Obj, newName string) (model.Obj, error) {
	if err := d.WaitLimit(ctx); err != nil {
		return nil, err
	}
	_, err := d.client.UpdateFile(ctx, &sdk.UpdateFileReq{
		FileID:  srcObj.GetID(),
		FileNma: newName,
	})
	if err != nil {
		return nil, err
	}
	obj, ok := srcObj.(*Obj)
	if ok {
		obj.Fn = newName
	}
	return srcObj, nil
}

func (d *Open115) Copy(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) {
	if err := d.WaitLimit(ctx); err != nil {
		return nil, err
	}
	_, err := d.client.Copy(ctx, &sdk.CopyReq{
		PID:     dstDir.GetID(),
		FileID:  srcObj.GetID(),
		NoDupli: "1",
	})
	if err != nil {
		return nil, err
	}
	return srcObj, nil
}

func (d *Open115) Remove(ctx context.Context, obj model.Obj) error {
	if err := d.WaitLimit(ctx); err != nil {
		return err
	}
	_obj, ok := obj.(*Obj)
	if !ok {
		return fmt.Errorf("can't convert obj")
	}
	_, err := d.client.DelFile(ctx, &sdk.DelFileReq{
		FileIDs:  _obj.GetID(),
		ParentID: _obj.Pid,
	})
	if err != nil {
		return err
	}
	return nil
}

func (d *Open115) Put(ctx context.Context, dstDir model.Obj, file model.FileStreamer, up driver.UpdateProgress) error {
	if err := d.WaitLimit(ctx); err != nil {
		return err
	}
	tempF, err := file.CacheFullInTempFile()
	if err != nil {
		return err
	}
	// cal full sha1
	sha1, err := utils.HashReader(utils.SHA1, tempF)
	if err != nil {
		return err
	}
	_, err = tempF.Seek(0, io.SeekStart)
	if err != nil {
		return err
	}
	// pre 128k sha1
	sha1128k, err := utils.HashReader(utils.SHA1, io.LimitReader(tempF, 128*1024))
	if err != nil {
		return err
	}
	_, err = tempF.Seek(0, io.SeekStart)
	if err != nil {
		return err
	}
	// 1. Init
	resp, err := d.client.UploadInit(ctx, &sdk.UploadInitReq{
		FileName: file.GetName(),
		FileSize: file.GetSize(),
		Target:   dstDir.GetID(),
		FileID:   strings.ToUpper(sha1),
		PreID:    strings.ToUpper(sha1128k),
	})
	if err != nil {
		return err
	}
	if resp.Status == 2 {
		return nil
	}
	// 2. two way verify
	if utils.SliceContains([]int{6, 7, 8}, resp.Status) {
		signCheck := strings.Split(resp.SignCheck, "-") //"sign_check": "2392148-2392298" 取2392148-2392298之间的内容(包含2392148、2392298)的sha1
		start, err := strconv.ParseInt(signCheck[0], 10, 64)
		if err != nil {
			return err
		}
		end, err := strconv.ParseInt(signCheck[1], 10, 64)
		if err != nil {
			return err
		}
		_, err = tempF.Seek(start, io.SeekStart)
		if err != nil {
			return err
		}
		signVal, err := utils.HashReader(utils.SHA1, io.LimitReader(tempF, end-start+1))
		if err != nil {
			return err
		}
		_, err = tempF.Seek(0, io.SeekStart)
		if err != nil {
			return err
		}
		resp, err = d.client.UploadInit(ctx, &sdk.UploadInitReq{
			FileName: file.GetName(),
			FileSize: file.GetSize(),
			Target:   dstDir.GetID(),
			FileID:   strings.ToUpper(sha1),
			PreID:    strings.ToUpper(sha1128k),
			SignKey:  resp.SignKey,
			SignVal:  strings.ToUpper(signVal),
		})
		if err != nil {
			return err
		}
		if resp.Status == 2 {
			return nil
		}
	}
	// 3. get upload token
	tokenResp, err := d.client.UploadGetToken(ctx)
	if err != nil {
		return err
	}
	// 4. upload
	err = d.multpartUpload(ctx, tempF, file, up, tokenResp, resp)
	if err != nil {
		return err
	}
	return nil
}

// func (d *Open115) GetArchiveMeta(ctx context.Context, obj model.Obj, args model.ArchiveArgs) (model.ArchiveMeta, error) {
// 	// TODO get archive file meta-info, return errs.NotImplement to use an internal archive tool, optional
// 	return nil, errs.NotImplement
// }

// func (d *Open115) ListArchive(ctx context.Context, obj model.Obj, args model.ArchiveInnerArgs) ([]model.Obj, error) {
// 	// TODO list args.InnerPath in the archive obj, return errs.NotImplement to use an internal archive tool, optional
// 	return nil, errs.NotImplement
// }

// func (d *Open115) Extract(ctx context.Context, obj model.Obj, args model.ArchiveInnerArgs) (*model.Link, error) {
// 	// TODO return link of file args.InnerPath in the archive obj, return errs.NotImplement to use an internal archive tool, optional
// 	return nil, errs.NotImplement
// }

// func (d *Open115) ArchiveDecompress(ctx context.Context, srcObj, dstDir model.Obj, args model.ArchiveDecompressArgs) ([]model.Obj, error) {
// 	// TODO extract args.InnerPath path in the archive srcObj to the dstDir location, optional
// 	// a folder with the same name as the archive file needs to be created to store the extracted results if args.PutIntoNewDir
// 	// return errs.NotImplement to use an internal archive tool
// 	return nil, errs.NotImplement
// }

//func (d *Template) Other(ctx context.Context, args model.OtherArgs) (interface{}, error) {
//	return nil, errs.NotSupport
//}

var _ driver.Driver = (*Open115)(nil)


================================================
FILE: drivers/115_open/meta.go
================================================
package _115_open

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.RootID
	// define other
	RefreshToken   string  `json:"refresh_token" required:"true"`
	OrderBy        string  `json:"order_by" type:"select" options:"file_name,file_size,user_utime,file_type"`
	OrderDirection string  `json:"order_direction" type:"select" options:"asc,desc"`
	LimitRate      float64 `json:"limit_rate" type:"float" default:"1" help:"limit all api request rate ([limit]r/1s)"`
	AccessToken    string
}

var config = driver.Config{
	Name:              "115 Open",
	LocalSort:         false,
	OnlyLocal:         false,
	OnlyProxy:         false,
	NoCache:           false,
	NoUpload:          false,
	NeedMs:            false,
	DefaultRoot:       "0",
	CheckStatus:       false,
	Alert:             "",
	NoOverwriteUpload: false,
}

func init() {
	op.RegisterDriver(func() driver.Driver {
		return &Open115{}
	})
}


================================================
FILE: drivers/115_open/types.go
================================================
package _115_open

import (
	"time"

	"github.com/alist-org/alist/v3/internal/model"
	"github.com/alist-org/alist/v3/pkg/utils"
	sdk "github.com/xhofe/115-sdk-go"
)

type Obj sdk.GetFilesResp_File

// Thumb implements model.Thumb.
func (o *Obj) Thumb() string {
	return o.Thumbnail
}

// CreateTime implements model.Obj.
func (o *Obj) CreateTime() time.Time {
	return time.Unix(o.UpPt, 0)
}

// GetHash implements model.Obj.
func (o *Obj) GetHash() utils.HashInfo {
	return utils.NewHashInfo(utils.SHA1, o.Sha1)
}

// GetID implements model.Obj.
func (o *Obj) GetID() string {
	return o.Fid
}

// GetName implements model.Obj.
func (o *Obj) GetName() string {
	return o.Fn
}

// GetPath implements model.Obj.
func (o *Obj) GetPath() string {
	return ""
}

// GetSize implements model.Obj.
func (o *Obj) GetSize() int64 {
	return o.FS
}

// IsDir implements model.Obj.
func (o *Obj) IsDir() bool {
	return o.Fc == "0"
}

// ModTime implements model.Obj.
func (o *Obj) ModTime() time.Time {
	return time.Unix(o.Upt, 0)
}

var _ model.Obj = (*Obj)(nil)
var _ model.Thumb = (*Obj)(nil)


================================================
FILE: drivers/115_open/upload.go
================================================
package _115_open

import (
	"context"
	"encoding/base64"
	"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"
	"github.com/aliyun/aliyun-oss-go-sdk/oss"
	"github.com/avast/retry-go"
	sdk "github.com/xhofe/115-sdk-go"
)

func calPartSize(fileSize int64) int64 {
	var partSize int64 = 20 * utils.MB
	if fileSize > partSize {
		if fileSize > 1*utils.TB { // file Size over 1TB
			partSize = 5 * utils.GB // file part size 5GB
		} else if fileSize > 768*utils.GB { // over 768GB
			partSize = 109951163 // ≈ 104.8576MB, split 1TB into 10,000 part
		} else if fileSize > 512*utils.GB { // over 512GB
			partSize = 82463373 // ≈ 78.6432MB
		} else if fileSize > 384*utils.GB { // over 384GB
			partSize = 54975582 // ≈ 52.4288MB
		} else if fileSize > 256*utils.GB { // over 256GB
			partSize = 41231687 // ≈ 39.3216MB
		} else if fileSize > 128*utils.GB { // over 128GB
			partSize = 27487791 // ≈ 26.2144MB
		}
	}
	return partSize
}

func (d *Open115) singleUpload(ctx context.Context, tempF model.File, tokenResp *sdk.UploadGetTokenResp, initResp *sdk.UploadInitResp) error {
	ossClient, err := oss.New(tokenResp.Endpoint, tokenResp.AccessKeyId, tokenResp.AccessKeySecret, oss.SecurityToken(tokenResp.SecurityToken))
	if err != nil {
		return err
	}
	bucket, err := ossClient.Bucket(initResp.Bucket)
	if err != nil {
		return err
	}

	err = bucket.PutObject(initResp.Object, tempF,
		oss.Callback(base64.StdEncoding.EncodeToString([]byte(initResp.Callback.Value.Callback))),
		oss.CallbackVar(base64.StdEncoding.EncodeToString([]byte(initResp.Callback.Value.CallbackVar))),
	)

	return err
}

// type CallbackResult struct {
// 	State   bool   `json:"state"`
// 	Code    int    `json:"code"`
// 	Message string `json:"message"`
// 	Data    struct {
// 		PickCode string `json:"pick_code"`
// 		FileName string `json:"file_name"`
// 		FileSize int64  `json:"file_size"`
// 		FileID   string `json:"file_id"`
// 		ThumbURL string `json:"thumb_url"`
// 		Sha1     string `json:"sha1"`
// 		Aid      int    `json:"aid"`
// 		Cid      string `json:"cid"`
// 	} `json:"data"`
// }

func (d *Open115) multpartUpload(ctx context.Context, tempF model.File, stream model.FileStreamer, up driver.UpdateProgress, tokenResp *sdk.UploadGetTokenResp, initResp *sdk.UploadInitResp) error {
	fileSize := stream.GetSize()
	chunkSize := calPartSize(fileSize)

	ossClient, err := oss.New(tokenResp.Endpoint, tokenResp.AccessKeyId, tokenResp.AccessKeySecret, oss.SecurityToken(tokenResp.SecurityToken))
	if err != nil {
		return err
	}
	bucket, err := ossClient.Bucket(initResp.Bucket)
	if err != nil {
		return err
	}

	imur, err := bucket.InitiateMultipartUpload(initResp.Object, oss.Sequential())
	if err != nil {
		return err
	}

	partNum := (stream.GetSize() + chunkSize - 1) / chunkSize
	parts := make([]oss.UploadPart, partNum)
	offset := int64(0)
	for i := int64(1); i <= partNum; i++ {
		if utils.IsCanceled(ctx) {
			return ctx.Err()
		}

		partSize := chunkSize
		if i == partNum {
			partSize = fileSize - (i-1)*chunkSize
		}
		rd := utils.NewMultiReadable(io.LimitReader(stream, partSize))
		err = retry.Do(func() error {
			_ = rd.Reset()
			rateLimitedRd := driver.NewLimitedUploadStream(ctx, rd)
			part, err := bucket.UploadPart(imur, rateLimitedRd, partSize, int(i))
			if err != nil {
				return err
			}
			parts[i-1] = part
			return nil
		},
			retry.Attempts(3),
			retry.DelayType(retry.BackOffDelay),
			retry.Delay(time.Second))
		if err != nil {
			return err
		}

		if i == partNum {
			offset = fileSize
		} else {
			offset += partSize
		}
		up(float64(offset) / float64(fileSize))
	}

	// callbackRespBytes := make([]byte, 1024)
	_, err = bucket.CompleteMultipartUpload(
		imur,
		parts,
		oss.Callback(base64.StdEncoding.EncodeToString([]byte(initResp.Callback.Value.Callback))),
		oss.CallbackVar(base64.StdEncoding.EncodeToString([]byte(initResp.Callback.Value.CallbackVar))),
		// oss.CallbackResult(&callbackRespBytes),
	)
	if err != nil {
		return err
	}

	return nil
}


================================================
FILE: drivers/115_open/util.go
================================================
package _115_open

// do others that not defined in Driver interface


================================================
FILE: drivers/115_share/driver.go
================================================
package _115_share

import (
	"context"

	driver115 "github.com/SheltonZhu/115driver/pkg/driver"
	"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"
	"golang.org/x/time/rate"
)

type Pan115Share struct {
	model.Storage
	Addition
	client  *driver115.Pan115Client
	limiter *rate.Limiter
}

func (d *Pan115Share) Config() driver.Config {
	return config
}

func (d *Pan115Share) GetAddition() driver.Additional {
	return &d.Addition
}

func (d *Pan115Share) Init(ctx context.Context) error {
	if d.LimitRate > 0 {
		d.limiter = rate.NewLimiter(rate.Limit(d.LimitRate), 1)
	}

	return d.login()
}

func (d *Pan115Share) WaitLimit(ctx context.Context) error {
	if d.limiter != nil {
		return d.limiter.Wait(ctx)
	}
	return nil
}

func (d *Pan115Share) Drop(ctx context.Context) error {
	return nil
}

func (d *Pan115Share) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
	if err := d.WaitLimit(ctx); err != nil {
		return nil, err
	}

	ua := base.UserAgent
	files := make([]shareFile, 0)
	fileResp, err := d.getShareSnapWithUA(ua, dir.GetID(), driver115.QueryLimit(int(d.PageSize)))
	if err != nil {
		return nil, err
	}
	files = append(files, fileResp.Data.List...)
	total := fileResp.Data.Count
	count := len(fileResp.Data.List)
	for total > count {
		fileResp, err := d.getShareSnapWithUA(ua, dir.GetID(), driver115.QueryLimit(int(d.PageSize)), driver115.QueryOffset(count))
		if err != nil {
			return nil, err
		}
		files = append(files, fileResp.Data.List...)
		count += len(fileResp.Data.List)
	}

	return utils.SliceConvert(files, transFunc)
}

func (d *Pan115Share) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
	if err := d.WaitLimit(ctx); err != nil {
		return nil, err
	}
	ua := ""
	if args.Header != nil {
		ua = args.Header.Get("User-Agent")
	}
	if ua == "" {
		ua = base.UserAgent
	}
	downloadInfo, err := d.downloadByShareCodeWithUA(ua, file.GetID())
	if err != nil {
		return nil, err
	}

	return &model.Link{URL: downloadInfo.URL.URL}, nil
}

func (d *Pan115Share) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
	return errs.NotSupport
}

func (d *Pan115Share) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
	return errs.NotSupport
}

func (d *Pan115Share) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
	return errs.NotSupport
}

func (d *Pan115Share) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
	return errs.NotSupport
}

func (d *Pan115Share) Remove(ctx context.Context, obj model.Obj) error {
	return errs.NotSupport
}

func (d *Pan115Share) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
	return errs.NotSupport
}

var _ driver.Driver = (*Pan115Share)(nil)


================================================
FILE: drivers/115_share/meta.go
================================================
package _115_share

import (
	"github.com/alist-org/alist/v3/internal/driver"
	"github.com/alist-org/alist/v3/internal/op"
)

type Addition struct {
	Cookie       string  `json:"cookie" type:"text" help:"one of QR code token and cookie required"`
	QRCodeToken  string  `json:"qrcode_token" type:"text" help:"one of QR code token and cookie required"`
	QRCodeSource string  `json:"qrcode_source" type:"select" options:"web,android,ios,tv,alipaymini,wechatmini,qandroid" default:"linux" help:"select the QR code device, default linux"`
	PageSize     int64   `json:"page_size" type:"number" default:"1000" help:"list api per page size of 115 driver"`
	LimitRate    float64 `json:"limit_rate" type:"float" default:"2" help:"limit all api request rate (1r/[limit_rate]s)"`
	ShareCode    string  `json:"share_code" type:"text" required:"true" help:"share code of 115 share link"`
	ReceiveCode  string  `json:"receive_code" type:"text" required:"true" help:"receive code of 115 share link"`
	driver.RootID
}

var config = driver.Config{
	Name:        "115 Share",
	DefaultRoot: "0",
	// OnlyProxy:   true,
	// OnlyLocal:         true,
	CheckStatus:       false,
	Alert:             "",
	NoOverwriteUpload: true,
	NoUpload:          true,
}

func init() {
	op.RegisterDriver(func() driver.Driver {
		return &Pan115Share{}
	})
}


================================================
FILE: drivers/115_share/utils.go
================================================
package _115_share

import (
	"fmt"
	"strconv"
	"time"

	driver115 "github.com/SheltonZhu/115driver/pkg/driver"
	"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/pkg/errors"
)

var _ model.Obj = (*FileObj)(nil)

type FileObj struct {
	Size     int64
	Sha1     string
	Utm      time.Time
	FileName string
	isDir    bool
	FileID   string
	ThumbURL string
}

func (f *FileObj) CreateTime() time.Time {
	return f.Utm
}

func (f *FileObj) GetHash() utils.HashInfo {
	return utils.NewHashInfo(utils.SHA1, f.Sha1)
}

func (f *FileObj) GetSize() int64 {
	return f.Size
}

func (f *FileObj) GetName() string {
	return f.FileName
}

func (f *FileObj) ModTime() time.Time {
	return f.Utm
}

func (f *FileObj) IsDir() bool {
	return f.isDir
}

func (f *FileObj) GetID() string {
	return f.FileID
}

func (f *FileObj) GetPath() string {
	return ""
}

func (f *FileObj) Thumb() string {
	return f.ThumbURL
}

type shareFile struct {
	FileID     string                 `json:"fid"`
	UID        int                    `json:"uid"`
	CategoryID driver115.IntString    `json:"cid"`
	FileName   string                 `json:"n"`
	Type       string                 `json:"ico"`
	Sha1       string                 `json:"sha"`
	Size       driver115.StringInt64  `json:"s"`
	Labels     []*driver115.LabelInfo `json:"fl"`
	UpdateTime string                 `json:"t"`
	IsFile     int                    `json:"fc"`
	ParentID   string                 `json:"pid"`
	ThumbURL   string                 `json:"u"`
}

type shareSnapResp struct {
	driver115.BasicResp
	Data struct {
		Count int         `json:"count"`
		List  []shareFile `json:"list"`
	} `json:"data"`
}

type downloadShareResp struct {
	driver115.BasicResp
	Data driver115.SharedDownloadInfo `json:"data"`
}

func transFunc(sf shareFile) (model.Obj, error) {
	timeInt, err := strconv.ParseInt(sf.UpdateTime, 10, 64)
	if err != nil {
		return nil, err
	}
	var (
		utm    = time.Unix(timeInt, 0)
		isDir  = (sf.IsFile == 0)
		fileID = string(sf.FileID)
	)
	if isDir {
		fileID = string(sf.CategoryID)
	}
	return &FileObj{
		Size:     int64(sf.Size),
		Sha1:     sf.Sha1,
		Utm:      utm,
		FileName: string(sf.FileName),
		isDir:    isDir,
		FileID:   fileID,
		ThumbURL: sf.ThumbURL,
	}, nil
}

func buildShareReferer(shareCode, receiveCode string) string {
	return fmt.Sprintf("https://115cdn.com/s/%s?password=%s&", shareCode, receiveCode)
}

func (d *Pan115Share) getShareSnapWithUA(ua, dirID string, queries ...driver115.Query) (*shareSnapResp, error) {
	result := shareSnapResp{}
	query := map[string]string{
		"share_code":   d.ShareCode,
		"receive_code": d.ReceiveCode,
		"cid":          dirID,
		"limit":        "20",
		"asc":          "0",
		"offset":       "0",
		"format":       "json",
	}
	for _, q := range queries {
		q(&query)
	}

	req := d.client.NewRequest().
		SetQueryParams(query).
		SetHeader("referer", buildShareReferer(d.ShareCode, d.ReceiveCode)).
		ForceContentType("application/json;charset=UTF-8").
		SetResult(&result)
	if ua != "" {
		req = req.SetHeader("User-Agent", ua)
	}

	resp, err := req.Get(driver115.ApiShareSnap)
	if err := driver115.CheckErr(err, &result, resp); err != nil {
		return nil, err
	}
	return &result, nil
}

func (d *Pan115Share) downloadByShareCodeWithUA(ua, fileID string) (*driver115.SharedDownloadInfo, error) {
	result := downloadShareResp{}
	params := map[string]string{
		"share_code":   d.ShareCode,
		"receive_code": d.ReceiveCode,
		"file_id":      fileID,
		"dl":           "1",
	}

	req := d.client.NewRequest().
		SetQueryParams(params).
		ForceContentType("application/json").
		SetHeader("referer", buildShareReferer(d.ShareCode, d.ReceiveCode)).
		SetResult(&result)
	if ua != "" {
		req = req.SetHeader("User-Agent", ua)
	}

	resp, err := req.Get(driver115.ApiDownloadGetShareUrl)
	if err := driver115.CheckErr(err, &result, resp); err != nil {
		return nil, err
	}
	return &result.Data, nil
}

func (d *Pan115Share) login() error {
	var err error
	opts := []driver115.Option{
		driver115.UA(base.UserAgent),
	}
	d.client = driver115.New(opts...)
	if _, err = d.getShareSnapWithUA(base.UserAgent, ""); err != nil {
		return errors.Wrap(err, "failed to get share snap")
	}
	cr := &driver115.Credential{}
	if d.QRCodeToken != "" {
		s := &driver115.QRCodeSession{
			UID: d.QRCodeToken,
		}
		if cr, err = d.client.QRCodeLoginWithApp(s, driver115.LoginApp(d.QRCodeSource)); err != nil {
			return errors.Wrap(err, "failed to login by qrcode")
		}
		d.Cookie = fmt.Sprintf("UID=%s;CID=%s;SEID=%s;KID=%s", cr.UID, cr.CID, cr.SEID, cr.KID)
		d.QRCodeToken = ""
	} else if d.Cookie != "" {
		if err = cr.FromCookie(d.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()
}


================================================
FILE: drivers/123/driver.go
================================================
package _123

import (
	"context"
	"encoding/base64"
	"fmt"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"sync"
	"time"

	"golang.org/x/time/rate"

	"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/stream"
	"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"
	log "github.com/sirupsen/logrus"
)

type Pan123 struct {
	model.Storage
	Addition
	apiRateLimit    sync.Map
	safeBoxUnlocked sync.Map
}

func (d *Pan123) Config() driver.Config {
	return config
}

func (d *Pan123) GetAddition() driver.Additional {
	return &d.Addition
}

func (d *Pan123) Init(ctx context.Context) error {
	_, err := d.Request(UserInfo, http.MethodGet, nil, nil)
	return err
}

func (d *Pan123) Drop(ctx context.Context) error {
	_, _ = d.Request(Logout, http.MethodPost, func(req *resty.Request) {
		req.SetBody(base.Json{})
	}, nil)
	return nil
}

func (d *Pan123) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
	if f, ok := dir.(File); ok && f.IsLock {
		if err := d.unlockSafeBox(f.FileId); err != nil {
			return nil, err
		}
	}
	files, err := d.getFiles(ctx, dir.GetID(), dir.GetName())
	if err != nil {
		msg := strings.ToLower(err.Error())
		if strings.Contains(msg, "safe box") || strings.Contains(err.Error(), "保险箱") {
			if id, e := strconv.ParseInt(dir.GetID(), 10, 64); e == nil {
				if e = d.unlockSafeBox(id); e == nil {
					files, err = d.getFiles(ctx, dir.GetID(), dir.GetName())
				} else {
					return nil, e
				}
			}
		}
		if err != nil {
			return nil, err
		}
	}
	return utils.SliceConvert(files, func(src File) (model.Obj, error) {
		return src, nil
	})
}

func (d *Pan123) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
	if f, ok := file.(File); ok {
		//var resp DownResp
		var headers map[string]string
		if !utils.IsLocalIPAddr(args.IP) {
			headers = map[string]string{
				//"X-Real-IP":       "1.1.1.1",
				"X-Forwarded-For": args.IP,
			}
		}
		data := base.Json{
			"driveId":   0,
			"etag":      f.Etag,
			"fileId":    f.FileId,
			"fileName":  f.FileName,
			"s3keyFlag": f.S3KeyFlag,
			"size":      f.Size,
			"type":      f.Type,
		}
		resp, err := d.Request(DownloadInfo, http.MethodPost, func(req *resty.Request) {

			req.SetBody(data).SetHeaders(headers)
		}, nil)
		if err != nil {
			return nil, err
		}
		downloadUrl := utils.Json.Get(resp, "data", "DownloadUrl").ToString()
		u, err := url.Parse(downloadUrl)
		if err != nil {
			return nil, err
		}
		nu := u.Query().Get("params")
		if nu != "" {
			du, _ := base64.StdEncoding.DecodeString(nu)
			u, err = url.Parse(string(du))
			if err != nil {
				return nil, err
			}
		}
		u_ := u.String()
		log.Debug("download url: ", u_)
		res, err := base.NoRedirectClient.R().SetHeader("Referer", "https://www.123pan.com/").Get(u_)
		if err != nil {
			return nil, err
		}
		log.Debug(res.String())
		link := model.Link{
			URL: u_,
		}
		log.Debugln("res code: ", res.StatusCode())
		if res.StatusCode() == 302 {
			link.URL = res.Header().Get("location")
		} else if res.StatusCode() < 300 {
			link.URL = utils.Json.Get(res.Body(), "data", "redirect_url").ToString()
		}
		link.Header = http.Header{
			"Referer": []string{"https://www.123pan.com/"},
		}
		return &link, nil
	} else {
		return nil, fmt.Errorf("can't convert obj")
	}
}

func (d *Pan123) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
	dat
Download .txt
gitextract_zld5nmnw/

├── .air.toml
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.yml
│   │   ├── config.yml
│   │   └── feature_request.yml
│   ├── config.yml
│   ├── stale.yml
│   └── workflows/
│       ├── auto_lang.yml
│       ├── beta_release.yml
│       ├── build.yml
│       ├── changelog.yml
│       ├── issue_close_question.yml
│       ├── issue_close_stale.yml
│       ├── issue_duplicate.yml
│       ├── issue_invalid.yml
│       ├── issue_on_close.yml
│       ├── issue_question.yml
│       ├── issue_similarity.yml
│       ├── issue_translate.yml
│       ├── issue_wontfix.yml
│       ├── release.yml
│       ├── release_android.yml
│       ├── release_docker.yml
│       ├── release_freebsd.yml
│       ├── release_linux_musl.yml
│       └── release_linux_musl_arm.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── Dockerfile.ci
├── LICENSE
├── README.md
├── README_cn.md
├── README_ja.md
├── build.sh
├── cmd/
│   ├── admin.go
│   ├── cancel2FA.go
│   ├── common.go
│   ├── flags/
│   │   └── config.go
│   ├── kill.go
│   ├── lang.go
│   ├── restart.go
│   ├── root.go
│   ├── server.go
│   ├── start.go
│   ├── stop_default.go
│   ├── stop_windows.go
│   ├── storage.go
│   ├── user.go
│   └── version.go
├── docker-compose.yml
├── drivers/
│   ├── 115/
│   │   ├── appver.go
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── 115_open/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   ├── upload.go
│   │   └── util.go
│   ├── 115_share/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   └── utils.go
│   ├── 123/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   ├── upload.go
│   │   └── util.go
│   ├── 123_link/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── parse.go
│   │   ├── types.go
│   │   └── util.go
│   ├── 123_open/
│   │   ├── api.go
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── sign.go
│   │   ├── token.go
│   │   ├── types.go
│   │   ├── upload.go
│   │   └── util.go
│   ├── 123_share/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── 139/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── 189/
│   │   ├── driver.go
│   │   ├── help.go
│   │   ├── login.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── 189pc/
│   │   ├── driver.go
│   │   ├── help.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── utils.go
│   ├── alias/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── alist_v2/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── alist_v3/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── aliyundrive/
│   │   ├── driver.go
│   │   ├── global.go
│   │   ├── help.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── aliyundrive_open/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   ├── upload.go
│   │   └── util.go
│   ├── aliyundrive_share/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── all.go
│   ├── azure_blob/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── baidu_netdisk/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── baidu_photo/
│   │   ├── driver.go
│   │   ├── help.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── utils.go
│   ├── baidu_share/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── base/
│   │   ├── client.go
│   │   ├── types.go
│   │   ├── upload.go
│   │   └── util.go
│   ├── bitqiu/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── chaoxing/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── cloudreve/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── cloudreve_v4/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── crypt/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── doubao/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── doubao_new/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── doubao_share/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── dropbox/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── febbox/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── oauth2.go
│   │   ├── types.go
│   │   └── util.go
│   ├── ftp/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── ftps/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── gitee/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── github/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── github_releases/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── models.go
│   │   ├── types.go
│   │   └── util.go
│   ├── gofile/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── google_drive/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── google_photo/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── halalcloud/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── options.go
│   │   ├── types.go
│   │   └── util.go
│   ├── ilanzou/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── ipfs_api/
│   │   ├── driver.go
│   │   └── meta.go
│   ├── kodbox/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── lanzou/
│   │   ├── driver.go
│   │   ├── help.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── lark/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── lark.go
│   ├── lenovonas_share/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── local/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── token_bucket.go
│   │   └── util.go
│   ├── mediafire/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── mediatrack/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── mega/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── misskey/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── mopan/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── netease_music/
│   │   ├── crypto.go
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   ├── upload.go
│   │   └── util.go
│   ├── onedrive/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── onedrive_app/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── onedrive_sharelink/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── pcloud/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── pikpak/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── pikpak_share/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── proton_drive/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── quark_uc/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── quark_uc_tv/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── quqi/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── s3/
│   │   ├── doge.go
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── other.go
│   │   ├── types.go
│   │   └── util.go
│   ├── seafile/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── sftp/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── smb/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── streamtape/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── strm/
│   │   ├── driver.go
│   │   ├── hook.go
│   │   ├── meta.go
│   │   └── util.go
│   ├── teambition/
│   │   ├── driver.go
│   │   ├── help.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── template/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── terabox/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── thunder/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── thunder_browser/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── thunderx/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── trainbit/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── url_tree/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   ├── urls_test.go
│   │   └── util.go
│   ├── uss/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── virtual/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   └── util.go
│   ├── vtencent/
│   │   ├── drive.go
│   │   ├── meta.go
│   │   ├── signature.go
│   │   ├── types.go
│   │   └── util.go
│   ├── webdav/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── odrvcookie/
│   │   │   ├── cookie.go
│   │   │   └── fetch.go
│   │   ├── types.go
│   │   └── util.go
│   ├── weiyun/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   └── types.go
│   ├── wopan/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   ├── types.go
│   │   └── util.go
│   ├── wukong/
│   │   ├── driver.go
│   │   ├── meta.go
│   │   └── types.go
│   └── yandex_disk/
│       ├── driver.go
│       ├── meta.go
│       ├── types.go
│       └── util.go
├── entrypoint.sh
├── go.mod
├── go.sum
├── internal/
│   ├── archive/
│   │   ├── all.go
│   │   ├── archives/
│   │   │   ├── archives.go
│   │   │   └── utils.go
│   │   ├── iso9660/
│   │   │   ├── iso9660.go
│   │   │   └── utils.go
│   │   ├── rardecode/
│   │   │   ├── rardecode.go
│   │   │   └── utils.go
│   │   ├── sevenzip/
│   │   │   ├── sevenzip.go
│   │   │   └── utils.go
│   │   ├── tool/
│   │   │   ├── base.go
│   │   │   ├── helper.go
│   │   │   ├── securepath.go
│   │   │   ├── securepath_test.go
│   │   │   └── utils.go
│   │   └── zip/
│   │       ├── utils.go
│   │       └── zip.go
│   ├── authn/
│   │   └── authn.go
│   ├── bootstrap/
│   │   ├── config.go
│   │   ├── data/
│   │   │   ├── data.go
│   │   │   ├── dev.go
│   │   │   ├── role.go
│   │   │   ├── setting.go
│   │   │   ├── task.go
│   │   │   └── user.go
│   │   ├── db.go
│   │   ├── index.go
│   │   ├── log.go
│   │   ├── offline_download.go
│   │   ├── patch/
│   │   │   ├── all.go
│   │   │   ├── v3_24_0/
│   │   │   │   └── hash_password.go
│   │   │   ├── v3_32_0/
│   │   │   │   └── update_authn.go
│   │   │   ├── v3_41_0/
│   │   │   │   └── grant_permission.go
│   │   │   └── v3_46_0/
│   │   │       └── convert_role.go
│   │   ├── patch.go
│   │   ├── storage.go
│   │   ├── stream_limit.go
│   │   └── task.go
│   ├── conf/
│   │   ├── config.go
│   │   ├── const.go
│   │   └── var.go
│   ├── db/
│   │   ├── db.go
│   │   ├── label.go
│   │   ├── label_file_binding.go
│   │   ├── meta.go
│   │   ├── obj_file.go
│   │   ├── role.go
│   │   ├── searchnode.go
│   │   ├── session.go
│   │   ├── settingitem.go
│   │   ├── sshkey.go
│   │   ├── storage.go
│   │   ├── tasks.go
│   │   ├── user.go
│   │   └── util.go
│   ├── device/
│   │   └── session.go
│   ├── driver/
│   │   ├── config.go
│   │   ├── driver.go
│   │   ├── item.go
│   │   └── utils.go
│   ├── errs/
│   │   ├── device.go
│   │   ├── driver.go
│   │   ├── errors.go
│   │   ├── errors_test.go
│   │   ├── object.go
│   │   ├── operate.go
│   │   ├── role.go
│   │   ├── search.go
│   │   └── user.go
│   ├── fs/
│   │   ├── archive.go
│   │   ├── copy.go
│   │   ├── fs.go
│   │   ├── get.go
│   │   ├── link.go
│   │   ├── list.go
│   │   ├── other.go
│   │   ├── put.go
│   │   ├── s3_transition.go
│   │   └── walk.go
│   ├── fuse/
│   │   ├── fs.go
│   │   └── mount.go
│   ├── message/
│   │   ├── http.go
│   │   ├── message.go
│   │   └── ws.go
│   ├── model/
│   │   ├── archive.go
│   │   ├── args.go
│   │   ├── file.go
│   │   ├── label.go
│   │   ├── label_file_binding.go
│   │   ├── meta.go
│   │   ├── obj.go
│   │   ├── obj_file.go
│   │   ├── object.go
│   │   ├── paths.go
│   │   ├── req.go
│   │   ├── role.go
│   │   ├── roles.go
│   │   ├── search.go
│   │   ├── session.go
│   │   ├── setting.go
│   │   ├── sshkey.go
│   │   ├── storage.go
│   │   ├── task.go
│   │   └── user.go
│   ├── net/
│   │   ├── request.go
│   │   ├── request_test.go
│   │   ├── serve.go
│   │   └── util.go
│   ├── offline_download/
│   │   ├── 115/
│   │   │   └── client.go
│   │   ├── all.go
│   │   ├── aria2/
│   │   │   ├── aria2.go
│   │   │   └── notify.go
│   │   ├── http/
│   │   │   ├── client.go
│   │   │   └── util.go
│   │   ├── pikpak/
│   │   │   ├── pikpak.go
│   │   │   └── util.go
│   │   ├── qbit/
│   │   │   └── qbit.go
│   │   ├── thunder/
│   │   │   ├── thunder.go
│   │   │   └── util.go
│   │   ├── tool/
│   │   │   ├── add.go
│   │   │   ├── base.go
│   │   │   ├── download.go
│   │   │   ├── tools.go
│   │   │   └── transfer.go
│   │   └── transmission/
│   │       └── client.go
│   ├── op/
│   │   ├── archive.go
│   │   ├── const.go
│   │   ├── driver.go
│   │   ├── driver_test.go
│   │   ├── fs.go
│   │   ├── hook.go
│   │   ├── label.go
│   │   ├── label_file_binding.go
│   │   ├── meta.go
│   │   ├── path.go
│   │   ├── role.go
│   │   ├── setting.go
│   │   ├── sshkey.go
│   │   ├── storage.go
│   │   ├── storage_test.go
│   │   └── user.go
│   ├── search/
│   │   ├── bleve/
│   │   │   ├── init.go
│   │   │   └── search.go
│   │   ├── build.go
│   │   ├── db/
│   │   │   ├── init.go
│   │   │   └── search.go
│   │   ├── db_non_full_text/
│   │   │   ├── init.go
│   │   │   └── search.go
│   │   ├── import.go
│   │   ├── meilisearch/
│   │   │   ├── init.go
│   │   │   └── search.go
│   │   ├── search.go
│   │   ├── searcher/
│   │   │   ├── manage.go
│   │   │   └── searcher.go
│   │   └── util.go
│   ├── session/
│   │   └── session.go
│   ├── setting/
│   │   └── setting.go
│   ├── sign/
│   │   ├── archive.go
│   │   └── sign.go
│   ├── stream/
│   │   ├── limit.go
│   │   ├── stream.go
│   │   └── util.go
│   └── task/
│       ├── base.go
│       └── manager.go
├── main.go
├── pkg/
│   ├── aria2/
│   │   └── rpc/
│   │       ├── README.md
│   │       ├── call.go
│   │       ├── call_test.go
│   │       ├── client.go
│   │       ├── client_test.go
│   │       ├── const.go
│   │       ├── json2.go
│   │       ├── notification.go
│   │       ├── proc.go
│   │       ├── proto.go
│   │       └── resp.go
│   ├── chanio/
│   │   └── chanio.go
│   ├── cookie/
│   │   └── cookie.go
│   ├── cron/
│   │   ├── cron.go
│   │   └── cron_test.go
│   ├── errgroup/
│   │   └── errgroup.go
│   ├── generic/
│   │   └── queue.go
│   ├── generic_sync/
│   │   ├── map.go
│   │   └── map_test.go
│   ├── http_range/
│   │   └── range.go
│   ├── mq/
│   │   └── mq.go
│   ├── qbittorrent/
│   │   └── client.go
│   ├── sign/
│   │   ├── hmac.go
│   │   └── sign.go
│   ├── singleflight/
│   │   ├── signleflight_test.go
│   │   └── singleflight.go
│   ├── task/
│   │   ├── errors.go
│   │   ├── manager.go
│   │   ├── task.go
│   │   └── task_test.go
│   └── utils/
│       ├── balance.go
│       ├── bool.go
│       ├── ctx.go
│       ├── email.go
│       ├── file.go
│       ├── hash/
│       │   └── gcid.go
│       ├── hash.go
│       ├── hash_test.go
│       ├── io.go
│       ├── ip.go
│       ├── json.go
│       ├── log.go
│       ├── map.go
│       ├── mask.go
│       ├── oauth2.go
│       ├── path.go
│       ├── path_test.go
│       ├── random/
│       │   └── random.go
│       ├── slice.go
│       ├── str.go
│       ├── time.go
│       └── url.go
├── public/
│   └── public.go
├── server/
│   ├── common/
│   │   ├── auth.go
│   │   ├── base.go
│   │   ├── check.go
│   │   ├── check_test.go
│   │   ├── common.go
│   │   ├── hide_privacy_test.go
│   │   ├── proxy.go
│   │   ├── resp.go
│   │   ├── role_perm.go
│   │   └── sign.go
│   ├── debug.go
│   ├── ftp/
│   │   ├── afero.go
│   │   ├── fsmanage.go
│   │   ├── fsread.go
│   │   ├── fsup.go
│   │   └── site.go
│   ├── ftp.go
│   ├── handles/
│   │   ├── archive.go
│   │   ├── auth.go
│   │   ├── const.go
│   │   ├── down.go
│   │   ├── driver.go
│   │   ├── fsbatch.go
│   │   ├── fsmanage.go
│   │   ├── fsread.go
│   │   ├── fsup.go
│   │   ├── helper.go
│   │   ├── index.go
│   │   ├── label.go
│   │   ├── label_file_binding.go
│   │   ├── ldap_login.go
│   │   ├── meta.go
│   │   ├── offline_download.go
│   │   ├── role.go
│   │   ├── search.go
│   │   ├── session.go
│   │   ├── setting.go
│   │   ├── sshkey.go
│   │   ├── ssologin.go
│   │   ├── storage.go
│   │   ├── task.go
│   │   ├── user.go
│   │   └── webauthn.go
│   ├── middlewares/
│   │   ├── auth.go
│   │   ├── check.go
│   │   ├── down.go
│   │   ├── fsup.go
│   │   ├── https.go
│   │   ├── limit.go
│   │   ├── search.go
│   │   └── session_refresh.go
│   ├── router.go
│   ├── s3/
│   │   ├── backend.go
│   │   ├── ioutils.go
│   │   ├── list.go
│   │   ├── logger.go
│   │   ├── pager.go
│   │   ├── server.go
│   │   └── utils.go
│   ├── s3.go
│   ├── sftp/
│   │   ├── const.go
│   │   ├── hostkey.go
│   │   └── sftp.go
│   ├── sftp.go
│   ├── static/
│   │   ├── config.go
│   │   └── static.go
│   ├── webdav/
│   │   ├── buffered_response_writer.go
│   │   ├── file.go
│   │   ├── if.go
│   │   ├── internal/
│   │   │   └── xml/
│   │   │       ├── README
│   │   │       ├── atom_test.go
│   │   │       ├── example_test.go
│   │   │       ├── marshal.go
│   │   │       ├── marshal_test.go
│   │   │       ├── read.go
│   │   │       ├── read_test.go
│   │   │       ├── typeinfo.go
│   │   │       ├── xml.go
│   │   │       └── xml_test.go
│   │   ├── litmus_test_server.go
│   │   ├── lock.go
│   │   ├── lock_test.go
│   │   ├── path.go
│   │   ├── prop.go
│   │   ├── util.go
│   │   ├── webdav.go
│   │   ├── xml.go
│   │   └── xml_test.go
│   └── webdav.go
└── wrapper/
    ├── zcc-arm64
    └── zcxx-arm64
Download .txt
Showing preview only (528K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (6244 symbols across 649 files)

FILE: cmd/admin.go
  function setAdminPassword (line 67) | func setAdminPassword(pwd string) {
  function init (line 86) | func init() {

FILE: cmd/cancel2FA.go
  function init (line 34) | func init() {

FILE: cmd/common.go
  function Init (line 16) | func Init() {
  function Release (line 32) | func Release() {
  function initDaemon (line 39) | func initDaemon() {

FILE: cmd/kill.go
  function kill (line 18) | func kill() {
  function init (line 42) | func init() {

FILE: cmd/lang.go
  type KV (line 24) | type KV
  type Drivers (line 26) | type Drivers
  function firstUpper (line 28) | func firstUpper(s string) string {
  function convert (line 35) | func convert(s string) string {
  function writeFile (line 41) | func writeFile(name string, data interface{}) {
  function generateDriversJson (line 79) | func generateDriversJson() {
  function generateSettingsJson (line 115) | func generateSettingsJson() {
  function init (line 151) | func init() {

FILE: cmd/restart.go
  function init (line 20) | func init() {

FILE: cmd/root.go
  function Execute (line 22) | func Execute() {
  function init (line 29) | func init() {

FILE: cmd/server.go
  function init (line 225) | func init() {
  function OutAlistInit (line 240) | func OutAlistInit() {

FILE: cmd/start.go
  function start (line 25) | func start() {
  function init (line 59) | func init() {

FILE: cmd/stop_default.go
  function stop (line 22) | func stop() {
  function init (line 46) | func init() {

FILE: cmd/stop_windows.go
  function stop (line 18) | func stop() {
  function init (line 22) | func init() {

FILE: cmd/storage.go
  type model (line 54) | type model struct
    method Init (line 58) | func (m model) Init() tea.Cmd { return nil }
    method Update (line 60) | func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method View (line 83) | func (m model) View() string {
  function init (line 148) | func init() {

FILE: cmd/user.go
  function DelAdminCacheOnline (line 15) | func DelAdminCacheOnline() {
  function DelUserCacheOnline (line 24) | func DelUserCacheOnline(username string) {

FILE: cmd/version.go
  function init (line 33) | func init() {

FILE: drivers/115/appver.go
  method getAppVersion (line 14) | func (d *Pan115) getAppVersion() ([]driver115.AppVersion, error) {
  method getAppVer (line 26) | func (d *Pan115) getAppVer() string {
  method initAppVer (line 41) | func (d *Pan115) initAppVer() {

FILE: drivers/115/driver.go
  type Pan115 (line 17) | type Pan115 struct
    method Config (line 25) | func (d *Pan115) Config() driver.Config {
    method GetAddition (line 29) | func (d *Pan115) GetAddition() driver.Additional {
    method Init (line 33) | func (d *Pan115) Init(ctx context.Context) error {
    method WaitLimit (line 41) | func (d *Pan115) WaitLimit(ctx context.Context) error {
    method Drop (line 48) | func (d *Pan115) Drop(ctx context.Context) error {
    method List (line 52) | func (d *Pan115) List(ctx context.Context, dir model.Obj, args model.L...
    method Link (line 65) | func (d *Pan115) Link(ctx context.Context, file model.Obj, args model....
    method MakeDir (line 84) | func (d *Pan115) MakeDir(ctx context.Context, parentDir model.Obj, dir...
    method Move (line 112) | func (d *Pan115) Move(ctx context.Context, srcObj, dstDir model.Obj) (...
    method Rename (line 126) | func (d *Pan115) Rename(ctx context.Context, srcObj model.Obj, newName...
    method Copy (line 140) | func (d *Pan115) Copy(ctx context.Context, srcObj, dstDir model.Obj) e...
    method Remove (line 147) | func (d *Pan115) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 154) | func (d *Pan115) Put(ctx context.Context, dstDir model.Obj, stream mod...
    method OfflineList (line 237) | func (d *Pan115) OfflineList(ctx context.Context) ([]*driver115.Offlin...
    method OfflineDownload (line 245) | func (d *Pan115) OfflineDownload(ctx context.Context, uris []string, d...
    method DeleteOfflineTasks (line 249) | func (d *Pan115) DeleteOfflineTasks(ctx context.Context, hashes []stri...

FILE: drivers/115/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 25) | func init() {

FILE: drivers/115/types.go
  type FileObj (line 13) | type FileObj struct
    method CreateTime (line 18) | func (f *FileObj) CreateTime() time.Time {
    method GetHash (line 22) | func (f *FileObj) GetHash() utils.HashInfo {
    method Thumb (line 26) | func (f *FileObj) Thumb() string {
  type UploadResult (line 30) | type UploadResult struct

FILE: drivers/115/util.go
  type fileInfoWithThumb (line 31) | type fileInfoWithThumb struct
  type fileListRespWithThumb (line 36) | type fileListRespWithThumb struct
  type getFileInfoResponseWithThumb (line 44) | type getFileInfoResponseWithThumb struct
  method login (line 50) | func (d *Pan115) login() error {
  method getFiles (line 80) | func (d *Pan115) getFiles(fileId string) ([]FileObj, error) {
  method getNewFile (line 114) | func (d *Pan115) getNewFile(fileId string) (*FileObj, error) {
  method getNewFileByPickCode (line 123) | func (d *Pan115) getNewFileByPickCode(pickCode string) (*FileObj, error) {
  method getUA (line 132) | func (d *Pan115) getUA() string {
  function fileObjFromInfo (line 136) | func fileObjFromInfo(fileInfo *fileInfoWithThumb) FileObj {
  method getFileInfoWithThumb (line 145) | func (d *Pan115) getFileInfoWithThumb(queryKey, queryVal string) (*fileI...
  method getFilesPageWithThumb (line 161) | func (d *Pan115) getFilesPageWithThumb(dirID, apiURL string, limit, offs...
  method GenerateToken (line 194) | func (c *Pan115) GenerateToken(fileID, preID, timeStamp, fileSize, signK...
  method rapidUpload (line 201) | func (d *Pan115) rapidUpload(fileSize int64, fileName, dirID, preID, fil...
  function UploadDigestRange (line 286) | func UploadDigestRange(stream model.FileStreamer, rangeSpec string) (res...
  method UploadByOSS (line 306) | func (c *Pan115) UploadByOSS(ctx context.Context, params *driver115.Uplo...
  method UploadByMultipart (line 340) | func (d *Pan115) UploadByMultipart(ctx context.Context, params *driver11...
  function chunksProducer (line 492) | func chunksProducer(ch chan oss.FileChunk, chunks []oss.FileChunk) {
  function SplitFile (line 498) | func SplitFile(fileSize int64) (chunks []oss.FileChunk, err error) {
  function SplitFileByPartNum (line 523) | func SplitFileByPartNum(fileSize int64, chunkNum int) ([]oss.FileChunk, ...
  function SplitFileByPartSize (line 551) | func SplitFileByPartSize(fileSize int64, chunkSize int64) ([]oss.FileChu...

FILE: drivers/115_open/driver.go
  type Open115 (line 22) | type Open115 struct
    method Config (line 29) | func (d *Open115) Config() driver.Config {
    method GetAddition (line 33) | func (d *Open115) GetAddition() driver.Additional {
    method Init (line 37) | func (d *Open115) Init(ctx context.Context) error {
    method WaitLimit (line 58) | func (d *Open115) WaitLimit(ctx context.Context) error {
    method Drop (line 65) | func (d *Open115) Drop(ctx context.Context) error {
    method List (line 69) | func (d *Open115) List(ctx context.Context, dir model.Obj, args model....
    method Link (line 101) | func (d *Open115) Link(ctx context.Context, file model.Obj, args model...
    method MakeDir (line 133) | func (d *Open115) MakeDir(ctx context.Context, parentDir model.Obj, di...
    method Move (line 152) | func (d *Open115) Move(ctx context.Context, srcObj, dstDir model.Obj) ...
    method Rename (line 166) | func (d *Open115) Rename(ctx context.Context, srcObj model.Obj, newNam...
    method Copy (line 184) | func (d *Open115) Copy(ctx context.Context, srcObj, dstDir model.Obj) ...
    method Remove (line 199) | func (d *Open115) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 217) | func (d *Open115) Put(ctx context.Context, dstDir model.Obj, file mode...

FILE: drivers/115_open/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 33) | func init() {

FILE: drivers/115_open/types.go
  type Obj (line 11) | type Obj
    method Thumb (line 14) | func (o *Obj) Thumb() string {
    method CreateTime (line 19) | func (o *Obj) CreateTime() time.Time {
    method GetHash (line 24) | func (o *Obj) GetHash() utils.HashInfo {
    method GetID (line 29) | func (o *Obj) GetID() string {
    method GetName (line 34) | func (o *Obj) GetName() string {
    method GetPath (line 39) | func (o *Obj) GetPath() string {
    method GetSize (line 44) | func (o *Obj) GetSize() int64 {
    method IsDir (line 49) | func (o *Obj) IsDir() bool {
    method ModTime (line 54) | func (o *Obj) ModTime() time.Time {

FILE: drivers/115_open/upload.go
  function calPartSize (line 17) | func calPartSize(fileSize int64) int64 {
  method singleUpload (line 37) | func (d *Open115) singleUpload(ctx context.Context, tempF model.File, to...
  method multpartUpload (line 71) | func (d *Open115) multpartUpload(ctx context.Context, tempF model.File, ...

FILE: drivers/115_share/driver.go
  type Pan115Share (line 15) | type Pan115Share struct
    method Config (line 22) | func (d *Pan115Share) Config() driver.Config {
    method GetAddition (line 26) | func (d *Pan115Share) GetAddition() driver.Additional {
    method Init (line 30) | func (d *Pan115Share) Init(ctx context.Context) error {
    method WaitLimit (line 38) | func (d *Pan115Share) WaitLimit(ctx context.Context) error {
    method Drop (line 45) | func (d *Pan115Share) Drop(ctx context.Context) error {
    method List (line 49) | func (d *Pan115Share) List(ctx context.Context, dir model.Obj, args mo...
    method Link (line 75) | func (d *Pan115Share) Link(ctx context.Context, file model.Obj, args m...
    method MakeDir (line 94) | func (d *Pan115Share) MakeDir(ctx context.Context, parentDir model.Obj...
    method Move (line 98) | func (d *Pan115Share) Move(ctx context.Context, srcObj, dstDir model.O...
    method Rename (line 102) | func (d *Pan115Share) Rename(ctx context.Context, srcObj model.Obj, ne...
    method Copy (line 106) | func (d *Pan115Share) Copy(ctx context.Context, srcObj, dstDir model.O...
    method Remove (line 110) | func (d *Pan115Share) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 114) | func (d *Pan115Share) Put(ctx context.Context, dstDir model.Obj, strea...

FILE: drivers/115_share/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 30) | func init() {

FILE: drivers/115_share/utils.go
  type FileObj (line 17) | type FileObj struct
    method CreateTime (line 27) | func (f *FileObj) CreateTime() time.Time {
    method GetHash (line 31) | func (f *FileObj) GetHash() utils.HashInfo {
    method GetSize (line 35) | func (f *FileObj) GetSize() int64 {
    method GetName (line 39) | func (f *FileObj) GetName() string {
    method ModTime (line 43) | func (f *FileObj) ModTime() time.Time {
    method IsDir (line 47) | func (f *FileObj) IsDir() bool {
    method GetID (line 51) | func (f *FileObj) GetID() string {
    method GetPath (line 55) | func (f *FileObj) GetPath() string {
    method Thumb (line 59) | func (f *FileObj) Thumb() string {
  type shareFile (line 63) | type shareFile struct
  type shareSnapResp (line 78) | type shareSnapResp struct
  type downloadShareResp (line 86) | type downloadShareResp struct
  function transFunc (line 91) | func transFunc(sf shareFile) (model.Obj, error) {
  function buildShareReferer (line 115) | func buildShareReferer(shareCode, receiveCode string) string {
  method getShareSnapWithUA (line 119) | func (d *Pan115Share) getShareSnapWithUA(ua, dirID string, queries ...dr...
  method downloadByShareCodeWithUA (line 150) | func (d *Pan115Share) downloadByShareCodeWithUA(ua, fileID string) (*dri...
  method login (line 175) | func (d *Pan115Share) login() error {

FILE: drivers/123/driver.go
  type Pan123 (line 30) | type Pan123 struct
    method Config (line 37) | func (d *Pan123) Config() driver.Config {
    method GetAddition (line 41) | func (d *Pan123) GetAddition() driver.Additional {
    method Init (line 45) | func (d *Pan123) Init(ctx context.Context) error {
    method Drop (line 50) | func (d *Pan123) Drop(ctx context.Context) error {
    method List (line 57) | func (d *Pan123) List(ctx context.Context, dir model.Obj, args model.L...
    method Link (line 84) | func (d *Pan123) Link(ctx context.Context, file model.Obj, args model....
    method MakeDir (line 148) | func (d *Pan123) MakeDir(ctx context.Context, parentDir model.Obj, dir...
    method Move (line 163) | func (d *Pan123) Move(ctx context.Context, srcObj, dstDir model.Obj) e...
    method Rename (line 174) | func (d *Pan123) Rename(ctx context.Context, srcObj model.Obj, newName...
    method Copy (line 186) | func (d *Pan123) Copy(ctx context.Context, srcObj, dstDir model.Obj) e...
    method Remove (line 190) | func (d *Pan123) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 206) | func (d *Pan123) Put(ctx context.Context, dstDir model.Obj, file model...
    method APIRateLimit (line 274) | func (d *Pan123) APIRateLimit(ctx context.Context, api string) error {

FILE: drivers/123/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 24) | func init() {

FILE: drivers/123/types.go
  type File (line 14) | type File struct
    method CreateTime (line 26) | func (f File) CreateTime() time.Time {
    method GetHash (line 30) | func (f File) GetHash() utils.HashInfo {
    method GetPath (line 34) | func (f File) GetPath() string {
    method GetSize (line 38) | func (f File) GetSize() int64 {
    method GetName (line 42) | func (f File) GetName() string {
    method ModTime (line 46) | func (f File) ModTime() time.Time {
    method IsDir (line 50) | func (f File) IsDir() bool {
    method GetID (line 54) | func (f File) GetID() string {
    method Thumb (line 58) | func (f File) Thumb() string {
  type Files (line 88) | type Files struct
  type UploadResp (line 104) | type UploadResp struct
  type S3PreSignedURLs (line 120) | type S3PreSignedURLs struct

FILE: drivers/123/upload.go
  method getS3PreSignedUrls (line 17) | func (d *Pan123) getS3PreSignedUrls(ctx context.Context, upReq *UploadRe...
  method getS3Auth (line 36) | func (d *Pan123) getS3Auth(ctx context.Context, upReq *UploadResp, start...
  method completeS3 (line 55) | func (d *Pan123) completeS3(ctx context.Context, upReq *UploadResp, file...
  method newUpload (line 71) | func (d *Pan123) newUpload(ctx context.Context, upReq *UploadResp, file ...
  method uploadS3Chunk (line 123) | func (d *Pan123) uploadS3Chunk(ctx context.Context, upReq *UploadResp, s...

FILE: drivers/123/util.go
  constant Api (line 26) | Api              = "https://www.123pan.com/api"
  constant AApi (line 27) | AApi             = "https://www.123pan.com/a/api"
  constant BApi (line 28) | BApi             = "https://www.123pan.com/b/api"
  constant LoginApi (line 29) | LoginApi         = "https://login.123pan.com/api"
  constant MainApi (line 30) | MainApi          = BApi
  constant SignIn (line 31) | SignIn           = LoginApi + "/user/sign_in"
  constant Logout (line 32) | Logout           = MainApi + "/user/logout"
  constant UserInfo (line 33) | UserInfo         = MainApi + "/user/info"
  constant FileList (line 34) | FileList         = MainApi + "/file/list/new"
  constant DownloadInfo (line 35) | DownloadInfo     = MainApi + "/file/download_info"
  constant Mkdir (line 36) | Mkdir            = MainApi + "/file/upload_request"
  constant Move (line 37) | Move             = MainApi + "/file/mod_pid"
  constant Rename (line 38) | Rename           = MainApi + "/file/rename"
  constant Trash (line 39) | Trash            = MainApi + "/file/trash"
  constant UploadRequest (line 40) | UploadRequest    = MainApi + "/file/upload_request"
  constant UploadComplete (line 41) | UploadComplete   = MainApi + "/file/upload_complete"
  constant S3PreSignedUrls (line 42) | S3PreSignedUrls  = MainApi + "/file/s3_repare_upload_parts_batch"
  constant S3Auth (line 43) | S3Auth           = MainApi + "/file/s3_upload_object/auth"
  constant UploadCompleteV2 (line 44) | UploadCompleteV2 = MainApi + "/file/upload_complete/v2"
  constant S3Complete (line 45) | S3Complete       = MainApi + "/file/s3_complete_multipart_upload"
  constant SafeBoxUnlock (line 46) | SafeBoxUnlock    = MainApi + "/restful/goapi/v1/file/safe_box/auth/unloc...
  function signPath (line 50) | func signPath(path string, os string, version string) (k string, v strin...
  function GetApi (line 65) | func GetApi(rawUrl string) string {
  method login (line 148) | func (d *Pan123) login() error {
  method Request (line 198) | func (d *Pan123) Request(url string, method string, callback base.ReqCal...
  method unlockSafeBox (line 242) | func (d *Pan123) unlockSafeBox(fileId int64) error {
  method getFiles (line 258) | func (d *Pan123) getFiles(ctx context.Context, parentId string, name str...

FILE: drivers/123_link/driver.go
  type Pan123Link (line 14) | type Pan123Link struct
    method Config (line 20) | func (d *Pan123Link) Config() driver.Config {
    method GetAddition (line 24) | func (d *Pan123Link) GetAddition() driver.Additional {
    method Init (line 28) | func (d *Pan123Link) Init(ctx context.Context) error {
    method Drop (line 38) | func (d *Pan123Link) Drop(ctx context.Context) error {
    method Get (line 42) | func (d *Pan123Link) Get(ctx context.Context, path string) (model.Obj,...
    method List (line 47) | func (d *Pan123Link) List(ctx context.Context, dir model.Obj, args mod...
    method Link (line 60) | func (d *Pan123Link) Link(ctx context.Context, file model.Obj, args mo...

FILE: drivers/123_link/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 19) | func init() {

FILE: drivers/123_link/parse.go
  function BuildTree (line 32) | func BuildTree(text string) (*Node, error) {
  function isFolder (line 88) | func isFolder(line string) bool {
  function parseFileLine (line 94) | func parseFileLine(line string) (*Node, error) {
  function splitPath (line 141) | func splitPath(path string) []string {
  function GetNodeFromRootByPath (line 150) | func GetNodeFromRootByPath(root *Node, path string) *Node {

FILE: drivers/123_link/types.go
  type Node (line 11) | type Node struct
    method getByPath (line 20) | func (node *Node) getByPath(paths []string) *Node {
    method isFile (line 39) | func (node *Node) isFile() bool {
    method calSize (line 43) | func (node *Node) calSize() int64 {
  function nodeToObj (line 55) | func nodeToObj(node *Node, path string) (model.Obj, error) {

FILE: drivers/123_link/util.go
  function SignURL (line 11) | func SignURL(originURL, privateKey string, uid uint64, validDuration tim...

FILE: drivers/123_open/api.go
  constant ApiBaseURL (line 11) | ApiBaseURL = "https://open-api.123pan.com"
  constant ApiToken (line 14) | ApiToken = "/api/v1/access_token"
  constant ApiFileList (line 17) | ApiFileList = "/api/v2/file/list"
  constant ApiGetDirectLink (line 20) | ApiGetDirectLink = "/api/v1/direct-link/url"
  constant ApiMakeDir (line 23) | ApiMakeDir = "/upload/v1/file/mkdir"
  constant ApiRemove (line 26) | ApiRemove = "/api/v1/file/trash"
  constant ApiUploadDomainURL (line 29) | ApiUploadDomainURL   = "/upload/v2/file/domain"
  constant ApiSingleUploadURL (line 30) | ApiSingleUploadURL   = "/upload/v2/file/single/create"
  constant ApiCreateUploadURL (line 31) | ApiCreateUploadURL   = "/upload/v2/file/create"
  constant ApiUploadSliceURL (line 32) | ApiUploadSliceURL    = "/upload/v2/file/slice"
  constant ApiUploadCompleteURL (line 33) | ApiUploadCompleteURL = "/upload/v2/file/upload_complete"
  constant ApiMove (line 36) | ApiMove = "/api/v1/file/move"
  constant ApiRename (line 39) | ApiRename = "/api/v1/file/name"
  type Response (line 42) | type Response struct
  type TokenResp (line 48) | type TokenResp struct
  type TokenData (line 54) | type TokenData struct
  type FileListResp (line 59) | type FileListResp struct
  type FileListData (line 65) | type FileListData struct
  type DirectLinkResp (line 70) | type DirectLinkResp struct
  type DirectLinkData (line 76) | type DirectLinkData struct
  type MakeDirRequest (line 80) | type MakeDirRequest struct
  type MakeDirResp (line 85) | type MakeDirResp struct
  type MakeDirData (line 91) | type MakeDirData struct
  type RemoveRequest (line 95) | type RemoveRequest struct
  type UploadCreateResp (line 99) | type UploadCreateResp struct
  type UploadCreateData (line 105) | type UploadCreateData struct
  type UploadUrlResp (line 113) | type UploadUrlResp struct
  type UploadUrlData (line 119) | type UploadUrlData struct
  type UploadCompleteResp (line 123) | type UploadCompleteResp struct
  type UploadCompleteData (line 129) | type UploadCompleteData struct
  method Request (line 134) | func (d *Open123) Request(endpoint string, method string, setup func(*re...
  method RequestTo (line 163) | func (d *Open123) RequestTo(fullURL string, method string, setup func(*r...

FILE: drivers/123_open/driver.go
  type Open123 (line 17) | type Open123 struct
    method Config (line 25) | func (d *Open123) Config() driver.Config {
    method GetAddition (line 29) | func (d *Open123) GetAddition() driver.Additional {
    method Init (line 33) | func (d *Open123) Init(ctx context.Context) error {
    method Drop (line 43) | func (d *Open123) Drop(ctx context.Context) error {
    method List (line 47) | func (d *Open123) List(ctx context.Context, dir model.Obj, args model....
    method Link (line 76) | func (d *Open123) Link(ctx context.Context, file model.Obj, args model...
    method MakeDir (line 114) | func (d *Open123) MakeDir(ctx context.Context, parentDir model.Obj, di...
    method Move (line 147) | func (d *Open123) Move(ctx context.Context, srcObj, dstDir model.Obj) ...
    method Rename (line 185) | func (d *Open123) Rename(ctx context.Context, srcObj model.Obj, newNam...
    method Copy (line 223) | func (d *Open123) Copy(ctx context.Context, srcObj, dstDir model.Obj) ...
    method Remove (line 227) | func (d *Open123) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 252) | func (d *Open123) Put(ctx context.Context, dstDir model.Obj, file mode...
    method GetArchiveMeta (line 274) | func (d *Open123) GetArchiveMeta(ctx context.Context, obj model.Obj, a...
    method ListArchive (line 278) | func (d *Open123) ListArchive(ctx context.Context, obj model.Obj, args...
    method Extract (line 282) | func (d *Open123) Extract(ctx context.Context, obj model.Obj, args mod...
    method ArchiveDecompress (line 286) | func (d *Open123) ArchiveDecompress(ctx context.Context, srcObj, dstDi...

FILE: drivers/123_open/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 32) | func init() {

FILE: drivers/123_open/sign.go
  function SignURL (line 11) | func SignURL(originURL, privateKey string, uid uint64, validDuration tim...

FILE: drivers/123_open/token.go
  constant tokenURL (line 12) | tokenURL = ApiBaseURL + ApiToken
  type tokenManager (line 14) | type tokenManager struct
    method getToken (line 30) | func (tm *tokenManager) getToken() (string, error) {
    method buildHeaders (line 75) | func (tm *tokenManager) buildHeaders() (http.Header, error) {
  function newTokenManager (line 23) | func newTokenManager(clientID, clientSecret string) *tokenManager {

FILE: drivers/123_open/types.go
  type File (line 9) | type File struct
    method GetID (line 24) | func (f File) GetID() string {
    method GetName (line 28) | func (f File) GetName() string {
    method GetSize (line 32) | func (f File) GetSize() int64 {
    method IsDir (line 36) | func (f File) IsDir() bool {
    method GetModified (line 40) | func (f File) GetModified() string {
    method GetThumb (line 44) | func (f File) GetThumb() string {
    method ModTime (line 48) | func (f File) ModTime() time.Time {
    method CreateTime (line 56) | func (f File) CreateTime() time.Time {
    method GetHash (line 64) | func (f File) GetHash() utils.HashInfo {
    method GetPath (line 68) | func (f File) GetPath() string {

FILE: drivers/123_open/upload.go
  method create (line 26) | func (d *Open123) create(parentFileID int64, filename, etag string, size...
  method GetUploadDomains (line 51) | func (d *Open123) GetUploadDomains() ([]string, error) {
  method UploadSingle (line 68) | func (d *Open123) UploadSingle(ctx context.Context, createResp *UploadCr...
  method Upload (line 130) | func (d *Open123) Upload(ctx context.Context, file model.FileStreamer, p...

FILE: drivers/123_open/util.go
  method getFiles (line 8) | func (d *Open123) getFiles(parentFileId int64, limit int, lastFileId int...

FILE: drivers/123_share/driver.go
  type Pan123Share (line 24) | type Pan123Share struct
    method Config (line 31) | func (d *Pan123Share) Config() driver.Config {
    method GetAddition (line 35) | func (d *Pan123Share) GetAddition() driver.Additional {
    method Init (line 39) | func (d *Pan123Share) Init(ctx context.Context) error {
    method InitReference (line 45) | func (d *Pan123Share) InitReference(storage driver.Driver) error {
    method Drop (line 54) | func (d *Pan123Share) Drop(ctx context.Context) error {
    method List (line 59) | func (d *Pan123Share) List(ctx context.Context, dir model.Obj, args mo...
    method Link (line 70) | func (d *Pan123Share) Link(ctx context.Context, file model.Obj, args m...
    method MakeDir (line 132) | func (d *Pan123Share) MakeDir(ctx context.Context, parentDir model.Obj...
    method Move (line 137) | func (d *Pan123Share) Move(ctx context.Context, srcObj, dstDir model.O...
    method Rename (line 142) | func (d *Pan123Share) Rename(ctx context.Context, srcObj model.Obj, ne...
    method Copy (line 147) | func (d *Pan123Share) Copy(ctx context.Context, srcObj, dstDir model.O...
    method Remove (line 152) | func (d *Pan123Share) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 157) | func (d *Pan123Share) Put(ctx context.Context, dstDir model.Obj, strea...
    method APIRateLimit (line 166) | func (d *Pan123Share) APIRateLimit(ctx context.Context, api string) er...

FILE: drivers/123_share/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 31) | func init() {

FILE: drivers/123_share/types.go
  type File (line 14) | type File struct
    method GetHash (line 25) | func (f File) GetHash() utils.HashInfo {
    method GetPath (line 29) | func (f File) GetPath() string {
    method GetSize (line 33) | func (f File) GetSize() int64 {
    method GetName (line 37) | func (f File) GetName() string {
    method ModTime (line 41) | func (f File) ModTime() time.Time {
    method CreateTime (line 44) | func (f File) CreateTime() time.Time {
    method IsDir (line 48) | func (f File) IsDir() bool {
    method GetID (line 52) | func (f File) GetID() string {
    method Thumb (line 56) | func (f File) Thumb() string {
  type Files (line 86) | type Files struct

FILE: drivers/123_share/util.go
  constant Api (line 23) | Api          = "https://www.123pan.com/api"
  constant AApi (line 24) | AApi         = "https://www.123pan.com/a/api"
  constant BApi (line 25) | BApi         = "https://www.123pan.com/b/api"
  constant MainApi (line 26) | MainApi      = BApi
  constant FileList (line 27) | FileList     = MainApi + "/share/get"
  constant DownloadInfo (line 28) | DownloadInfo = MainApi + "/share/download/info"
  function signPath (line 32) | func signPath(path string, os string, version string) (k string, v strin...
  function GetApi (line 47) | func GetApi(rawUrl string) string {
  method request (line 55) | func (d *Pan123Share) request(url string, method string, callback base.R...
  method getFiles (line 87) | func (d *Pan123Share) getFiles(ctx context.Context, parentId string) ([]...

FILE: drivers/139/driver.go
  type Yun139 (line 24) | type Yun139 struct
    method Config (line 33) | func (d *Yun139) Config() driver.Config {
    method GetAddition (line 37) | func (d *Yun139) GetAddition() driver.Additional {
    method Init (line 41) | func (d *Yun139) Init(ctx context.Context) error {
    method InitReference (line 101) | func (d *Yun139) InitReference(storage driver.Driver) error {
    method Drop (line 110) | func (d *Yun139) Drop(ctx context.Context) error {
    method List (line 118) | func (d *Yun139) List(ctx context.Context, dir model.Obj, args model.L...
    method Link (line 133) | func (d *Yun139) Link(ctx context.Context, file model.Obj, args model....
    method MakeDir (line 154) | func (d *Yun139) MakeDir(ctx context.Context, parentDir model.Obj, dir...
    method Move (line 211) | func (d *Yun139) Move(ctx context.Context, srcObj, dstDir model.Obj) (...
    method Rename (line 286) | func (d *Yun139) Rename(ctx context.Context, srcObj model.Obj, newName...
    method Copy (line 387) | func (d *Yun139) Copy(ctx context.Context, srcObj, dstDir model.Obj) e...
    method Remove (line 429) | func (d *Yun139) Remove(ctx context.Context, obj model.Obj) error {
    method getPartSize (line 508) | func (d *Yun139) getPartSize(size int64) int64 {
    method Put (line 519) | func (d *Yun139) Put(ctx context.Context, dstDir model.Obj, stream mod...
    method Other (line 848) | func (d *Yun139) Other(ctx context.Context, args model.OtherArgs) (int...

FILE: drivers/139/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 25) | func init() {

FILE: drivers/139/types.go
  constant MetaPersonal (line 8) | MetaPersonal    string = "personal"
  constant MetaFamily (line 9) | MetaFamily      string = "family"
  constant MetaGroup (line 10) | MetaGroup       string = "group"
  constant MetaPersonalNew (line 11) | MetaPersonalNew string = "personal_new"
  type BaseResp (line 14) | type BaseResp struct
  type Catalog (line 20) | type Catalog struct
  type Content (line 50) | type Content struct
  type GetDiskResp (line 105) | type GetDiskResp struct
  type UploadResp (line 122) | type UploadResp struct
  type InterLayerUploadResult (line 146) | type InterLayerUploadResult struct
  type CloudContent (line 153) | type CloudContent struct
  type CloudCatalog (line 183) | type CloudCatalog struct
  type QueryContentListResp (line 193) | type QueryContentListResp struct
  type QueryGroupContentListResp (line 208) | type QueryGroupContentListResp struct
  type ParallelHashCtx (line 229) | type ParallelHashCtx struct
  type PartInfo (line 233) | type PartInfo struct
  type PersonalThumbnail (line 239) | type PersonalThumbnail struct
  type PersonalFileItem (line 244) | type PersonalFileItem struct
  type PersonalListResp (line 254) | type PersonalListResp struct
  type PersonalPartInfo (line 262) | type PersonalPartInfo struct
  type PersonalUploadResp (line 267) | type PersonalUploadResp struct
  type PersonalUploadUrlResp (line 279) | type PersonalUploadUrlResp struct
  type QueryRoutePolicyResp (line 288) | type QueryRoutePolicyResp struct
  type RefreshTokenResp (line 307) | type RefreshTokenResp struct

FILE: drivers/139/util.go
  method isFamily (line 26) | func (d *Yun139) isFamily() bool {
  function encodeURIComponent (line 30) | func encodeURIComponent(str string) string {
  function calSign (line 41) | func calSign(body, ts, randStr string) string {
  function getTime (line 52) | func getTime(t string) time.Time {
  method refreshToken (line 57) | func (d *Yun139) refreshToken() error {
  method request (line 107) | func (d *Yun139) request(pathname string, method string, callback base.R...
  method requestRoute (line 161) | func (d *Yun139) requestRoute(data interface{}, resp interface{}) ([]byt...
  method post (line 218) | func (d *Yun139) post(pathname string, data interface{}, resp interface{...
  method getFiles (line 224) | func (d *Yun139) getFiles(catalogID string) ([]model.Obj, error) {
  method newJson (line 280) | func (d *Yun139) newJson(data map[string]interface{}) base.Json {
  method familyGetFiles (line 293) | func (d *Yun139) familyGetFiles(catalogID string) ([]model.Obj, error) {
  method groupGetFiles (line 347) | func (d *Yun139) groupGetFiles(catalogID string) ([]model.Obj, error) {
  method getLink (line 402) | func (d *Yun139) getLink(contentId string) (string, error) {
  method familyGetLink (line 418) | func (d *Yun139) familyGetLink(contentId string, path string) (string, e...
  method groupGetLink (line 431) | func (d *Yun139) groupGetLink(contentId string, path string) (string, er...
  function unicode (line 445) | func unicode(str string) string {
  method personalRequest (line 451) | func (d *Yun139) personalRequest(pathname string, method string, callbac...
  method personalPost (line 510) | func (d *Yun139) personalPost(pathname string, data interface{}, resp in...
  function getPersonalTime (line 516) | func getPersonalTime(t string) time.Time {
  method personalGetFiles (line 524) | func (d *Yun139) personalGetFiles(fileId string) ([]model.Obj, error) {
  method personalGetLink (line 591) | func (d *Yun139) personalGetLink(fileId string) (string, error) {
  method getAuthorization (line 608) | func (d *Yun139) getAuthorization() string {
  method getAccount (line 614) | func (d *Yun139) getAccount() string {
  method getPersonalCloudHost (line 620) | func (d *Yun139) getPersonalCloudHost() string {

FILE: drivers/189/driver.go
  type Cloud189 (line 16) | type Cloud189 struct
    method Config (line 24) | func (d *Cloud189) Config() driver.Config {
    method GetAddition (line 28) | func (d *Cloud189) GetAddition() driver.Additional {
    method Init (line 32) | func (d *Cloud189) Init(ctx context.Context) error {
    method Drop (line 38) | func (d *Cloud189) Drop(ctx context.Context) error {
    method List (line 42) | func (d *Cloud189) List(ctx context.Context, dir model.Obj, args model...
    method Link (line 46) | func (d *Cloud189) Link(ctx context.Context, file model.Obj, args mode...
    method MakeDir (line 82) | func (d *Cloud189) MakeDir(ctx context.Context, parentDir model.Obj, d...
    method Move (line 94) | func (d *Cloud189) Move(ctx context.Context, srcObj, dstDir model.Obj)...
    method Rename (line 121) | func (d *Cloud189) Rename(ctx context.Context, srcObj model.Obj, newNa...
    method Copy (line 141) | func (d *Cloud189) Copy(ctx context.Context, srcObj, dstDir model.Obj)...
    method Remove (line 168) | func (d *Cloud189) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 195) | func (d *Cloud189) Put(ctx context.Context, dstDir model.Obj, stream m...

FILE: drivers/189/help.go
  function random (line 25) | func random() string {
  function RsaEncode (line 29) | func RsaEncode(origData []byte, j_rsakey string, hex bool) string {
  function int2char (line 49) | func int2char(a int) string {
  function b64tohex (line 53) | func b64tohex(a string) string {
  function qs (line 87) | func qs(form map[string]string) string {
  function EncodeParam (line 100) | func EncodeParam(v url.Values) string {
  function encode (line 127) | func encode(str string) string {
  function AesEncrypt (line 135) | func AesEncrypt(data, key []byte) []byte {
  function PKCS7Padding (line 149) | func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
  function hmacSha1 (line 155) | func hmacSha1(data string, secret string) string {
  function getMd5 (line 161) | func getMd5(data []byte) []byte {
  function decodeURIComponent (line 167) | func decodeURIComponent(str string) string {
  function Random (line 173) | func Random(v string) string {

FILE: drivers/189/login.go
  type AppConf (line 11) | type AppConf struct
  type EncryptConf (line 35) | type EncryptConf struct
  method newLogin (line 45) | func (d *Cloud189) newLogin() error {

FILE: drivers/189/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 23) | func init() {

FILE: drivers/189/types.go
  type LoginResp (line 3) | type LoginResp struct
  type Error (line 9) | type Error struct
  type File (line 14) | type File struct
  type Folder (line 26) | type Folder struct
  type Files (line 32) | type Files struct
  type UploadUrlsResp (line 42) | type UploadUrlsResp struct
  type Part (line 47) | type Part struct
  type Rsa (line 52) | type Rsa struct
  type Down (line 58) | type Down struct
  type DownResp (line 64) | type DownResp struct

FILE: drivers/189/util.go
  method request (line 145) | func (d *Cloud189) request(url string, method string, callback base.ReqC...
  method getFiles (line 178) | func (d *Cloud189) getFiles(fileId string) ([]model.Obj, error) {
  method sanitizeName (line 227) | func (d *Cloud189) sanitizeName(name string) string {
  method oldUpload (line 250) | func (d *Cloud189) oldUpload(dstDir model.Obj, file model.FileStreamer) ...
  method getSessionKey (line 268) | func (d *Cloud189) getSessionKey() (string, error) {
  method getResKey (line 277) | func (d *Cloud189) getResKey() (string, string, error) {
  method uploadRequest (line 292) | func (d *Cloud189) uploadRequest(uri string, form map[string]string, res...
  method newUpload (line 333) | func (d *Cloud189) newUpload(ctx context.Context, dstDir model.Obj, file...

FILE: drivers/189pc/driver.go
  type Cloud189PC (line 20) | type Cloud189PC struct
    method Config (line 40) | func (y *Cloud189PC) Config() driver.Config {
    method GetAddition (line 47) | func (y *Cloud189PC) GetAddition() driver.Additional {
    method Init (line 51) | func (y *Cloud189PC) Init(ctx context.Context) (err error) {
    method InitReference (line 120) | func (d *Cloud189PC) InitReference(storage driver.Driver) error {
    method Drop (line 129) | func (y *Cloud189PC) Drop(ctx context.Context) error {
    method List (line 134) | func (y *Cloud189PC) List(ctx context.Context, dir model.Obj, args mod...
    method Link (line 138) | func (y *Cloud189PC) Link(ctx context.Context, file model.Obj, args mo...
    method MakeDir (line 199) | func (y *Cloud189PC) MakeDir(ctx context.Context, parentDir model.Obj,...
    method Move (line 233) | func (y *Cloud189PC) Move(ctx context.Context, srcObj, dstDir model.Ob...
    method Rename (line 251) | func (y *Cloud189PC) Rename(ctx context.Context, srcObj model.Obj, new...
    method Copy (line 295) | func (y *Cloud189PC) Copy(ctx context.Context, srcObj, dstDir model.Ob...
    method Remove (line 311) | func (y *Cloud189PC) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 326) | func (y *Cloud189PC) Put(ctx context.Context, dstDir model.Obj, stream...

FILE: drivers/189pc/help.go
  function clientSuffix (line 25) | func clientSuffix() map[string]string {
  function signatureOfHmac (line 36) | func signatureOfHmac(sessionSecret, sessionKey, operate, fullUrl, dateOf...
  function RsaEncrypt (line 48) | func RsaEncrypt(publicKey, origData string) string {
  function AesECBEncrypt (line 56) | func AesECBEncrypt(data, key string) string {
  function PKCS7Padding (line 67) | func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
  function getHttpDateStr (line 74) | func getHttpDateStr() string {
  function timestamp (line 79) | func timestamp() int64 {
  function MustParseTime (line 83) | func MustParseTime(str string) *time.Time {
  type Time (line 88) | type Time
    method UnmarshalJSON (line 90) | func (t *Time) UnmarshalJSON(b []byte) error { return t.Unmarshal(b) }
    method UnmarshalXML (line 91) | func (t *Time) UnmarshalXML(e *xml.Decoder, ee xml.StartElement) error {
    method Unmarshal (line 103) | func (t *Time) Unmarshal(b []byte) error {
  type String (line 117) | type String
    method UnmarshalJSON (line 119) | func (t *String) UnmarshalJSON(b []byte) error { return t.Unmarshal(b) }
    method UnmarshalXML (line 120) | func (t *String) UnmarshalXML(e *xml.Decoder, ee xml.StartElement) err...
    method Unmarshal (line 132) | func (s *String) Unmarshal(b []byte) error {
  function toFamilyOrderBy (line 137) | func toFamilyOrderBy(o string) string {
  function toDesc (line 150) | func toDesc(o string) string {
  function ParseHttpHeader (line 161) | func ParseHttpHeader(str string) map[string]string {
  function MustString (line 171) | func MustString(str string, err error) string {
  function BoolToNumber (line 175) | func BoolToNumber(b bool) int {
  function partSize (line 186) | func partSize(size int64) int64 {
  function isBool (line 197) | func isBool(bs ...bool) bool {
  function IF (line 206) | func IF[V any](o bool, t V, f V) V {
  type WrapFileStreamer (line 213) | type WrapFileStreamer struct
    method GetName (line 218) | func (w *WrapFileStreamer) GetName() string {

FILE: drivers/189pc/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 31) | func init() {

FILE: drivers/189pc/types.go
  type RespErr (line 14) | type RespErr struct
    method HasError (line 29) | func (e *RespErr) HasError() bool {
    method Error (line 39) | func (e *RespErr) Error() string {
  type LoginParam (line 72) | type LoginParam struct
  type EncryptConfResp (line 92) | type EncryptConfResp struct
  type LoginResp (line 102) | type LoginResp struct
  type UserSessionResp (line 109) | type UserSessionResp struct
  type AppSessionResp (line 128) | type AppSessionResp struct
  type FamilyInfoListResp (line 140) | type FamilyInfoListResp struct
  type FamilyInfoResp (line 143) | type FamilyInfoResp struct
  type Cloud189File (line 155) | type Cloud189File struct
    method CreateTime (line 180) | func (c *Cloud189File) CreateTime() time.Time {
    method GetHash (line 184) | func (c *Cloud189File) GetHash() utils.HashInfo {
    method GetSize (line 188) | func (c *Cloud189File) GetSize() int64     { return c.Size }
    method GetName (line 189) | func (c *Cloud189File) GetName() string    { return c.Name }
    method ModTime (line 190) | func (c *Cloud189File) ModTime() time.Time { return time.Time(c.LastOp...
    method IsDir (line 191) | func (c *Cloud189File) IsDir() bool        { return false }
    method GetID (line 192) | func (c *Cloud189File) GetID() string      { return string(c.ID) }
    method GetPath (line 193) | func (c *Cloud189File) GetPath() string    { return "" }
    method Thumb (line 194) | func (c *Cloud189File) Thumb() string      { return c.Icon.SmallUrl }
  type Cloud189Folder (line 197) | type Cloud189Folder struct
    method CreateTime (line 212) | func (c *Cloud189Folder) CreateTime() time.Time {
    method GetHash (line 216) | func (c *Cloud189Folder) GetHash() utils.HashInfo {
    method GetSize (line 220) | func (c *Cloud189Folder) GetSize() int64     { return 0 }
    method GetName (line 221) | func (c *Cloud189Folder) GetName() string    { return c.Name }
    method ModTime (line 222) | func (c *Cloud189Folder) ModTime() time.Time { return time.Time(c.Last...
    method IsDir (line 223) | func (c *Cloud189Folder) IsDir() bool        { return true }
    method GetID (line 224) | func (c *Cloud189Folder) GetID() string      { return string(c.ID) }
    method GetPath (line 225) | func (c *Cloud189Folder) GetPath() string    { return "" }
  type Cloud189FilesResp (line 227) | type Cloud189FilesResp struct
  type BatchTaskInfo (line 238) | type BatchTaskInfo struct
  type InitMultiUploadResp (line 255) | type InitMultiUploadResp struct
  type UploadUrlsResp (line 264) | type UploadUrlsResp struct
  type UploadUrlsData (line 268) | type UploadUrlsData struct
  type UploadUrlInfo (line 273) | type UploadUrlInfo struct
  type UploadProgress (line 279) | type UploadProgress struct
  type CreateUploadFileResp (line 285) | type CreateUploadFileResp struct
  type GetUploadFileStatusResp (line 296) | type GetUploadFileStatusResp struct
    method GetSize (line 304) | func (r *GetUploadFileStatusResp) GetSize() int64 {
  type CommitMultiUploadFileResp (line 308) | type CommitMultiUploadFileResp struct
    method toFile (line 318) | func (f *CommitMultiUploadFileResp) toFile() *Cloud189File {
  type OldCommitUploadFileResp (line 329) | type OldCommitUploadFileResp struct
    method toFile (line 338) | func (f *OldCommitUploadFileResp) toFile() *Cloud189File {
  type CreateBatchTaskResp (line 349) | type CreateBatchTaskResp struct
  type BatchTaskStateResp (line 353) | type BatchTaskStateResp struct
  type BatchTaskConflictTaskInfoResp (line 364) | type BatchTaskConflictTaskInfoResp struct
  type Params (line 373) | type Params
    method Set (line 375) | func (p Params) Set(k, v string) {
    method Encode (line 379) | func (p Params) Encode() string {

FILE: drivers/189pc/utils.go
  constant ACCOUNT_TYPE (line 44) | ACCOUNT_TYPE = "02"
  constant APP_ID (line 45) | APP_ID       = "8025431004"
  constant CLIENT_TYPE (line 46) | CLIENT_TYPE  = "10020"
  constant VERSION (line 47) | VERSION      = "6.2"
  constant WEB_URL (line 49) | WEB_URL    = "https://cloud.189.cn"
  constant AUTH_URL (line 50) | AUTH_URL   = "https://open.e.189.cn"
  constant API_URL (line 51) | API_URL    = "https://api.cloud.189.cn"
  constant UPLOAD_URL (line 52) | UPLOAD_URL = "https://upload.cloud.189.cn"
  constant RETURN_URL (line 54) | RETURN_URL = "https://m.cloud.189.cn/zhuanti/2020/loginErrorPc/index.html"
  constant PC (line 56) | PC  = "TELEPC"
  constant MAC (line 57) | MAC = "TELEMAC"
  constant CHANNEL_ID (line 59) | CHANNEL_ID = "web_cloud.189.cn"
  method sanitizeName (line 62) | func (y *Cloud189PC) sanitizeName(name string) string {
  method SignatureHeader (line 85) | func (y *Cloud189PC) SignatureHeader(url, method, params string, isFamil...
  method EncryptParams (line 103) | func (y *Cloud189PC) EncryptParams(params Params, isFamily bool) string {
  method request (line 114) | func (y *Cloud189PC) request(url, method string, callback base.ReqCallba...
  method get (line 162) | func (y *Cloud189PC) get(url string, callback base.ReqCallback, resp int...
  method post (line 166) | func (y *Cloud189PC) post(url string, callback base.ReqCallback, resp in...
  method put (line 170) | func (y *Cloud189PC) put(ctx context.Context, url string, headers map[st...
  method getFiles (line 214) | func (y *Cloud189PC) getFiles(ctx context.Context, fileId string, isFami...
  method getFilesWithPage (line 236) | func (y *Cloud189PC) getFilesWithPage(ctx context.Context, fileId string...
  method findFileByName (line 274) | func (y *Cloud189PC) findFileByName(ctx context.Context, searchName stri...
  method login (line 293) | func (y *Cloud189PC) login() (err error) {
  method initLoginParam (line 372) | func (y *Cloud189PC) initLoginParam() error {
  method refreshSession (line 459) | func (y *Cloud189PC) refreshSession() (err error) {
  method StreamUpload (line 500) | func (y *Cloud189PC) StreamUpload(ctx context.Context, dstDir model.Obj,...
  method RapidUpload (line 619) | func (y *Cloud189PC) RapidUpload(ctx context.Context, dstDir model.Obj, ...
  method FastUpload (line 639) | func (y *Cloud189PC) FastUpload(ctx context.Context, dstDir model.Obj, f...
  method GetMultiUploadUrls (line 814) | func (y *Cloud189PC) GetMultiUploadUrls(ctx context.Context, isFamily bo...
  method OldUpload (line 858) | func (y *Cloud189PC) OldUpload(ctx context.Context, dstDir model.Obj, fi...
  method OldUploadCreate (line 923) | func (y *Cloud189PC) OldUploadCreate(ctx context.Context, parentID strin...
  method OldUploadCommit (line 962) | func (y *Cloud189PC) OldUploadCommit(ctx context.Context, fileCommitUrl ...
  method isFamily (line 987) | func (y *Cloud189PC) isFamily() bool {
  method isLogin (line 991) | func (y *Cloud189PC) isLogin() bool {
  method createFamilyTransferFolder (line 1000) | func (y *Cloud189PC) createFamilyTransferFolder() error {
  method cleanFamilyTransfer (line 1016) | func (y *Cloud189PC) cleanFamilyTransfer(ctx context.Context) error {
  method getFamilyInfoList (line 1069) | func (y *Cloud189PC) getFamilyInfoList() ([]FamilyInfoResp, error) {
  method getFamilyID (line 1079) | func (y *Cloud189PC) getFamilyID() (string, error) {
  method SaveFamilyFileToPersonCloud (line 1096) | func (y *Cloud189PC) SaveFamilyFileToPersonCloud(ctx context.Context, fa...
  method Delete (line 1141) | func (y *Cloud189PC) Delete(ctx context.Context, familyId string, srcObj...
  method CreateBatchTask (line 1168) | func (y *Cloud189PC) CreateBatchTask(aType string, familyID string, targ...
  method CheckBatchTask (line 1190) | func (y *Cloud189PC) CheckBatchTask(aType string, taskID string) (*Batch...
  method GetConflictTaskInfo (line 1205) | func (y *Cloud189PC) GetConflictTaskInfo(aType string, taskID string) (*...
  method ManageBatchTask (line 1220) | func (y *Cloud189PC) ManageBatchTask(aType string, taskID string, target...
  method WaitBatchTask (line 1235) | func (y *Cloud189PC) WaitBatchTask(aType string, taskID string, t time.D...
  method getTokenInfo (line 1251) | func (y *Cloud189PC) getTokenInfo() *AppSessionResp {
  method getClient (line 1258) | func (y *Cloud189PC) getClient() *resty.Client {

FILE: drivers/alias/driver.go
  type Alias (line 16) | type Alias struct
    method Config (line 24) | func (d *Alias) Config() driver.Config {
    method GetAddition (line 28) | func (d *Alias) GetAddition() driver.Additional {
    method Init (line 32) | func (d *Alias) Init(ctx context.Context) error {
    method Drop (line 57) | func (d *Alias) Drop(ctx context.Context) error {
    method Get (line 62) | func (d *Alias) Get(ctx context.Context, path string) (model.Obj, erro...
    method List (line 84) | func (d *Alias) List(ctx context.Context, dir model.Obj, args model.Li...
    method Link (line 105) | func (d *Alias) Link(ctx context.Context, file model.Obj, args model.L...
    method MakeDir (line 130) | func (d *Alias) MakeDir(ctx context.Context, parentDir model.Obj, dirN...
    method Move (line 144) | func (d *Alias) Move(ctx context.Context, srcObj, dstDir model.Obj) er...
    method Rename (line 165) | func (d *Alias) Rename(ctx context.Context, srcObj model.Obj, newName ...
    method Copy (line 179) | func (d *Alias) Copy(ctx context.Context, srcObj, dstDir model.Obj) er...
    method Remove (line 201) | func (d *Alias) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 215) | func (d *Alias) Put(ctx context.Context, dstDir model.Obj, s model.Fil...
    method PutURL (line 229) | func (d *Alias) PutURL(ctx context.Context, dstDir model.Obj, name, ur...
    method GetArchiveMeta (line 243) | func (d *Alias) GetArchiveMeta(ctx context.Context, obj model.Obj, arg...
    method ListArchive (line 258) | func (d *Alias) ListArchive(ctx context.Context, obj model.Obj, args m...
    method Extract (line 273) | func (d *Alias) Extract(ctx context.Context, obj model.Obj, args model...
    method ArchiveDecompress (line 299) | func (d *Alias) ArchiveDecompress(ctx context.Context, srcObj, dstDir ...

FILE: drivers/alias/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 28) | func init() {

FILE: drivers/alias/util.go
  method listRoot (line 20) | func (d *Alias) listRoot() []model.Obj {
  function getPair (line 34) | func getPair(path string) (string, string) {
  method getRootAndPath (line 45) | func (d *Alias) getRootAndPath(path string) (string, string) {
  method get (line 57) | func (d *Alias) get(ctx context.Context, path string, dst, sub string) (...
  method list (line 72) | func (d *Alias) list(ctx context.Context, dst, sub string, args *fs.List...
  method link (line 99) | func (d *Alias) link(ctx context.Context, dst, sub string, args model.Li...
  method getReqPath (line 130) | func (d *Alias) getReqPath(ctx context.Context, obj model.Obj, isParent ...
  method getArchiveMeta (line 162) | func (d *Alias) getArchiveMeta(ctx context.Context, dst, sub string, arg...
  method listArchive (line 177) | func (d *Alias) listArchive(ctx context.Context, dst, sub string, args m...
  method extract (line 192) | func (d *Alias) extract(ctx context.Context, dst, sub string, args model...

FILE: drivers/alist_v2/driver.go
  type AListV2 (line 13) | type AListV2 struct
    method Config (line 18) | func (d *AListV2) Config() driver.Config {
    method GetAddition (line 22) | func (d *AListV2) GetAddition() driver.Additional {
    method Init (line 26) | func (d *AListV2) Init(ctx context.Context) error {
    method Drop (line 35) | func (d *AListV2) Drop(ctx context.Context) error {
    method List (line 39) | func (d *AListV2) List(ctx context.Context, dir model.Obj, args model....
    method Link (line 70) | func (d *AListV2) Link(ctx context.Context, file model.Obj, args model...
    method MakeDir (line 90) | func (d *AListV2) MakeDir(ctx context.Context, parentDir model.Obj, di...
    method Move (line 94) | func (d *AListV2) Move(ctx context.Context, srcObj, dstDir model.Obj) ...
    method Rename (line 98) | func (d *AListV2) Rename(ctx context.Context, srcObj model.Obj, newNam...
    method Copy (line 102) | func (d *AListV2) Copy(ctx context.Context, srcObj, dstDir model.Obj) ...
    method Remove (line 106) | func (d *AListV2) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 110) | func (d *AListV2) Put(ctx context.Context, dstDir model.Obj, stream mo...

FILE: drivers/alist_v2/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 22) | func init() {

FILE: drivers/alist_v2/types.go
  type File (line 7) | type File struct
  type PathResp (line 20) | type PathResp struct
  type PathReq (line 26) | type PathReq struct

FILE: drivers/alist_v3/driver.go
  type AListV3 (line 23) | type AListV3 struct
    method Config (line 28) | func (d *AListV3) Config() driver.Config {
    method GetAddition (line 32) | func (d *AListV3) GetAddition() driver.Additional {
    method Init (line 36) | func (d *AListV3) Init(ctx context.Context) error {
    method Drop (line 73) | func (d *AListV3) Drop(ctx context.Context) error {
    method List (line 77) | func (d *AListV3) List(ctx context.Context, dir model.Obj, args model....
    method Link (line 111) | func (d *AListV3) Link(ctx context.Context, file model.Obj, args model...
    method MakeDir (line 135) | func (d *AListV3) MakeDir(ctx context.Context, parentDir model.Obj, di...
    method Move (line 144) | func (d *AListV3) Move(ctx context.Context, srcObj, dstDir model.Obj) ...
    method Rename (line 155) | func (d *AListV3) Rename(ctx context.Context, srcObj model.Obj, newNam...
    method Copy (line 165) | func (d *AListV3) Copy(ctx context.Context, srcObj, dstDir model.Obj) ...
    method Remove (line 176) | func (d *AListV3) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 186) | func (d *AListV3) Put(ctx context.Context, dstDir model.Obj, s model.F...
    method GetArchiveMeta (line 237) | func (d *AListV3) GetArchiveMeta(ctx context.Context, obj model.Obj, a...
    method ListArchive (line 270) | func (d *AListV3) ListArchive(ctx context.Context, obj model.Obj, args...
    method Extract (line 314) | func (d *AListV3) Extract(ctx context.Context, obj model.Obj, args mod...
    method ArchiveDecompress (line 339) | func (d *AListV3) ArchiveDecompress(ctx context.Context, srcObj, dstDi...

FILE: drivers/alist_v3/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 27) | func init() {

FILE: drivers/alist_v3/types.go
  type ListReq (line 11) | type ListReq struct
  type ObjResp (line 18) | type ObjResp struct
  type FsListResp (line 30) | type FsListResp struct
  type FsGetReq (line 38) | type FsGetReq struct
  type FsGetResp (line 43) | type FsGetResp struct
  type MkdirOrLinkReq (line 51) | type MkdirOrLinkReq struct
  type MoveCopyReq (line 55) | type MoveCopyReq struct
  type RenameReq (line 61) | type RenameReq struct
  type RemoveReq (line 66) | type RemoveReq struct
  type LoginResp (line 71) | type LoginResp struct
  type MeResp (line 75) | type MeResp struct
  type ArchiveMetaReq (line 87) | type ArchiveMetaReq struct
  type TreeResp (line 94) | type TreeResp struct
    method GetSize (line 100) | func (t *TreeResp) GetSize() int64 {
    method GetName (line 104) | func (t *TreeResp) GetName() string {
    method ModTime (line 108) | func (t *TreeResp) ModTime() time.Time {
    method CreateTime (line 112) | func (t *TreeResp) CreateTime() time.Time {
    method IsDir (line 116) | func (t *TreeResp) IsDir() bool {
    method GetHash (line 120) | func (t *TreeResp) GetHash() utils.HashInfo {
    method GetID (line 124) | func (t *TreeResp) GetID() string {
    method GetPath (line 128) | func (t *TreeResp) GetPath() string {
    method GetChildren (line 132) | func (t *TreeResp) GetChildren() []model.ObjTree {
    method Thumb (line 140) | func (t *TreeResp) Thumb() string {
  type ArchiveMetaResp (line 144) | type ArchiveMetaResp struct
  type ArchiveListReq (line 152) | type ArchiveListReq struct
  type ArchiveListResp (line 158) | type ArchiveListResp struct
  type DecompressReq (line 163) | type DecompressReq struct
  type IntSlice (line 173) | type IntSlice
    method UnmarshalJSON (line 175) | func (s *IntSlice) UnmarshalJSON(data []byte) error {

FILE: drivers/alist_v3/util.go
  method login (line 15) | func (d *AListV3) login() error {
  method request (line 34) | func (d *AListV3) request(api, method string, callback base.ReqCallback,...

FILE: drivers/aliyundrive/driver.go
  type AliDrive (line 29) | type AliDrive struct
    method Config (line 38) | func (d *AliDrive) Config() driver.Config {
    method GetAddition (line 42) | func (d *AliDrive) GetAddition() driver.Additional {
    method Init (line 46) | func (d *AliDrive) Init(ctx context.Context) error {
    method Drop (line 85) | func (d *AliDrive) Drop(ctx context.Context) error {
    method List (line 92) | func (d *AliDrive) List(ctx context.Context, dir model.Obj, args model...
    method Link (line 102) | func (d *AliDrive) Link(ctx context.Context, file model.Obj, args mode...
    method MakeDir (line 122) | func (d *AliDrive) MakeDir(ctx context.Context, parentDir model.Obj, d...
    method Move (line 135) | func (d *AliDrive) Move(ctx context.Context, srcObj, dstDir model.Obj)...
    method Rename (line 140) | func (d *AliDrive) Rename(ctx context.Context, srcObj model.Obj, newNa...
    method Copy (line 152) | func (d *AliDrive) Copy(ctx context.Context, srcObj, dstDir model.Obj)...
    method Remove (line 157) | func (d *AliDrive) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 167) | func (d *AliDrive) Put(ctx context.Context, dstDir model.Obj, streamer...
    method Other (line 331) | func (d *AliDrive) Other(ctx context.Context, args model.OtherArgs) (i...

FILE: drivers/aliyundrive/global.go
  type State (line 9) | type State struct

FILE: drivers/aliyundrive/help.go
  function NewPrivateKey (line 12) | func NewPrivateKey() (*ecdsa.PrivateKey, error) {
  function NewPrivateKeyFromHex (line 17) | func NewPrivateKeyFromHex(hex_ string) (*ecdsa.PrivateKey, error) {
  function NewPrivateKeyFromBytes (line 26) | func NewPrivateKeyFromBytes(priv []byte) *ecdsa.PrivateKey {
  function PrivateKeyToHex (line 39) | func PrivateKeyToHex(private *ecdsa.PrivateKey) string {
  function PrivateKeyToBytes (line 43) | func PrivateKeyToBytes(private *ecdsa.PrivateKey) []byte {
  function PublicKeyToHex (line 47) | func PublicKeyToHex(public *ecdsa.PublicKey) string {
  function PublicKeyToBytes (line 51) | func PublicKeyToBytes(public *ecdsa.PublicKey) []byte {

FILE: drivers/aliyundrive/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 26) | func init() {

FILE: drivers/aliyundrive/types.go
  type RespErr (line 9) | type RespErr struct
  type Files (line 14) | type Files struct
  type File (line 19) | type File struct
  function fileToObj (line 34) | func fileToObj(f File) *model.ObjThumb {
  type UploadResp (line 47) | type UploadResp struct

FILE: drivers/aliyundrive/util.go
  method createSession (line 18) | func (d *AliDrive) createSession() error {
  method sign (line 49) | func (d *AliDrive) sign() {
  method refreshToken (line 60) | func (d *AliDrive) refreshToken() error {
  method request (line 84) | func (d *AliDrive) request(url, method string, callback base.ReqCallback...
  method getFiles (line 140) | func (d *AliDrive) getFiles(fileId string) ([]File, error) {
  method batch (line 174) | func (d *AliDrive) batch(srcId, dstId string, url string) error {

FILE: drivers/aliyundrive_open/driver.go
  type AliyundriveOpen (line 21) | type AliyundriveOpen struct
    method Config (line 32) | func (d *AliyundriveOpen) Config() driver.Config {
    method GetAddition (line 36) | func (d *AliyundriveOpen) GetAddition() driver.Additional {
    method Init (line 40) | func (d *AliyundriveOpen) Init(ctx context.Context) error {
    method InitReference (line 63) | func (d *AliyundriveOpen) InitReference(storage driver.Driver) error {
    method Drop (line 72) | func (d *AliyundriveOpen) Drop(ctx context.Context) error {
    method GetRoot (line 78) | func (d *AliyundriveOpen) GetRoot(ctx context.Context) (model.Obj, err...
    method List (line 89) | func (d *AliyundriveOpen) List(ctx context.Context, dir model.Obj, arg...
    method link (line 110) | func (d *AliyundriveOpen) link(ctx context.Context, file model.Obj) (*...
    method Link (line 135) | func (d *AliyundriveOpen) Link(ctx context.Context, file model.Obj, ar...
    method MakeDir (line 142) | func (d *AliyundriveOpen) MakeDir(ctx context.Context, parentDir model...
    method Move (line 169) | func (d *AliyundriveOpen) Move(ctx context.Context, srcObj, dstDir mod...
    method Rename (line 199) | func (d *AliyundriveOpen) Rename(ctx context.Context, srcObj model.Obj...
    method Copy (line 231) | func (d *AliyundriveOpen) Copy(ctx context.Context, srcObj, dstDir mod...
    method Remove (line 254) | func (d *AliyundriveOpen) Remove(ctx context.Context, obj model.Obj) e...
    method Put (line 268) | func (d *AliyundriveOpen) Put(ctx context.Context, dstDir model.Obj, s...
    method Other (line 283) | func (d *AliyundriveOpen) Other(ctx context.Context, args model.OtherA...

FILE: drivers/aliyundrive_open/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 37) | func init() {

FILE: drivers/aliyundrive_open/types.go
  type ErrResp (line 10) | type ErrResp struct
  type Files (line 15) | type Files struct
  type File (line 20) | type File struct
  function fileToObj (line 39) | func fileToObj(f File) *model.ObjThumb {
  type PartInfo (line 57) | type PartInfo struct
  type CreateResp (line 65) | type CreateResp struct
  type MoveOrCopyResp (line 80) | type MoveOrCopyResp struct

FILE: drivers/aliyundrive_open/upload.go
  function makePartInfos (line 25) | func makePartInfos(size int) []base.Json {
  function calPartSize (line 33) | func calPartSize(fileSize int64) int64 {
  method getUploadUrl (line 53) | func (d *AliyundriveOpen) getUploadUrl(count int, fileId, uploadId strin...
  method uploadPart (line 67) | func (d *AliyundriveOpen) uploadPart(ctx context.Context, r io.Reader, p...
  method completeUpload (line 87) | func (d *AliyundriveOpen) completeUpload(fileId, uploadId string) (model...
  type ProofRange (line 103) | type ProofRange struct
  function getProofRange (line 108) | func getProofRange(input string, size int64) (*ProofRange, error) {
  method calProofCode (line 128) | func (d *AliyundriveOpen) calProofCode(stream model.FileStreamer) (strin...
  method upload (line 149) | func (d *AliyundriveOpen) upload(ctx context.Context, dstDir model.Obj, ...

FILE: drivers/aliyundrive_open/util.go
  method _refreshToken (line 22) | func (d *AliyundriveOpen) _refreshToken() (string, string, error) {
  function getSub (line 65) | func getSub(token string) (string, error) {
  method refreshToken (line 77) | func (d *AliyundriveOpen) refreshToken() error {
  method request (line 99) | func (d *AliyundriveOpen) request(uri, method string, callback base.ReqC...
  method requestReturnErrResp (line 104) | func (d *AliyundriveOpen) requestReturnErrResp(uri, method string, callb...
  method list (line 137) | func (d *AliyundriveOpen) list(ctx context.Context, data base.Json) (*Fi...
  method getFiles (line 148) | func (d *AliyundriveOpen) getFiles(ctx context.Context, fileId string) (...
  function getNowTime (line 178) | func getNowTime() (time.Time, string) {
  method getAccessToken (line 184) | func (d *AliyundriveOpen) getAccessToken() string {
  method removeDuplicateFiles (line 193) | func (d *AliyundriveOpen) removeDuplicateFiles(ctx context.Context, pare...

FILE: drivers/aliyundrive_share/driver.go
  type AliyundriveShare (line 20) | type AliyundriveShare struct
    method Config (line 32) | func (d *AliyundriveShare) Config() driver.Config {
    method GetAddition (line 36) | func (d *AliyundriveShare) GetAddition() driver.Additional {
    method Init (line 40) | func (d *AliyundriveShare) Init(ctx context.Context) error {
    method Drop (line 67) | func (d *AliyundriveShare) Drop(ctx context.Context) error {
    method List (line 75) | func (d *AliyundriveShare) List(ctx context.Context, dir model.Obj, ar...
    method list (line 82) | func (d *AliyundriveShare) list(ctx context.Context, dir model.Obj) ([...
    method Link (line 92) | func (d *AliyundriveShare) Link(ctx context.Context, file model.Obj, a...
    method link (line 99) | func (d *AliyundriveShare) link(ctx context.Context, file model.Obj) (...
    method Other (line 122) | func (d *AliyundriveShare) Other(ctx context.Context, args model.Other...

FILE: drivers/aliyundrive_share/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 25) | func init() {

FILE: drivers/aliyundrive_share/types.go
  type ErrorResp (line 9) | type ErrorResp struct
  type ShareTokenResp (line 14) | type ShareTokenResp struct
  type ListResp (line 20) | type ListResp struct
  type File (line 26) | type File struct
  function fileToObj (line 40) | func fileToObj(f File) *model.ObjThumb {
  type ShareLinkResp (line 54) | type ShareLinkResp struct

FILE: drivers/aliyundrive_share/util.go
  constant CanaryHeaderKey (line 14) | CanaryHeaderKey   = "X-Canary"
  constant CanaryHeaderValue (line 15) | CanaryHeaderValue = "client=web,app=share,version=v2.3.1"
  method refreshToken (line 18) | func (d *AliyundriveShare) refreshToken() error {
  method getShareToken (line 39) | func (d *AliyundriveShare) getShareToken() error {
  method request (line 61) | func (d *AliyundriveShare) request(url, method string, callback base.Req...
  method getFiles (line 96) | func (d *AliyundriveShare) getFiles(fileId string) ([]File, error) {

FILE: drivers/all.go
  function All (line 90) | func All() {

FILE: drivers/azure_blob/driver.go
  type AzureBlob (line 22) | type AzureBlob struct
    method Config (line 31) | func (d *AzureBlob) Config() driver.Config {
    method GetAddition (line 36) | func (d *AzureBlob) GetAddition() driver.Additional {
    method Init (line 41) | func (d *AzureBlob) Init(ctx context.Context) error {
    method Drop (line 80) | func (d *AzureBlob) Drop(ctx context.Context) error {
    method List (line 86) | func (d *AzureBlob) List(ctx context.Context, dir model.Obj, args mode...
    method Link (line 130) | func (d *AzureBlob) Link(ctx context.Context, file model.Obj, args mod...
    method MakeDir (line 142) | func (d *AzureBlob) MakeDir(ctx context.Context, parentDir model.Obj, ...
    method Move (line 156) | func (d *AzureBlob) Move(ctx context.Context, srcObj, dstDir model.Obj...
    method Rename (line 174) | func (d *AzureBlob) Rename(ctx context.Context, srcObj model.Obj, newN...
    method Copy (line 192) | func (d *AzureBlob) Copy(ctx context.Context, srcObj, dstDir model.Obj...
    method Remove (line 262) | func (d *AzureBlob) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 275) | func (d *AzureBlob) Put(ctx context.Context, dstDir model.Obj, stream ...

FILE: drivers/azure_blob/meta.go
  type Addition (line 8) | type Addition struct
    method GetRootId (line 16) | func (r Addition) GetRootId() string {
  function init (line 26) | func init() {

FILE: drivers/azure_blob/types.go
  type progressTracker (line 6) | type progressTracker struct
    method Write (line 13) | func (pt *progressTracker) Write(p []byte) (n int, err error) {

FILE: drivers/azure_blob/util.go
  constant MaxRetries (line 26) | MaxRetries = 3
  constant RetryDelay (line 28) | RetryDelay = 3 * time.Second
  constant MaxBatchSize (line 30) | MaxBatchSize = 128
  function extractAccountName (line 34) | func extractAccountName(endpoint string) string {
  function isNotFoundError (line 49) | func isNotFoundError(err error) bool {
  method flattenListBlobs (line 59) | func (d *AzureBlob) flattenListBlobs(ctx context.Context, prefix string)...
  method batchDeleteBlobs (line 86) | func (d *AzureBlob) batchDeleteBlobs(ctx context.Context, blobPaths []st...
  method deleteFolder (line 132) | func (d *AzureBlob) deleteFolder(ctx context.Context, prefix string) err...
  method deleteFile (line 194) | func (d *AzureBlob) deleteFile(ctx context.Context, path string, isDir b...
  method copyFile (line 204) | func (d *AzureBlob) copyFile(ctx context.Context, srcPath, dstPath strin...
  method createContainerIfNotExists (line 222) | func (d *AzureBlob) createContainerIfNotExists(ctx context.Context, cont...
  method mkDir (line 240) | func (d *AzureBlob) mkDir(ctx context.Context, fullDirName string) error {
  function ensureTrailingSlash (line 260) | func ensureTrailingSlash(path string) string {
  method moveOrRename (line 268) | func (d *AzureBlob) moveOrRename(ctx context.Context, srcPath, dstPath s...
  function optimizedUploadOptions (line 331) | func optimizedUploadOptions(fileSize int64) *azblob.UploadStreamOptions {
  function isDirectory (line 354) | func isDirectory(blob container.BlobItem) bool {
  method deleteEmptyDirectory (line 383) | func (d *AzureBlob) deleteEmptyDirectory(ctx context.Context, dirPath st...

FILE: drivers/baidu_netdisk/driver.go
  type BaiduNetdisk (line 31) | type BaiduNetdisk struct
    method Config (line 47) | func (d *BaiduNetdisk) Config() driver.Config {
    method GetAddition (line 51) | func (d *BaiduNetdisk) GetAddition() driver.Additional {
    method Init (line 55) | func (d *BaiduNetdisk) Init(ctx context.Context) error {
    method Drop (line 83) | func (d *BaiduNetdisk) Drop(ctx context.Context) error {
    method List (line 87) | func (d *BaiduNetdisk) List(ctx context.Context, dir model.Obj, args m...
    method Link (line 97) | func (d *BaiduNetdisk) Link(ctx context.Context, file model.Obj, args ...
    method MakeDir (line 106) | func (d *BaiduNetdisk) MakeDir(ctx context.Context, parentDir model.Ob...
    method Move (line 115) | func (d *BaiduNetdisk) Move(ctx context.Context, srcObj, dstDir model....
    method Rename (line 135) | func (d *BaiduNetdisk) Rename(ctx context.Context, srcObj model.Obj, n...
    method Copy (line 156) | func (d *BaiduNetdisk) Copy(ctx context.Context, srcObj, dstDir model....
    method Remove (line 168) | func (d *BaiduNetdisk) Remove(ctx context.Context, obj model.Obj) error {
    method PutRapid (line 174) | func (d *BaiduNetdisk) PutRapid(ctx context.Context, dstDir model.Obj,...
    method Put (line 201) | func (d *BaiduNetdisk) Put(ctx context.Context, dstDir model.Obj, stre...
    method precreate (line 395) | func (d *BaiduNetdisk) precreate(ctx context.Context, path string, str...
    method uploadSlice (line 429) | func (d *BaiduNetdisk) uploadSlice(ctx context.Context, uploadUrl stri...

FILE: drivers/baidu_netdisk/meta.go
  type Addition (line 10) | type Addition struct
  constant UPLOAD_FALLBACK_API (line 29) | UPLOAD_FALLBACK_API        = "https://d.pcs.baidu.com"
  constant UPLOAD_URL_EXPIRE_TIME (line 30) | UPLOAD_URL_EXPIRE_TIME     = time.Minute * 60
  constant UPLOAD_TIMEOUT (line 31) | UPLOAD_TIMEOUT             = time.Minute * 30
  constant UPLOAD_RETRY_COUNT (line 32) | UPLOAD_RETRY_COUNT         = 3
  constant UPLOAD_RETRY_WAIT_TIME (line 33) | UPLOAD_RETRY_WAIT_TIME     = time.Second * 1
  constant UPLOAD_RETRY_MAX_WAIT_TIME (line 34) | UPLOAD_RETRY_MAX_WAIT_TIME = time.Second * 5
  function init (line 42) | func init() {

FILE: drivers/baidu_netdisk/types.go
  type TokenErrResp (line 17) | type TokenErrResp struct
  type File (line 22) | type File struct
  function fileToObj (line 60) | func fileToObj(f File) *model.ObjThumb {
  type ListResp (line 87) | type ListResp struct
  type DownloadResp (line 95) | type DownloadResp struct
  type DownloadResp2 (line 125) | type DownloadResp2 struct
  type PrecreateResp (line 184) | type PrecreateResp struct
  type UploadServerResp (line 198) | type UploadServerResp struct

FILE: drivers/baidu_netdisk/util.go
  method refreshToken (line 25) | func (d *BaiduNetdisk) refreshToken() error {
  method _refreshToken (line 33) | func (d *BaiduNetdisk) _refreshToken() error {
  method request (line 57) | func (d *BaiduNetdisk) request(furl string, method string, callback base...
  method get (line 100) | func (d *BaiduNetdisk) get(pathname string, params map[string]string, re...
  method postForm (line 106) | func (d *BaiduNetdisk) postForm(pathname string, params map[string]strin...
  method getFiles (line 113) | func (d *BaiduNetdisk) getFiles(dir string) ([]File, error) {
  method linkOfficial (line 154) | func (d *BaiduNetdisk) linkOfficial(file model.Obj, _ model.LinkArgs) (*...
  method linkCrack (line 182) | func (d *BaiduNetdisk) linkCrack(file model.Obj, _ model.LinkArgs) (*mod...
  method linkCrackVideo (line 205) | func (d *BaiduNetdisk) linkCrackVideo(file model.Obj, _ model.LinkArgs) ...
  method manage (line 233) | func (d *BaiduNetdisk) manage(opera string, filelist any) ([]byte, error) {
  method create (line 246) | func (d *BaiduNetdisk) create(path string, size int64, isdir int, upload...
  function joinTime (line 269) | func joinTime(form map[string]string, ctime, mtime int64) {
  constant DefaultSliceSize (line 275) | DefaultSliceSize int64 = 4 * utils.MB
  constant VipSliceSize (line 276) | VipSliceSize     int64 = 16 * utils.MB
  constant SVipSliceSize (line 277) | SVipSliceSize    int64 = 32 * utils.MB
  constant MaxSliceNum (line 279) | MaxSliceNum       = 2048
  constant SliceStep (line 280) | SliceStep   int64 = 1 * utils.MB
  method getSliceSize (line 283) | func (d *BaiduNetdisk) getSliceSize(filesize int64) int64 {
  method getUploadUrl (line 346) | func (d *BaiduNetdisk) getUploadUrl(path, uploadId string) string {
  method requestForUploadUrl (line 393) | func (d *BaiduNetdisk) requestForUploadUrl(path, uploadId string) (strin...
  function DecryptMd5 (line 427) | func DecryptMd5(encryptMd5 string) string {
  function EncryptMd5 (line 447) | func EncryptMd5(originalMd5 string) string {

FILE: drivers/baidu_photo/driver.go
  type BaiduPhoto (line 29) | type BaiduPhoto struct
    method Config (line 41) | func (d *BaiduPhoto) Config() driver.Config {
    method GetAddition (line 45) | func (d *BaiduPhoto) GetAddition() driver.Additional {
    method Init (line 49) | func (d *BaiduPhoto) Init(ctx context.Context) error {
    method GetRoot (line 88) | func (d *BaiduPhoto) GetRoot(ctx context.Context) (model.Obj, error) {
    method Drop (line 92) | func (d *BaiduPhoto) Drop(ctx context.Context) error {
    method List (line 99) | func (d *BaiduPhoto) List(ctx context.Context, dir model.Obj, args mod...
    method Link (line 143) | func (d *BaiduPhoto) Link(ctx context.Context, file model.Obj, args mo...
    method MakeDir (line 166) | func (d *BaiduPhoto) MakeDir(ctx context.Context, parentDir model.Obj,...
    method Copy (line 177) | func (d *BaiduPhoto) Copy(ctx context.Context, srcObj, dstDir model.Ob...
    method Move (line 201) | func (d *BaiduPhoto) Move(ctx context.Context, srcObj, dstDir model.Ob...
    method Rename (line 217) | func (d *BaiduPhoto) Rename(ctx context.Context, srcObj model.Obj, new...
    method Remove (line 225) | func (d *BaiduPhoto) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 237) | func (d *BaiduPhoto) Put(ctx context.Context, dstDir model.Obj, stream...

FILE: drivers/baidu_photo/help.go
  function getTid (line 14) | func getTid() string {
  function toTime (line 18) | func toTime(t int64) *time.Time {
  function fsidsFormatNotUk (line 23) | func fsidsFormatNotUk(ids ...int64) string {
  function getFileName (line 30) | func getFileName(path string) string {
  function MustString (line 34) | func MustString(str string, err error) string {
  function copyFile (line 42) | func copyFile(file *AlbumFile, cf *CopyFile) *File {
  function moveFileToAlbumFile (line 53) | func moveFileToAlbumFile(file *File, album *Album, uk int64) *AlbumFile {
  function renameAlbum (line 62) | func renameAlbum(album *Album, newName string) *Album {
  function BoolToIntStr (line 73) | func BoolToIntStr(b bool) string {

FILE: drivers/baidu_photo/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 25) | func init() {

FILE: drivers/baidu_photo/types.go
  type TokenErrResp (line 12) | type TokenErrResp struct
    method Error (line 17) | func (e *TokenErrResp) Error() string {
  type Erron (line 21) | type Erron struct
  type UInfo (line 27) | type UInfo struct
  type Page (line 32) | type Page struct
    method HasNextPage (line 37) | func (p Page) HasNextPage() bool {
  type FileListResp (line 44) | type FileListResp struct
  type File (line 49) | type File struct
    method GetSize (line 60) | func (c *File) GetSize() int64        { return c.Size }
    method GetName (line 61) | func (c *File) GetName() string       { return getFileName(c.Path) }
    method CreateTime (line 62) | func (c *File) CreateTime() time.Time { return time.Unix(c.Ctime, 0) }
    method ModTime (line 63) | func (c *File) ModTime() time.Time    { return time.Unix(c.Mtime, 0) }
    method IsDir (line 64) | func (c *File) IsDir() bool           { return false }
    method GetID (line 65) | func (c *File) GetID() string         { return "" }
    method GetPath (line 66) | func (c *File) GetPath() string       { return "" }
    method Thumb (line 67) | func (c *File) Thumb() string {
    method GetHash (line 74) | func (c *File) GetHash() utils.HashInfo {
  type AlbumListResp (line 80) | type AlbumListResp struct
  type Album (line 87) | type Album struct
    method GetHash (line 113) | func (a *Album) GetHash() utils.HashInfo {
    method GetSize (line 117) | func (a *Album) GetSize() int64        { return 0 }
    method GetName (line 118) | func (a *Album) GetName() string       { return a.Title }
    method CreateTime (line 119) | func (a *Album) CreateTime() time.Time { return time.Unix(a.CreationTi...
    method ModTime (line 120) | func (a *Album) ModTime() time.Time    { return time.Unix(a.Mtime, 0) }
    method IsDir (line 121) | func (a *Album) IsDir() bool           { return true }
    method GetID (line 122) | func (a *Album) GetID() string         { return "" }
    method GetPath (line 123) | func (a *Album) GetPath() string       { return "" }
  type AlbumFileListResp (line 98) | type AlbumFileListResp struct
  type AlbumFile (line 105) | type AlbumFile struct
  type CopyFileResp (line 126) | type CopyFileResp struct
  type CopyFile (line 129) | type CopyFile struct
  type UploadFile (line 140) | type UploadFile struct
    method toFile (line 170) | func (f *UploadFile) toFile() *File {
  type CreateFileResp (line 154) | type CreateFileResp struct
  type PrecreateResp (line 158) | type PrecreateResp struct
  type InviteResp (line 182) | type InviteResp struct
  type JoinOrCreateAlbumResp (line 193) | type JoinOrCreateAlbumResp struct

FILE: drivers/baidu_photo/utils.go
  constant API_URL (line 19) | API_URL         = "https://photo.baidu.com/youai"
  constant USER_API_URL (line 20) | USER_API_URL    = API_URL + "/user/v1"
  constant ALBUM_API_URL (line 21) | ALBUM_API_URL   = API_URL + "/album/v1"
  constant FILE_API_URL_V1 (line 22) | FILE_API_URL_V1 = API_URL + "/file/v1"
  constant FILE_API_URL_V2 (line 23) | FILE_API_URL_V2 = API_URL + "/file/v2"
  method Request (line 26) | func (d *BaiduPhoto) Request(client *resty.Client, furl string, method s...
  method Get (line 93) | func (d *BaiduPhoto) Get(furl string, callback base.ReqCallback, resp in...
  method Post (line 97) | func (d *BaiduPhoto) Post(furl string, callback base.ReqCallback, resp i...
  method GetAllFile (line 102) | func (d *BaiduPhoto) GetAllFile(ctx context.Context) (files []File, err ...
  method DeleteFile (line 127) | func (d *BaiduPhoto) DeleteFile(ctx context.Context, file *File) error {
  method GetAllAlbum (line 138) | func (d *BaiduPhoto) GetAllAlbum(ctx context.Context) (albums []Album, e...
  method GetAllAlbumFile (line 167) | func (d *BaiduPhoto) GetAllAlbumFile(ctx context.Context, album *Album, ...
  method CreateAlbum (line 198) | func (d *BaiduPhoto) CreateAlbum(ctx context.Context, name string) (*Alb...
  method SetAlbumName (line 215) | func (d *BaiduPhoto) SetAlbumName(ctx context.Context, album *Album, nam...
  method DeleteAlbum (line 231) | func (d *BaiduPhoto) DeleteAlbum(ctx context.Context, album *Album) error {
  method DeleteAlbumFile (line 244) | func (d *BaiduPhoto) DeleteAlbumFile(ctx context.Context, file *AlbumFil...
  method AddAlbumFile (line 258) | func (d *BaiduPhoto) AddAlbumFile(ctx context.Context, album *Album, fil...
  method CopyAlbumFile (line 274) | func (d *BaiduPhoto) CopyAlbumFile(ctx context.Context, file *AlbumFile)...
  method JoinAlbum (line 293) | func (d *BaiduPhoto) JoinAlbum(ctx context.Context, code string) (*Album...
  method GetAlbumDetail (line 319) | func (d *BaiduPhoto) GetAlbumDetail(ctx context.Context, albumID string)...
  method linkAlbum (line 333) | func (d *BaiduPhoto) linkAlbum(ctx context.Context, file *AlbumFile, arg...
  method linkFile (line 375) | func (d *BaiduPhoto) linkFile(ctx context.Context, file *File, args mode...
  method uInfo (line 468) | func (d *BaiduPhoto) uInfo() (*UInfo, error) {
  method getBDStoken (line 479) | func (d *BaiduPhoto) getBDStoken() (string, error) {
  function DecryptMd5 (line 494) | func DecryptMd5(encryptMd5 string) string {
  function EncryptMd5 (line 514) | func EncryptMd5(originalMd5 string) string {

FILE: drivers/baidu_share/driver.go
  type BaiduShare (line 19) | type BaiduShare struct
    method Config (line 31) | func (d *BaiduShare) Config() driver.Config {
    method GetAddition (line 35) | func (d *BaiduShare) GetAddition() driver.Additional {
    method Init (line 39) | func (d *BaiduShare) Init(ctx context.Context) error {
    method Drop (line 79) | func (d *BaiduShare) Drop(ctx context.Context) error {
    method List (line 83) | func (d *BaiduShare) List(ctx context.Context, dir model.Obj, args mod...
    method Link (line 149) | func (d *BaiduShare) Link(ctx context.Context, file model.Obj, args mo...
    method MakeDir (line 217) | func (d *BaiduShare) MakeDir(ctx context.Context, parentDir model.Obj,...
    method Move (line 222) | func (d *BaiduShare) Move(ctx context.Context, srcObj, dstDir model.Ob...
    method Rename (line 227) | func (d *BaiduShare) Rename(ctx context.Context, srcObj model.Obj, new...
    method Copy (line 232) | func (d *BaiduShare) Copy(ctx context.Context, srcObj, dstDir model.Ob...
    method Remove (line 237) | func (d *BaiduShare) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 242) | func (d *BaiduShare) Put(ctx context.Context, dstDir model.Obj, stream...

FILE: drivers/baidu_share/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 33) | func init() {

FILE: drivers/base/client.go
  function InitClient (line 21) | func InitClient() {
  function NewRestyClient (line 33) | func NewRestyClient() *resty.Client {

FILE: drivers/base/types.go
  type Json (line 5) | type Json
  type TokenResp (line 7) | type TokenResp struct
  type ReqCallback (line 12) | type ReqCallback

FILE: drivers/base/upload.go
  function SaveUploadProgress (line 16) | func SaveUploadProgress(driver driver.Driver, state any, keys ...string)...
  function GetUploadProgress (line 25) | func GetUploadProgress[T any](driver driver.Driver, keys ...string) (sta...

FILE: drivers/bitqiu/driver.go
  constant baseURL (line 26) | baseURL             = "https://pan.bitqiu.com"
  constant loginURL (line 27) | loginURL            = baseURL + "/loginServer/login"
  constant userInfoURL (line 28) | userInfoURL         = baseURL + "/user/getInfo"
  constant listURL (line 29) | listURL             = baseURL + "/apiToken/cfi/fs/resources/pages"
  constant uploadInitializeURL (line 30) | uploadInitializeURL = baseURL + "/apiToken/cfi/fs/upload/v2/initialize"
  constant uploadCompleteURL (line 31) | uploadCompleteURL   = baseURL + "/apiToken/cfi/fs/upload/v2/complete"
  constant downloadURL (line 32) | downloadURL         = baseURL + "/download/getUrl"
  constant createDirURL (line 33) | createDirURL        = baseURL + "/resource/create"
  constant moveResourceURL (line 34) | moveResourceURL     = baseURL + "/resource/remove"
  constant renameResourceURL (line 35) | renameResourceURL   = baseURL + "/resource/rename"
  constant copyResourceURL (line 36) | copyResourceURL     = baseURL + "/apiToken/cfi/fs/async/copy"
  constant copyManagerURL (line 37) | copyManagerURL      = baseURL + "/apiToken/cfi/fs/async/manager"
  constant deleteResourceURL (line 38) | deleteResourceURL   = baseURL + "/resource/delete"
  constant successCode (line 40) | successCode       = "10200"
  constant uploadSuccessCode (line 41) | uploadSuccessCode = "30010"
  constant copySubmittedCode (line 42) | copySubmittedCode = "10300"
  constant orgChannel (line 43) | orgChannel        = "default|default|default"
  constant copyPollInterval (line 47) | copyPollInterval    = time.Second
  constant copyPollMaxAttempts (line 48) | copyPollMaxAttempts = 60
  constant chunkSize (line 49) | chunkSize           = int64(1 << 20)
  constant defaultUserAgent (line 52) | defaultUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKi...
  type BitQiu (line 54) | type BitQiu struct
    method Config (line 62) | func (d *BitQiu) Config() driver.Config {
    method GetAddition (line 66) | func (d *BitQiu) GetAddition() driver.Additional {
    method Init (line 70) | func (d *BitQiu) Init(ctx context.Context) error {
    method Drop (line 90) | func (d *BitQiu) Drop(ctx context.Context) error {
    method List (line 96) | func (d *BitQiu) List(ctx context.Context, dir model.Obj, args model.L...
    method Link (line 157) | func (d *BitQiu) Link(ctx context.Context, file model.Obj, args model....
    method MakeDir (line 193) | func (d *BitQiu) MakeDir(ctx context.Context, parentDir model.Obj, dir...
    method Move (line 250) | func (d *BitQiu) Move(ctx context.Context, srcObj, dstDir model.Obj) (...
    method Rename (line 299) | func (d *BitQiu) Rename(ctx context.Context, srcObj model.Obj, newName...
    method Copy (line 335) | func (d *BitQiu) Copy(ctx context.Context, srcObj, dstDir model.Obj) (...
    method Remove (line 375) | func (d *BitQiu) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 412) | func (d *BitQiu) Put(ctx context.Context, dstDir model.Obj, file model...
    method uploadFileInChunks (line 477) | func (d *BitQiu) uploadFileInChunks(ctx context.Context, tmpFile model...
    method completeChunkUpload (line 538) | func (d *BitQiu) completeChunkUpload(ctx context.Context, initData Upl...
    method login (line 567) | func (d *BitQiu) login(ctx context.Context) error {
    method ensureRootFolderID (line 590) | func (d *BitQiu) ensureRootFolderID(ctx context.Context) error {
    method postForm (line 616) | func (d *BitQiu) postForm(ctx context.Context, url string, form map[st...
    method waitForCopiedObject (line 631) | func (d *BitQiu) waitForCopiedObject(ctx context.Context, srcObj, dstD...
    method checkCopyFailure (line 662) | func (d *BitQiu) checkCopyFailure(ctx context.Context) error {
    method findObjectInDir (line 688) | func (d *BitQiu) findObjectInDir(ctx context.Context, dir model.Obj, n...
    method commonHeaders (line 712) | func (d *BitQiu) commonHeaders() map[string]string {
    method userAgent (line 728) | func (d *BitQiu) userAgent() string {
    method resolveParentID (line 735) | func (d *BitQiu) resolveParentID(dir model.Obj) string {
    method pageSize (line 745) | func (d *BitQiu) pageSize() int {
    method orderType (line 752) | func (d *BitQiu) orderType() string {
    method orderDesc (line 759) | func (d *BitQiu) orderDesc() string {
  function waitWithContext (line 701) | func waitWithContext(ctx context.Context, d time.Duration) error {

FILE: drivers/bitqiu/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 24) | func init() {

FILE: drivers/bitqiu/types.go
  type Response (line 5) | type Response struct
  type LoginData (line 11) | type LoginData struct
  type ResourcePage (line 15) | type ResourcePage struct
  type Resource (line 24) | type Resource struct
  type DownloadData (line 37) | type DownloadData struct
  type UserInfoData (line 43) | type UserInfoData struct
  type CreateDirData (line 47) | type CreateDirData struct
  type AsyncManagerData (line 53) | type AsyncManagerData struct
  type AsyncTask (line 61) | type AsyncTask struct
    method ErrorMessage (line 79) | func (t AsyncTask) ErrorMessage() string {
  type AsyncTaskInfo (line 71) | type AsyncTaskInfo struct
  type UploadInitData (line 89) | type UploadInitData struct
  type ChunkUploadResponse (line 102) | type ChunkUploadResponse struct

FILE: drivers/bitqiu/util.go
  type Object (line 12) | type Object struct
  method toObject (line 17) | func (r Resource) toObject(parentID, parentPath string) (model.Obj, erro...
  function parseBitQiuTime (line 48) | func parseBitQiuTime(value *string) time.Time {
  function updateObjectName (line 62) | func updateObjectName(obj model.Obj, newName string) model.Obj {
  function parentPathOf (line 93) | func parentPathOf(p string) string {

FILE: drivers/chaoxing/driver.go
  type ChaoXing (line 26) | type ChaoXing struct
    method Config (line 34) | func (d *ChaoXing) Config() driver.Config {
    method GetAddition (line 38) | func (d *ChaoXing) GetAddition() driver.Additional {
    method refreshCookie (line 42) | func (d *ChaoXing) refreshCookie() error {
    method Init (line 54) | func (d *ChaoXing) Init(ctx context.Context) error {
    method Drop (line 69) | func (d *ChaoXing) Drop(ctx context.Context) error {
    method List (line 76) | func (d *ChaoXing) List(ctx context.Context, dir model.Obj, args model...
    method Link (line 86) | func (d *ChaoXing) Link(ctx context.Context, file model.Obj, args mode...
    method MakeDir (line 109) | func (d *ChaoXing) MakeDir(ctx context.Context, parentDir model.Obj, d...
    method Move (line 129) | func (d *ChaoXing) Move(ctx context.Context, srcObj, dstDir model.Obj)...
    method Rename (line 156) | func (d *ChaoXing) Rename(ctx context.Context, srcObj model.Obj, newNa...
    method Copy (line 186) | func (d *ChaoXing) Copy(ctx context.Context, srcObj, dstDir model.Obj)...
    method Remove (line 191) | func (d *ChaoXing) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 218) | func (d *ChaoXing) Put(ctx context.Context, dstDir model.Obj, file mod...

FILE: drivers/chaoxing/meta.go
  type Addition (line 11) | type Addition struct
  type Conf (line 22) | type Conf struct
  function init (line 29) | func init() {

FILE: drivers/chaoxing/types.go
  type Resp (line 12) | type Resp struct
  type UserAuth (line 16) | type UserAuth struct
  type int_str (line 96) | type int_str
    method UnmarshalJSON (line 99) | func (ios *int_str) UnmarshalJSON(data []byte) error {
  type File (line 108) | type File struct
  type ListFileResp (line 161) | type ListFileResp struct
  type DownResp (line 169) | type DownResp struct
  type UploadDataRsp (line 178) | type UploadDataRsp struct
  type UploadFileDataRsp (line 186) | type UploadFileDataRsp struct
  type UploadDoneParam (line 224) | type UploadDoneParam struct
  function fileToObj (line 258) | func fileToObj(f File) *model.Object {

FILE: drivers/chaoxing/util.go
  method requestDownload (line 18) | func (d *ChaoXing) requestDownload(pathname string, method string, callb...
  method request (line 41) | func (d *ChaoXing) request(pathname string, method string, callback base...
  method GetFiles (line 67) | func (d *ChaoXing) GetFiles(parent string) ([]File, error) {
  function EncryptByAES (line 110) | func EncryptByAES(message, key string) (string, error) {
  function CookiesToString (line 130) | func CookiesToString(cookies []*http.Cookie) string {
  method Login (line 141) | func (d *ChaoXing) Login() (string, error) {

FILE: drivers/cloudreve/driver.go
  type Cloudreve (line 18) | type Cloudreve struct
    method Config (line 24) | func (d *Cloudreve) Config() driver.Config {
    method GetAddition (line 28) | func (d *Cloudreve) GetAddition() driver.Additional {
    method Init (line 32) | func (d *Cloudreve) Init(ctx context.Context) error {
    method InitReference (line 41) | func (d *Cloudreve) InitReference(storage driver.Driver) error {
    method Drop (line 50) | func (d *Cloudreve) Drop(ctx context.Context) error {
    method List (line 56) | func (d *Cloudreve) List(ctx context.Context, dir model.Obj, args mode...
    method Link (line 80) | func (d *Cloudreve) Link(ctx context.Context, file model.Obj, args mod...
    method MakeDir (line 94) | func (d *Cloudreve) MakeDir(ctx context.Context, parentDir model.Obj, ...
    method Move (line 102) | func (d *Cloudreve) Move(ctx context.Context, srcObj, dstDir model.Obj...
    method Rename (line 114) | func (d *Cloudreve) Rename(ctx context.Context, srcObj model.Obj, newN...
    method Copy (line 125) | func (d *Cloudreve) Copy(ctx context.Context, srcObj, dstDir model.Obj...
    method Remove (line 136) | func (d *Cloudreve) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 144) | func (d *Cloudreve) Put(ctx context.Context, dstDir model.Obj, stream ...
    method create (line 193) | func (d *Cloudreve) create(ctx context.Context, dir model.Obj, file mo...

FILE: drivers/cloudreve/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 25) | func init() {

FILE: drivers/cloudreve/types.go
  type Resp (line 9) | type Resp struct
  type Policy (line 15) | type Policy struct
  type UploadInfo (line 23) | type UploadInfo struct
  type DirectoryResp (line 32) | type DirectoryResp struct
  type Object (line 38) | type Object struct
  type DirectoryProp (line 50) | type DirectoryProp struct
  function objectToObj (line 54) | func objectToObj(f Object, t model.Thumbnail) *model.ObjThumb {
  type Config (line 67) | type Config struct

FILE: drivers/cloudreve/util.go
  constant loginPath (line 29) | loginPath = "/user/session"
  method getUA (line 31) | func (d *Cloudreve) getUA() string {
  method request (line 38) | func (d *Cloudreve) request(method string, path string, callback base.Re...
  method login (line 99) | func (d *Cloudreve) login() error {
  method doLogin (line 117) | func (d *Cloudreve) doLogin(needCaptcha bool) error {
  function convertSrc (line 153) | func convertSrc(obj model.Obj) map[string]interface{} {
  method GetThumb (line 167) | func (d *Cloudreve) GetThumb(file Object) (model.Thumbnail, error) {
  method upLocal (line 186) | func (d *Cloudreve) upLocal(ctx context.Context, stream model.FileStream...
  method upRemote (line 237) | func (d *Cloudreve) upRemote(ctx context.Context, stream model.FileStrea...
  method upOneDrive (line 309) | func (d *Cloudreve) upOneDrive(ctx context.Context, stream model.FileStr...
  method upS3 (line 370) | func (d *Cloudreve) upS3(ctx context.Context, stream model.FileStreamer,...

FILE: drivers/cloudreve_v4/driver.go
  type CloudreveV4 (line 20) | type CloudreveV4 struct
    method Config (line 26) | func (d *CloudreveV4) Config() driver.Config {
    method GetAddition (line 36) | func (d *CloudreveV4) GetAddition() driver.Additional {
    method Init (line 40) | func (d *CloudreveV4) Init(ctx context.Context) error {
    method InitReference (line 56) | func (d *CloudreveV4) InitReference(storage driver.Driver) error {
    method Drop (line 65) | func (d *CloudreveV4) Drop(ctx context.Context) error {
    method List (line 70) | func (d *CloudreveV4) List(ctx context.Context, dir model.Obj, args mo...
    method Link (line 134) | func (d *CloudreveV4) Link(ctx context.Context, file model.Obj, args m...
    method MakeDir (line 155) | func (d *CloudreveV4) MakeDir(ctx context.Context, parentDir model.Obj...
    method Move (line 165) | func (d *CloudreveV4) Move(ctx context.Context, srcObj, dstDir model.O...
    method Rename (line 175) | func (d *CloudreveV4) Rename(ctx context.Context, srcObj model.Obj, ne...
    method Copy (line 185) | func (d *CloudreveV4) Copy(ctx context.Context, srcObj, dstDir model.O...
    method Remove (line 195) | func (d *CloudreveV4) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 205) | func (d *CloudreveV4) Put(ctx context.Context, dstDir model.Obj, file ...
    method GetArchiveMeta (line 279) | func (d *CloudreveV4) GetArchiveMeta(ctx context.Context, obj model.Ob...
    method ListArchive (line 284) | func (d *CloudreveV4) ListArchive(ctx context.Context, obj model.Obj, ...
    method Extract (line 289) | func (d *CloudreveV4) Extract(ctx context.Context, obj model.Obj, args...
    method ArchiveDecompress (line 294) | func (d *CloudreveV4) ArchiveDecompress(ctx context.Context, srcObj, d...

FILE: drivers/cloudreve_v4/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 40) | func init() {

FILE: drivers/cloudreve_v4/types.go
  type Object (line 9) | type Object struct
  type Resp (line 14) | type Resp struct
  type BasicConfigResp (line 20) | type BasicConfigResp struct
  type SiteLoginConfigResp (line 43) | type SiteLoginConfigResp struct
  type PrepareLoginResp (line 48) | type PrepareLoginResp struct
  type CaptchaResp (line 53) | type CaptchaResp struct
  type Token (line 58) | type Token struct
  type TokenResponse (line 65) | type TokenResponse struct
  type File (line 84) | type File struct
  type StoragePolicy (line 98) | type StoragePolicy struct
  type Pagination (line 106) | type Pagination struct
  type Props (line 113) | type Props struct
  type FileResp (line 120) | type FileResp struct
  type FileUrlResp (line 130) | type FileUrlResp struct
  type FileUploadResp (line 137) | type FileUploadResp struct
  type FileThumbResp (line 150) | type FileThumbResp struct
  type FolderSummaryResp (line 155) | type FolderSummaryResp struct

FILE: drivers/cloudreve_v4/util.go
  method getUA (line 29) | func (d *CloudreveV4) getUA() string {
  method request (line 36) | func (d *CloudreveV4) request(method string, path string, callback base....
  method login (line 92) | func (d *CloudreveV4) login() error {
  method doLogin (line 124) | func (d *CloudreveV4) doLogin(needCaptcha bool) error {
  method refreshToken (line 177) | func (d *CloudreveV4) refreshToken() error {
  method upLocal (line 201) | func (d *CloudreveV4) upLocal(ctx context.Context, file model.FileStream...
  method upRemote (line 255) | func (d *CloudreveV4) upRemote(ctx context.Context, file model.FileStrea...
  method upOneDrive (line 327) | func (d *CloudreveV4) upOneDrive(ctx context.Context, file model.FileStr...
  method upS3 (line 388) | func (d *CloudreveV4) upS3(ctx context.Context, file model.FileStreamer,...

FILE: drivers/crypt/driver.go
  type Crypt (line 27) | type Crypt struct
    method Config (line 36) | func (d *Crypt) Config() driver.Config {
    method GetAddition (line 40) | func (d *Crypt) GetAddition() driver.Additional {
    method Init (line 44) | func (d *Crypt) Init(ctx context.Context) error {
    method updateObfusParm (line 91) | func (d *Crypt) updateObfusParm(str *string) error {
    method Drop (line 104) | func (d *Crypt) Drop(ctx context.Context) error {
    method List (line 108) | func (d *Crypt) List(ctx context.Context, dir model.Obj, args model.Li...
    method Get (line 187) | func (d *Crypt) Get(ctx context.Context, path string) (model.Obj, erro...
    method Link (line 244) | func (d *Crypt) Link(ctx context.Context, file model.Obj, args model.L...
    method MakeDir (line 311) | func (d *Crypt) MakeDir(ctx context.Context, parentDir model.Obj, dirN...
    method Move (line 320) | func (d *Crypt) Move(ctx context.Context, srcObj, dstDir model.Obj) er...
    method Rename (line 332) | func (d *Crypt) Rename(ctx context.Context, srcObj model.Obj, newName ...
    method Copy (line 346) | func (d *Crypt) Copy(ctx context.Context, srcObj, dstDir model.Obj) er...
    method Remove (line 359) | func (d *Crypt) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 367) | func (d *Crypt) Put(ctx context.Context, dstDir model.Obj, streamer mo...
  constant obfuscatedPrefix (line 34) | obfuscatedPrefix = "___Obfuscated___"

FILE: drivers/crypt/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 42) | func init() {

FILE: drivers/crypt/util.go
  function guessPath (line 12) | func guessPath(path string) (isFolder, secondTry bool) {
  method getPathForRemote (line 25) | func (d *Crypt) getPathForRemote(path string, isFolder bool) (remoteFull...
  method getActualPathForRemote (line 41) | func (d *Crypt) getActualPathForRemote(path string, isFolder bool) (stri...

FILE: drivers/doubao/driver.go
  type Doubao (line 20) | type Doubao struct
    method Config (line 28) | func (d *Doubao) Config() driver.Config {
    method GetAddition (line 32) | func (d *Doubao) GetAddition() driver.Additional {
    method Init (line 36) | func (d *Doubao) Init(ctx context.Context) error {
    method Drop (line 67) | func (d *Doubao) Drop(ctx context.Context) error {
    method List (line 71) | func (d *Doubao) List(ctx context.Context, dir model.Obj, args model.L...
    method Link (line 97) | func (d *Doubao) Link(ctx context.Context, file model.Obj, args model....
    method MakeDir (line 162) | func (d *Doubao) MakeDir(ctx context.Context, parentDir model.Obj, dir...
    method Move (line 179) | func (d *Doubao) Move(ctx context.Context, srcObj, dstDir model.Obj) e...
    method Rename (line 193) | func (d *Doubao) Rename(ctx context.Context, srcObj model.Obj, newName...
    method Copy (line 204) | func (d *Doubao) Copy(ctx context.Context, srcObj, dstDir model.Obj) (...
    method Remove (line 209) | func (d *Doubao) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 217) | func (d *Doubao) Put(ctx context.Context, dstDir model.Obj, file model...
    method GetArchiveMeta (line 245) | func (d *Doubao) GetArchiveMeta(ctx context.Context, obj model.Obj, ar...
    method ListArchive (line 250) | func (d *Doubao) ListArchive(ctx context.Context, obj model.Obj, args ...
    method Extract (line 255) | func (d *Doubao) Extract(ctx context.Context, obj model.Obj, args mode...
    method ArchiveDecompress (line 260) | func (d *Doubao) ArchiveDecompress(ctx context.Context, srcObj, dstDir...

FILE: drivers/doubao/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 32) | func init() {

FILE: drivers/doubao/types.go
  type BaseResp (line 11) | type BaseResp struct
  type NodeInfoResp (line 16) | type NodeInfoResp struct
  type File (line 26) | type File struct
  type GetDownloadInfoResp (line 42) | type GetDownloadInfoResp struct
  type GetFileUrlResp (line 53) | type GetFileUrlResp struct
  type GetVideoFileUrlResp (line 64) | type GetVideoFileUrlResp struct
  type UploadNodeResp (line 97) | type UploadNodeResp struct
  type Object (line 111) | type Object struct
  type UserInfoResp (line 117) | type UserInfoResp struct
  type AppUserInfo (line 121) | type AppUserInfo struct
  type AuditInfo (line 124) | type AuditInfo struct
  type Details (line 126) | type Details struct
  type BuiAuditInfo (line 128) | type BuiAuditInfo struct
  type Connects (line 136) | type Connects struct
  type OperStaffRelationInfo (line 150) | type OperStaffRelationInfo struct
  type UserInfo (line 156) | type UserInfo struct
  type UploadToken (line 195) | type UploadToken struct
  type UploadAuthToken (line 201) | type UploadAuthToken struct
  type MediaUploadAuthToken (line 215) | type MediaUploadAuthToken struct
  type UploadAuthTokenResp (line 229) | type UploadAuthTokenResp struct
  type MediaUploadAuthTokenResp (line 234) | type MediaUploadAuthTokenResp struct
  type ResponseMetadata (line 239) | type ResponseMetadata struct
  type UploadConfig (line 252) | type UploadConfig struct
  type UploadConfigResp (line 260) | type UploadConfigResp struct
  type StoreInfo (line 266) | type StoreInfo struct
  type UploadAddress (line 275) | type UploadAddress struct
  type FallbackUploadAddress (line 284) | type FallbackUploadAddress struct
  type UploadNode (line 293) | type UploadNode struct
  type AdvanceOption (line 309) | type AdvanceOption struct
  type InnerUploadAddress (line 317) | type InnerUploadAddress struct
  type UploadPart (line 323) | type UploadPart struct
  type UploadResp (line 332) | type UploadResp struct
  type VideoCommitUpload (line 339) | type VideoCommitUpload struct
  type VideoCommitUploadResp (line 361) | type VideoCommitUploadResp struct
  type CommonResp (line 369) | type CommonResp struct
    method IsSuccess (line 382) | func (r *CommonResp) IsSuccess() bool {
    method GetError (line 387) | func (r *CommonResp) GetError() error {
    method UnmarshalData (line 405) | func (r *CommonResp) UnmarshalData(v interface{}) error {

FILE: drivers/doubao/util.go
  constant DirectoryType (line 35) | DirectoryType      = 1
  constant FileType (line 36) | FileType           = 2
  constant LinkType (line 37) | LinkType           = 3
  constant ImageType (line 38) | ImageType          = 4
  constant PagesType (line 39) | PagesType          = 5
  constant VideoType (line 40) | VideoType          = 6
  constant AudioType (line 41) | AudioType          = 7
  constant MeetingMinutesType (line 42) | MeetingMinutesType = 8
  constant BaseURL (line 57) | BaseURL          = "https://www.doubao.com"
  constant FileDataType (line 58) | FileDataType     = "file"
  constant ImgDataType (line 59) | ImgDataType      = "image"
  constant VideoDataType (line 60) | VideoDataType    = "video"
  constant DefaultChunkSize (line 61) | DefaultChunkSize = int64(5 * 1024 * 1024)
  constant MaxRetryAttempts (line 62) | MaxRetryAttempts = 3
  constant UserAgent (line 63) | UserAgent        = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKi...
  constant Region (line 64) | Region           = "cn-north-1"
  constant UploadTimeout (line 65) | UploadTimeout    = 3 * time.Minute
  method request (line 69) | func (d *Doubao) request(path string, method string, callback base.ReqCa...
  method getFiles (line 104) | func (d *Doubao) getFiles(dirId, cursor string) (resp []File, err error) {
  method getUserInfo (line 142) | func (d *Doubao) getUserInfo() (UserInfo, error) {
  method signRequest (line 154) | func (d *Doubao) signRequest(req *resty.Request, method, tokenType, uplo...
  method requestApi (line 243) | func (d *Doubao) requestApi(url, method, tokenType string, callback base...
  method initUploadToken (line 275) | func (d *Doubao) initUploadToken() (*UploadToken, error) {
  method getUploadAuthToken (line 303) | func (d *Doubao) getUploadAuthToken(dataType string) (ut UploadAuthToken...
  method getSamantaUploadAuthToken (line 315) | func (d *Doubao) getSamantaUploadAuthToken() (mt MediaUploadAuthToken, e...
  method getUploadConfig (line 325) | func (d *Doubao) getUploadConfig(upConfig *UploadConfig, dataType string...
  method uploadNode (line 405) | func (d *Doubao) uploadNode(uploadConfig *UploadConfig, dir model.Obj, f...
  method Upload (line 449) | func (d *Doubao) Upload(config *UploadConfig, dstDir model.Obj, file mod...
  method UploadByMultipart (line 498) | func (d *Doubao) UploadByMultipart(ctx context.Context, config *UploadCo...
  method uploadRequest (line 623) | func (d *Doubao) uploadRequest(uploadUrl string, method string, storeInf...
  method initMultipartUpload (line 662) | func (d *Doubao) initMultipartUpload(config *UploadConfig, uploadUrl str...
  method uploadPart (line 684) | func (d *Doubao) uploadPart(config *UploadConfig, uploadUrl, uploadID st...
  method completeMultipartUpload (line 720) | func (d *Doubao) completeMultipartUpload(config *UploadConfig, uploadUrl...
  method commitMultipartUpload (line 755) | func (d *Doubao) commitMultipartUpload(uploadConfig *UploadConfig) error {
  function calculateCRC32 (line 788) | func calculateCRC32(data []byte) string {
  method _retryOperation (line 795) | func (d *Doubao) _retryOperation(operation string, fn func() error) error {
  function _convertUploadParts (line 809) | func _convertUploadParts(parts []UploadPart) string {
  function getCanonicalQueryString (line 827) | func getCanonicalQueryString(query url.Values) string {
  function urlEncode (line 849) | func urlEncode(s string) string {
  function getCanonicalHeadersFromMap (line 856) | func getCanonicalHeadersFromMap(headers map[string][]string) (string, st...
  function hmacSHA256 (line 901) | func hmacSHA256(key []byte, data string) []byte {
  function hmacSHA256Hex (line 908) | func hmacSHA256Hex(key []byte, data string) string {
  function hashSHA256 (line 913) | func hashSHA256(data string) string {
  function getSigningKey (line 920) | func getSigningKey(secretKey, dateStamp, region, service string) []byte {
  function generateContentDisposition (line 929) | func generateContentDisposition(filename string) string {
  function encodeRFC5987 (line 941) | func encodeRFC5987(s string) string {
  function randomString (line 958) | func randomString() string {

FILE: drivers/doubao_new/driver.go
  type DoubaoNew (line 24) | type DoubaoNew struct
    method Config (line 30) | func (d *DoubaoNew) Config() driver.Config {
    method GetAddition (line 34) | func (d *DoubaoNew) GetAddition() driver.Additional {
    method Init (line 38) | func (d *DoubaoNew) Init(ctx context.Context) error {
    method Drop (line 44) | func (d *DoubaoNew) Drop(ctx context.Context) error {
    method List (line 48) | func (d *DoubaoNew) List(ctx context.Context, dir model.Obj, args mode...
    method Link (line 79) | func (d *DoubaoNew) Link(ctx context.Context, file model.Obj, args mod...
    method MakeDir (line 118) | func (d *DoubaoNew) MakeDir(ctx context.Context, parentDir model.Obj, ...
    method Move (line 140) | func (d *DoubaoNew) Move(ctx context.Context, srcObj, dstDir model.Obj...
    method Rename (line 167) | func (d *DoubaoNew) Rename(ctx context.Context, srcObj model.Obj, newN...
    method Copy (line 196) | func (d *DoubaoNew) Copy(ctx context.Context, srcObj, dstDir model.Obj...
    method Remove (line 201) | func (d *DoubaoNew) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 217) | func (d *DoubaoNew) Put(ctx context.Context, dstDir model.Obj, file mo...
    method GetArchiveMeta (line 420) | func (d *DoubaoNew) GetArchiveMeta(ctx context.Context, obj model.Obj,...
    method ListArchive (line 425) | func (d *DoubaoNew) ListArchive(ctx context.Context, obj model.Obj, ar...
    method Extract (line 430) | func (d *DoubaoNew) Extract(ctx context.Context, obj model.Obj, args m...
    method ArchiveDecompress (line 435) | func (d *DoubaoNew) ArchiveDecompress(ctx context.Context, srcObj, dst...
    method Other (line 442) | func (d *DoubaoNew) Other(ctx context.Context, args model.OtherArgs) (...
    method listAllChildren (line 482) | func (d *DoubaoNew) listAllChildren(ctx context.Context, parentToken s...
    method previewLink (line 517) | func (d *DoubaoNew) previewLink(ctx context.Context, obj *Object, args...
  function parseSize (line 587) | func parseSize(size string) int64 {

FILE: drivers/doubao_new/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 32) | func init() {

FILE: drivers/doubao_new/types.go
  type BaseResp (line 5) | type BaseResp struct
  type ListResp (line 11) | type ListResp struct
  type ListData (line 16) | type ListData struct
  type Node (line 26) | type Node struct
  type User (line 43) | type User struct
  type Object (line 48) | type Object struct
  type CreateFolderResp (line 56) | type CreateFolderResp struct
  type FileInfoResp (line 66) | type FileInfoResp struct
  type FileInfo (line 72) | type FileInfo struct
  type PreviewMeta (line 81) | type PreviewMeta struct
  type PreviewMetaEntry (line 85) | type PreviewMetaEntry struct
  type PreviewImageExtra (line 91) | type PreviewImageExtra struct
  type UserStorageResp (line 96) | type UserStorageResp struct
  type UserStorageData (line 101) | type UserStorageData struct
  type UploadPrepareResp (line 107) | type UploadPrepareResp struct
  type UploadPrepareData (line 112) | type UploadPrepareData struct
  type UploadBlock (line 120) | type UploadBlock struct
  type UploadBlocksResp (line 128) | type UploadBlocksResp struct
  type UploadBlocksData (line 133) | type UploadBlocksData struct
  type UploadBlockNeed (line 137) | type UploadBlockNeed struct
  type UploadMergeResp (line 144) | type UploadMergeResp struct
  type UploadMergeData (line 149) | type UploadMergeData struct
  type UploadFinishResp (line 153) | type UploadFinishResp struct
  type UploadFinishData (line 158) | type UploadFinishData struct
  type RemoveResp (line 167) | type RemoveResp struct
  type TaskStatusResp (line 174) | type TaskStatusResp struct
  type TaskStatusData (line 179) | type TaskStatusData struct

FILE: drivers/doubao_new/util.go
  constant BaseURL (line 22) | BaseURL         = "https://my.feishu.cn"
  constant DownloadBaseURL (line 23) | DownloadBaseURL = "https://internal-api-drive-stream.feishu.cn"
  method request (line 28) | func (d *DoubaoNew) request(ctx context.Context, path string, method str...
  function getCookieValue (line 85) | func getCookieValue(cookie, name string) string {
  function adler32String (line 97) | func adler32String(data []byte) string {
  function buildCommaHeader (line 102) | func buildCommaHeader(items []string) string {
  function joinIntComma (line 106) | func joinIntComma(items []int) string {
  function previewList (line 120) | func previewList(items []string, n int) string {
  method resolveAuthorization (line 130) | func (d *DoubaoNew) resolveAuthorization() string {
  method resolveDpop (line 146) | func (d *DoubaoNew) resolveDpop() string {
  method listChildren (line 154) | func (d *DoubaoNew) listChildren(ctx context.Context, parentToken string...
  method getFileInfo (line 183) | func (d *DoubaoNew) getFileInfo(ctx context.Context, fileToken string) (...
  method createFolder (line 201) | func (d *DoubaoNew) createFolder(ctx context.Context, parentToken, name ...
  method renameFolder (line 281) | func (d *DoubaoNew) renameFolder(ctx context.Context, token, name string...
  function isCsrfTokenError (line 321) | func isCsrfTokenError(body []byte, res *resty.Response) bool {
  function doRequestWithCsrf (line 334) | func doRequestWithCsrf(doRequest func(csrfToken string) (*resty.Response...
  function extractCsrfTokenFromResponse (line 348) | func extractCsrfTokenFromResponse(res *resty.Response) string {
  function decodeBaseResp (line 368) | func decodeBaseResp(body []byte, res *resty.Response) error {
  method renameFile (line 389) | func (d *DoubaoNew) renameFile(ctx context.Context, fileToken, name stri...
  method moveObj (line 403) | func (d *DoubaoNew) moveObj(ctx context.Context, srcToken, destToken str...
  method removeObj (line 444) | func (d *DoubaoNew) removeObj(ctx context.Context, tokens []string) error {
  method getUserStorage (line 503) | func (d *DoubaoNew) getUserStorage(ctx context.Context) (UserStorageData...
  method waitTask (line 550) | func (d *DoubaoNew) waitTask(ctx context.Context, taskID string) error {
  method getTaskStatus (line 580) | func (d *DoubaoNew) getTaskStatus(ctx context.Context, taskID string) (T...
  function waitWithContext (line 622) | func waitWithContext(ctx context.Context, d time.Duration) error {
  method prepareUpload (line 633) | func (d *DoubaoNew) prepareUpload(ctx context.Context, name string, size...
  method uploadBlocks (line 664) | func (d *DoubaoNew) uploadBlocks(ctx context.Context, uploadID string, b...
  method mergeUploadBlocks (line 695) | func (d *DoubaoNew) mergeUploadBlocks(ctx context.Context, uploadID stri...
  method uploadBlockV3 (line 819) | func (d *DoubaoNew) uploadBlockV3(ctx context.Context, uploadID string, ...
  method finishUpload (line 874) | func (d *DoubaoNew) finishUpload(ctx context.Context, uploadID string, n...

FILE: drivers/doubao_share/driver.go
  type DoubaoShare (line 14) | type DoubaoShare struct
    method Config (line 20) | func (d *DoubaoShare) Config() driver.Config {
    method GetAddition (line 24) | func (d *DoubaoShare) GetAddition() driver.Additional {
    method Init (line 28) | func (d *DoubaoShare) Init(ctx context.Context) error {
    method Drop (line 37) | func (d *DoubaoShare) Drop(ctx context.Context) error {
    method List (line 41) | func (d *DoubaoShare) List(ctx context.Context, dir model.Obj, args mo...
    method Link (line 72) | func (d *DoubaoShare) Link(ctx context.Context, file model.Obj, args m...
    method MakeDir (line 121) | func (d *DoubaoShare) MakeDir(ctx context.Context, parentDir model.Obj...
    method Move (line 126) | func (d *DoubaoShare) Move(ctx context.Context, srcObj, dstDir model.O...
    method Rename (line 131) | func (d *DoubaoShare) Rename(ctx context.Context, srcObj model.Obj, ne...
    method Copy (line 136) | func (d *DoubaoShare) Copy(ctx context.Context, srcObj, dstDir model.O...
    method Remove (line 141) | func (d *DoubaoShare) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 146) | func (d *DoubaoShare) Put(ctx context.Context, dstDir model.Obj, file ...
    method GetArchiveMeta (line 151) | func (d *DoubaoShare) GetArchiveMeta(ctx context.Context, obj model.Ob...
    method ListArchive (line 156) | func (d *DoubaoShare) ListArchive(ctx context.Context, obj model.Obj, ...
    method Extract (line 161) | func (d *DoubaoShare) Extract(ctx context.Context, obj model.Obj, args...
    method ArchiveDecompress (line 166) | func (d *DoubaoShare) ArchiveDecompress(ctx context.Context, srcObj, d...

FILE: drivers/doubao_share/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 28) | func init() {

FILE: drivers/doubao_share/types.go
  type BaseResp (line 9) | type BaseResp struct
  type NodeInfoData (line 14) | type NodeInfoData struct
  type NodeInfoResp (line 25) | type NodeInfoResp struct
  type RootFileList (line 30) | type RootFileList struct
  type File (line 37) | type File struct
  type FileObject (line 53) | type FileObject struct
  type ShareInfo (line 61) | type ShareInfo struct
  type CreatorInfo (line 90) | type CreatorInfo struct
  type FilePath (line 101) | type FilePath
  type GetFileUrlResp (line 117) | type GetFileUrlResp struct
  type GetVideoFileUrlResp (line 128) | type GetVideoFileUrlResp struct
  type CommonResp (line 161) | type CommonResp struct
    method IsSuccess (line 174) | func (r *CommonResp) IsSuccess() bool {
    method GetError (line 179) | func (r *CommonResp) GetError() error {
    method UnmarshalData (line 197) | func (r *CommonResp) UnmarshalData(v interface{}) error {

FILE: drivers/doubao_share/util.go
  constant DirectoryType (line 20) | DirectoryType      = 1
  constant FileType (line 21) | FileType           = 2
  constant LinkType (line 22) | LinkType           = 3
  constant ImageType (line 23) | ImageType          = 4
  constant PagesType (line 24) | PagesType          = 5
  constant VideoType (line 25) | VideoType          = 6
  constant AudioType (line 26) | AudioType          = 7
  constant MeetingMinutesType (line 27) | MeetingMinutesType = 8
  constant BaseURL (line 42) | BaseURL       = "https://www.doubao.com"
  constant FileDataType (line 43) | FileDataType  = "file"
  constant ImgDataType (line 44) | ImgDataType   = "image"
  constant VideoDataType (line 45) | VideoDataType = "video"
  constant UserAgent (line 46) | UserAgent     = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/5...
  method request (line 49) | func (d *DoubaoShare) request(path string, method string, callback base....
  method getFiles (line 94) | func (d *DoubaoShare) getFiles(dirId, nodeId, cursor string) (resp []Fil...
  method getShareOverview (line 133) | func (d *DoubaoShare) getShareOverview(shareId, cursor string) (resp []F...
  method getShareOverviewWithHistory (line 137) | func (d *DoubaoShare) getShareOverviewWithHistory(shareId, cursor string...
  method initShareList (line 183) | func (d *DoubaoShare) initShareList() error {
  method _parseShareConfigs (line 215) | func (d *DoubaoShare) _parseShareConfigs() (map[string]string, []string,...
  method _detectPathConflicts (line 265) | func (d *DoubaoShare) _detectPathConflicts(shareConfigs map[string]strin...
  method _buildTreeStructure (line 298) | func (d *DoubaoShare) _buildTreeStructure(shareConfigs map[string]string...
  method _extractTopLevelNodes (line 336) | func (d *DoubaoShare) _extractTopLevelNodes(rootMap map[string]*RootFile...
  function _ensurePathExists (line 375) | func _ensurePathExists(rootMap map[string]*RootFileList, path string) {
  function _extractShareId (line 410) | func _extractShareId(input string) string {
  function _findRootFileByShareID (line 423) | func _findRootFileByShareID(rootFiles []RootFileList, shareID string) *R...
  function _findNodeByPath (line 438) | func _findNodeByPath(rootFiles []RootFileList, path string) *RootFileList {
  function _findShareByPath (line 453) | func _findShareByPath(rootFiles []RootFileList, path string) (*RootFileL...
  method _findShareAndPath (line 498) | func (d *DoubaoShare) _findShareAndPath(dir model.Obj) (string, string, ...
  method convertToFileObject (line 556) | func (d *DoubaoShare) convertToFileObject(file File, shareId string, rel...
  method getFilesInPath (line 578) | func (d *DoubaoShare) getFilesInPath(ctx context.Context, shareId, nodeI...
  method listRootDirectory (line 614) | func (d *DoubaoShare) listRootDirectory(ctx context.Context) ([]model.Ob...
  method listVirtualDirectoryContent (line 670) | func (d *DoubaoShare) listVirtualDirectoryContent(dir model.Obj) ([]mode...
  function generateContentDisposition (line 711) | func generateContentDisposition(filename string) string {
  function encodeRFC5987 (line 723) | func encodeRFC5987(s string) string {
  function urlEncode (line 740) | func urlEncode(s string) string {

FILE: drivers/dropbox/driver.go
  type Dropbox (line 19) | type Dropbox struct
    method Config (line 26) | func (d *Dropbox) Config() driver.Config {
    method GetAddition (line 30) | func (d *Dropbox) GetAddition() driver.Additional {
    method Init (line 34) | func (d *Dropbox) Init(ctx context.Context) error {
    method GetRootNamespaceId (line 53) | func (d *Dropbox) GetRootNamespaceId(ctx context.Context) (string, err...
    method Drop (line 69) | func (d *Dropbox) Drop(ctx context.Context) error {
    method List (line 73) | func (d *Dropbox) List(ctx context.Context, dir model.Obj, args model....
    method Link (line 83) | func (d *Dropbox) Link(ctx context.Context, file model.Obj, args model...
    method MakeDir (line 100) | func (d *Dropbox) MakeDir(ctx context.Context, parentDir model.Obj, di...
    method Move (line 110) | func (d *Dropbox) Move(ctx context.Context, srcObj, dstDir model.Obj) ...
    method Rename (line 125) | func (d *Dropbox) Rename(ctx context.Context, srcObj model.Obj, newNam...
    method Copy (line 142) | func (d *Dropbox) Copy(ctx context.Context, srcObj, dstDir model.Obj) ...
    method Remove (line 156) | func (d *Dropbox) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 166) | func (d *Dropbox) Put(ctx context.Context, dstDir model.Obj, stream mo...

FILE: drivers/dropbox/meta.go
  constant DefaultClientID (line 9) | DefaultClientID = "76lrwrklhdn1icb"
  type Addition (line 12) | type Addition struct
  function init (line 36) | func init() {

FILE: drivers/dropbox/types.go
  type TokenResp (line 8) | type TokenResp struct
  type ErrorResp (line 14) | type ErrorResp struct
  type RefreshTokenErrorResp (line 21) | type RefreshTokenErrorResp struct
  type CurrentAccountResp (line 26) | type CurrentAccountResp struct
  type File (line 33) | type File struct
  type ListResp (line 47) | type ListResp struct
  type UploadCursor (line 53) | type UploadCursor struct
  type UploadAppendArgs (line 58) | type UploadAppendArgs struct
  type UploadFinishArgs (line 63) | type UploadFinishArgs struct
  function fileToObj (line 74) | func fileToObj(f File) *model.ObjThumb {

FILE: drivers/dropbox/util.go
  method refreshToken (line 17) | func (d *Dropbox) refreshToken() error {
  method request (line 46) | func (d *Dropbox) request(uri, method string, callback base.ReqCallback,...
  method list (line 90) | func (d *Dropbox) list(ctx context.Context, data base.Json, isContinue b...
  method getFiles (line 105) | func (d *Dropbox) getFiles(ctx context.Context, path string) ([]File, er...
  method finishUploadSession (line 142) | func (d *Dropbox) finishUploadSession(ctx context.Context, toPath string...
  method startUploadSession (line 187) | func (d *Dropbox) startUploadSession(ctx context.Context) (string, error) {

FILE: drivers/febbox/driver.go
  type FebBox (line 15) | type FebBox struct
    method Config (line 22) | func (d *FebBox) Config() driver.Config {
    method GetAddition (line 26) | func (d *FebBox) GetAddition() driver.Additional {
    method Init (line 30) | func (d *FebBox) Init(ctx context.Context) error {
    method Drop (line 52) | func (d *FebBox) Drop(ctx context.Context) error {
    method List (line 56) | func (d *FebBox) List(ctx context.Context, dir model.Obj, args model.L...
    method Link (line 66) | func (d *FebBox) Link(ctx context.Context, file model.Obj, args model....
    method MakeDir (line 83) | func (d *FebBox) MakeDir(ctx context.Context, parentDir model.Obj, dir...
    method Move (line 92) | func (d *FebBox) Move(ctx context.Context, srcObj, dstDir model.Obj) (...
    method Rename (line 101) | func (d *FebBox) Rename(ctx context.Context, srcObj model.Obj, newName...
    method Copy (line 110) | func (d *FebBox) Copy(ctx context.Context, srcObj, dstDir model.Obj) (...
    method Remove (line 119) | func (d *FebBox) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 128) | func (d *FebBox) Put(ctx context.Context, dstDir model.Obj, stream mod...

FILE: drivers/febbox/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 32) | func init() {

FILE: drivers/febbox/oauth2.go
  type customTokenSource (line 16) | type customTokenSource struct
    method Token (line 22) | func (c *customTokenSource) Token() (*oauth2.Token, error) {
  method initializeOAuth2Token (line 82) | func (d *FebBox) initializeOAuth2Token(ctx context.Context, oauth2Config...

FILE: drivers/febbox/types.go
  type ErrResp (line 12) | type ErrResp struct
    method IsError (line 19) | func (e *ErrResp) IsError() bool {
    method Error (line 23) | func (e *ErrResp) Error() string {
  type FileListResp (line 27) | type FileListResp struct
  type Rules (line 36) | type Rules struct
  type File (line 44) | type File struct
  function fileToObj (line 90) | func fileToObj(f File) *model.ObjThumb {
  type FileDownloadResp (line 107) | type FileDownloadResp struct

FILE: drivers/febbox/util.go
  method refreshTokenByOAuth2 (line 14) | func (d *FebBox) refreshTokenByOAuth2() error {
  method request (line 26) | func (d *FebBox) request(url string, method string, callback base.ReqCal...
  method getFilesList (line 68) | func (d *FebBox) getFilesList(id string) ([]File, error) {
  method listWithLimit (line 79) | func (d *FebBox) listWithLimit(dirID string, pageLimit int64) (*[]File, ...
  method getFiles (line 97) | func (d *FebBox) getFiles(dirID string, page, pageLimit int64) (*[]File,...
  method getDownloadLink (line 121) | func (d *FebBox) getDownloadLink(id string, ip string) (string, error) {
  method makeDir (line 146) | func (d *FebBox) makeDir(id string, name string) error {
  method move (line 163) | func (d *FebBox) move(id string, id2 string) error {
  method rename (line 180) | func (d *FebBox) rename(id string, name string) error {
  method copy (line 197) | func (d *FebBox) copy(id string, id2 string) error {
  method remove (line 214) | func (d *FebBox) remove(id string) error {

FILE: drivers/ftp/driver.go
  type FTP (line 13) | type FTP struct
    method Config (line 19) | func (d *FTP) Config() driver.Config {
    method GetAddition (line 23) | func (d *FTP) GetAddition() driver.Additional {
    method Init (line 27) | func (d *FTP) Init(ctx context.Context) error {
    method Drop (line 31) | func (d *FTP) Drop(ctx context.Context) error {
    method List (line 38) | func (d *FTP) List(ctx context.Context, dir model.Obj, args model.List...
    method Link (line 62) | func (d *FTP) Link(ctx context.Context, file model.Obj, args model.Lin...
    method MakeDir (line 74) | func (d *FTP) MakeDir(ctx context.Context, parentDir model.Obj, dirNam...
    method Move (line 81) | func (d *FTP) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
    method Rename (line 91) | func (d *FTP) Rename(ctx context.Context, srcObj model.Obj, newName st...
    method Copy (line 101) | func (d *FTP) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
    method Remove (line 105) | func (d *FTP) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 117) | func (d *FTP) Put(ctx context.Context, dstDir model.Obj, s model.FileS...

FILE: drivers/ftp/meta.go
  function encode (line 9) | func encode(str string, encoding string) string {
  function decode (line 17) | func decode(str string, encoding string) string {
  type Addition (line 25) | type Addition struct
  function init (line 40) | func init() {

FILE: drivers/ftp/util.go
  method login (line 15) | func (d *FTP) login() error {
  type FileReader (line 35) | type FileReader struct
    method Read (line 53) | func (r *FileReader) Read(buf []byte) (n int, err error) {
    method ReadAt (line 59) | func (r *FileReader) ReadAt(buf []byte, off int64) (n int, err error) {
    method Seek (line 85) | func (r *FileReader) Seek(offset int64, whence int) (int64, error) {
    method Close (line 111) | func (r *FileReader) Close() error {
  function NewFileReader (line 45) | func NewFileReader(conn *ftp.ServerConn, path string, size int64) *FileR...

FILE: drivers/ftps/driver.go
  type FTPS (line 13) | type FTPS struct
    method Config (line 19) | func (d *FTPS) Config() driver.Config {
    method GetAddition (line 23) | func (d *FTPS) GetAddition() driver.Additional {
    method Init (line 27) | func (d *FTPS) Init(ctx context.Context) error {
    method Drop (line 31) | func (d *FTPS) Drop(ctx context.Context) error {
    method List (line 38) | func (d *FTPS) List(ctx context.Context, dir model.Obj, args model.Lis...
    method Link (line 62) | func (d *FTPS) Link(ctx context.Context, file model.Obj, args model.Li...
    method MakeDir (line 73) | func (d *FTPS) MakeDir(ctx context.Context, parentDir model.Obj, dirNa...
    method Move (line 80) | func (d *FTPS) Move(ctx context.Context, srcObj, dstDir model.Obj) err...
    method Rename (line 90) | func (d *FTPS) Rename(ctx context.Context, srcObj model.Obj, newName s...
    method Copy (line 100) | func (d *FTPS) Copy(ctx context.Context, srcObj, dstDir model.Obj) err...
    method Remove (line 104) | func (d *FTPS) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 116) | func (d *FTPS) Put(ctx context.Context, dstDir model.Obj, s model.File...

FILE: drivers/ftps/meta.go
  function encode (line 9) | func encode(str string, encoding string) string {
  function decode (line 17) | func decode(str string, encoding string) string {
  type Addition (line 25) | type Addition struct
  function init (line 42) | func init() {

FILE: drivers/ftps/util.go
  method login (line 15) | func (d *FTPS) login() error {
  type FileReader (line 55) | type FileReader struct
    method Read (line 73) | func (r *FileReader) Read(buf []byte) (n int, err error) {
    method ReadAt (line 82) | func (r *FileReader) ReadAt(buf []byte, off int64) (n int, err error) {
    method readAtLocked (line 91) | func (r *FileReader) readAtLocked(buf []byte, off int64) (n int, err e...
    method Seek (line 110) | func (r *FileReader) Seek(offset int64, whence int) (int64, error) {
    method Close (line 134) | func (r *FileReader) Close() error {
  function NewFileReader (line 65) | func NewFileReader(conn *ftp.ServerConn, path string, size int64) *FileR...

FILE: drivers/gitee/driver.go
  type Gitee (line 20) | type Gitee struct
    method Config (line 26) | func (d *Gitee) Config() driver.Config {
    method GetAddition (line 30) | func (d *Gitee) GetAddition() driver.Additional {
    method Init (line 34) | func (d *Gitee) Init(ctx context.Context) error {
    method Drop (line 62) | func (d *Gitee) Drop(ctx context.Context) error {
    method List (line 66) | func (d *Gitee) List(ctx context.Context, dir model.Obj, args model.Li...
    method Link (line 79) | func (d *Gitee) Link(ctx context.Context, file model.Obj, args model.L...
    method newRequest (line 115) | func (d *Gitee) newRequest() *resty.Request {
    method apiPath (line 126) | func (d *Gitee) apiPath(path string) string {
    method listContents (line 135) | func (d *Gitee) listContents(path string) ([]Content, error) {
    method getContent (line 160) | func (d *Gitee) getContent(path string) (*Content, error) {
    method relativePath (line 181) | func (d *Gitee) relativePath(full string) string {
    method applyProxy (line 197) | func (d *Gitee) applyProxy(raw string) string {
  function encodePath (line 208) | func encodePath(p string) string {
  function joinPath (line 219) | func joinPath(base, name string) string {

FILE: drivers/gitee/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 25) | func init() {

FILE: drivers/gitee/types.go
  type Links (line 9) | type Links struct
  type Content (line 14) | type Content struct
    method toModelObj (line 26) | func (c Content) toModelObj() model.Obj {
  type Object (line 44) | type Object struct
    method URL (line 50) | func (o *Object) URL() string {
  type Repo (line 54) | type Repo struct
  type ErrResp (line 58) | type ErrResp struct

FILE: drivers/gitee/util.go
  method getRepo (line 11) | func (d *Gitee) getRepo() (*Repo, error) {
  function toErr (line 38) | func toErr(res *resty.Response) error {

FILE: drivers/github/driver.go
  type Github (line 25) | type Github struct
    method Config (line 40) | func (d *Github) Config() driver.Config {
    method GetAddition (line 44) | func (d *Github) GetAddition() driver.Additional {
    method Init (line 48) | func (d *Github) Init(ctx context.Context) error {
    method Drop (line 130) | func (d *Github) Drop(ctx context.Context) error {
    method List (line 134) | func (d *Github) List(ctx context.Context, dir model.Obj, args model.L...
    method Link (line 168) | func (d *Github) Link(ctx context.Context, file model.Obj, args model....
    method MakeDir (line 186) | func (d *Github) MakeDir(ctx context.Context, parentDir model.Obj, dir...
    method Move (line 247) | func (d *Github) Move(ctx context.Context, srcObj, dstDir model.Obj) e...
    method Rename (line 471) | func (d *Github) Rename(ctx context.Context, srcObj model.Obj, newName...
    method Copy (line 524) | func (d *Github) Copy(ctx context.Context, srcObj, dstDir model.Obj) e...
    method Remove (line 557) | func (d *Github) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 613) | func (d *Github) Put(ctx context.Context, dstDir model.Obj, stream mod...
    method getContentApiUrl (line 669) | func (d *Github) getContentApiUrl(path string) string {
    method get (line 674) | func (d *Github) get(path string) (*Object, error) {
    method putBlob (line 687) | func (d *Github) putBlob(ctx context.Context, s model.FileStreamer, up...
    method renewParentTrees (line 747) | func (d *Github) renewParentTrees(path, prevSha, curSha, until string)...
    method getTree (line 774) | func (d *Github) getTree(sha string) (*TreeResp, error) {
    method getTreeDirectly (line 789) | func (d *Github) getTreeDirectly(path string) (*TreeResp, string, erro...
    method newTree (line 807) | func (d *Github) newTree(baseSha string, tree []interface{}) (string, ...
    method commit (line 827) | func (d *Github) commit(message, treeSha string) error {
    method getBranchHead (line 870) | func (d *Github) getBranchHead() (string, error) {
    method copyWithoutRenewTree (line 885) | func (d *Github) copyWithoutRenewTree(srcObj, dstDir model.Obj) (dstSh...
    method getRepo (line 930) | func (d *Github) getRepo() (*RepoResp, error) {
    method getAuthenticatedUser (line 945) | func (d *Github) getAuthenticatedUser() (*UserResp, error) {
    method addCommitterAndAuthor (line 960) | func (d *Github) addCommitterAndAuthor(m *map[string]interface{}) {

FILE: drivers/github/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 35) | func init() {

FILE: drivers/github/types.go
  type Links (line 8) | type Links struct
  type Object (line 14) | type Object struct
    method toModelObj (line 32) | func (o *Object) toModelObj() *model.Object {
  type PutBlobResp (line 41) | type PutBlobResp struct
  type ErrResp (line 46) | type ErrResp struct
  type TreeObjReq (line 52) | type TreeObjReq struct
  type TreeObjResp (line 59) | type TreeObjResp struct
    method toModelObj (line 65) | func (o *TreeObjResp) toModelObj() *model.Object {
  type TreeResp (line 74) | type TreeResp struct
  type TreeReq (line 81) | type TreeReq struct
  type CommitResp (line 86) | type CommitResp struct
  type BranchResp (line 90) | type BranchResp struct
  type UpdateRefReq (line 95) | type UpdateRefReq struct
  type RepoResp (line 100) | type RepoResp struct
  type UserResp (line 104) | type UserResp struct

FILE: drivers/github/util.go
  type MessageTemplateVars (line 19) | type MessageTemplateVars struct
  function getMessage (line 29) | func getMessage(tmpl *template.Template, vars *MessageTemplateVars, defa...
  function calculateBase64Length (line 37) | func calculateBase64Length(inputLength int64) int64 {
  function toErr (line 41) | func toErr(res *resty.Response) error {
  function getPathCommonAncestor (line 60) | func getPathCommonAncestor(a, b string) (ancestor, aChildName, bChildNam...
  function getUsername (line 98) | func getUsername(ctx context.Context) string {
  function loadPrivateKey (line 106) | func loadPrivateKey(key, passphrase string) (*openpgp.Entity, error) {
  function signCommit (line 132) | func signCommit(m *map[string]interface{}, entity *openpgp.Entity) (stri...

FILE: drivers/github_releases/driver.go
  type GithubReleases (line 16) | type GithubReleases struct
    method Config (line 23) | func (d *GithubReleases) Config() driver.Config {
    method GetAddition (line 27) | func (d *GithubReleases) GetAddition() driver.Additional {
    method Init (line 31) | func (d *GithubReleases) Init(ctx context.Context) error {
    method Drop (line 36) | func (d *GithubReleases) Drop(ctx context.Context) error {
    method processPoint (line 41) | func (d *GithubReleases) processPoint(point *MountPoint, path string, ...
    method processLatestVersion (line 56) | func (d *GithubReleases) processLatestVersion(point *MountPoint, path ...
    method processAllVersions (line 85) | func (d *GithubReleases) processAllVersions(point *MountPoint, path st...
    method mergeFiles (line 119) | func (d *GithubReleases) mergeFiles(files *[]File, newFiles []File) {
    method List (line 139) | func (d *GithubReleases) List(ctx context.Context, dir model.Obj, args...
    method Link (line 172) | func (d *GithubReleases) Link(ctx context.Context, file model.Obj, arg...
    method MakeDir (line 187) | func (d *GithubReleases) MakeDir(ctx context.Context, parentDir model....
    method Move (line 192) | func (d *GithubReleases) Move(ctx context.Context, srcObj, dstDir mode...
    method Rename (line 197) | func (d *GithubReleases) Rename(ctx context.Context, srcObj model.Obj,...
    method Copy (line 202) | func (d *GithubReleases) Copy(ctx context.Context, srcObj, dstDir mode...
    method Remove (line 207) | func (d *GithubReleases) Remove(ctx context.Context, obj model.Obj) er...

FILE: drivers/github_releases/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 32) | func init() {

FILE: drivers/github_releases/models.go
  type Release (line 3) | type Release struct
  type User (line 25) | type User struct
  type Asset (line 47) | type Asset struct
  type Reactions (line 63) | type Reactions struct
  type FileInfo (line 76) | type FileInfo struct

FILE: drivers/github_releases/types.go
  type MountPoint (line 12) | type MountPoint struct
    method RequestLatestRelease (line 21) | func (m *MountPoint) RequestLatestRelease(get func(url string) (*resty...
    method RequestReleases (line 34) | func (m *MountPoint) RequestReleases(get func(url string) (*resty.Resp...
    method GetLatestRelease (line 47) | func (m *MountPoint) GetLatestRelease() []File {
    method GetLatestSize (line 64) | func (m *MountPoint) GetLatestSize() int64 {
    method GetAllVersion (line 73) | func (m *MountPoint) GetAllVersion() []File {
    method GetReleaseByTagName (line 94) | func (m *MountPoint) GetReleaseByTagName(tagName string) []File {
    method GetSizeByTagName (line 116) | func (m *MountPoint) GetSizeByTagName(tagName string) int64 {
    method GetAllVersionSize (line 133) | func (m *MountPoint) GetAllVersionSize() int64 {
    method GetOtherFile (line 146) | func (m *MountPoint) GetOtherFile(get func(url string) (*resty.Respons...
  type File (line 171) | type File struct
    method GetHash (line 181) | func (f File) GetHash() utils.HashInfo {
    method GetPath (line 185) | func (f File) GetPath() string {
    method GetSize (line 189) | func (f File) GetSize() int64 {
    method GetName (line 193) | func (f File) GetName() string {
    method ModTime (line 197) | func (f File) ModTime() time.Time {
    method CreateTime (line 202) | func (f File) CreateTime() time.Time {
    method IsDir (line 207) | func (f File) IsDir() bool {
    method GetID (line 211) | func (f File) GetID() string {

FILE: drivers/github_releases/util.go
  method GetRequest (line 14) | func (d *GithubReleases) GetRequest(url string) (*resty.Response, error) {
  method ParseRepos (line 32) | func (d *GithubReleases) ParseRepos(text string) ([]MountPoint, error) {
  function GetNextDir (line 64) | func GetNextDir(wholePath string, basePath string) string {
  function IsAncestorDir (line 81) | func IsAncestorDir(parentDir string, targetDir string) bool {

FILE: drivers/gofile/driver.go
  type Gofile (line 14) | type Gofile struct
    method Config (line 21) | func (d *Gofile) Config() driver.Config {
    method GetAddition (line 25) | func (d *Gofile) GetAddition() driver.Additional {
    method Init (line 29) | func (d *Gofile) Init(ctx context.Context) error {
    method Drop (line 55) | func (d *Gofile) Drop(ctx context.Context) error {
    method List (line 59) | func (d *Gofile) List(ctx context.Context, dir model.Obj, args model.L...
    method Link (line 90) | func (d *Gofile) Link(ctx context.Context, file model.Obj, args model....
    method MakeDir (line 115) | func (d *Gofile) MakeDir(ctx context.Context, parentDir model.Obj, dir...
    method Move (line 141) | func (d *Gofile) Move(ctx context.Context, srcObj, dstDir model.Obj) (...
    method Rename (line 169) | func (d *Gofile) Rename(ctx context.Context, srcObj model.Obj, newName...
    method Copy (line 190) | func (d *Gofile) Copy(ctx context.Context, srcObj, dstDir model.Obj) (...
    method Remove (line 226) | func (d *Gofile) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 234) | func (d *Gofile) Put(ctx context.Context, dstDir model.Obj, fileStream...
    method GetArchiveMeta (line 255) | func (d *Gofile) GetArchiveMeta(ctx context.Context, obj model.Obj, ar...
    method ListArchive (line 259) | func (d *Gofile) ListArchive(ctx context.Context, obj model.Obj, args ...
    method Extract (line 263) | func (d *Gofile) Extract(ctx context.Context, obj model.Obj, args mode...
    method ArchiveDecompress (line 267) | func (d *Gofile) ArchiveDecompress(ctx context.Context, srcObj, dstDir...

FILE: drivers/gofile/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 24) | func init() {

FILE: drivers/gofile/types.go
  type APIResponse (line 5) | type APIResponse struct
  type AccountResponse (line 10) | type AccountResponse struct
  type AccountInfoResponse (line 17) | type AccountInfoResponse struct
  type Content (line 27) | type Content struct
    method ModifiedTime (line 115) | func (c *Content) ModifiedTime() time.Time {
    method IsDir (line 122) | func (c *Content) IsDir() bool {
  type ContentsResponse (line 42) | type ContentsResponse struct
  type UploadResponse (line 61) | type UploadResponse struct
  type DirectLinkResponse (line 73) | type DirectLinkResponse struct
  type CreateFolderResponse (line 81) | type CreateFolderResponse struct
  type CopyResponse (line 92) | type CopyResponse struct
  type UpdateResponse (line 99) | type UpdateResponse struct
  type ErrorResponse (line 107) | type ErrorResponse struct

FILE: drivers/gofile/util.go
  constant baseAPI (line 22) | baseAPI   = "https://api.gofile.io"
  constant uploadAPI (line 23) | uploadAPI = "https://upload.gofile.io"
  method request (line 26) | func (d *Gofile) request(ctx context.Context, method, endpoint string, b...
  method getJSON (line 49) | func (d *Gofile) getJSON(ctx context.Context, endpoint string, result in...
  method postJSON (line 63) | func (d *Gofile) postJSON(ctx context.Context, endpoint string, data int...
  method putJSON (line 90) | func (d *Gofile) putJSON(ctx context.Context, endpoint string, data inte...
  method deleteJSON (line 117) | func (d *Gofile) deleteJSON(ctx context.Context, endpoint string, data i...
  method handleError (line 140) | func (d *Gofile) handleError(resp *http.Response) error {
  method uploadFile (line 152) | func (d *Gofile) uploadFile(ctx context.Context, folderId string, file m...
  method createDirectLink (line 202) | func (d *Gofile) createDirectLink(ctx context.Context, contentId string)...
  method convertContentToObj (line 219) | func (d *Gofile) convertContentToObj(content Content) model.Obj {
  method getAccountId (line 231) | func (d *Gofile) getAccountId(ctx context.Context) (string, error) {
  method getAccountInfo (line 240) | func (d *Gofile) getAccountInfo(ctx context.Context, accountId string) (...
  type progressReader (line 250) | type progressReader struct
    method Read (line 257) | func (pr *progressReader) Read(p []byte) (n int, err error) {

FILE: drivers/google_drive/driver.go
  type GoogleDrive (line 17) | type GoogleDrive struct
    method Config (line 25) | func (d *GoogleDrive) Config() driver.Config {
    method GetAddition (line 29) | func (d *GoogleDrive) GetAddition() driver.Additional {
    method Init (line 33) | func (d *GoogleDrive) Init(ctx context.Context) error {
    method Drop (line 40) | func (d *GoogleDrive) Drop(ctx context.Context) error {
    method List (line 44) | func (d *GoogleDrive) List(ctx context.Context, dir model.Obj, args mo...
    method Link (line 54) | func (d *GoogleDrive) Link(ctx context.Context, file model.Obj, args m...
    method MakeDir (line 69) | func (d *GoogleDrive) MakeDir(ctx context.Context, parentDir model.Obj...
    method Move (line 81) | func (d *GoogleDrive) Move(ctx context.Context, srcObj, dstDir model.O...
    method Rename (line 93) | func (d *GoogleDrive) Rename(ctx context.Context, srcObj model.Obj, ne...
    method Copy (line 104) | func (d *GoogleDrive) Copy(ctx context.Context, srcObj, dstDir model.O...
    method Remove (line 108) | func (d *GoogleDrive) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 114) | func (d *GoogleDrive) Put(ctx context.Context, dstDir model.Obj, strea...

FILE: drivers/google_drive/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 24) | func init() {

FILE: drivers/google_drive/types.go
  type TokenError (line 12) | type TokenError struct
  type Files (line 17) | type Files struct
  type File (line 22) | type File struct
  function fileToObj (line 40) | func fileToObj(f File) *model.ObjThumb {
  type Error (line 68) | type Error struct

FILE: drivers/google_drive/util.go
  type googleDriveServiceAccount (line 26) | type googleDriveServiceAccount struct
  method refreshToken (line 39) | func (d *GoogleDrive) refreshToken() error {
  method request (line 153) | func (d *GoogleDrive) request(url string, method string, callback base.R...
  method getFiles (line 183) | func (d *GoogleDrive) getFiles(id string) ([]File, error) {
  method chunkUpload (line 216) | func (d *GoogleDrive) chunkUpload(ctx context.Context, stream model.File...

FILE: drivers/google_photo/driver.go
  type GooglePhoto (line 18) | type GooglePhoto struct
    method Config (line 24) | func (d *GooglePhoto) Config() driver.Config {
    method GetAddition (line 28) | func (d *GooglePhoto) GetAddition() driver.Additional {
    method Init (line 32) | func (d *GooglePhoto) Init(ctx context.Context) error {
    method Drop (line 36) | func (d *GooglePhoto) Drop(ctx context.Context) error {
    method List (line 40) | func (d *GooglePhoto) List(ctx context.Context, dir model.Obj, args mo...
    method Link (line 50) | func (d *GooglePhoto) Link(ctx context.Context, file model.Obj, args m...
    method MakeDir (line 68) | func (d *GooglePhoto) MakeDir(ctx context.Context, parentDir model.Obj...
    method Move (line 72) | func (d *GooglePhoto) Move(ctx context.Context, srcObj, dstDir model.O...
    method Rename (line 76) | func (d *GooglePhoto) Rename(ctx context.Context, srcObj model.Obj, ne...
    method Copy (line 80) | func (d *GooglePhoto) Copy(ctx context.Context, srcObj, dstDir model.O...
    method Remove (line 84) | func (d *GooglePhoto) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 88) | func (d *GooglePhoto) Put(ctx context.Context, dstDir model.Obj, strea...

FILE: drivers/google_photo/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 24) | func init() {

FILE: drivers/google_photo/types.go
  type TokenError (line 10) | type TokenError struct
  type Items (line 15) | type Items struct
  type MediaItem (line 22) | type MediaItem struct
  type MediaMetadata (line 32) | type MediaMetadata struct
  type Photo (line 40) | type Photo struct
  type Video (line 43) | type Video struct
  function fileToObj (line 46) | func fileToObj(f MediaItem) *model.ObjThumb {
  type Error (line 73) | type Error struct

FILE: drivers/google_photo/util.go
  constant FETCH_ALL (line 14) | FETCH_ALL = "all"
  constant FETCH_ALBUMS (line 15) | FETCH_ALBUMS = "albums"
  constant FETCH_ROOT (line 16) | FETCH_ROOT = "root"
  constant FETCH_SHARE_ALBUMS (line 17) | FETCH_SHARE_ALBUMS = "share_albums"
  method refreshToken (line 20) | func (d *GooglePhoto) refreshToken() error {
  method request (line 41) | func (d *GooglePhoto) request(url string, method string, callback base.R...
  method getFiles (line 74) | func (d *GooglePhoto) getFiles(id string) ([]MediaItem, error) {
  method getFakeRoot (line 89) | func (d *GooglePhoto) getFakeRoot() ([]MediaItem, error) {
  method getAlbums (line 106) | func (d *GooglePhoto) getAlbums() ([]MediaItem, error) {
  method getShareAlbums (line 117) | func (d *GooglePhoto) getShareAlbums() ([]MediaItem, error) {
  method getMedias (line 128) | func (d *GooglePhoto) getMedias(albumId string) ([]MediaItem, error) {
  method getAllMedias (line 139) | func (d *GooglePhoto) getAllMedias() ([]MediaItem, error) {
  method getMedia (line 150) | func (d *GooglePhoto) getMedia(id string) (MediaItem, error) {
  method fetchItems (line 166) | func (d *GooglePhoto) fetchItems(url string, query map[string]string, me...

FILE: drivers/halalcloud/driver.go
  type HalalCloud (line 29) | type HalalCloud struct
    method Config (line 37) | func (d *HalalCloud) Config() driver.Config {
    method GetAddition (line 41) | func (d *HalalCloud) GetAddition() driver.Additional {
    method Init (line 45) | func (d *HalalCloud) Init(ctx context.Context) error {
    method Drop (line 106) | func (d *HalalCloud) Drop(ctx context.Context) error {
    method List (line 110) | func (d *HalalCloud) List(ctx context.Context, dir model.Obj, args mod...
    method Link (line 114) | func (d *HalalCloud) Link(ctx context.Context, file model.Obj, args mo...
    method MakeDir (line 118) | func (d *HalalCloud) MakeDir(ctx context.Context, parentDir model.Obj,...
    method Move (line 122) | func (d *HalalCloud) Move(ctx context.Context, srcObj, dstDir model.Ob...
    method Rename (line 126) | func (d *HalalCloud) Rename(ctx context.Context, srcObj model.Obj, new...
    method Copy (line 130) | func (d *HalalCloud) Copy(ctx context.Context, srcObj, dstDir model.Ob...
    method Remove (line 134) | func (d *HalalCloud) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 138) | func (d *HalalCloud) Put(ctx context.Context, dstDir model.Obj, stream...
    method IsLogin (line 142) | func (d *HalalCloud) IsLogin() bool {
    method SetTokenResp (line 173) | func (d *HalalCloud) SetTokenResp(tr *TokenResp) {
    method getFiles (line 177) | func (d *HalalCloud) getFiles(ctx context.Context, dir model.Obj) ([]m...
    method getLink (line 211) | func (d *HalalCloud) getLink(ctx context.Context, file model.Obj, args...
    method makeDir (line 289) | func (d *HalalCloud) makeDir(ctx context.Context, dir model.Obj, name ...
    method move (line 297) | func (d *HalalCloud) move(ctx context.Context, obj model.Obj, dir mode...
    method rename (line 315) | func (d *HalalCloud) rename(ctx context.Context, obj model.Obj, name s...
    method copy (line 327) | func (d *HalalCloud) copy(ctx context.Context, obj model.Obj, dir mode...
    method remove (line 349) | func (d *HalalCloud) remove(ctx context.Context, obj model.Obj) error {
    method put (line 366) | func (d *HalalCloud) put(ctx context.Context, dstDir model.Obj, fileSt...
  type HalalCommon (line 165) | type HalalCommon struct

FILE: drivers/halalcloud/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 34) | func init() {

FILE: drivers/halalcloud/options.go
  function defaultOptions (line 5) | func defaultOptions() halalOptions {
  type HalalOption (line 15) | type HalalOption interface
  type halalOptions (line 21) | type halalOptions struct
  type funcDialOption (line 28) | type funcDialOption struct
    method apply (line 32) | func (fdo *funcDialOption) apply(do *halalOptions) {
  function newFuncDialOption (line 36) | func newFuncDialOption(f func(*halalOptions)) *funcDialOption {
  function WithRefreshTokenRefreshedCallback (line 42) | func WithRefreshTokenRefreshedCallback(s func(accessToken string, access...
  function WithGrpcDialOptions (line 48) | func WithGrpcDialOptions(opts ...grpc.DialOption) HalalOption {

FILE: drivers/halalcloud/types.go
  type AuthService (line 12) | type AuthService struct
  type TokenResp (line 21) | type TokenResp struct
  type UserInfo (line 28) | type UserInfo struct
  type OrderByInfo (line 35) | type OrderByInfo struct
  type ListInfo (line 40) | type ListInfo struct
  type FilesList (line 47) | type FilesList struct
  type Files (line 54) | type Files
    method GetSize (line 56) | func (f *Files) GetSize() int64 {
    method GetName (line 60) | func (f *Files) GetName() string {
    method ModTime (line 64) | func (f *Files) ModTime() time.Time {
    method CreateTime (line 68) | func (f *Files) CreateTime() time.Time {
    method IsDir (line 72) | func (f *Files) IsDir() bool {
    method GetHash (line 76) | func (f *Files) GetHash() utils.HashInfo {
    method GetID (line 80) | func (f *Files) GetID() string {
    method GetPath (line 87) | func (f *Files) GetPath() string {
  type SteamFile (line 91) | type SteamFile struct
    method Read (line 95) | func (s *SteamFile) Read(p []byte) (n int, err error) {
    method Close (line 99) | func (s *SteamFile) Close() error {

FILE: drivers/halalcloud/util.go
  constant AppID (line 32) | AppID      = "alist/10001"
  constant AppVersion (line 33) | AppVersion = "1.0.0"
  constant AppSecret (line 34) | AppSecret  = "bR4SJwOkvnG5WvVJ"
  constant grpcServer (line 38) | grpcServer     = "grpcuserapi.2dland.cn:443"
  constant grpcServerAuth (line 39) | grpcServerAuth = "grpcuserapi.2dland.cn"
  method NewAuthServiceWithOauth (line 42) | func (d *HalalCloud) NewAuthServiceWithOauth(options ...HalalOption) (*A...
  method NewAuthService (line 90) | func (d *HalalCloud) NewAuthService(refreshToken string, options ...Hala...
  method OnAccessTokenRefreshed (line 156) | func (s *AuthService) OnAccessTokenRefreshed(accessToken string, accessT...
  method GetGrpcConnection (line 168) | func (s *AuthService) GetGrpcConnection() *grpc.ClientConn {
  method Close (line 172) | func (s *AuthService) Close() {
  method signContext (line 176) | func (s *AuthService) signContext(method string, ctx context.Context) co...
  method GetCurrentOpDir (line 197) | func (d *HalalCloud) GetCurrentOpDir(dir model.Obj, args []string, index...
  method GetCurrentDir (line 209) | func (d *HalalCloud) GetCurrentDir(dir model.Obj) string {
  type Common (line 217) | type Common struct
  function getRawFiles (line 220) | func getRawFiles(addr *pubUserFile.SliceDownloadInfo) ([]byte, error) {
  type openObject (line 269) | type openObject struct
    method getChunk (line 283) | func (oo *openObject) getChunk(ctx context.Context) (err error) {
    method Read (line 301) | func (oo *openObject) Read(p []byte) (n int, err error) {
    method Close (line 339) | func (oo *openObject) Close() (err error) {
    method ChunkLocation (line 379) | func (oo *openObject) ChunkLocation(id int) (position int64, size int,...
  function GetMD5Hash (line 354) | func GetMD5Hash(text string) string {
  type chunkSize (line 360) | type chunkSize struct
  function getChunkSizes (line 365) | func getChunkSizes(sliceSize []*pubUserFile.SliceSize) (chunks []chunkSi...

FILE: drivers/ilanzou/driver.go
  type ILanZou (line 26) | type ILanZou struct
    method Config (line 37) | func (d *ILanZou) Config() driver.Config {
    method GetAddition (line 41) | func (d *ILanZou) GetAddition() driver.Additional {
    method Init (line 45) | func (d *ILanZou) Init(ctx context.Context) error {
    method Drop (line 64) | func (d *ILanZou) Drop(ctx context.Context) error {
    method List (line 68) | func (d *ILanZou) List(ctx context.Context, dir model.Obj, args model....
    method Link (line 118) | func (d *ILanZou) Link(ctx context.Context, file model.Obj, args model...
    method MakeDir (line 175) | func (d *ILanZou) MakeDir(ctx context.Context, parentDir model.Obj, di...
    method Move (line 198) | func (d *ILanZou) Move(ctx context.Context, srcObj, dstDir model.Obj) ...
    method Rename (line 218) | func (d *ILanZou) Rename(ctx context.Context, srcObj model.Obj, newNam...
    method Copy (line 251) | func (d *ILanZou) Copy(ctx context.Context, srcObj, dstDir model.Obj) ...
    method Remove (line 256) | func (d *ILanZou) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 275) | func (d *ILanZou) Put(ctx context.Context, dstDir model.Obj, s model.F...
  constant DefaultPartSize (line 273) | DefaultPartSize = 1024 * 1024 * 8

FILE: drivers/ilanzou/meta.go
  type Addition (line 8) | type Addition struct
  type Conf (line 18) | type Conf struct
  function init (line 28) | func init() {

FILE: drivers/ilanzou/types.go
  type ListResp (line 3) | type ListResp struct
  type ListItem (line 13) | type ListItem struct
  type Part (line 41) | type Part struct
  type UploadResultResp (line 46) | type UploadResultResp struct

FILE: drivers/ilanzou/util.go
  method login (line 19) | func (d *ILanZou) login() error {
  function getTimestamp (line 36) | func getTimestamp(secret []byte) (int64, string, error) {
  method request (line 46) | func (d *ILanZou) request(pathname, method string, callback base.ReqCall...
  method unproved (line 111) | func (d *ILanZou) unproved(pathname, method string, callback base.ReqCal...
  method proved (line 115) | func (d *ILanZou) proved(pathname, method string, callback base.ReqCallb...

FILE: drivers/ipfs_api/driver.go
  type IPFS (line 15) | type IPFS struct
    method Config (line 22) | func (d *IPFS) Config() driver.Config {
    method GetAddition (line 26) | func (d *IPFS) GetAddition() driver.Additional {
    method Init (line 30) | func (d *IPFS) Init(ctx context.Context) error {
    method Drop (line 40) | func (d *IPFS) Drop(ctx context.Context) error {
    method List (line 44) | func (d *IPFS) List(ctx context.Context, dir model.Obj, args model.Lis...
    method Link (line 80) | func (d *IPFS) Link(ctx context.Context, file model.Obj, args model.Li...
    method Get (line 86) | func (d *IPFS) Get(ctx context.Context, rawPath string) (model.Obj, er...
    method MakeDir (line 110) | func (d *IPFS) MakeDir(ctx context.Context, parentDir model.Obj, dirNa...
    method Move (line 126) | func (d *IPFS) Move(ctx context.Context, srcObj, dstDir model.Obj) (mo...
    method Rename (line 136) | func (d *IPFS) Rename(ctx context.Context, srcObj model.Obj, newName s...
    method Copy (line 146) | func (d *IPFS) Copy(ctx context.Context, srcObj, dstDir model.Obj) (mo...
    method Remove (line 156) | func (d *IPFS) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 163) | func (d *IPFS) Put(ctx context.Context, dstDir model.Obj, s model.File...

FILE: drivers/ipfs_api/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 23) | func init() {

FILE: drivers/kodbox/driver.go
  type KodBox (line 17) | type KodBox struct
    method Config (line 23) | func (d *KodBox) Config() driver.Config {
    method GetAddition (line 27) | func (d *KodBox) GetAddition() driver.Additional {
    method Init (line 31) | func (d *KodBox) Init(ctx context.Context) error {
    method Drop (line 37) | func (d *KodBox) Drop(ctx context.Context) error {
    method List (line 41) | func (d *KodBox) List(ctx context.Context, dir model.Obj, args model.L...
    method Link (line 82) | func (d *KodBox) Link(ctx context.Context, file model.Obj, args model....
    method MakeDir (line 91) | func (d *KodBox) MakeDir(ctx context.Context, parentDir model.Obj, dir...
    method Move (line 119) | func (d *KodBox) Move(ctx context.Context, srcObj, dstDir model.Obj) (...
    method Rename (line 148) | func (d *KodBox) Rename(ctx context.Context, srcObj model.Obj, newName...
    method Copy (line 174) | func (d *KodBox) Copy(ctx context.Context, srcObj, dstDir model.Obj) (...
    method Remove (line 208) | func (d *KodBox) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 228) | func (d *KodBox) Put(ctx context.Context, dstDir model.Obj, s model.Fi...
    method getFileOrFolderName (line 261) | func (d *KodBox) getFileOrFolderName(ctx context.Context, path string)...

FILE: drivers/kodbox/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 21) | func init() {

FILE: drivers/kodbox/types.go
  type CommonResp (line 3) | type CommonResp struct
  type ListPathData (line 11) | type ListPathData struct
  type FolderOrFile (line 16) | type FolderOrFile struct

FILE: drivers/kodbox/util.go
  method getToken (line 11) | func (d *KodBox) getToken() error {
  method request (line 35) | func (d *KodBox) request(method string, pathname string, callback base.R...

FILE: drivers/lanzou/driver.go
  type LanZou (line 15) | type LanZou struct
    method Config (line 24) | func (d *LanZou) Config() driver.Config {
    method GetAddition (line 28) | func (d *LanZou) GetAddition() driver.Additional {
    method Init (line 32) | func (d *LanZou) Init(ctx context.Context) (err error) {
    method Drop (line 52) | func (d *LanZou) Drop(ctx context.Context) error {
    method List (line 58) | func (d *LanZou) List(ctx context.Context, dir model.Obj, args model.L...
    method Link (line 66) | func (d *LanZou) Link(ctx context.Context, file model.Obj, args model....
    method MakeDir (line 126) | func (d *LanZou) MakeDir(ctx context.Context, parentDir model.Obj, dir...
    method Move (line 148) | func (d *LanZou) Move(ctx context.Context, srcObj, dstDir model.Obj) (...
    method Rename (line 168) | func (d *LanZou) Rename(ctx context.Context, srcObj model.Obj, newName...
    method Remove (line 190) | func (d *LanZou) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 211) | func (d *LanZou) Put(ctx context.Context, dstDir model.Obj, s model.Fi...

FILE: drivers/lanzou/help.go
  constant DAY (line 16) | DAY time.Duration = 84600000000000
  function MustParseTime (line 22) | func MustParseTime(str string) time.Time {
  function SizeStrToInt64 (line 53) | func SizeStrToInt64(size string) int64 {
  function RemoveNotes (line 72) | func RemoveNotes(html string) string {
  function RemoveJSComment (line 82) | func RemoveJSComment(data string) string {
  function CalcAcwScV2 (line 125) | func CalcAcwScV2(html string) (string, error) {
  function Unbox (line 134) | func Unbox(hex string) string {
  function HexXor (line 146) | func HexXor(hex1, hex2 string) string {
  function findJSVarFunc (line 160) | func findJSVarFunc(key, data string) string {
  function findJSFunctionIndex (line 184) | func findJSFunctionIndex(data string, all bool) [][2]int {
  function removeJSGlobalFunction (line 219) | func removeJSGlobalFunction(html string) string {
  function getJSFunctionByName (line 231) | func getJSFunctionByName(html string, name string) (string, error) {
  function htmlJsonToMap2 (line 243) | func htmlJsonToMap2(html string) (map[string]string, error) {
  function htmlJsonToMap (line 258) | func htmlJsonToMap(html string) (map[string]string, error) {
  function jsonToMap (line 266) | func jsonToMap(data, html string) map[string]string {
  function IsNumber (line 280) | func IsNumber(str string) bool {
  function htmlFormToMap (line 292) | func htmlFormToMap(html string) (map[string]string, error) {
  function formToMap (line 300) | func formToMap(from string) map[string]string {
  function GetExpirationTime (line 311) | func GetExpirationTime(url string) (etime time.Duration) {
  function CookieToString (line 324) | func CookieToString(cookies []*http.Cookie) string {

FILE: drivers/lanzou/meta.go
  type Addition (line 8) | type Addition struct
    method IsCookie (line 24) | func (a *Addition) IsCookie() bool {
    method IsAccount (line 28) | func (a *Addition) IsAccount() bool {
  function init (line 38) | func init() {

FILE: drivers/lanzou/types.go
  type RespText (line 15) | type RespText struct
  type RespInfo (line 19) | type RespInfo struct
  type FileOrFolder (line 26) | type FileOrFolder struct
    method CreateTime (line 57) | func (f *FileOrFolder) CreateTime() time.Time {
    method GetHash (line 61) | func (f *FileOrFolder) GetHash() utils.HashInfo {
    method GetID (line 65) | func (f *FileOrFolder) GetID() string {
    method GetName (line 71) | func (f *FileOrFolder) GetName() string {
    method GetPath (line 77) | func (f *FileOrFolder) GetPath() string { return "" }
    method GetSize (line 78) | func (f *FileOrFolder) GetSize() int64 {
    method IsDir (line 85) | func (f *FileOrFolder) IsDir() bool { return f.FolID != "" }
    method ModTime (line 86) | func (f *FileOrFolder) ModTime() time.Time {
    method SetShareInfo (line 94) | func (f *FileOrFolder) SetShareInfo(fs *FileShare) {
    method GetShareInfo (line 97) | func (f *FileOrFolder) GetShareInfo() *FileShare {
  type FileShare (line 102) | type FileShare struct
  type FileOrFolderByShareUrlResp (line 118) | type FileOrFolderByShareUrlResp struct
  type FileOrFolderByShareUrl (line 121) | type FileOrFolderByShareUrl struct
    method CreateTime (line 146) | func (f *FileOrFolderByShareUrl) CreateTime() time.Time {
    method GetHash (line 150) | func (f *FileOrFolderByShareUrl) GetHash() utils.HashInfo {
    method GetID (line 154) | func (f *FileOrFolderByShareUrl) GetID() string   { return f.ID }
    method GetName (line 155) | func (f *FileOrFolderByShareUrl) GetName() string { return f.NameAll }
    method GetPath (line 156) | func (f *FileOrFolderByShareUrl) GetPath() string { return "" }
    method GetSize (line 157) | func (f *FileOrFolderByShareUrl) GetSize() int64 {
    method IsDir (line 164) | func (f *FileOrFolderByShareUrl) IsDir() bool { return f.IsFloder }
    method ModTime (line 165) | func (f *FileOrFolderByShareUrl) ModTime() time.Time {
  type FileShareInfoAndUrlResp (line 174) | type FileShareInfoAndUrlResp struct
  method GetBaseUrl (line 180) | func (u *FileShareInfoAndUrlResp[T]) GetBaseUrl() string {
  method GetDownloadUrl (line 184) | func (u *FileShareInfoAndUrlResp[T]) GetDownloadUrl() string {

FILE: drivers/lanzou/util.go
  method doupload (line 26) | func (d *LanZou) doupload(callback base.ReqCallback, resp interface{}) (...
  method get (line 38) | func (d *LanZou) get(url string, callback base.ReqCallback) ([]byte, err...
  method post (line 42) | func (d *LanZou) post(url string, callback base.ReqCallback, resp interf...
  method _post (line 63) | func (d *LanZou) _post(url string, callback base.ReqCallback, resp inter...
  method request (line 97) | func (d *LanZou) request(url string, method string, callback base.ReqCal...
  method Login (line 129) | func (d *LanZou) Login() ([]*http.Cookie, error) {
  method GetAllFiles (line 156) | func (d *LanZou) GetAllFiles(folderID string) ([]model.Obj, error) {
  method GetFolders (line 175) | func (d *LanZou) GetFolders(folderID string) ([]FileOrFolder, error) {
  method GetFiles (line 190) | func (d *LanZou) GetFiles(folderID string) ([]FileOrFolder, error) {
  method getFolderShareUrlByID (line 213) | func (d *LanZou) getFolderShareUrlByID(fileID string) (*FileShare, error) {
  method getFileShareUrlByID (line 228) | func (d *LanZou) getFileShareUrlByID(fileID string) (*FileShare, error) {
  method getShareUrlHtml (line 271) | func (d *LanZou) getShareUrlHtml(shareID string) (string, error) {
  method GetFileOrFolderByShareUrl (line 309) | func (d *LanZou) GetFileOrFolderByShareUrl(shareID, pwd string) ([]model...
  method GetFilesByShareUrl (line 335) | func (d *LanZou) GetFilesByShareUrl(shareID, pwd string) (file *FileOrFo...
  method getFilesByShareUrl (line 343) | func (d *LanZou) getFilesByShareUrl(shareID, pwd string, sharePageData s...
  method GetFolderByShareUrl (line 483) | func (d *LanZou) GetFolderByShareUrl(shareID, pwd string) ([]FileOrFolde...
  method getFolderByShareUrl (line 491) | func (d *LanZou) getFolderByShareUrl(pwd string, sharePageData string) (...
  method getFileRealInfo (line 534) | func (d *LanZou) getFileRealInfo(downURL string) (*int64, *time.Time) {
  method getVeiAndUid (line 544) | func (d *LanZou) getVeiAndUid() (vei string, uid string, err error) {

FILE: drivers/lark/driver.go
  type Lark (line 22) | type Lark struct
    method Config (line 30) | func (c *Lark) Config() driver.Config {
    method GetAddition (line 34) | func (c *Lark) GetAddition() driver.Additional {
    method Init (line 38) | func (c *Lark) Init(ctx context.Context) error {
    method Drop (line 79) | func (c *Lark) Drop(ctx context.Context) error {
    method List (line 83) | func (c *Lark) List(ctx context.Context, dir model.Obj, args model.Lis...
    method Link (line 130) | func (c *Lark) Link(ctx context.Context, file model.Obj, args model.Li...
    method MakeDir (line 182) | func (c *Lark) MakeDir(ctx context.Context, parentDir model.Obj, dirNa...
    method Move (line 212) | func (c *Lark) Move(ctx context.Context, srcObj, dstDir model.Obj) (mo...
    method Rename (line 243) | func (c *Lark) Rename(ctx context.Context, srcObj model.Obj, newName s...
    method Copy (line 248) | func (c *Lark) Copy(ctx context.Context, srcObj, dstDir model.Obj) (mo...
    method Remove (line 280) | func (c *Lark) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 306) | func (c *Lark) Put(ctx context.Context, dstDir model.Obj, stream model...

FILE: drivers/lark/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 32) | func init() {

FILE: drivers/lark/types.go
  type TokenCache (line 9) | type TokenCache struct
    method Set (line 13) | func (t *TokenCache) Set(_ context.Context, key string, value string, ...
    method Get (line 19) | func (t *TokenCache) Get(_ context.Context, key string) (string, error) {
  function newTokenCache (line 28) | func newTokenCache() *TokenCache {

FILE: drivers/lark/util.go
  constant objTokenCacheDuration (line 12) | objTokenCacheDuration = 5 * time.Minute
  constant emptyFolderToken (line 13) | emptyFolderToken = "empty"
  method getObjToken (line 18) | func (c *Lark) getObjToken(ctx context.Context, folderPath string) (stri...

FILE: drivers/lenovonas_share/driver.go
  type LenovoNasShare (line 16) | type LenovoNasShare struct
    method Config (line 23) | func (d *LenovoNasShare) Config() driver.Config {
    method GetAddition (line 27) | func (d *LenovoNasShare) GetAddition() driver.Additional {
    method Init (line 31) | func (d *LenovoNasShare) Init(ctx context.Context) error {
    method Drop (line 38) | func (d *LenovoNasShare) Drop(ctx context.Context) error {
    method List (line 42) | func (d *LenovoNasShare) List(ctx context.Context, dir model.Obj, args...
    method checkStoken (line 66) | func (d *LenovoNasShare) checkStoken() { // 检查stoken是否过期
    method getStoken (line 72) | func (d *LenovoNasShare) getStoken() error { // 获取stoken
    method Link (line 91) | func (d *LenovoNasShare) Link(ctx context.Context, file model.Obj, arg...
    method MakeDir (line 115) | func (d *LenovoNasShare) MakeDir(ctx context.Context, parentDir model....
    method Move (line 119) | func (d *LenovoNasShare) Move(ctx context.Context, srcObj, dstDir mode...
    method Rename (line 123) | func (d *LenovoNasShare) Rename(ctx context.Context, srcObj model.Obj,...
    method Copy (line 127) | func (d *LenovoNasShare) Copy(ctx context.Context, srcObj, dstDir mode...
    method Remove (line 131) | func (d *LenovoNasShare) Remove(ctx context.Context, obj model.Obj) er...
    method Put (line 135) | func (d *LenovoNasShare) Put(ctx context.Context, dstDir model.Obj, st...

FILE: drivers/lenovonas_share/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 29) | func init() {

FILE: drivers/lenovonas_share/types.go
  type File (line 32) | type File struct
    method UnmarshalJSON (line 12) | func (f *File) UnmarshalJSON(data []byte) error {
    method GetHash (line 41) | func (f File) GetHash() utils.HashInfo {
    method GetPath (line 45) | func (f File) GetPath() string {
    method GetSize (line 49) | func (f File) GetSize() int64 {
    method GetName (line 57) | func (f File) GetName() string {
    method ModTime (line 61) | func (f File) ModTime() time.Time {
    method CreateTime (line 65) | func (f File) CreateTime() time.Time {
    method IsDir (line 69) | func (f File) IsDir() bool {
    method GetID (line 73) | func (f File) GetID() string {
  type Files (line 77) | type Files struct

FILE: drivers/lenovonas_share/util.go
  method request (line 11) | func (d *LenovoNasShare) request(url string, method string, callback bas...

FILE: drivers/local/driver.go
  type Local (line 31) | type Local struct
    method Config (line 50) | func (d *Local) Config() driver.Config {
    method Init (line 54) | func (d *Local) Init(ctx context.Context) error {
    method Drop (line 143) | func (d *Local) Drop(ctx context.Context) error {
    method GetAddition (line 147) | func (d *Local) GetAddition() driver.Additional {
    method List (line 151) | func (d *Local) List(ctx context.Context, dir model.Obj, args model.Li...
    method FileInfoToObj (line 167) | func (d *Local) FileInfoToObj(ctx context.Context, f fs.FileInfo, reqP...
    method GetMeta (line 206) | func (d *Local) GetMeta(ctx context.Context, path string) (model.Obj, ...
    method Get (line 220) | func (d *Local) Get(ctx context.Context, path string) (model.Obj, erro...
    method Link (line 252) | func (d *Local) Link(ctx context.Context, file model.Obj, args model.L...
    method MakeDir (line 289) | func (d *Local) MakeDir(ctx context.Context, parentDir model.Obj, dirN...
    method Move (line 298) | func (d *Local) Move(ctx context.Context, srcObj, dstDir model.Obj) er...
    method Rename (line 322) | func (d *Local) Rename(ctx context.Context, srcObj model.Obj, newName ...
    method Copy (line 332) | func (d *Local) Copy(_ context.Context, srcObj, dstDir model.Obj) error {
    method Remove (line 346) | func (d *Local) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 367) | func (d *Local) Put(ctx context.Context, dstDir model.Obj, stream mode...

FILE: drivers/local/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 29) | func init() {

FILE: drivers/local/token_bucket.go
  type TokenBucket (line 5) | type TokenBucket interface
  type StaticTokenBucket (line 14) | type StaticTokenBucket struct
    method Take (line 58) | func (b StaticTokenBucket) Take() <-chan struct{} {
    method Put (line 62) | func (b StaticTokenBucket) Put() {
    method Do (line 66) | func (b StaticTokenBucket) Do(ctx context.Context, f func() error) err...
  function NewStaticTokenBucket (line 18) | func NewStaticTokenBucket(size int) StaticTokenBucket {
  function NewStaticTokenBucketWithMigration (line 26) | func NewStaticTokenBucketWithMigration(oldBucket TokenBucket, size int) ...
  type NopTokenBucket (line 79) | type NopTokenBucket struct
    method Take (line 89) | func (b NopTokenBucket) Take() <-chan struct{} {
    method Put (line 93) | func (b NopTokenBucket) Put() {}
    method Do (line 95) | func (b NopTokenBucket) Do(_ context.Context, f func() error) error { ...
  function NewNopTokenBucket (line 83) | func NewNopTokenBucket() NopTokenBucket {

FILE: drivers/local/util.go
  function isLinkedDir (line 22) | func isLinkedDir(f fs.FileInfo, path string) bool {
  function resizeImageToBufferWithFFmpegGo (line 45) | func resizeImageToBufferWithFFmpegGo(inputFile string, width int, output...
  function generateThumbnailWithImagingOptimized (line 90) | func generateThumbnailWithImagingOptimized(imagePath string, targetWidth...
  method GetSnapshot (line 126) | func (d *Local) GetSnapshot(videoPath string) (imgData *bytes.Buffer, er...
  function readDir (line 178) | func readDir(dirname string) ([]fs.FileInfo, error) {
  method getThumb (line 192) | func (d *Local) getThumb(file model.Obj) (*bytes.Buffer, *string, error) {

FILE: drivers/mediafire/driver.go
  type Mediafire (line 27) | type Mediafire struct
    method Config (line 44) | func (d *Mediafire) Config() driver.Config {
    method GetAddition (line 48) | func (d *Mediafire) GetAddition() driver.Additional {
    method Init (line 52) | func (d *Mediafire) Init(ctx context.Context) error {
    method Drop (line 77) | func (d *Mediafire) Drop(ctx context.Context) error {
    method List (line 81) | func (d *Mediafire) List(ctx context.Context, dir model.Obj, args mode...
    method Link (line 91) | func (d *Mediafire) Link(ctx context.Context, file model.Obj, args mod...
    method MakeDir (line 123) | func (d *Mediafire) MakeDir(ctx context.Context, parentDir model.Obj, ...
    method Move (line 156) | func (d *Mediafire) Move(ctx context.Context, srcObj, dstDir model.Obj...
    method Rename (line 193) | func (d *Mediafire) Rename(ctx context.Context, srcObj model.Obj, newN...
    method Copy (line 240) | func (d *Mediafire) Copy(ctx context.Context, srcObj, dstDir model.Obj...
    method Remove (line 298) | func (d *Mediafire) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 333) | func (d *Mediafire) Put(ctx context.Context, dstDir model.Obj, file mo...
    method PutResult (line 338) | func (d *Mediafire) PutResult(ctx context.Context, dstDir model.Obj, f...
    method GetArchiveMeta (line 407) | func (d *Mediafire) GetArchiveMeta(ctx context.Context, obj model.Obj,...
    method ListArchive (line 412) | func (d *Mediafire) ListArchive(ctx context.Context, obj model.Obj, ar...
    method Extract (line 417) | func (d *Mediafire) Extract(ctx context.Context, obj model.Obj, args m...
    method ArchiveDecompress (line 422) | func (d *Mediafire) ArchiveDecompress(ctx context.Context, srcObj, dst...

FILE: drivers/mediafire/meta.go
  type Addition (line 16) | type Addition struct
  function init (line 42) | func init() {

FILE: drivers/mediafire/types.go
  type MediafireRenewTokenResponse (line 11) | type MediafireRenewTokenResponse struct
  type MediafireResponse (line 20) | type MediafireResponse struct
  type MediafireFolder (line 36) | type MediafireFolder struct
  type MediafireFile (line 43) | type MediafireFile struct
  type File (line 52) | type File struct
  type FolderContentResponse (line 60) | type FolderContentResponse struct
  type MediafireLinksResponse (line 66) | type MediafireLinksResponse struct
  type MediafireDirectDownloadResponse (line 85) | type MediafireDirectDownloadResponse struct
  type MediafireFolderCreateResponse (line 98) | type MediafireFolderCreateResponse struct
  type MediafireMoveResponse (line 120) | type MediafireMoveResponse struct
  type MediafireRenameResponse (line 131) | type MediafireRenameResponse struct
  type MediafireCopyResponse (line 141) | type MediafireCopyResponse struct
  type MediafireRemoveResponse (line 155) | type MediafireRemoveResponse struct
  type MediafireCheckResponse (line 165) | type MediafireCheckResponse struct
  type MediafireActionTokenResponse (line 196) | type MediafireActionTokenResponse struct
  type MediafirePollResponse (line 205) | type MediafirePollResponse struct
  type MediafireFileSearchResponse (line 225) | type MediafireFileSearchResponse struct

FILE: drivers/mediafire/util.go
  method getSessionToken (line 32) | func (d *Mediafire) getSessionToken(ctx context.Context) (string, error) {
  method renewToken (line 117) | func (d *Mediafire) renewToken(_ context.Context) error {
  method getFiles (line 145) | func (d *Mediafire) getFiles(ctx context.Context, folderKey string) ([]F...
  method getFolderContent (line 184) | func (d *Mediafire) getFolderContent(ctx context.Context, folderKey stri...
  method getFolderContentByType (line 203) | func (d *Mediafire) getFolderContentByType(_ context.Context, folderKey,...
  method fileToObj (line 230) | func (d *Mediafire) fileToObj(f File) *model.ObjThumb {
  method getForm (line 254) | func (d *Mediafire) getForm(endpoint string, query map[string]string, re...
  method postForm (line 281) | func (d *Mediafire) postForm(endpoint string, data map[string]string, re...
  method getDirectDownloadLink (line 309) | func (d *Mediafire) getDirectDownloadLink(_ context.Context, fileID stri...
  method calculateSHA256 (line 334) | func (d *Mediafire) calculateSHA256(file *os.File) (string, error) {
  method uploadCheck (line 345) | func (d *Mediafire) uploadCheck(ctx context.Context, filename string, fi...
  method resumableUpload (line 381) | func (d *Mediafire) resumableUpload(ctx context.Context, folderKey, uplo...
  method uploadUnits (line 450) | func (d *Mediafire) uploadUnits(ctx context.Context, file *os.File, chec...
  method uploadSingleUnit (line 487) | func (d *Mediafire) uploadSingleUnit(ctx context.Context, file *os.File,...
  method getActionToken (line 509) | func (d *Mediafire) getActionToken(_ context.Context) (string, error) {
  method pollUpload (line 535) | func (d *Mediafire) pollUpload(ctx context.Context, key string) (*Mediaf...
  method sha256Hex (line 568) | func (d *Mediafire) sha256Hex(r io.Reader) string {
  method isUnitUploaded (line 574) | func (d *Mediafire) isUnitUploaded(words []int, unitID int) bool {
  method getExistingFileInfo (line 583) | func (d *Mediafire) getExistingFileInfo(ctx context.Context, fileHash, f...
  method getFileByHash (line 603) | func (d *Mediafire) getFileByHash(_ context.Context, hash string) (*mode...

FILE: drivers/mediatrack/driver.go
  type MediaTrack (line 26) | type MediaTrack struct
    method Config (line 31) | func (d *MediaTrack) Config() driver.Config {
    method GetAddition (line 35) | func (d *MediaTrack) GetAddition() driver.Additional {
    method Init (line 39) | func (d *MediaTrack) Init(ctx context.Context) error {
    method Drop (line 44) | func (d *MediaTrack) Drop(ctx context.Context) error {
    method List (line 48) | func (d *MediaTrack) List(ctx context.Context, dir model.Obj, args mod...
    method Link (line 73) | func (d *MediaTrack) Link(ctx context.Context, file model.Obj, args mo...
    method MakeDir (line 100) | func (d *MediaTrack) MakeDir(ctx context.Context, parentDir model.Obj,...
    method Move (line 111) | func (d *MediaTrack) Move(ctx context.Context, srcObj, dstDir model.Ob...
    method Rename (line 123) | func (d *MediaTrack) Rename(ctx context.Context, srcObj model.Obj, new...
    method Copy (line 134) | func (d *MediaTrack) Copy(ctx context.Context, srcObj, dstDir model.Ob...
    method Remove (line 146) | func (d *MediaTrack) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 164) | func (d *MediaTrack) Put(ctx context.Context, dstDir model.Obj, file m...

FILE: drivers/mediatrack/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 21) | func init() {

FILE: drivers/mediatrack/types.go
  type BaseResp (line 9) | type BaseResp struct
  type File (line 13) | type File struct
  type ChildrenResp (line 35) | type ChildrenResp struct
  type UploadResp (line 46) | type UploadResp struct
  type Object (line 68) | type Object struct

FILE: drivers/mediatrack/util.go
  method request (line 17) | func (d *MediaTrack) request(url string, method string, callback base.Re...
  method getFiles (line 42) | func (d *MediaTrack) getFiles(parentId string) ([]File, error) {

FILE: drivers/mega/driver.go
  type Mega (line 22) | type Mega struct
    method Config (line 28) | func (d *Mega) Config() driver.Config {
    method GetAddition (line 32) | func (d *Mega) GetAddition() driver.Additional {
    method Init (line 36) | func (d *Mega) Init(ctx context.Context) error {
    method Drop (line 49) | func (d *Mega) Drop(ctx context.Context) error {
    method List (line 53) | func (d *Mega) List(ctx context.Context, dir model.Obj, args model.Lis...
    method GetRoot (line 81) | func (d *Mega) GetRoot(ctx context.Context) (model.Obj, error) {
    method Link (line 87) | func (d *Mega) Link(ctx context.Context, file model.Obj, args model.Li...
    method MakeDir (line 126) | func (d *Mega) MakeDir(ctx context.Context, parentDir model.Obj, dirNa...
    method Move (line 134) | func (d *Mega) Move(ctx context.Context, srcObj, dstDir model.Obj) err...
    method Rename (line 143) | func (d *Mega) Rename(ctx context.Context, srcObj model.Obj, newName s...
    method Copy (line 150) | func (d *Mega) Copy(ctx context.Context, srcObj, dstDir model.Obj) err...
    method Remove (line 154) | func (d *Mega) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 161) | func (d *Mega) Put(ctx context.Context, dstDir model.Obj, stream model...

FILE: drivers/mega/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 24) | func init() {

FILE: drivers/mega/types.go
  type MegaNode (line 11) | type MegaNode struct
    method GetSize (line 15) | func (m *MegaNode) GetSize() int64 {
    method GetName (line 19) | func (m *MegaNode) GetName() string {
    method CreateTime (line 23) | func (m *MegaNode) CreateTime() time.Time {
    method GetHash (line 27) | func (m *MegaNode) GetHash() utils.HashInfo {
    method ModTime (line 32) | func (m *MegaNode) ModTime() time.Time {
    method IsDir (line 36) | func (m *MegaNode) IsDir() bool {
    method GetID (line 40) | func (m *MegaNode) GetID() string {
    method GetPath (line 44) | func (m *MegaNode) GetPath() string {

FILE: drivers/mega/util.go
  type openObject (line 15) | type openObject struct
    method getChunk (line 26) | func (oo *openObject) getChunk(ctx context.Context) (err error) {
    method Read (line 44) | func (oo *openObject) Read(p []byte) (n int, err error) {
    method Close (line 78) | func (oo *openObject) Close() (err error) {

FILE: drivers/misskey/driver.go
  type Misskey (line 12) | type Misskey struct
    method Config (line 17) | func (d *Misskey) Config() driver.Config {
    method GetAddition (line 21) | func (d *Misskey) GetAddition() driver.Additional {
    method Init (line 25) | func (d *Misskey) Init(ctx context.Context) error {
    method Drop (line 34) | func (d *Misskey) Drop(ctx context.Context) error {
    method List (line 38) | func (d *Misskey) List(ctx context.Context, dir model.Obj, args model....
    method Link (line 42) | func (d *Misskey) Link(ctx context.Context, file model.Obj, args model...
    method MakeDir (line 46) | func (d *Misskey) MakeDir(ctx context.Context, parentDir model.Obj, di...
    method Move (line 50) | func (d *Misskey) Move(ctx context.Context, srcObj, dstDir model.Obj) ...
    method Rename (line 54) | func (d *Misskey) Rename(ctx context.Context, srcObj model.Obj, newNam...
    method Copy (line 58) | func (d *Misskey) Copy(ctx context.Context, srcObj, dstDir model.Obj) ...
    method Remove (line 62) | func (d *Misskey) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 66) | func (d *Misskey) Put(ctx context.Context, dstDir model.Obj, stream mo...

FILE: drivers/misskey/meta.go
  type Addition (line 8) | type Addition struct
  function init (line 31) | func init() {

FILE: drivers/misskey/types.go
  type Resp (line 3) | type Resp struct
  type Properties (line 8) | type Properties struct
  type MFile (line 13) | type MFile struct
  type MFolder (line 30) | type MFolder struct

FILE: drivers/misskey/util.go
  method request (line 20) | func (d *Misskey) request(path, method string, callback base.ReqCallback...
  method getThumb (line 47) | func (d *Misskey) getThumb(ctx context.Context, obj model.Obj) (io.Reade...
  function setBody (line 52) | func setBody(body interface{}) base.ReqCallback {
  function handleFolderId (line 58) | func handleFolderId(dir model.Obj) interface{} {
  method getFiles (line 67) | func (d *Misskey) getFiles(dir model.Obj) ([]model.Obj, error) {
  method getFolders (line 84) | func (d *Misskey) getFolders(dir model.Obj) ([]model.Obj, error) {
  method list (line 101) | func (d *Misskey) list(dir model.Obj) ([]model.Obj, error) {
  method link (line 107) | func (d *Misskey) link(file model.Obj) (*model.Link, error) {
  method makeDir (line 118) | func (d *Misskey) makeDir(parentDir model.Obj, dirName string) (model.Ob...
  method move (line 127) | func (d *Misskey) move(srcObj, dstDir model.Obj) (model.Obj, error) {
  method rename (line 139) | func (d *Misskey) rename(srcObj model.Obj, newName string) (model.Obj, e...
  method copy (line 151) | func (d *Misskey) copy(srcObj, dstDir model.Obj) (model.Obj, error) {
  method remove (line 182) | func (d *Misskey) remove(obj model.Obj) error {
  method put (line 192) | func (d *Misskey) put(ctx context.Context, dstDir model.Obj, stream mode...
  function mFile2Object (line 223) | func mFile2Object(file MFile) *model.ObjThumbURL {
  function mFolder2Object (line 245) | func mFolder2Object(folder MFolder) *model.Object {

FILE: drivers/mopan/driver.go
  type MoPan (line 26) | type MoPan struct
    method Config (line 35) | func (d *MoPan) Config() driver.Config {
    method GetAddition (line 39) | func (d *MoPan) GetAddition() driver.Additional {
    method Init (line 43) | func (d *MoPan) Init(ctx context.Context) error {
    method Drop (line 106) | func (d *MoPan) Drop(ctx context.Context) error {
    method List (line 112) | func (d *MoPan) List(ctx context.Context, dir model.Obj, args model.Li...
    method Link (line 137) | func (d *MoPan) Link(ctx context.Context, file model.Obj, args model.L...
    method MakeDir (line 160) | func (d *MoPan) MakeDir(ctx context.Context, parentDir model.Obj, dirN...
    method Move (line 170) | func (d *MoPan) Move(ctx context.Context, srcObj, dstDir model.Obj) (m...
    method Rename (line 174) | func (d *MoPan) Rename(ctx context.Context, srcObj model.Obj, newName ...
    method Copy (line 193) | func (d *MoPan) Copy(ctx context.Context, srcObj, dstDir model.Obj) (m...
    method newTask (line 197) | func (d *MoPan) newTask(srcObj, dstDir model.Obj, taskType mopan.TaskT...
    method Remove (line 256) | func (d *MoPan) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 267) | func (d *MoPan) Put(ctx context.Context, dstDir model.Obj, stream mode...

FILE: drivers/mopan/meta.go
  type Addition (line 8) | type Addition struct
    method GetRootId (line 25) | func (a *Addition) GetRootId() string {
  function init (line 36) | func init() {

FILE: drivers/mopan/util.go
  function fileToObj (line 11) | func fileToObj(f mopan.File) model.Obj {
  function folderToObj (line 27) | func folderToObj(f mopan.Folder) model.Obj {
  function CloneObj (line 37) | func CloneObj(o model.Obj, newID, newName string) model.Obj {

FILE: drivers/netease_music/crypto.go
  function aesKeyPending (line 29) | func aesKeyPending(key []byte) []byte {
  function pkcs7Padding (line 49) | func pkcs7Padding(src []byte, blockSize int) []byte {
  function aesCBCEncrypt (line 55) | func aesCBCEncrypt(src, key, iv []byte) []byte {
  function aesECBEncrypt (line 66) | func aesECBEncrypt(src, key []byte) []byte {
  function ecbCryptBlocks (line 77) | func ecbCryptBlocks(block cipher.Block, dst, src []byte) {
  function rsaEncrypt (line 87) | func rsaEncrypt(buffer, key []byte) []byte {
  function getSecretKey (line 97) | func getSecretKey() ([]byte, []byte) {
  function weapi (line 108) | func weapi(data map[string]string) map[string]string {
  function eapi (line 118) | func eapi(url string, data map[string]interface{}) map[string]string {
  function linuxapi (line 130) | func linuxapi(data map[string]interface{}) map[string]string {

FILE: drivers/netease_music/driver.go
  type NeteaseMusic (line 13) | type NeteaseMusic struct
    method Config (line 22) | func (d *NeteaseMusic) Config() driver.Config {
    method GetAddition (line 26) | func (d *NeteaseMusic) GetAddition() driver.Additional {
    method Init (line 30) | func (d *NeteaseMusic) Init(ctx context.Context) error {
    method Drop (line 41) | func (d *NeteaseMusic) Drop(ctx context.Context) error {
    method Get (line 45) | func (d *NeteaseMusic) Get(ctx context.Context, path string) (model.Ob...
    method List (line 70) | func (d *NeteaseMusic) List(ctx context.Context, dir model.Obj, args m...
    method Link (line 74) | func (d *NeteaseMusic) Link(ctx context.Context, file model.Obj, args ...
    method Remove (line 86) | func (d *NeteaseMusic) Remove(ctx context.Context, obj model.Obj) error {
    method Put (line 90) | func (d *NeteaseMusic) Put(ctx context.Context, dstDir model.Obj, stre...
    method Copy (line 94) | func (d *NeteaseMusic) Copy(ctx context.Context, srcObj, dstDir model....
    method Move (line 98) | func (d *NeteaseMusic) Move(ctx context.Context, srcObj, dstDir model....
    method MakeDir (line 102) | func (d *NeteaseMusic) MakeDir(ctx context.Context, parentDir model.Ob...
    method Rename (line 106) | func (d *NeteaseMusic) Rename(ctx context.Context, srcObj model.Obj, n...

FILE: drivers/netease_music/meta.go
  type Addition (line 10) | type Addition struct
    method getCookie (line 15) | func (ad *Addition) getCookie(name string) string {
  function init (line 28) | func init() {

FILE: drivers/netease_music/types.go
  type HostsResp (line 20) | type HostsResp struct
  type SongResp (line 24) | type SongResp struct
  type ListResp (line 30) | type ListResp struct
  type LyricObj (line 46) | type LyricObj struct
    method getProxyLink (line 51) | func (lrc *LyricObj) getProxyLink(args model.LinkArgs) *model.Link {
    method getLyricLink (line 57) | func (lrc *LyricObj) getLyricLink() *model.Link {
  type ReqOption (line 72) | type ReqOption struct
  type Characteristic (line 83) | type Characteristic
    method fromDriver (line 85) | func (ch *Characteristic) fromDriver(d *NeteaseMusic) *Characteristic {
    method toCookies (line 102) | func (ch Characteristic) toCookies() []*http.Cookie {
    method merge (line 110) | func (ch *Characteristic) merge(data map[string]string) map[string]int...

FILE: drivers/netease_music/upload.go
  type token (line 18) | type token struct
  type songmeta (line 24) | type songmeta struct
  type uploader (line 32) | type uploader struct
    method init (line 42) | func (u *uploader) init(stream model.FileStreamer) error {
    method checkIfExisted (line 88) | func (u *uploader) checkIfExisted() error {
    method allocToken (line 116) | func (u *uploader) allocToken(bucket ...string) (token, error) {
    method publishInfo (line 144) | func (u *uploader) publishInfo(resourceId string) error {
    method upload (line 175) | func (u *uploader) upload(ctx context.Context, stream model.FileStream...

FILE: drivers/netease_music/util.go
  method request (line 19) | func (d *NeteaseMusic) request(url, method string, opt ReqOption) ([]byt...
  method getSongObjs (line 96) | func (d *NeteaseMusic) getSongObjs(args model.ListArgs) ([]model.Obj, er...
  method getSongLink (line 147) | func (d *NeteaseMusic) getSongLink(file model.Obj) (*model.Link, error) {
  method getLyricObj (line 177) | func (d *NeteaseMusic) getLyricObj(file model.Obj) (model.Obj, error) {
  method removeSongObj (line 214) | func (d *NeteaseMusic) removeSongObj(file model.Obj) error {
  method putSongStream (line 225) | func (d *NeteaseMusic) putSongStream(ctx context.Context, stream model.F...

FILE: drivers/onedrive/driver.go
  type Onedrive (line 19) | type Onedrive struct
    method Config (line 27) | func (d *Onedrive) Config() driver.Config {
    method GetAddition (line 31) | func (d *Onedrive) GetAddition() driver.Additional {
    method Init (line 35) | func (d *Onedrive) Init(ctx context.Context) error {
    method Drop (line 42) | func (d *Onedrive) Drop(ctx context.Context) error {
    method GetRoot (line 46) | func (d *Onedrive) GetRoot(ctx context.Context) (model.Obj, error) {
    method List (line 82) | func (d *Onedrive) List(ctx context.Context, dir model.Obj, args model...
    method Link (line 92) | func (d *Onedrive) Link(ctx context.Context, file model.Obj, args mode...
    method MakeDir (line 114) | func (d *Onedrive) MakeDir(ctx context.Context, parentDir model.Obj, d...
    method Move (line 128) | func (d *Onedrive) Move(ctx context.Context, srcObj, dstDir model.Obj)...
    me
Condensed preview — 727 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,425K chars).
[
  {
    "path": ".air.toml",
    "chars": 748,
    "preview": "root = \".\"\ntestdata_dir = \"testdata\"\ntmp_dir = \"tmp\"\n\n[build]\nargs_bin = [\"server\"]\nbin = \"./tmp/main\"\ncmd = \"go build -"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 780,
    "preview": "# These are supported funding model platforms\n\ngithub: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [u"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.yml",
    "chars": 3259,
    "preview": "name: \"Bug report\"\ndescription: Bug report\nlabels: [bug]\nbody:\n  - type: markdown\n    attributes:\n      value: |\n       "
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 217,
    "preview": "blank_issues_enabled: false\ncontact_links:\n  - name: Questions & Discussions\n    url: https://github.com/alist-org/alist"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.yml",
    "chars": 1120,
    "preview": "name: \"Feature request\"\ndescription: Feature request\nlabels: [enhancement]\nbody:\n  - type: checkboxes\n    attributes:\n  "
  },
  {
    "path": ".github/config.yml",
    "chars": 924,
    "preview": "# Configuration for welcome - https://github.com/behaviorbot/welcome\n\n# Configuration for new-issue-welcome - https://gi"
  },
  {
    "path": ".github/stale.yml",
    "chars": 872,
    "preview": "# Number of days of inactivity before an issue becomes stale\ndaysUntilStale: 44\n# Number of days of inactivity before a "
  },
  {
    "path": ".github/workflows/auto_lang.yml",
    "chars": 1729,
    "preview": "name: auto_lang\n\non:\n  push:\n    branches:\n      - 'main'\n    paths:\n      - 'drivers/**'\n      - 'internal/bootstrap/da"
  },
  {
    "path": ".github/workflows/beta_release.yml",
    "chars": 3727,
    "preview": "name: beta release\n\non:\n  push:\n    branches: [ 'main' ]\n\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.event."
  },
  {
    "path": ".github/workflows/build.yml",
    "chars": 1638,
    "preview": "name: build\n\non:\n  push:\n    branches: [ 'main' ]\n  pull_request:\n    branches: [ 'main' ]\n\nconcurrency:\n  group: ${{ gi"
  },
  {
    "path": ".github/workflows/changelog.yml",
    "chars": 478,
    "preview": "name: auto changelog\n\non:\n  push:\n    tags:\n      - 'v*'\n\njobs:\n  changelog:\n    name: Create Release\n    runs-on: ubunt"
  },
  {
    "path": ".github/workflows/issue_close_question.yml",
    "chars": 607,
    "preview": "name: Close need info\n\non:\n  schedule:\n    - cron: \"0 0 */1 * *\"\n  workflow_dispatch:\n\njobs:\n  close-need-info:\n    runs"
  },
  {
    "path": ".github/workflows/issue_close_stale.yml",
    "chars": 636,
    "preview": "name: Close inactive\n\non:\n  schedule:\n    - cron: \"0 0 */7 * *\"\n  workflow_dispatch:\n\njobs:\n  close-inactive:\n    runs-o"
  },
  {
    "path": ".github/workflows/issue_duplicate.yml",
    "chars": 746,
    "preview": "name: Issue Duplicate\n\non:\n  issues:\n    types: [labeled]\n\njobs:\n  create-comment:\n    runs-on: ubuntu-latest\n    if: gi"
  },
  {
    "path": ".github/workflows/issue_invalid.yml",
    "chars": 736,
    "preview": "name: Issue Invalid\n\non:\n  issues:\n    types: [labeled]\n\njobs:\n  create-comment:\n    runs-on: ubuntu-latest\n    if: gith"
  },
  {
    "path": ".github/workflows/issue_on_close.yml",
    "chars": 408,
    "preview": "name: Remove working label when issue closed\n\non:\n  issues:\n    types: [closed]\n\njobs:\n  rm-working:\n    runs-on: ubuntu"
  },
  {
    "path": ".github/workflows/issue_question.yml",
    "chars": 709,
    "preview": "name: Issue Question\n\non:\n  issues:\n    types: [labeled]\n\njobs:\n  create-comment:\n    runs-on: ubuntu-latest\n    if: git"
  },
  {
    "path": ".github/workflows/issue_similarity.yml",
    "chars": 451,
    "preview": "name: Issues Similarity Analysis\n\non:\n  issues:\n    types: [opened, edited]\n\njobs:\n  similarity-analysis:\n    runs-on: u"
  },
  {
    "path": ".github/workflows/issue_translate.yml",
    "chars": 213,
    "preview": "name: Translation Helper\n\non:\n  pull_request_target:\n    types: [opened]\n  issues:\n    types: [opened]\n\njobs:\n  translat"
  },
  {
    "path": ".github/workflows/issue_wontfix.yml",
    "chars": 740,
    "preview": "name: Issue Wontfix\n\non:\n  issues:\n    types: [labeled]\n\njobs:\n  lock-issue:\n    runs-on: ubuntu-latest\n    if: github.e"
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 2500,
    "preview": "name: release\n\non:\n  release:\n    types: [ published ]\n\njobs:\n  release:\n    strategy:\n      matrix:\n        platform: ["
  },
  {
    "path": ".github/workflows/release_android.yml",
    "chars": 663,
    "preview": "name: release_android\n\non:\n  release:\n    types: [ published ]\n\njobs:\n  release_android:\n    strategy:\n      matrix:\n   "
  },
  {
    "path": ".github/workflows/release_docker.yml",
    "chars": 4217,
    "preview": "name: release_docker\n\non:\n  push:\n    tags:\n      - 'v*'\n    branches:\n      - main\n  pull_request:\n    branches:\n      "
  },
  {
    "path": ".github/workflows/release_freebsd.yml",
    "chars": 663,
    "preview": "name: release_freebsd\n\non:\n  release:\n    types: [ published ]\n\njobs:\n  release_freebsd:\n    strategy:\n      matrix:\n   "
  },
  {
    "path": ".github/workflows/release_linux_musl.yml",
    "chars": 672,
    "preview": "name: release_linux_musl\n\non:\n  release:\n    types: [ published ]\n\njobs:\n  release_linux_musl:\n    strategy:\n      matri"
  },
  {
    "path": ".github/workflows/release_linux_musl_arm.yml",
    "chars": 684,
    "preview": "name: release_linux_musl_arm\n\non:\n  release:\n    types: [ published ]\n\njobs:\n  release_linux_musl_arm:\n    strategy:\n   "
  },
  {
    "path": ".gitignore",
    "chars": 423,
    "preview": ".idea/\n.DS_Store\noutput/\n/dist/\n\n# Binaries for programs and plugins\n*.exe\n*.exe~\n*.dll\n*.so\n*.dylib\n*.db\n*.bin\n\n# Test "
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 5209,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participa"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 3451,
    "preview": "# Contributing\n\n## Setup your machine\n\n`alist` is written in [Go](https://golang.org/) and [React](https://reactjs.org/)"
  },
  {
    "path": "Dockerfile",
    "chars": 1606,
    "preview": "FROM alpine:edge as builder\nLABEL stage=go-builder\nWORKDIR /app/\nRUN apk add --no-cache bash curl gcc git go musl-dev\nCO"
  },
  {
    "path": "Dockerfile.ci",
    "chars": 1424,
    "preview": "FROM alpine:3.20.7\n\nARG TARGETPLATFORM\nARG INSTALL_FFMPEG=false\nARG INSTALL_ARIA2=false\nLABEL MAINTAINER=\"i@nn.ci\"\n\nWORK"
  },
  {
    "path": "LICENSE",
    "chars": 34523,
    "preview": "                    GNU AFFERO GENERAL PUBLIC LICENSE\n                       Version 3, 19 November 2007\n\n Copyright (C)"
  },
  {
    "path": "README.md",
    "chars": 6831,
    "preview": "<div align=\"center\">\n  <a href=\"https://alistgo.com\"><img width=\"100px\" alt=\"logo\" src=\"https://cdn.jsdelivr.net/gh/alis"
  },
  {
    "path": "README_cn.md",
    "chars": 5192,
    "preview": "<div align=\"center\">\n  <a href=\"https://alistgo.com\"><img width=\"100px\" alt=\"logo\" src=\"https://cdn.jsdelivr.net/gh/alis"
  },
  {
    "path": "README_ja.md",
    "chars": 5855,
    "preview": "<div align=\"center\">\n  <a href=\"https://alistgo.com\"><img width=\"100px\" alt=\"logo\" src=\"https://cdn.jsdelivr.net/gh/alis"
  },
  {
    "path": "build.sh",
    "chars": 12807,
    "preview": "appName=\"alist\"\nbuiltAt=\"$(date +'%F %T %z')\"\ngitAuthor=\"Xhofe <i@nn.ci>\"\ngitCommit=$(git log --pretty=format:\"%h\" -1)\n\n"
  },
  {
    "path": "cmd/admin.go",
    "chars": 2919,
    "preview": "/*\nCopyright © 2022 NAME HERE <EMAIL ADDRESS>\n*/\npackage cmd\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/conf\"\n\t\""
  },
  {
    "path": "cmd/cancel2FA.go",
    "chars": 1187,
    "preview": "/*\nCopyright © 2022 NAME HERE <EMAIL ADDRESS>\n*/\npackage cmd\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/op\"\n\t\"gi"
  },
  {
    "path": "cmd/common.go",
    "chars": 1239,
    "preview": "package cmd\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/bootstrap/patch/v3_46_0\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv"
  },
  {
    "path": "cmd/flags/config.go",
    "chars": 133,
    "preview": "package flags\n\nvar (\n\tDataDir     string\n\tDebug       bool\n\tNoPrefix    bool\n\tDev         bool\n\tForceBinDir bool\n\tLogStd"
  },
  {
    "path": "cmd/kill.go",
    "chars": 1279,
    "preview": "package cmd\n\nimport (\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/spf13/cobra\"\n\t\"os\"\n)\n\n// KillCmd represents the kil"
  },
  {
    "path": "cmd/lang.go",
    "chars": 4328,
    "preview": "/*\nPackage cmd\nCopyright © 2022 Noah Hsu<i@nn.ci>\n*/\npackage cmd\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"reflect\"\n\t\"strings\"\n\n\t_ "
  },
  {
    "path": "cmd/restart.go",
    "chars": 783,
    "preview": "/*\nCopyright © 2022 NAME HERE <EMAIL ADDRESS>\n*/\npackage cmd\n\nimport (\n\t\"github.com/spf13/cobra\"\n)\n\n// RestartCmd repres"
  },
  {
    "path": "cmd/root.go",
    "chars": 1281,
    "preview": "package cmd\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/alist-org/alist/v3/cmd/flags\"\n\t_ \"github.com/alist-org/alist/v3/drivers"
  },
  {
    "path": "cmd/server.go",
    "chars": 7777,
    "preview": "package cmd\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"os\"\n\t\"os/signal\"\n\t\"strconv\"\n\t\"sync\"\n\t\"syscall\"\n\t\""
  },
  {
    "path": "cmd/start.go",
    "chars": 1751,
    "preview": "/*\nCopyright © 2022 NAME HERE <EMAIL ADDRESS>\n*/\npackage cmd\n\nimport (\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"strconv\"\n\n\tlo"
  },
  {
    "path": "cmd/stop_default.go",
    "chars": 1324,
    "preview": "//go:build !windows\n\npackage cmd\n\nimport (\n\t\"os\"\n\t\"syscall\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/spf13/cobra\""
  },
  {
    "path": "cmd/stop_windows.go",
    "chars": 733,
    "preview": "//go:build windows\n\npackage cmd\n\nimport (\n\t\"github.com/spf13/cobra\"\n)\n\n// StopCmd represents the stop command\nvar StopCm"
  },
  {
    "path": "cmd/storage.go",
    "chars": 3971,
    "preview": "/*\nCopyright © 2023 NAME HERE <EMAIL ADDRESS>\n*/\npackage cmd\n\nimport (\n\t\"os\"\n\t\"strconv\"\n\n\t\"github.com/alist-org/alist/v3"
  },
  {
    "path": "cmd/user.go",
    "chars": 1599,
    "preview": "package cmd\n\nimport (\n\t\"crypto/tls\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/alist-org/alist/v3/internal/conf\"\n\t\"github.com/alist-or"
  },
  {
    "path": "cmd/version.go",
    "chars": 1113,
    "preview": "/*\nCopyright © 2022 NAME HERE <EMAIL ADDRESS>\n*/\npackage cmd\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"runtime\"\n\n\t\"github.com/alist-org/a"
  },
  {
    "path": "docker-compose.yml",
    "chars": 293,
    "preview": "version: '3.3'\nservices:\n  alist:\n    restart: always\n    volumes:\n      - '/etc/alist:/opt/alist/data'\n    ports:\n     "
  },
  {
    "path": "drivers/115/appver.go",
    "chars": 869,
    "preview": "package _115\n\nimport (\n\tdriver115 \"github.com/SheltonZhu/115driver/pkg/driver\"\n\t\"github.com/alist-org/alist/v3/drivers/b"
  },
  {
    "path": "drivers/115/driver.go",
    "chars": 6366,
    "preview": "package _115\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"sync\"\n\n\tdriver115 \"github.com/SheltonZhu/115driver/pkg/driver\"\n\t\"github.c"
  },
  {
    "path": "drivers/115/meta.go",
    "chars": 1014,
    "preview": "package _115\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/op\"\n)\n\n"
  },
  {
    "path": "drivers/115/types.go",
    "chars": 877,
    "preview": "package _115\n\nimport (\n\t\"time\"\n\n\t\"github.com/SheltonZhu/115driver/pkg/driver\"\n\t\"github.com/alist-org/alist/v3/internal/m"
  },
  {
    "path": "drivers/115/util.go",
    "chars": 15549,
    "preview": "package _115\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/md5\"\n\t\"crypto/tls\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"n"
  },
  {
    "path": "drivers/115_open/driver.go",
    "chars": 8348,
    "preview": "package _115_open\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/alist-org/al"
  },
  {
    "path": "drivers/115_open/meta.go",
    "chars": 1008,
    "preview": "package _115_open\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/op"
  },
  {
    "path": "drivers/115_open/types.go",
    "chars": 1082,
    "preview": "package _115_open\n\nimport (\n\t\"time\"\n\n\t\"github.com/alist-org/alist/v3/internal/model\"\n\t\"github.com/alist-org/alist/v3/pkg"
  },
  {
    "path": "drivers/115_open/upload.go",
    "chars": 4086,
    "preview": "package _115_open\n\nimport (\n\t\"context\"\n\t\"encoding/base64\"\n\t\"io\"\n\t\"time\"\n\n\t\"github.com/alist-org/alist/v3/internal/driver"
  },
  {
    "path": "drivers/115_open/util.go",
    "chars": 69,
    "preview": "package _115_open\n\n// do others that not defined in Driver interface\n"
  },
  {
    "path": "drivers/115_share/driver.go",
    "chars": 2968,
    "preview": "package _115_share\n\nimport (\n\t\"context\"\n\n\tdriver115 \"github.com/SheltonZhu/115driver/pkg/driver\"\n\t\"github.com/alist-org/"
  },
  {
    "path": "drivers/115_share/meta.go",
    "chars": 1320,
    "preview": "package _115_share\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/o"
  },
  {
    "path": "drivers/115_share/utils.go",
    "chars": 4936,
    "preview": "package _115_share\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"time\"\n\n\tdriver115 \"github.com/SheltonZhu/115driver/pkg/driver\"\n\t\"github"
  },
  {
    "path": "drivers/123/driver.go",
    "chars": 7480,
    "preview": "package _123\n\nimport (\n\t\"context\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\""
  },
  {
    "path": "drivers/123/meta.go",
    "chars": 727,
    "preview": "package _123\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/op\"\n)\n\n"
  },
  {
    "path": "drivers/123/types.go",
    "chars": 2566,
    "preview": "package _123\n\nimport (\n\t\"github.com/alist-org/alist/v3/pkg/utils\"\n\t\"net/url\"\n\t\"path\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"gi"
  },
  {
    "path": "drivers/123/upload.go",
    "chars": 4938,
    "preview": "package _123\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"strconv\"\n\n\t\"github.com/alist-org/alist/v3/drivers/base\"\n\t\"g"
  },
  {
    "path": "drivers/123/util.go",
    "chars": 9937,
    "preview": "package _123\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"hash/crc32\"\n\t\"math\"\n\t\"math/rand\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strconv\"\n"
  },
  {
    "path": "drivers/123_link/driver.go",
    "chars": 1779,
    "preview": "package _123Link\n\nimport (\n\t\"context\"\n\tstdpath \"path\"\n\t\"time\"\n\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github"
  },
  {
    "path": "drivers/123_link/meta.go",
    "chars": 648,
    "preview": "package _123Link\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/op\""
  },
  {
    "path": "drivers/123_link/parse.go",
    "chars": 3665,
    "preview": "package _123Link\n\nimport (\n\t\"fmt\"\n\turl2 \"net/url\"\n\tstdpath \"path\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\n// build tree from te"
  },
  {
    "path": "drivers/123_link/types.go",
    "chars": 1150,
    "preview": "package _123Link\n\nimport (\n\t\"time\"\n\n\t\"github.com/alist-org/alist/v3/internal/errs\"\n\t\"github.com/alist-org/alist/v3/inter"
  },
  {
    "path": "drivers/123_link/util.go",
    "chars": 715,
    "preview": "package _123Link\n\nimport (\n\t\"crypto/md5\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"net/url\"\n\t\"time\"\n)\n\nfunc SignURL(originURL, privateKey st"
  },
  {
    "path": "drivers/123_open/api.go",
    "chars": 4192,
    "preview": "package _123Open\n\nimport (\n\t\"fmt\"\n\t\"github.com/go-resty/resty/v2\"\n\t\"net/http\"\n)\n\nconst (\n\t// baseurl\n\tApiBaseURL = \"http"
  },
  {
    "path": "drivers/123_open/driver.go",
    "chars": 7232,
    "preview": "package _123Open\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/ali"
  },
  {
    "path": "drivers/123_open/meta.go",
    "chars": 914,
    "preview": "package _123Open\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/op\""
  },
  {
    "path": "drivers/123_open/sign.go",
    "chars": 652,
    "preview": "package _123Open\n\nimport (\n\t\"crypto/md5\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"net/url\"\n\t\"time\"\n)\n\nfunc SignURL(originURL, privateKey st"
  },
  {
    "path": "drivers/123_open/token.go",
    "chars": 1833,
    "preview": "package _123Open\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"sync\"\n\t\"time\"\n)\n\nconst tokenURL = ApiBaseURL +"
  },
  {
    "path": "drivers/123_open/types.go",
    "chars": 1325,
    "preview": "package _123Open\n\nimport (\n\t\"fmt\"\n\t\"github.com/alist-org/alist/v3/pkg/utils\"\n\t\"time\"\n)\n\ntype File struct {\n\tFileName    "
  },
  {
    "path": "drivers/123_open/upload.go",
    "chars": 8004,
    "preview": "package _123Open\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/md5\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"github.com/alist-"
  },
  {
    "path": "drivers/123_open/util.go",
    "chars": 489,
    "preview": "package _123Open\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n)\n\nfunc (d *Open123) getFiles(parentFileId int64, limit int, lastFileId in"
  },
  {
    "path": "drivers/123_share/driver.go",
    "chars": 4498,
    "preview": "package _123Share\n\nimport (\n\t\"context\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"sync\"\n\t\"time\"\n\n\t\"golang.org/x/"
  },
  {
    "path": "drivers/123_share/meta.go",
    "chars": 934,
    "preview": "package _123Share\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/op"
  },
  {
    "path": "drivers/123_share/types.go",
    "chars": 1869,
    "preview": "package _123Share\n\nimport (\n\t\"github.com/alist-org/alist/v3/pkg/utils\"\n\t\"net/url\"\n\t\"path\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n"
  },
  {
    "path": "drivers/123_share/util.go",
    "chars": 3334,
    "preview": "package _123Share\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"hash/crc32\"\n\t\"math\"\n\t\"math/rand\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strc"
  },
  {
    "path": "drivers/139/driver.go",
    "chars": 22791,
    "preview": "package _139\n\nimport (\n\t\"context\"\n\t\"encoding/xml\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"path\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/alis"
  },
  {
    "path": "drivers/139/meta.go",
    "chars": 1064,
    "preview": "package _139\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/op\"\n)\n\n"
  },
  {
    "path": "drivers/139/types.go",
    "chars": 10800,
    "preview": "package _139\n\nimport (\n\t\"encoding/xml\"\n)\n\nconst (\n\tMetaPersonal    string = \"personal\"\n\tMetaFamily      string = \"family"
  },
  {
    "path": "drivers/139/util.go",
    "chars": 17200,
    "preview": "package _139\n\nimport (\n\t\"encoding/base64\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"path\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n"
  },
  {
    "path": "drivers/189/driver.go",
    "chars": 5260,
    "preview": "package _189\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/alist-org/alist/v3/drivers/base\"\n\t\"github.com/ali"
  },
  {
    "path": "drivers/189/help.go",
    "chars": 3942,
    "preview": "package _189\n\nimport (\n\t\"bytes\"\n\t\"crypto/aes\"\n\t\"crypto/hmac\"\n\t\"crypto/md5\"\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/sha1\"\n\t"
  },
  {
    "path": "drivers/189/login.go",
    "chars": 3989,
    "preview": "package _189\n\nimport (\n\t\"errors\"\n\t\"strconv\"\n\n\t\"github.com/alist-org/alist/v3/pkg/utils\"\n\tlog \"github.com/sirupsen/logrus"
  },
  {
    "path": "drivers/189/meta.go",
    "chars": 712,
    "preview": "package _189\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/op\"\n)\n\n"
  },
  {
    "path": "drivers/189/types.go",
    "chars": 1569,
    "preview": "package _189\n\ntype LoginResp struct {\n\tMsg    string `json:\"msg\"`\n\tResult int    `json:\"result\"`\n\tToUrl  string `json:\"t"
  },
  {
    "path": "drivers/189/util.go",
    "chars": 12982,
    "preview": "package _189\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/md5\"\n\t\"encoding/base64\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"mat"
  },
  {
    "path": "drivers/189pc/driver.go",
    "chars": 9879,
    "preview": "package _189pc\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/alist-org/alist/v3/dr"
  },
  {
    "path": "drivers/189pc/help.go",
    "chars": 4828,
    "preview": "package _189pc\n\nimport (\n\t\"bytes\"\n\t\"crypto/aes\"\n\t\"crypto/hmac\"\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/sha1\"\n\t\"crypto/x509"
  },
  {
    "path": "drivers/189pc/meta.go",
    "chars": 1264,
    "preview": "package _189pc\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/op\"\n)"
  },
  {
    "path": "drivers/189pc/types.go",
    "chars": 9666,
    "preview": "package _189pc\n\nimport (\n\t\"encoding/xml\"\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/alist-org/alist/v3/pkg/utils\"\n)"
  },
  {
    "path": "drivers/189pc/utils.go",
    "chars": 34042,
    "preview": "package _189pc\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/base64\"\n\t\"encoding/hex\"\n\t\"encoding/xml\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\""
  },
  {
    "path": "drivers/alias/driver.go",
    "chars": 7950,
    "preview": "package alias\n\nimport (\n\t\"context\"\n\t\"errors\"\n\tstdpath \"path\"\n\t\"strings\"\n\n\t\"github.com/alist-org/alist/v3/internal/driver"
  },
  {
    "path": "drivers/alias/meta.go",
    "chars": 1082,
    "preview": "package alias\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/op\"\n)\n"
  },
  {
    "path": "drivers/alias/types.go",
    "chars": 14,
    "preview": "package alias\n"
  },
  {
    "path": "drivers/alias/util.go",
    "chars": 5997,
    "preview": "package alias\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/url\"\n\tstdpath \"path\"\n\t\"strings\"\n\n\t\"github.com/alist-org/alist/v3/interna"
  },
  {
    "path": "drivers/alist_v2/driver.go",
    "chars": 2954,
    "preview": "package alist_v2\n\nimport (\n\t\"context\"\n\n\t\"github.com/alist-org/alist/v3/drivers/base\"\n\t\"github.com/alist-org/alist/v3/int"
  },
  {
    "path": "drivers/alist_v2/meta.go",
    "chars": 494,
    "preview": "package alist_v2\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/op\""
  },
  {
    "path": "drivers/alist_v2/types.go",
    "chars": 716,
    "preview": "package alist_v2\n\nimport (\n\t\"time\"\n)\n\ntype File struct {\n\tId        string     `json:\"-\"`\n\tName      string     `json:\"n"
  },
  {
    "path": "drivers/alist_v2/util.go",
    "chars": 17,
    "preview": "package alist_v2\n"
  },
  {
    "path": "drivers/alist_v3/driver.go",
    "chars": 9752,
    "preview": "package alist_v3\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"path\"\n\t\"strings\"\n\n\t\"github.com/alist-org/ali"
  },
  {
    "path": "drivers/alist_v3/meta.go",
    "chars": 787,
    "preview": "package alist_v3\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/op\""
  },
  {
    "path": "drivers/alist_v3/types.go",
    "chars": 4023,
    "preview": "package alist_v3\n\nimport (\n\t\"encoding/json\"\n\t\"time\"\n\n\t\"github.com/alist-org/alist/v3/internal/model\"\n\t\"github.com/alist-"
  },
  {
    "path": "drivers/alist_v3/util.go",
    "chars": 1687,
    "preview": "package alist_v3\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/alist-org/alist/v3/drivers/base\"\n\t\"github.com/alist-org/alis"
  },
  {
    "path": "drivers/aliyundrive/driver.go",
    "chars": 9375,
    "preview": "package aliyundrive\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/sha1\"\n\t\"encoding/base64\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\""
  },
  {
    "path": "drivers/aliyundrive/global.go",
    "chars": 257,
    "preview": "package aliyundrive\n\nimport (\n\t\"crypto/ecdsa\"\n\n\t\"github.com/alist-org/alist/v3/pkg/generic_sync\"\n)\n\ntype State struct {\n"
  },
  {
    "path": "drivers/aliyundrive/help.go",
    "chars": 1326,
    "preview": "package aliyundrive\n\nimport (\n\t\"crypto/ecdsa\"\n\t\"crypto/rand\"\n\t\"encoding/hex\"\n\t\"math/big\"\n\n\t\"github.com/dustinxie/ecc\"\n)\n"
  },
  {
    "path": "drivers/aliyundrive/meta.go",
    "chars": 923,
    "preview": "package aliyundrive\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/"
  },
  {
    "path": "drivers/aliyundrive/types.go",
    "chars": 1404,
    "preview": "package aliyundrive\n\nimport (\n\t\"time\"\n\n\t\"github.com/alist-org/alist/v3/internal/model\"\n)\n\ntype RespErr struct {\n\tCode   "
  },
  {
    "path": "drivers/aliyundrive/util.go",
    "chars": 5531,
    "preview": "package aliyundrive\n\nimport (\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/alist-org/alis"
  },
  {
    "path": "drivers/aliyundrive_open/driver.go",
    "chars": 8942,
    "preview": "package aliyundrive_open\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"path/filepath\"\n\t\"time\"\n\n\t\"github.com/Xhofe/"
  },
  {
    "path": "drivers/aliyundrive_open/meta.go",
    "chars": 1823,
    "preview": "package aliyundrive_open\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/inte"
  },
  {
    "path": "drivers/aliyundrive_open/types.go",
    "chars": 2275,
    "preview": "package aliyundrive_open\n\nimport (\n\t\"github.com/alist-org/alist/v3/pkg/utils\"\n\t\"time\"\n\n\t\"github.com/alist-org/alist/v3/i"
  },
  {
    "path": "drivers/aliyundrive_open/upload.go",
    "chars": 8068,
    "preview": "package aliyundrive_open\n\nimport (\n\t\"context\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"net/http\"\n\t\"strconv\"\n\t\"strings\"\n"
  },
  {
    "path": "drivers/aliyundrive_open/util.go",
    "chars": 6022,
    "preview": "package aliyundrive_open\n\nimport (\n\t\"context\"\n\t\"encoding/base64\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\t\"gith"
  },
  {
    "path": "drivers/aliyundrive_share/driver.go",
    "chars": 3617,
    "preview": "package aliyundrive_share\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/Xhofe/rateg\"\n\t\"github.com/alist-"
  },
  {
    "path": "drivers/aliyundrive_share/meta.go",
    "chars": 747,
    "preview": "package aliyundrive_share\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/int"
  },
  {
    "path": "drivers/aliyundrive_share/types.go",
    "chars": 1447,
    "preview": "package aliyundrive_share\n\nimport (\n\t\"time\"\n\n\t\"github.com/alist-org/alist/v3/internal/model\"\n)\n\ntype ErrorResp struct {\n"
  },
  {
    "path": "drivers/aliyundrive_share/util.go",
    "chars": 3759,
    "preview": "package aliyundrive_share\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/alist-org/alist/v3/drivers/base\"\n\t\"github.com/alist-o"
  },
  {
    "path": "drivers/all.go",
    "chars": 4367,
    "preview": "package drivers\n\nimport (\n\t_ \"github.com/alist-org/alist/v3/drivers/115\"\n\t_ \"github.com/alist-org/alist/v3/drivers/115_o"
  },
  {
    "path": "drivers/azure_blob/driver.go",
    "chars": 9795,
    "preview": "package azure_blob\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"path\"\n\t\"regexp\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/Azure/azure-sdk-"
  },
  {
    "path": "drivers/azure_blob/meta.go",
    "chars": 1298,
    "preview": "package azure_blob\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/o"
  },
  {
    "path": "drivers/azure_blob/types.go",
    "chars": 525,
    "preview": "package azure_blob\n\nimport \"github.com/alist-org/alist/v3/internal/driver\"\n\n// progressTracker is used to track upload p"
  },
  {
    "path": "drivers/azure_blob/util.go",
    "chars": 12201,
    "preview": "package azure_blob\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"path\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com"
  },
  {
    "path": "drivers/baidu_netdisk/driver.go",
    "chars": 12612,
    "preview": "package baidu_netdisk\n\nimport (\n\t\"context\"\n\t\"crypto/md5\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/url\"\n\t\"os\"\n\tstdpat"
  },
  {
    "path": "drivers/baidu_netdisk/meta.go",
    "chars": 2048,
    "preview": "package baidu_netdisk\n\nimport (\n\t\"time\"\n\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v"
  },
  {
    "path": "drivers/baidu_netdisk/types.go",
    "chars": 6341,
    "preview": "package baidu_netdisk\n\nimport (\n\t\"errors\"\n\t\"path\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/alist-org/alist/v3/internal/model\"\n\t\""
  },
  {
    "path": "drivers/baidu_netdisk/util.go",
    "chars": 12073,
    "preview": "package baidu_netdisk\n\nimport (\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\t\"unicode\"\n\n\t"
  },
  {
    "path": "drivers/baidu_photo/driver.go",
    "chars": 10347,
    "preview": "package baiduphoto\n\nimport (\n\t\"context\"\n\t\"crypto/md5\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"regexp\"\n\t\"strconv\"\n"
  },
  {
    "path": "drivers/baidu_photo/help.go",
    "chars": 1436,
    "preview": "package baiduphoto\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"math/rand\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/alist-org/alist/v3/pkg/utils\"\n"
  },
  {
    "path": "drivers/baidu_photo/meta.go",
    "chars": 945,
    "preview": "package baiduphoto\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/o"
  },
  {
    "path": "drivers/baidu_photo/types.go",
    "chars": 4512,
    "preview": "package baiduphoto\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/alist-org/alist/v3/pkg/utils\"\n\n\t\"github.com/alist-org/alist/v3"
  },
  {
    "path": "drivers/baidu_photo/utils.go",
    "chars": 13695,
    "preview": "package baiduphoto\n\nimport (\n\t\"context\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode\"\n\n\t\"github.co"
  },
  {
    "path": "drivers/baidu_share/driver.go",
    "chars": 6595,
    "preview": "package baidu_share\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"path\"\n\t\"time\"\n\n\t\"github."
  },
  {
    "path": "drivers/baidu_share/meta.go",
    "chars": 815,
    "preview": "package baidu_share\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/"
  },
  {
    "path": "drivers/baidu_share/types.go",
    "chars": 20,
    "preview": "package baidu_share\n"
  },
  {
    "path": "drivers/baidu_share/util.go",
    "chars": 71,
    "preview": "package baidu_share\n\n// do others that not defined in Driver interface\n"
  },
  {
    "path": "drivers/base/client.go",
    "chars": 1147,
    "preview": "package base\n\nimport (\n\t\"crypto/tls\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/alist-org/alist/v3/internal/conf\"\n\t\"github.com/al"
  },
  {
    "path": "drivers/base/types.go",
    "chars": 243,
    "preview": "package base\n\nimport \"github.com/go-resty/resty/v2\"\n\ntype Json map[string]interface{}\n\ntype TokenResp struct {\n\tAccessTo"
  },
  {
    "path": "drivers/base/upload.go",
    "chars": 866,
    "preview": "package base\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/Xhofe/go-cache\"\n\t\"github.com/alist-org/alist/v3/internal/"
  },
  {
    "path": "drivers/base/util.go",
    "chars": 13,
    "preview": "package base\n"
  },
  {
    "path": "drivers/bitqiu/driver.go",
    "chars": 19334,
    "preview": "package bitqiu\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http/cookiejar\"\n\t\"path\"\n\t\"strconv\"\n\t\"strings\"\n\t\""
  },
  {
    "path": "drivers/bitqiu/meta.go",
    "chars": 953,
    "preview": "package bitqiu\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/op\"\n)"
  },
  {
    "path": "drivers/bitqiu/types.go",
    "chars": 2902,
    "preview": "package bitqiu\n\nimport \"encoding/json\"\n\ntype Response[T any] struct {\n\tCode    string `json:\"code\"`\n\tMessage string `jso"
  },
  {
    "path": "drivers/bitqiu/util.go",
    "chars": 1960,
    "preview": "package bitqiu\n\nimport (\n\t\"path\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/alist-org/alist/v3/internal/model\"\n\t\"github.com/alist-"
  },
  {
    "path": "drivers/chaoxing/driver.go",
    "chars": 7449,
    "preview": "package chaoxing\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"mime/multipart\"\n\t\"net/http\"\n\t\"n"
  },
  {
    "path": "drivers/chaoxing/meta.go",
    "chars": 1238,
    "preview": "package chaoxing\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/op\""
  },
  {
    "path": "drivers/chaoxing/types.go",
    "chars": 10352,
    "preview": "package chaoxing\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/alist-org/alist/v3/internal/model\"\n)\n\ntype R"
  },
  {
    "path": "drivers/chaoxing/util.go",
    "chars": 4418,
    "preview": "package chaoxing\n\nimport (\n\t\"bytes\"\n\t\"crypto/aes\"\n\t\"crypto/cipher\"\n\t\"encoding/base64\"\n\t\"errors\"\n\t\"fmt\"\n\t\"mime/multipart\""
  },
  {
    "path": "drivers/cloudreve/driver.go",
    "chars": 5247,
    "preview": "package cloudreve\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"path\"\n\t\"strings\"\n\n\t\"github.com/alist-org/alist/v3/drivers/bas"
  },
  {
    "path": "drivers/cloudreve/meta.go",
    "chars": 709,
    "preview": "package cloudreve\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/op"
  },
  {
    "path": "drivers/cloudreve/types.go",
    "chars": 1659,
    "preview": "package cloudreve\n\nimport (\n\t\"time\"\n\n\t\"github.com/alist-org/alist/v3/internal/model\"\n)\n\ntype Resp struct {\n\tCode int    "
  },
  {
    "path": "drivers/cloudreve/util.go",
    "chars": 12740,
    "preview": "package cloudreve\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t"
  },
  {
    "path": "drivers/cloudreve_v4/driver.go",
    "chars": 8346,
    "preview": "package cloudreve_v4\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net/http\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/alist-org/al"
  },
  {
    "path": "drivers/cloudreve_v4/meta.go",
    "chars": 1373,
    "preview": "package cloudreve_v4\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal"
  },
  {
    "path": "drivers/cloudreve_v4/types.go",
    "chars": 4908,
    "preview": "package cloudreve_v4\n\nimport (\n\t\"time\"\n\n\t\"github.com/alist-org/alist/v3/internal/model\"\n)\n\ntype Object struct {\n\tmodel.O"
  },
  {
    "path": "drivers/cloudreve_v4/util.go",
    "chars": 13139,
    "preview": "package cloudreve_v4\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http"
  },
  {
    "path": "drivers/crypt/driver.go",
    "chars": 12162,
    "preview": "package crypt\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\tstdpath \"path\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/alist-org/alist/v3/in"
  },
  {
    "path": "drivers/crypt/meta.go",
    "chars": 1815,
    "preview": "package crypt\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/op\"\n)\n"
  },
  {
    "path": "drivers/crypt/types.go",
    "chars": 14,
    "preview": "package crypt\n"
  },
  {
    "path": "drivers/crypt/util.go",
    "chars": 1208,
    "preview": "package crypt\n\nimport (\n\tstdpath \"path\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/alist-org/alist/v3/internal/op\"\n)\n\n// "
  },
  {
    "path": "drivers/doubao/driver.go",
    "chars": 7440,
    "preview": "package doubao\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net/http\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/alist-org/alist/v3"
  },
  {
    "path": "drivers/doubao/meta.go",
    "chars": 855,
    "preview": "package doubao\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/op\"\n)"
  },
  {
    "path": "drivers/doubao/types.go",
    "chars": 13514,
    "preview": "package doubao\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/alist-org/alist/v3/internal/model\"\n)\n\ntype BaseRe"
  },
  {
    "path": "drivers/doubao/util.go",
    "chars": 25133,
    "preview": "package doubao\n\nimport (\n\t\"context\"\n\t\"crypto/hmac\"\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\""
  },
  {
    "path": "drivers/doubao_new/driver.go",
    "chars": 15600,
    "preview": "package doubao_new\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/sha256\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t"
  },
  {
    "path": "drivers/doubao_new/meta.go",
    "chars": 1022,
    "preview": "package doubao_new\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/o"
  },
  {
    "path": "drivers/doubao_new/types.go",
    "chars": 4080,
    "preview": "package doubao_new\n\nimport \"github.com/alist-org/alist/v3/internal/model\"\n\ntype BaseResp struct {\n\tCode    int    `json:"
  },
  {
    "path": "drivers/doubao_new/util.go",
    "chars": 27289,
    "preview": "package doubao_new\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/rand\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"hash/adler32\"\n"
  },
  {
    "path": "drivers/doubao_share/driver.go",
    "chars": 5174,
    "preview": "package doubao_share\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"github.com/alist-org/alist/v3/drivers/base\"\n\t\"github.com/alist-org"
  },
  {
    "path": "drivers/doubao_share/meta.go",
    "chars": 695,
    "preview": "package doubao_share\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal"
  },
  {
    "path": "drivers/doubao_share/types.go",
    "chars": 5896,
    "preview": "package doubao_share\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"github.com/alist-org/alist/v3/internal/model\"\n)\n\ntype BaseResp "
  },
  {
    "path": "drivers/doubao_share/util.go",
    "chars": 17224,
    "preview": "package doubao_share\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"github.com/alist-org/alist/v3/drivers/base\"\n\t\"github"
  },
  {
    "path": "drivers/dropbox/driver.go",
    "chars": 6219,
    "preview": "package dropbox\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/alist-org/alist/v3/drivers/b"
  },
  {
    "path": "drivers/dropbox/meta.go",
    "chars": 1084,
    "preview": "package dropbox\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/op\"\n"
  },
  {
    "path": "drivers/dropbox/types.go",
    "chars": 2131,
    "preview": "package dropbox\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/model\"\n\t\"time\"\n)\n\ntype TokenResp struct {\n\tAccessToke"
  },
  {
    "path": "drivers/dropbox/util.go",
    "chars": 5686,
    "preview": "package dropbox\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/alist-org/alist/v3/drivers/base\"\n"
  },
  {
    "path": "drivers/febbox/driver.go",
    "chars": 2955,
    "preview": "package febbox\n\nimport (\n\t\"context\"\n\t\"github.com/alist-org/alist/v3/internal/op\"\n\t\"github.com/alist-org/alist/v3/pkg/uti"
  },
  {
    "path": "drivers/febbox/meta.go",
    "chars": 1158,
    "preview": "package febbox\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/op\"\n)"
  },
  {
    "path": "drivers/febbox/oauth2.go",
    "chars": 2153,
    "preview": "package febbox\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\t\"time\"\n\n\t\"golang.org/x"
  },
  {
    "path": "drivers/febbox/types.go",
    "chars": 4034,
    "preview": "package febbox\n\nimport (\n\t\"fmt\"\n\t\"github.com/alist-org/alist/v3/internal/model\"\n\t\"github.com/alist-org/alist/v3/pkg/util"
  },
  {
    "path": "drivers/febbox/util.go",
    "chars": 4991,
    "preview": "package febbox\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"github.com/alist-org/alist/v3/drivers/base\"\n\t\"github.com/al"
  },
  {
    "path": "drivers/ftp/driver.go",
    "chars": 3046,
    "preview": "package ftp\n\nimport (\n\t\"context\"\n\tstdpath \"path\"\n\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-or"
  },
  {
    "path": "drivers/ftp/meta.go",
    "chars": 914,
    "preview": "package ftp\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/op\"\n\t\"gi"
  },
  {
    "path": "drivers/ftp/types.go",
    "chars": 12,
    "preview": "package ftp\n"
  },
  {
    "path": "drivers/ftp/util.go",
    "chars": 2159,
    "preview": "package ftp\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/jlaffaye/ftp\"\n)\n\n// do others that not de"
  },
  {
    "path": "drivers/ftps/driver.go",
    "chars": 3060,
    "preview": "package ftps\n\nimport (\n\t\"context\"\n\tstdpath \"path\"\n\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-o"
  },
  {
    "path": "drivers/ftps/meta.go",
    "chars": 1316,
    "preview": "package ftps\n\nimport (\n\t\"github.com/alist-org/alist/v3/internal/driver\"\n\t\"github.com/alist-org/alist/v3/internal/op\"\n\t\"g"
  },
  {
    "path": "drivers/ftps/types.go",
    "chars": 13,
    "preview": "package ftps\n"
  },
  {
    "path": "drivers/ftps/util.go",
    "chars": 2533,
    "preview": "package ftps\n\nimport (\n\t\"crypto/tls\"\n\t\"io\"\n\t\"net\"\n\t\"os\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/jlaffaye/ftp\"\n)\n\nfu"
  }
]

// ... and 527 more files (download for full content)

About this extraction

This page contains the full source code of the AlistGo/alist GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 727 files (2.9 MB), approximately 802.3k tokens, and a symbol index with 6244 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!