diff --git a/.gitignore b/.gitignore index e4d6531..f6bacce 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,22 @@ +# Dependencies node_modules/ -dist/ -tmp/ -static/ -*.db -*.exe -download/ + +# Build output build/ -.VSCodeCounter/ -.claude/ -server/bilidown.exe~ + +# IDE +.idea/ +.vscode/ +*.swp +*.swo + +# OS +.DS_Store +Thumbs.db + +# Project specific +.omc/ +backup/ +*.db +download/ +bin/ \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 0ba38e9..0000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2025 iuroc - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/README.md b/README.md deleted file mode 100644 index 286f5e7..0000000 --- a/README.md +++ /dev/null @@ -1,136 +0,0 @@ -# Bilidown - -[![GitHub Release](https://img.shields.io/github/v/release/iuroc/bilidown)](https://github.com/iuroc/bilidown/releases) - -哔哩哔哩视频解析下载工具,支持 8K 视频、Hi-Res 音频、杜比视界下载、批量解析,可扫码登录,常驻托盘。 - -## 支持解析的链接类型 - -- 【单个视频】https://www.bilibili.com/video/BV1LLDCYJEU3/ -- 【番剧和影视剧】https://www.bilibili.com/bangumi/play/ss48831 -- 【视频合集】https://space.bilibili.com/282565107/channel/collectiondetail?sid=1427135 -- 【收藏夹】https://space.bilibili.com/1176277996/favlist?fid=1234122612 -- 【UP 主空间地址】等待 3.x 版本支持 - -## 使用说明 - -1. 从 [Releases](https://github.com/iuroc/bilidown/releases) 下载适合您系统版本的安装包 -2. 非 Windows 系统,请先安装 [FFmpeg 工具](https://www.ffmpeg.org/) -3. 将安装包解压后执行即可 - -## 软件特色 - -1. 前端采用 [Bootstrap](https://github.com/twbs/bootstrap) 和 [VanJS](https://github.com/vanjs-org/van) 构建,轻量美观 -2. 后端使用 Go 语言开发,数据库采用 SQlite,简化构建和部署过程 -3. 前端通过 [p-queue](https://github.com/sindresorhus/p-queue) 控制并发请求,加快批量解析速度 - -## 其他说明 - -- 本程序不支持也不建议 HTTP 代理,直接使用国内网络访问能提升批量解析的成功率和稳定性。 - -## 打包可执行文件 - -```shell -git clone https://github.com/iuroc/bilidown -cd bilidown/client -pnpm install -pnpm build -cd ../server -go mod tidy -CGO_ENABLED=1 go build -``` - -## 交叉编译 - -### 说明 - -- 镜像名称:`iuroc/cgo-cross-build` -- 支持的系统架构 - - `linux/amd64` - - `windows/amd64` - - `windows/386` - - `windows/arm64` - - `darwin/amd64` - - `darwin/arm64` - -### 拉取镜像和项目源码 - -```shell -docker pull iuroc/cgo-cross-build:latest -git clone https://github.com/iuroc/bilidown -``` - -### 交叉编译发行版 - -> 执行 `goreleaser` 命令时将自动执行 `pnpm build` 和 `go mod tidy` - -将 `ffmpeg.exe` 放入 `server/bin` 目录内。 - -在项目根目录执行如下代码,进入 Docker 容器。 - -```shell -docker run --rm -it -v .:/usr/src/data iuroc/cgo-cross-build -``` - -在容器内的终端执行如下代码,开始交叉编译。 - -```shell -cd server -git tag v2.1.1 -goreleaser release --snapshot --clean -# 正式发行 -# GITHUB_TOKEN=xxx goreleaser release --clean -``` - -### 编译指定系统架构 - -```ini -# 按上面的步骤进入 Docker 容器内终端 - -# [darwin-amd64] -GOOS=darwin -GOARCH=amd64 -CC=o64-clang -CGO_ENABLED=1 -go build -``` - -### 非 Docker 环境编译 - -在 Linux amd64 平台上执行 `go build` 时,您可能需要安装以下依赖包: - -```bash -sudo apt install pkg-config gcc libayatana-appindicator3-dev -``` - -## 开发环境 - -```bash -# client -pnpm install -pnpm dev -# server -go build && ./bilidown -``` - -## 特别感谢 - -- [twbs/bootstrap](https://github.com/twbs/bootstrap) - 前端开发必备的响应式框架,简化页面布局 -- [vanjs-org/van](https://github.com/vanjs-org/van) - 轻量级的前端框架,专注于构建高效应用 -- [vitejs/vite](https://github.com/vitejs/vite) - 快速的前端构建工具,基于 ES 模块开发 -- [SocialSisterYi/bilibili-API-collec](https://github.com/SocialSisterYi/bilibili-API-collect) - B 站 API 集合,支持多种操作接口 -- [sindresorhus/p-queue](https://github.com/sindresorhus/p-queue) - 支持并发限制的 JavaScript 队列处理库 -- [iuroc/vanjs-router](https://github.com/iuroc/vanjs-router) - 轻量级前端路由工具,适用于 Van.js 框架 -- [uuidjs/uuid](https://www.npmjs.com/package/uuid) - 用于生成唯一标识符(UUID)的 JavaScript 库 -- [getlantern/systray](https://github.com/getlantern/systray) - 简单的跨平台系统托盘图标库,支持图标管理 -- [modernc.org/sqlite](https://pkg.go.dev/modernc.org/sqlite) - Go 语言的 SQLite3 数据库驱动,轻量高效 -- [skip2/go-qrcode](https://github.com/skip2/go-qrcode) - 生成 QR 码的 Go 语言库,简单易用 - -## 软件界面 - -![](./docs/2024-11-05_090604.png) - - -## Star History - -[![Star History Chart](https://api.star-history.com/svg?repos=iuroc/bilidown&type=Date)](https://www.star-history.com/#iuroc/bilidown&Date) diff --git a/cmd/bilidown/main.go b/cmd/bilidown/main.go new file mode 100644 index 0000000..1242101 --- /dev/null +++ b/cmd/bilidown/main.go @@ -0,0 +1,131 @@ +package main + +import ( + "database/sql" + "embed" + "fmt" + "io/fs" + "log" + "net/http" + "os" + + "bilidown/internal/router" + "bilidown/internal/util" + + _ "modernc.org/sqlite" +) + +//go:embed all:build/static +var staticFiles embed.FS + +const ( + HTTP_PORT = 8098 // HTTP 服务器端口 + HTTP_HOST = "" // HTTP 服务器主机 + VERSION = "v2.1.1" // 软件版本号 +) + +var urlLocal = fmt.Sprintf("http://127.0.0.1:%d", HTTP_PORT) + +func main() { + checkFFmpeg() + mustInitTables() + mustRunServer() + fmt.Printf("Bilidown %s server running at %s\n", VERSION, urlLocal) + select {} // 保持运行 +} + +// checkFFmpeg 检测 ffmpeg 的安装情况 +func checkFFmpeg() { + if _, err := util.GetFFmpegPath(); err != nil { + fmt.Println("FFmpeg is missing. Install it from https://www.ffmpeg.org/download.html, then restart.") + os.Exit(1) + } +} + +// mustRunServer 配置和启动 HTTP 服务器 +func mustRunServer() { + // 从嵌入的文件系统中获取静态文件 + staticFS, err := fs.Sub(staticFiles, "build/static") + if err != nil { + log.Fatal("Failed to load static files:", err) + } + // 前端静态文件 + http.Handle("/", http.FileServer(http.FS(staticFS))) + // 后端 API 接口 + http.Handle("/api/", http.StripPrefix("/api", router.API())) + // 启动 HTTP 服务器 + go func() { + err := http.ListenAndServe(fmt.Sprintf("%s:%d", HTTP_HOST, HTTP_PORT), nil) + if err != nil { + log.Fatal("http.ListenAndServe:", err) + } + }() +} + +// mustInitTables 初始化数据表 +func mustInitTables() { + db := util.MustGetDB() + defer db.Close() + + if _, err := db.Exec(`CREATE TABLE IF NOT EXISTS "field" ( + "name" TEXT PRIMARY KEY NOT NULL, + "value" TEXT + )`); err != nil { + log.Fatalln("create table field:", err) + } + + if _, err := db.Exec(`CREATE TABLE IF NOT EXISTS "log" ( + "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "content" TEXT NOT NULL, + "create_at" text NOT NULL DEFAULT CURRENT_TIMESTAMP + )`); err != nil { + log.Fatalln("create table log:", err) + } + + if _, err := db.Exec(`CREATE TABLE IF NOT EXISTS "task" ( + "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "bvid" text NOT NULL, + "cid" integer NOT NULL, + "format" integer NOT NULL, + "title" text NOT NULL, + "owner" text NOT NULL, + "cover" text NOT NULL, + "status" text NOT NULL, + "folder" text NOT NULL, + "duration" integer NOT NULL, + "download_type" text NOT NULL DEFAULT 'merge', + "create_at" text NOT NULL DEFAULT CURRENT_TIMESTAMP + )`); err != nil { + log.Fatalln("create table task:", err) + } + + if _, err := util.GetCurrentFolder(db); err != nil { + log.Fatalln("util.GetCurrentFolder:", err) + } + + if err := initHistoryTask(db); err != nil { + log.Fatalln("initHistoryTask:", err) + } + + // 添加可能缺失的列(用于数据库迁移) + if err := addMissingColumns(db); err != nil { + log.Fatalln("addMissingColumns:", err) + } +} + +// addMissingColumns 添加可能缺失的列(用于数据库迁移) +func addMissingColumns(db *sql.DB) error { + util.SqliteLock.Lock() + _, _ = db.Exec(`ALTER TABLE "task" ADD COLUMN "download_type" TEXT DEFAULT 'merge'`) + _, _ = db.Exec(`UPDATE "task" SET "download_type" = 'merge' WHERE "download_type" IS NULL`) + util.SqliteLock.Unlock() + return nil +} + +// initHistoryTask 将上一次程序运行时未完成的任务状态变为 error +func initHistoryTask(db *sql.DB) error { + util.SqliteLock.Lock() + _, err := db.Exec(`UPDATE "task" SET "status" = 'error' WHERE "status" IN ('waiting', 'running')`) + util.SqliteLock.Unlock() + return err +} \ No newline at end of file diff --git a/docs/2024-11-05_090604.png b/docs/2024-11-05_090604.png deleted file mode 100644 index 202184b..0000000 Binary files a/docs/2024-11-05_090604.png and /dev/null differ diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..0b546c5 --- /dev/null +++ b/go.mod @@ -0,0 +1,24 @@ +module bilidown + +go 1.23.0 + +require ( + github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e + modernc.org/sqlite v1.33.1 +) + +require ( + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/ncruces/go-strftime v0.1.9 // indirect + github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect + golang.org/x/sys v0.22.0 // indirect + modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect + modernc.org/libc v1.55.3 // indirect + modernc.org/mathutil v1.6.0 // indirect + modernc.org/memory v1.8.0 // indirect + modernc.org/strutil v1.2.0 // indirect + modernc.org/token v1.1.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..40e6873 --- /dev/null +++ b/go.sum @@ -0,0 +1,51 @@ +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo= +github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= +github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0= +github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= +golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= +golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= +golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= +modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ= +modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= +modernc.org/ccgo/v4 v4.19.2 h1:lwQZgvboKD0jBwdaeVCTouxhxAyN6iawF3STraAal8Y= +modernc.org/ccgo/v4 v4.19.2/go.mod h1:ysS3mxiMV38XGRTTcgo0DQTeTmAO4oCmJl1nX9VFI3s= +modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= +modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= +modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw= +modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= +modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= +modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= +modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U= +modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w= +modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= +modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= +modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= +modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= +modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= +modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= +modernc.org/sqlite v1.33.1 h1:trb6Z3YYoeM9eDL1O8do81kP+0ejv+YzgyFo+Gwy0nM= +modernc.org/sqlite v1.33.1/go.mod h1:pXV2xHxhzXZsgT/RtTFAPY6JJDEvOTcTdwADQCCWD4k= +modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= +modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= diff --git a/server/bilibili/bilibili_test.go b/internal/bilibili/bilibili_test.go similarity index 100% rename from server/bilibili/bilibili_test.go rename to internal/bilibili/bilibili_test.go diff --git a/server/bilibili/client.go b/internal/bilibili/client.go similarity index 99% rename from server/bilibili/client.go rename to internal/bilibili/client.go index fa4621f..da32138 100644 --- a/server/bilibili/client.go +++ b/internal/bilibili/client.go @@ -8,7 +8,7 @@ import ( "net/url" "regexp" - "bilidown/util" + "bilidown/internal/util" ) type BiliClient struct { diff --git a/server/bilibili/type.go b/internal/bilibili/type.go similarity index 99% rename from server/bilibili/type.go rename to internal/bilibili/type.go index b0bd78b..7297aca 100644 --- a/server/bilibili/type.go +++ b/internal/bilibili/type.go @@ -3,7 +3,7 @@ package bilibili import ( "encoding/json" - "bilidown/common" + "bilidown/internal/common" ) // BaseRes 来自 Bilibili 的接口响应,Message 字段为 msg diff --git a/server/bilibili/video.go b/internal/bilibili/video.go similarity index 100% rename from server/bilibili/video.go rename to internal/bilibili/video.go diff --git a/server/bilibili/wbi.go b/internal/bilibili/wbi.go similarity index 98% rename from server/bilibili/wbi.go rename to internal/bilibili/wbi.go index 2420899..5faf571 100644 --- a/server/bilibili/wbi.go +++ b/internal/bilibili/wbi.go @@ -1,7 +1,7 @@ package bilibili import ( - "bilidown/util" + "bilidown/internal/util" "database/sql" "net/url" "strconv" diff --git a/server/bilibili/wbi_test.go b/internal/bilibili/wbi_test.go similarity index 100% rename from server/bilibili/wbi_test.go rename to internal/bilibili/wbi_test.go diff --git a/server/common/common.go b/internal/common/common.go similarity index 100% rename from server/common/common.go rename to internal/common/common.go diff --git a/server/router/login.go b/internal/router/login.go similarity index 97% rename from server/router/login.go rename to internal/router/login.go index d819998..a293f0a 100644 --- a/server/router/login.go +++ b/internal/router/login.go @@ -4,8 +4,8 @@ import ( "encoding/base64" "net/http" - "bilidown/bilibili" - "bilidown/util" + "bilidown/internal/bilibili" + "bilidown/internal/util" "github.com/skip2/go-qrcode" ) diff --git a/server/router/router.go b/internal/router/router.go similarity index 98% rename from server/router/router.go rename to internal/router/router.go index c9f74bc..287d867 100644 --- a/server/router/router.go +++ b/internal/router/router.go @@ -6,8 +6,8 @@ import ( "net/http" "os" - "bilidown/util" - "bilidown/util/res_error" + "bilidown/internal/util" + "bilidown/internal/util/res_error" ) func API() *http.ServeMux { diff --git a/server/router/task.go b/internal/router/task.go similarity index 98% rename from server/router/task.go rename to internal/router/task.go index 9c8d767..e0778da 100644 --- a/server/router/task.go +++ b/internal/router/task.go @@ -10,8 +10,8 @@ import ( "runtime" "strconv" - "bilidown/task" - "bilidown/util" + "bilidown/internal/task" + "bilidown/internal/util" ) func createTask(w http.ResponseWriter, r *http.Request) { diff --git a/server/router/video.go b/internal/router/video.go similarity index 98% rename from server/router/video.go rename to internal/router/video.go index 1a6a556..4d0db05 100644 --- a/server/router/video.go +++ b/internal/router/video.go @@ -6,9 +6,9 @@ import ( "path/filepath" "strconv" "strings" - "bilidown/bilibili" - "bilidown/util" - "bilidown/util/res_error" + "bilidown/internal/bilibili" + "bilidown/internal/util" + "bilidown/internal/util/res_error" ) // getVideoInfo 通过 BV 号获取视频信息 diff --git a/server/task/task.go b/internal/task/task.go similarity index 99% rename from server/task/task.go rename to internal/task/task.go index be0743e..6663861 100644 --- a/server/task/task.go +++ b/internal/task/task.go @@ -18,9 +18,9 @@ import ( "sync" "time" - "bilidown/bilibili" - "bilidown/common" - "bilidown/util" + "bilidown/internal/bilibili" + "bilidown/internal/common" + "bilidown/internal/util" ) // TaskInitOption 创建任务时需要从 POST 请求获取的参数 diff --git a/server/task/task_test.go b/internal/task/task_test.go similarity index 100% rename from server/task/task_test.go rename to internal/task/task_test.go diff --git a/server/util/db.go b/internal/util/db.go similarity index 100% rename from server/util/db.go rename to internal/util/db.go diff --git a/server/util/field.go b/internal/util/field.go similarity index 100% rename from server/util/field.go rename to internal/util/field.go diff --git a/server/util/res_error/res_error.go b/internal/util/res_error/res_error.go similarity index 96% rename from server/util/res_error/res_error.go rename to internal/util/res_error/res_error.go index 305c481..c3db2ed 100644 --- a/server/util/res_error/res_error.go +++ b/internal/util/res_error/res_error.go @@ -3,7 +3,7 @@ package res_error import ( "net/http" - "bilidown/util" + "bilidown/internal/util" ) // Send 发送异常响应 diff --git a/server/util/response.go b/internal/util/response.go similarity index 100% rename from server/util/response.go rename to internal/util/response.go diff --git a/server/util/semaphore.go b/internal/util/semaphore.go similarity index 100% rename from server/util/semaphore.go rename to internal/util/semaphore.go diff --git a/server/util/util.go b/internal/util/util.go similarity index 98% rename from server/util/util.go rename to internal/util/util.go index 8e1329a..fd4a672 100644 --- a/server/util/util.go +++ b/internal/util/util.go @@ -11,7 +11,7 @@ import ( "regexp" "strconv" - "bilidown/common" + "bilidown/internal/common" ) func CheckBvidFormat(bvid string) bool { diff --git a/server/util/util_test.go b/internal/util/util_test.go similarity index 100% rename from server/util/util_test.go rename to internal/util/util_test.go diff --git a/server/.air.toml b/server/.air.toml deleted file mode 100644 index efac046..0000000 --- a/server/.air.toml +++ /dev/null @@ -1,3 +0,0 @@ -[build] -exclude_dir = ["download", "bin"] -include_ext = ["go"] \ No newline at end of file diff --git a/server/.goreleaser.yaml b/server/.goreleaser.yaml deleted file mode 100644 index 31b9617..0000000 --- a/server/.goreleaser.yaml +++ /dev/null @@ -1,71 +0,0 @@ -# This is an example .goreleaser.yml file with some sensible defaults. -# Make sure to check the documentation at https://goreleaser.com - -# The lines below are called `modelines`. See `:help modeline` -# Feel free to remove those if you don't want/need to use them. -# yaml-language-server: $schema=https://goreleaser.com/static/schema.json -# vim: set ts=2 sw=2 tw=0 fo=cnqoj - -version: 2 - -before: - hooks: - # You may remove this if you don't use go modules. - - go mod tidy - # you may remove this if you don't need go generate - - go generate ./... - -builds: - - id: bilidown_windows - env: - - CGO_ENABLED=1 - - >- - {{- if eq .Arch "amd64" }}CC=x86_64-w64-mingw32-gcc{{ end }} - {{- if eq .Arch "386" }}CC=i686-w64-mingw32-gcc{{ end }} - goos: - - windows - ldflags: - - -s -w -H windowsgui - - id: bilidown_darwin - env: - - CGO_ENABLED=1 - - CC=o64-clang - goos: - - darwin - ldflags: - - -s -w - - id: bilidown_linux - env: - - CGO_ENABLED=1 - - >- - {{- if eq .Arch "arm64" }}CC=aarch64-linux-gnu-gcc{{ end }} - goos: - - linux - goarch: - - amd64 - ldflags: - - -s -w -archives: - - format: tar.gz - # this name template makes the OS and Arch compatible with the results of `uname`. - name_template: >- - {{ .ProjectName }}_ - {{- title .Os }}_ - {{- if eq .Arch "amd64" }}x86_64 - {{- else if eq .Arch "386" }}i386 - {{- else }}{{ .Arch }}{{ end }} - {{- if .Arm }}v{{ .Arm }}{{ end }} - # use zip for windows archives - format_overrides: - - goos: windows - format: zip - files: - - static/** - - >- - {{- if eq .Os "windows" }}bin/ffmpeg.exe{{- end }} -changelog: - sort: asc - filters: - exclude: - - "^docs:" - - "^test:" diff --git a/server/go.mod b/server/go.mod deleted file mode 100644 index ae7fc76..0000000 --- a/server/go.mod +++ /dev/null @@ -1,41 +0,0 @@ -module bilidown - -go 1.23.0 - -require ( - github.com/getlantern/systray v1.2.2 - github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e - modernc.org/sqlite v1.33.1 -) - -require ( - github.com/dustin/go-humanize v1.0.1 // indirect - github.com/getlantern/context v0.0.0-20220418194847-3d5e7a086201 // indirect - github.com/getlantern/errors v1.0.4 // indirect - github.com/getlantern/golog v0.0.0-20230503153817-8e72de7e0a65 // indirect - github.com/getlantern/hex v0.0.0-20220104173244-ad7e4b9194dc // indirect - github.com/getlantern/hidden v0.0.0-20220104173330-f221c5a24770 // indirect - github.com/getlantern/ops v0.0.0-20231025133620-f368ab734534 // indirect - github.com/go-logr/logr v1.4.2 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-stack/stack v1.8.1 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/ncruces/go-strftime v0.1.9 // indirect - github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect - github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect - go.opentelemetry.io/otel v1.31.0 // indirect - go.opentelemetry.io/otel/metric v1.31.0 // indirect - go.opentelemetry.io/otel/trace v1.31.0 // indirect - go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect - golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 // indirect - golang.org/x/sys v0.26.0 // indirect - modernc.org/gc/v3 v3.0.0-20241004144649-1aea3fae8852 // indirect - modernc.org/libc v1.61.0 // indirect - modernc.org/mathutil v1.6.0 // indirect - modernc.org/memory v1.8.0 // indirect - modernc.org/strutil v1.2.0 // indirect - modernc.org/token v1.1.0 // indirect -) diff --git a/server/go.sum b/server/go.sum deleted file mode 100644 index c2a63ac..0000000 --- a/server/go.sum +++ /dev/null @@ -1,164 +0,0 @@ -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= -github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/getlantern/context v0.0.0-20190109183933-c447772a6520/go.mod h1:L+mq6/vvYHKjCX2oez0CgEAJmbq1fbb/oNJIWQkBybY= -github.com/getlantern/context v0.0.0-20220418194847-3d5e7a086201 h1:oEZYEpZo28Wdx+5FZo4aU7JFXu0WG/4wJWese5reQSA= -github.com/getlantern/context v0.0.0-20220418194847-3d5e7a086201/go.mod h1:Y9WZUHEb+mpra02CbQ/QczLUe6f0Dezxaw5DCJlJQGo= -github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7/go.mod h1:l+xpFBrCtDLpK9qNjxs+cHU6+BAdlBaxHqikB6Lku3A= -github.com/getlantern/errors v1.0.1/go.mod h1:l+xpFBrCtDLpK9qNjxs+cHU6+BAdlBaxHqikB6Lku3A= -github.com/getlantern/errors v1.0.4 h1:i2iR1M9GKj4WuingpNqJ+XQEw6i6dnAgKAmLj6ZB3X0= -github.com/getlantern/errors v1.0.4/go.mod h1:/Foq8jtSDGP8GOXzAjeslsC4Ar/3kB+UiQH+WyV4pzY= -github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7/go.mod h1:zx/1xUUeYPy3Pcmet8OSXLbF47l+3y6hIPpyLWoR9oc= -github.com/getlantern/golog v0.0.0-20230503153817-8e72de7e0a65 h1:NlQedYmPI3pRAXJb+hLVVDGqfvvXGRPV8vp7XOjKAZ0= -github.com/getlantern/golog v0.0.0-20230503153817-8e72de7e0a65/go.mod h1:+ZU1h+iOVqWReBpky6d5Y2WL0sF2Llxu+QcxJFs2+OU= -github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7/go.mod h1:dD3CgOrwlzca8ed61CsZouQS5h5jIzkK9ZWrTcf0s+o= -github.com/getlantern/hex v0.0.0-20220104173244-ad7e4b9194dc h1:sue+aeVx7JF5v36H1HfvcGFImLpSD5goj8d+MitovDU= -github.com/getlantern/hex v0.0.0-20220104173244-ad7e4b9194dc/go.mod h1:D9RWpXy/EFPYxiKUURo2TB8UBosbqkiLhttRrZYtvqM= -github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55/go.mod h1:6mmzY2kW1TOOrVy+r41Za2MxXM+hhqTtY3oBKd2AgFA= -github.com/getlantern/hidden v0.0.0-20220104173330-f221c5a24770 h1:cSrD9ryDfTV2yaur9Qk3rHYD414j3Q1rl7+L0AylxrE= -github.com/getlantern/hidden v0.0.0-20220104173330-f221c5a24770/go.mod h1:GOQsoDnEHl6ZmNIL+5uVo+JWRFWozMEp18Izcb++H+A= -github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA= -github.com/getlantern/ops v0.0.0-20220713155959-1315d978fff7/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA= -github.com/getlantern/ops v0.0.0-20231025133620-f368ab734534 h1:3BwvWj0JZzFEvNNiMhCu4bf60nqcIuQpTYb00Ezm1ag= -github.com/getlantern/ops v0.0.0-20231025133620-f368ab734534/go.mod h1:ZsLfOY6gKQOTyEcPYNA9ws5/XHZQFroxqCOhHjGcs9Y= -github.com/getlantern/systray v1.2.2 h1:dCEHtfmvkJG7HZ8lS/sLklTH4RKUcIsKrAD9sThoEBE= -github.com/getlantern/systray v1.2.2/go.mod h1:pXFOI1wwqwYXEhLPm9ZGjS2u/vVELeIgNMY5HvhHhcE= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= -github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo= -github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= -github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/lxn/walk v0.0.0-20210112085537-c389da54e794/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ= -github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= -github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= -github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw= -github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= -github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0= -github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= -github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.opentelemetry.io/otel v1.9.0/go.mod h1:np4EoPGzoPs3O67xUVNoPPcmSvsfOxNlNA4F4AC+0Eo= -go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= -go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= -go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= -go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= -go.opentelemetry.io/otel/trace v1.9.0/go.mod h1:2737Q0MuG8q1uILYm2YYVkAyLtOofiTNGg6VODnOiPo= -go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= -go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= -go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 h1:mchzmB1XO2pMaKFRqk/+MV3mgGG96aqaPXaMifQU47w= -golang.org/x/exp v0.0.0-20231108232855-2478ac86f678/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/Knetic/govaluate.v3 v3.0.0/go.mod h1:csKLBORsPbafmSCGTEh3U7Ozmsuq8ZSIlKk1bcqph0E= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ= -modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= -modernc.org/ccgo/v4 v4.21.0 h1:kKPI3dF7RIag8YcToh5ZwDcVMIv6VGa0ED5cvh0LMW4= -modernc.org/ccgo/v4 v4.21.0/go.mod h1:h6kt6H/A2+ew/3MW/p6KEoQmrq/i3pr0J/SiwiaF/g0= -modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= -modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= -modernc.org/gc/v2 v2.5.0 h1:bJ9ChznK1L1mUtAQtxi0wi5AtAs5jQuw4PrPHO5pb6M= -modernc.org/gc/v2 v2.5.0/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= -modernc.org/gc/v3 v3.0.0-20241004144649-1aea3fae8852 h1:IYXPPTTjjoSHvUClZIYexDiO7g+4x+XveKT4gCIAwiY= -modernc.org/gc/v3 v3.0.0-20241004144649-1aea3fae8852/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= -modernc.org/libc v1.61.0 h1:eGFcvWpqlnoGwzZeZe3PWJkkKbM/3SUGyk1DVZQ0TpE= -modernc.org/libc v1.61.0/go.mod h1:DvxVX89wtGTu+r72MLGhygpfi3aUGgZRdAYGCAVVud0= -modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= -modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= -modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= -modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= -modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= -modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= -modernc.org/sqlite v1.33.1 h1:trb6Z3YYoeM9eDL1O8do81kP+0ejv+YzgyFo+Gwy0nM= -modernc.org/sqlite v1.33.1/go.mod h1:pXV2xHxhzXZsgT/RtTFAPY6JJDEvOTcTdwADQCCWD4k= -modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= -modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= -modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= -modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= diff --git a/server/main.go b/server/main.go deleted file mode 100644 index e3aaf2e..0000000 --- a/server/main.go +++ /dev/null @@ -1,226 +0,0 @@ -package main - -import ( - "database/sql" - "errors" - "fmt" - "log" - "net/http" - "os" - "os/exec" - "runtime" - "time" - - "bilidown/router" - "bilidown/util" - - "github.com/getlantern/systray" - _ "modernc.org/sqlite" -) - -const ( - HTTP_PORT = 8098 // 限定 HTTP 服务器端口 - HTTP_HOST = "" // 限定 HTTP 服务器主机 - VERSION = "v2.1.1" // 软件版本号,将影响托盘标题显示 -) - -var urlLocal = fmt.Sprintf("http://127.0.0.1:%d", HTTP_PORT) -var urlLocalUnix = fmt.Sprintf("%s?___%d", urlLocal, time.Now().UnixMilli()) - -func main() { - checkFFmpeg() - // 启动托盘程序 - systray.Run(onReady, nil) -} - -func onReady() { - // 设置托盘图标 - setIcon() - // 设置托盘标题 - setTitle() - // 设置托盘菜单 - setMenuItem() - // 初始化数据表 - mustInitTables() - // 配置和启动 HTTP 服务器 - mustRunServer() - // 调用默认浏览器访问端口 - time.Sleep(time.Millisecond * 1000) - openBrowser(urlLocalUnix) - // 保持运行 - select {} -} - -// checkFFmpeg 检测 ffmpeg 的安装情况,如果未安装则打印提示信息。 -func checkFFmpeg() { - if _, err := util.GetFFmpegPath(); err != nil { - fmt.Println("🚨 FFmpeg is missing. Install it from https://www.ffmpeg.org/download.html or place it in ./bin, then restart the application.") - select {} - } -} - -// 配置和启动 HTTP 服务器 -func mustRunServer() { - // 前端打包文件 - http.Handle("/", http.FileServer(http.Dir("static"))) - // 后端接口服务 - http.Handle("/api/", http.StripPrefix("/api", router.API())) - // 启动 HTTP 服务器 - go func() { - err := http.ListenAndServe(fmt.Sprintf("%s:%d", HTTP_HOST, HTTP_PORT), nil) - if err != nil { - log.Fatal("http.ListenAndServe:", err) - } - }() -} - -// openBrowser 调用系统默认浏览器打开指定 URL -func openBrowser(url string) { - var cmd *exec.Cmd - switch runtime.GOOS { - case "windows": - cmd = exec.Command("rundll32", "url.dll,FileProtocolHandler", url) - case "darwin": - cmd = exec.Command("open", url) - case "linux": - cmd = exec.Command("xdg-open", url) - default: - log.Printf("openBrowser: %v.", errors.New("unsupported operating system")) - } - if err := cmd.Start(); err != nil { - log.Printf("openBrowser: %v.", err) - } - fmt.Printf("Opened in default browser: %s.\n", url) -} - -// setIcon 设置托盘图标 -func setIcon() { - var path string - if runtime.GOOS == "windows" { - path = "static/favicon.ico" - } else { - path = "static/favicon-32x32.png" - } - systray.SetIcon(mustReadFile(path)) -} - -// mustReadFile 返回文件字节内容 -func mustReadFile(path string) []byte { - data, err := os.ReadFile(path) - if err != nil { - log.Fatalln("os.ReadFile:", err) - } - return data -} - -// setTitle 设置托盘标题和工具提示 -func setTitle() { - title := "Bilidown" - tooltip := fmt.Sprintf("%s 视频解析器 %s (port:%d)", title, VERSION, HTTP_PORT) - // only available on Mac and Windows. - systray.SetTooltip(tooltip) -} - -// setMenuItem 设置托盘菜单 -func setMenuItem() { - openBrowserItemText := fmt.Sprintf("打开主界面 (port:%d)", HTTP_PORT) - openBrowserItem := systray.AddMenuItem(openBrowserItemText, openBrowserItemText) - go func() { - for { - <-openBrowserItem.ClickedCh - openBrowser(urlLocalUnix) - } - }() - - aboutItemText := "Github 项目主页" - aboutItem := systray.AddMenuItem(aboutItemText, aboutItemText) - go func() { - for { - <-aboutItem.ClickedCh - openBrowser("https://github.com/iuroc/bilidown") - } - }() - - exitItemText := "退出应用" - exitItem := systray.AddMenuItem(exitItemText, exitItemText) - go func() { - <-exitItem.ClickedCh - log.Printf("Bilidown has exited.") - systray.Quit() - }() -} - -// mustInitTables 初始化数据表 -func mustInitTables() { - db := util.MustGetDB() - defer db.Close() - - if _, err := db.Exec(`CREATE TABLE IF NOT EXISTS "field" ( - "name" TEXT PRIMARY KEY NOT NULL, - "value" TEXT - )`); err != nil { - log.Fatalln("create table field:", err) - } - - if _, err := db.Exec(`CREATE TABLE IF NOT EXISTS "log" ( - "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, - "content" TEXT NOT NULL, - "create_at" text NOT NULL DEFAULT CURRENT_TIMESTAMP - )`); err != nil { - log.Fatalln("create table log:", err) - } - - if _, err := db.Exec(`CREATE TABLE IF NOT EXISTS "task" ( - "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, - "bvid" text NOT NULL, - "cid" integer NOT NULL, - "format" integer NOT NULL, - "title" text NOT NULL, - "owner" text NOT NULL, - "cover" text NOT NULL, - "status" text NOT NULL, - "folder" text NOT NULL, - "duration" integer NOT NULL, - "download_type" text NOT NULL DEFAULT 'merge', - "create_at" text NOT NULL DEFAULT CURRENT_TIMESTAMP - )`); err != nil { - log.Fatalln("create table task:", err) - } - - if _, err := util.GetCurrentFolder(db); err != nil { - log.Fatalln("util.GetCurrentFolder:", err) - } - - if err := initHistoryTask(db); err != nil { - log.Fatalln("initHistoryTask:", err) - } - - // 添加可能缺失的列(用于数据库迁移) - if err := addMissingColumns(db); err != nil { - log.Fatalln("addMissingColumns:", err) - } -} - -// addMissingColumns 添加可能缺失的列(用于数据库迁移) -func addMissingColumns(db *sql.DB) error { - // 检查download_type列是否存在,如果不存在则添加 - // SQLite没有直接的方法检查列是否存在,我们尝试添加列并忽略错误 - // 使用事务确保操作原子性 - util.SqliteLock.Lock() - _, _ = db.Exec(`ALTER TABLE "task" ADD COLUMN "download_type" TEXT DEFAULT 'merge'`) - // 将现有记录中的NULL值更新为默认值'merge' - _, _ = db.Exec(`UPDATE "task" SET "download_type" = 'merge' WHERE "download_type" IS NULL`) - util.SqliteLock.Unlock() - - // 忽略错误,因为列可能已经存在 - // SQLite错误码为1表示列已存在 - return nil -} - -// initHistoryTask 将上一次程序运行时未完成的任务进度全部变为 error -func initHistoryTask(db *sql.DB) error { - util.SqliteLock.Lock() - _, err := db.Exec(`UPDATE "task" SET "status" = 'error' WHERE "status" IN ('waiting', 'running')`) - util.SqliteLock.Unlock() - return err -} diff --git a/client/index.html b/web/index.html similarity index 100% rename from client/index.html rename to web/index.html diff --git a/client/package.json b/web/package.json similarity index 100% rename from client/package.json rename to web/package.json diff --git a/client/pnpm-lock.yaml b/web/pnpm-lock.yaml similarity index 100% rename from client/pnpm-lock.yaml rename to web/pnpm-lock.yaml diff --git a/client/public/favicon-32x32.png b/web/public/favicon-32x32.png similarity index 100% rename from client/public/favicon-32x32.png rename to web/public/favicon-32x32.png diff --git a/client/public/favicon.ico b/web/public/favicon.ico similarity index 100% rename from client/public/favicon.ico rename to web/public/favicon.ico diff --git a/client/src/error/index.ts b/web/src/error/index.ts similarity index 100% rename from client/src/error/index.ts rename to web/src/error/index.ts diff --git a/client/src/header.ts b/web/src/header.ts similarity index 100% rename from client/src/header.ts rename to web/src/header.ts diff --git a/client/src/index.ts b/web/src/index.ts similarity index 100% rename from client/src/index.ts rename to web/src/index.ts diff --git a/client/src/login/data.ts b/web/src/login/data.ts similarity index 100% rename from client/src/login/data.ts rename to web/src/login/data.ts diff --git a/client/src/login/index.ts b/web/src/login/index.ts similarity index 100% rename from client/src/login/index.ts rename to web/src/login/index.ts diff --git a/client/src/mixin.ts b/web/src/mixin.ts similarity index 100% rename from client/src/mixin.ts rename to web/src/mixin.ts diff --git a/client/src/scss/index.scss b/web/src/scss/index.scss similarity index 100% rename from client/src/scss/index.scss rename to web/src/scss/index.scss diff --git a/client/src/setting/data.ts b/web/src/setting/data.ts similarity index 100% rename from client/src/setting/data.ts rename to web/src/setting/data.ts diff --git a/client/src/setting/index.ts b/web/src/setting/index.ts similarity index 100% rename from client/src/setting/index.ts rename to web/src/setting/index.ts diff --git a/client/src/setting/view.ts b/web/src/setting/view.ts similarity index 100% rename from client/src/setting/view.ts rename to web/src/setting/view.ts diff --git a/client/src/task/data.ts b/web/src/task/data.ts similarity index 100% rename from client/src/task/data.ts rename to web/src/task/data.ts diff --git a/client/src/task/index.ts b/web/src/task/index.ts similarity index 100% rename from client/src/task/index.ts rename to web/src/task/index.ts diff --git a/client/src/task/playerModal.ts b/web/src/task/playerModal.ts similarity index 100% rename from client/src/task/playerModal.ts rename to web/src/task/playerModal.ts diff --git a/client/src/view.ts b/web/src/view.ts similarity index 100% rename from client/src/view.ts rename to web/src/view.ts diff --git a/client/src/work/data.ts b/web/src/work/data.ts similarity index 100% rename from client/src/work/data.ts rename to web/src/work/data.ts diff --git a/client/src/work/index.ts b/web/src/work/index.ts similarity index 100% rename from client/src/work/index.ts rename to web/src/work/index.ts diff --git a/client/src/work/mixin.ts b/web/src/work/mixin.ts similarity index 100% rename from client/src/work/mixin.ts rename to web/src/work/mixin.ts diff --git a/client/src/work/type.ts b/web/src/work/type.ts similarity index 100% rename from client/src/work/type.ts rename to web/src/work/type.ts diff --git a/client/src/work/view/inputBox.ts b/web/src/work/view/inputBox.ts similarity index 100% rename from client/src/work/view/inputBox.ts rename to web/src/work/view/inputBox.ts diff --git a/client/src/work/view/parseModal.ts b/web/src/work/view/parseModal.ts similarity index 100% rename from client/src/work/view/parseModal.ts rename to web/src/work/view/parseModal.ts diff --git a/client/src/work/view/videoInfoCard.ts b/web/src/work/view/videoInfoCard.ts similarity index 100% rename from client/src/work/view/videoInfoCard.ts rename to web/src/work/view/videoInfoCard.ts diff --git a/client/src/work/view/videoItemList.ts b/web/src/work/view/videoItemList.ts similarity index 100% rename from client/src/work/view/videoItemList.ts rename to web/src/work/view/videoItemList.ts diff --git a/client/tsconfig.json b/web/tsconfig.json similarity index 100% rename from client/tsconfig.json rename to web/tsconfig.json diff --git a/client/vite.config.ts b/web/vite.config.ts similarity index 91% rename from client/vite.config.ts rename to web/vite.config.ts index 8c160c7..1d779b9 100644 --- a/client/vite.config.ts +++ b/web/vite.config.ts @@ -9,7 +9,7 @@ export default defineConfig({ host: '0.0.0.0' }, build: { - outDir: '../server/static', + outDir: '../build/static', emptyOutDir: true, }, css: {