From 8461188f3b343b1ea9677016049132c6bb4e8914 Mon Sep 17 00:00:00 2001 From: TGY Date: Tue, 25 Feb 2025 18:05:52 +0800 Subject: [PATCH 01/27] =?UTF-8?q?add=20kirara=20=E3=80=81one-hub=E3=80=81n?= =?UTF-8?q?ew-api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kirara/README.md | 82 ++++++++++++++++ kirara/data.yml | 21 ++++ kirara/latest/data.yml | 17 ++++ kirara/latest/docker-compose.yml | 18 ++++ new-api/README.md | 157 ++++++++++++++++++++++++++++++ new-api/data.yml | 19 ++++ new-api/latest/data.yml | 52 ++++++++++ new-api/latest/docker-compose.yml | 26 +++++ new-api/logo.png | Bin 0 -> 7749 bytes one-hub/README.md | 131 +++++++++++++++++++++++++ one-hub/data.yml | 19 ++++ one-hub/latest/data.yml | 56 +++++++++++ one-hub/latest/docker-compose.yml | 28 ++++++ one-hub/logo.png | Bin 0 -> 18577 bytes 14 files changed, 626 insertions(+) create mode 100644 kirara/README.md create mode 100644 kirara/data.yml create mode 100644 kirara/latest/data.yml create mode 100644 kirara/latest/docker-compose.yml create mode 100644 new-api/README.md create mode 100644 new-api/data.yml create mode 100644 new-api/latest/data.yml create mode 100644 new-api/latest/docker-compose.yml create mode 100644 new-api/logo.png create mode 100644 one-hub/README.md create mode 100644 one-hub/data.yml create mode 100644 one-hub/latest/data.yml create mode 100644 one-hub/latest/docker-compose.yml create mode 100644 one-hub/logo.png diff --git a/kirara/README.md b/kirara/README.md new file mode 100644 index 000000000..571c73648 --- /dev/null +++ b/kirara/README.md @@ -0,0 +1,82 @@ +
+ +# Kirara AI Chatbot Framework + +[![GitHub stars](https://img.shields.io/github/stars/lss233/chatgpt-mirai-qq-bot?style=social)](https://github.com/lss233/chatgpt-mirai-qq-bot) + +
+ +## 概述 + +Kirara 是一个基于插件生态和工作流系统的 AI 聊天机器人框架,支持多种 AI 模型和即时通讯平台。 + +## 主要特性 + +- 支持多种 AI 模型:DeepSeek、Claude、Grok、OpenAI、Gemini、ChatGLM、Ollama +- 人设调教与虚拟女仆功能 +- 语音对话支持 +- 多平台支持:QQ、Telegram、Discord、微信等 +- 插件系统扩展 +- 工作流自定义 + +## 部署 + +### 使用 Docker Compose 部署(推荐) + +```yaml +version: "3.8" +services: + kirara-agent: + image: lss233/kirara-agent-framework:latest + container_name: kirara-agent + restart: always + volumes: + - ./data:/app/data + ports: + - "${PANEL_APP_PORT_HTTP}:8080" +``` + +启动命令: + +```bash +docker-compose up -d +``` + +### 直接使用 Docker 镜像 + +```bash +docker run -d \ + --name kirara-agent \ + --restart always \ + -v $(pwd)/data:/app/data \ + -p 8080:8080 \ + lss233/kirara-agent-framework:latest +``` + +## 配置 + +环境变量配置: + +| 变量名 | 描述 | 默认值 | +|--------|------|--------| +| PANEL_APP_PORT_HTTP | HTTP 服务端口 | 8080 | +| DATA_PATH | 数据存储路径 | /app/data | + +## 界面截图 + +(截图待添加) + +## 交流与支持 + +- GitHub Issues: [https://github.com/lss233/chatgpt-mirai-qq-bot/issues](https://github.com/lss233/chatgpt-mirai-qq-bot/issues) +- QQ 群: 123456789 +- Telegram 群: @kirara_chat + +## 相关项目 + +- [Mirai](https://github.com/mamoe/mirai): QQ 协议实现 +- [ChatGPT-Mirai](https://github.com/lss233/chatgpt-mirai-qq-bot): 项目基础 + +## Star History + +[![Star History Chart](https://api.star-history.com/svg?repos=lss233/chatgpt-mirai-qq-bot&type=Date)](https://star-history.com/#lss233/chatgpt-mirai-qq-bot&Date) diff --git a/kirara/data.yml b/kirara/data.yml new file mode 100644 index 000000000..1f4d98a44 --- /dev/null +++ b/kirara/data.yml @@ -0,0 +1,21 @@ +name: kirara +tags: +- AI / 大模型 +- 聊天机器人 +title: Kirara AI 聊天机器人框架 +description: Kirara AI 聊天机器人框架 +additionalProperties: + key: kirara + name: kirara + tags: + - AI + - Chatbot + shortDescZh: 插件生态 x 工作流系统,DIY 你自己的 AI 聊天机器人!支持DeepSeek、Claude、Grok、OpenAI、Gemini、ChatGLM、Ollama,人设调教,虚拟女仆、语音对话 | 支持 QQ、Telegram、Discord、微信 等平台 + shortDescEn: Plugin ecosystem x workflow system, DIY your own AI chatbot! Supports DeepSeek, Claude, Grok, OpenAI, Gemini, ChatGLM, Ollama, character customization, virtual maid, voice chat | Supports QQ, Telegram, Discord, WeChat and other platforms + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://kirara-docs.app.lss233.com/ + github: https://github.com/lss233/chatgpt-mirai-qq-bot/ + document: https://github.com/lss233/chatgpt-mirai-qq-bot/blob/master/README.md diff --git a/kirara/latest/data.yml b/kirara/latest/data.yml new file mode 100644 index 000000000..68c4eccc4 --- /dev/null +++ b/kirara/latest/data.yml @@ -0,0 +1,17 @@ +additionalProperties: + formFields: + - default: 48080 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: ./data + edit: true + envKey: DATA_PATH + labelEn: Data folder path + labelZh: 数据文件夹路径 + required: true + type: text diff --git a/kirara/latest/docker-compose.yml b/kirara/latest/docker-compose.yml new file mode 100644 index 000000000..4b03c3363 --- /dev/null +++ b/kirara/latest/docker-compose.yml @@ -0,0 +1,18 @@ +version: "3.8" +services: + kirara-agent: + image: lss233/kirara-agent-framework:latest + container_name: ${CONTAINER_NAME} + restart: always + volumes: + - "${DATA_PATH}:/app/data" + ports: + - "${PANEL_APP_PORT_HTTP}:8080" + networks: + - 1panel-network + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/new-api/README.md b/new-api/README.md new file mode 100644 index 000000000..d571d3c9a --- /dev/null +++ b/new-api/README.md @@ -0,0 +1,157 @@ +
+ +![new-api](https://raw.githubusercontent.com/Calcium-Ion/new-api/refs/heads/main/web/public/logo.png) + +# New API + +Calcium-Ion%2Fnew-api | Trendshift + +
+ +> [!NOTE] +> 本项目为开源项目,在[One API](https://github.com/songquanpeng/one-api)的基础上进行二次开发 + +> [!IMPORTANT] +> 使用者必须在遵循 OpenAI 的[使用条款](https://openai.com/policies/terms-of-use)以及**法律法规**的情况下使用,不得用于非法用途。 +> 本项目仅供个人学习使用,不保证稳定性,且不提供任何技术支持。 +> 根据[《生成式人工智能服务管理暂行办法》](http://www.cac.gov.cn/2023-07/13/c_1690898327029107.htm)的要求,请勿对中国地区公众提供一切未经备案的生成式人工智能服务。 + +> [!TIP] +> 最新版Docker镜像:`calciumion/new-api:latest` +> 默认账号root 密码123456 +> 更新指令: +> ``` +> docker run --rm -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower -cR +> ``` + + +## 主要变更 +此分叉版本的主要变更如下: + +1. 全新的UI界面(部分界面还待更新) +2. 添加[Midjourney-Proxy(Plus)](https://github.com/novicezk/midjourney-proxy)接口的支持,[对接文档](Midjourney.md) +3. 支持在线充值功能,可在系统设置中设置,当前支持的支付接口: + + [x] 易支付 +4. 支持用key查询使用额度: + + 配合项目[neko-api-key-tool](https://github.com/Calcium-Ion/neko-api-key-tool)可实现用key查询使用 +5. 渠道显示已使用额度,支持指定组织访问 +6. 分页支持选择每页显示数量 +7. 兼容原版One API的数据库,可直接使用原版数据库(one-api.db) +8. 支持模型按次数收费,可在 系统设置-运营设置 中设置 +9. 支持渠道**加权随机** +10. 数据看板 +11. 可设置令牌能调用的模型 +12. 支持Telegram授权登录。 + 1. 系统设置-配置登录注册-允许通过Telegram登录 + 2. 对[@Botfather](https://t.me/botfather)输入指令/setdomain + 3. 选择你的bot,然后输入http(s)://你的网站地址/login + 4. Telegram Bot 名称是bot username 去掉@后的字符串 +13. 添加 [Suno API](https://github.com/Suno-API/Suno-API)接口的支持,[对接文档](Suno.md) +14. 支持Rerank模型,目前仅兼容Cohere和Jina,可接入Dify,[对接文档](Rerank.md) +15. **[OpenAI Realtime API](https://platform.openai.com/docs/guides/realtime/integration)** - 支持OpenAI的Realtime API,支持Azure渠道。 + +## 模型支持 +此版本额外支持以下模型: +1. 第三方模型 **gps** (gpt-4-gizmo-*) +2. 智谱glm-4v,glm-4v识图 +3. Anthropic Claude 3 +4. [Ollama](https://github.com/ollama/ollama?tab=readme-ov-file),添加渠道时,密钥可以随便填写,默认的请求地址是[http://localhost:11434](http://localhost:11434),如果需要修改请在渠道中修改 +5. [Midjourney-Proxy(Plus)](https://github.com/novicezk/midjourney-proxy)接口,[对接文档](Midjourney.md) +6. [零一万物](https://platform.lingyiwanwu.com/) +7. 自定义渠道,支持填入完整调用地址 +8. [Suno API](https://github.com/Suno-API/Suno-API) 接口,[对接文档](Suno.md) +9. Rerank模型,目前支持[Cohere](https://cohere.ai/)和[Jina](https://jina.ai/),[对接文档](Rerank.md) +10. Dify +11. Vertex AI,目前兼容Claude,Gemini,Llama3.1 + +您可以在渠道中添加自定义模型gpt-4-gizmo-*,此模型并非OpenAI官方模型,而是第三方模型,使用官方key无法调用。 + +## 比原版One API多出的配置 +- `GENERATE_DEFAULT_TOKEN`:是否为新注册用户生成初始令牌,默认为 `false`。 +- `STREAMING_TIMEOUT`:设置流式一次回复的超时时间,默认为 60 秒。 +- `DIFY_DEBUG`:设置 Dify 渠道是否输出工作流和节点信息到客户端,默认为 `true`。 +- `FORCE_STREAM_OPTION`:是否覆盖客户端stream_options参数,请求上游返回流模式usage,默认为 `true`,建议开启,不影响客户端传入stream_options参数返回结果。 +- `GET_MEDIA_TOKEN`:是否统计图片token,默认为 `true`,关闭后将不再在本地计算图片token,可能会导致和上游计费不同,此项覆盖 `GET_MEDIA_TOKEN_NOT_STREAM` 选项作用。 +- `GET_MEDIA_TOKEN_NOT_STREAM`:是否在非流(`stream=false`)情况下统计图片token,默认为 `true`。 +- `UPDATE_TASK`:是否更新异步任务(Midjourney、Suno),默认为 `true`,关闭后将不会更新任务进度。 +- `GEMINI_MODEL_MAP`:Gemini模型指定版本(v1/v1beta),使用“模型:版本”指定,","分隔,例如:-e GEMINI_MODEL_MAP="gemini-1.5-pro-latest:v1beta,gemini-1.5-pro-001:v1beta",为空则使用默认配置(v1beta) +- `COHERE_SAFETY_SETTING`:Cohere模型[安全设置](https://docs.cohere.com/docs/safety-modes#overview),可选值为 `NONE`, `CONTEXTUAL`,`STRICT`,默认为 `NONE`。 +## 部署 +### 部署要求 +- 本地数据库(默认):SQLite(Docker 部署默认使用 SQLite,必须挂载 `/data` 目录到宿主机) +- 远程数据库:MySQL 版本 >= 5.7.8,PgSQL 版本 >= 9.6 + +### 使用宝塔面板Docker功能部署 +安装宝塔面板 (**9.2.0版本**及以上),前往 [宝塔面板](https://www.bt.cn/new/download.html) 官网,选择正式版的脚本下载安装 +安装后登录宝塔面板,在菜单栏中点击 Docker ,首次进入会提示安装 Docker 服务,点击立即安装,按提示完成安装 +安装完成后在应用商店中找到 **New-API** ,点击安装,配置基本选项 即可完成安装 +[图文教程](BT.md) + +### 基于 Docker 进行部署 +### 使用 Docker Compose 部署(推荐) +```shell +# 下载项目 +git clone https://github.com/Calcium-Ion/new-api.git +cd new-api +# 按需编辑 docker-compose.yml +# 启动 +docker-compose up -d +``` + +### 直接使用 Docker 镜像 +```shell +# 使用 SQLite 的部署命令: +docker run --name new-api -d --restart always -p 3000:3000 -e TZ=Asia/Shanghai -v /home/ubuntu/data/new-api:/data calciumion/new-api:latest +# 使用 MySQL 的部署命令,在上面的基础上添加 `-e SQL_DSN="root:123456@tcp(localhost:3306)/oneapi"`,请自行修改数据库连接参数。 +# 例如: +docker run --name new-api -d --restart always -p 3000:3000 -e SQL_DSN="root:123456@tcp(localhost:3306)/oneapi" -e TZ=Asia/Shanghai -v /home/ubuntu/data/new-api:/data calciumion/new-api:latest +``` + +## 渠道重试 +渠道重试功能已经实现,可以在`设置->运营设置->通用设置`设置重试次数,**建议开启缓存**功能。 +如果开启了重试功能,第一次重试使用同优先级,第二次重试使用下一个优先级,以此类推。 +### 缓存设置方法 +1. `REDIS_CONN_STRING`:设置之后将使用 Redis 作为缓存使用。 + + 例子:`REDIS_CONN_STRING=redis://default:redispw@localhost:49153` +2. `MEMORY_CACHE_ENABLED`:启用内存缓存(如果设置了`REDIS_CONN_STRING`,则无需手动设置),会导致用户额度的更新存在一定的延迟,可选值为 `true` 和 `false`,未设置则默认为 `false`。 + + 例子:`MEMORY_CACHE_ENABLED=true` +### 为什么有的时候没有重试 +这些错误码不会重试:400,504,524 +### 我想让400也重试 +在`渠道->编辑`中,将`状态码复写`改为 +```json +{ + "400": "500" +} +``` +可以实现400错误转为500错误,从而重试 + +## Midjourney接口设置文档 +[对接文档](Midjourney.md) + +## Suno接口设置文档 +[对接文档](Suno.md) + +## 界面截图 +![796df8d287b7b7bd7853b2497e7df511](https://github.com/user-attachments/assets/255b5e97-2d3a-4434-b4fa-e922ad88ff5a) + +![image](https://github.com/Calcium-Ion/new-api/assets/61247483/ad0e7aae-0203-471c-9716-2d83768927d4) +![image](https://github.com/user-attachments/assets/29f81de5-33fc-4fc5-a5ff-f9b54b653c7c) + +![image](https://github.com/Calcium-Ion/new-api/assets/61247483/3ca0b282-00ff-4c96-bf9d-e29ef615c605) +夜间模式 +![image](https://github.com/Calcium-Ion/new-api/assets/61247483/1c66b593-bb9e-4757-9720-ff2759539242) +![image](https://github.com/Calcium-Ion/new-api/assets/61247483/af9a07ee-5101-4b3d-8bd9-ae21a4fd7e9e) + +## 交流群 + + +## 相关项目 +- [One API](https://github.com/songquanpeng/one-api):原版项目 +- [Midjourney-Proxy](https://github.com/novicezk/midjourney-proxy):Midjourney接口支持 +- [chatnio](https://github.com/Deeptrain-Community/chatnio):下一代 AI 一站式 B/C 端解决方案 +- [neko-api-key-tool](https://github.com/Calcium-Ion/neko-api-key-tool):用key查询使用额度 + +## Star History + +[![Star History Chart](https://api.star-history.com/svg?repos=Calcium-Ion/new-api&type=Date)](https://star-history.com/#Calcium-Ion/new-api&Date) \ No newline at end of file diff --git a/new-api/data.yml b/new-api/data.yml new file mode 100644 index 000000000..462e0d59f --- /dev/null +++ b/new-api/data.yml @@ -0,0 +1,19 @@ +name: new api +tags: + - AI / 大模型 +title: OpenAI 接口管理 & 分发系统 +description: OpenAI 接口管理 & 分发系统 +additionalProperties: + key: new-api + name: new api + tags: + - AI + shortDescZh: AI模型接口管理与分发系统,支持将多种大模型转为OpenAI格式调用、支持Midjourney Proxy、Suno、Rerank,兼容易支付协议,可供个人或者企业内部管理与分发渠道使用,本项目基于One API二次开发。 + shortDescEn: Access all LLM through the standard OpenAI API format, easy to deploy & use + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://nekoapi.com/ + github: https://github.com/Calcium-Ion/new-api + document: https://github.com/Calcium-Ion/new-api/blob/main/README.md diff --git a/new-api/latest/data.yml b/new-api/latest/data.yml new file mode 100644 index 000000000..2c2c3e0e0 --- /dev/null +++ b/new-api/latest/data.yml @@ -0,0 +1,52 @@ +additionalProperties: + formFields: + - default: "" + edit: true + envKey: PANEL_DB_HOST + key: mysql + labelEn: Database Service + labelZh: 数据库服务 + required: true + type: service + - default: newapi + edit: true + envKey: PANEL_DB_NAME + labelEn: Database + labelZh: 数据库名 + random: true + required: true + rule: paramCommon + type: text + - default: newapi + edit: true + envKey: PANEL_DB_USER + labelEn: User + labelZh: 数据库用户 + random: true + required: true + rule: paramCommon + type: text + - default: newapi + edit: true + envKey: PANEL_DB_USER_PASSWORD + labelEn: Password + labelZh: 数据库用户密码 + random: true + required: true + rule: paramComplexity + type: password + - default: 3000 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: Asia/Shanghai + edit: true + envKey: TZ + labelEn: Time Zone + labelZh: 时区 + required: true + type: text diff --git a/new-api/latest/docker-compose.yml b/new-api/latest/docker-compose.yml new file mode 100644 index 000000000..1e361775b --- /dev/null +++ b/new-api/latest/docker-compose.yml @@ -0,0 +1,26 @@ +services: + one-api: + image: calciumion/new-api:latest + container_name: ${CONTAINER_NAME} + restart: always + ports: + - ${PANEL_APP_PORT_HTTP}:3000 + networks: + - 1panel-network + command: --log-dir /app/logs + volumes: + - ./data:/data + - ./logs:/app/logs + environment: + - SQL_DSN=${PANEL_DB_USER}:${PANEL_DB_USER_PASSWORD}@tcp(${PANEL_DB_HOST}:3306)/${PANEL_DB_NAME} # 修改此行,或注释掉以使用 SQLite 作为数据库 + - TZ=${TZ} +# - SESSION_SECRET=${SESSION_SECRET} +# - REDIS_CONN_STRING=redis://redis +# - NODE_TYPE=slave # 多机部署时从节点取消注释该行 +# - SYNC_FREQUENCY=60 # 需要定期从数据库加载数据时取消注释该行 +# - FRONTEND_BASE_URL=https://openai.justsong.cn # 多机部署时从节点取消注释该行 + labels: + createdBy: "Apps" +networks: + 1panel-network: + external: true diff --git a/new-api/logo.png b/new-api/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8aea273d4c9cf94636ddc350337516501c6e2e89 GIT binary patch literal 7749 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 LNkvXXu0mjfIs7~s literal 0 HcmV?d00001 diff --git a/one-hub/README.md b/one-hub/README.md new file mode 100644 index 000000000..ff0f0f1f2 --- /dev/null +++ b/one-hub/README.md @@ -0,0 +1,131 @@ +

+ 中文 | English +

+ +

+ + + + +

+ +
+ +# One Hub + +_本项目是基于[one-api](https://github.com/songquanpeng/one-api)二次开发而来的_ + +

+ + license + + + release + + + docker + + + docker + + + GoReportCard + +

+ +**请不要和原版混用,因为新增功能,数据库与原版不兼容** + +**为了更加简洁,本项目之后,除了新增供应商时会更新程序自带的模型列表,平常不再更新程序自带的模型列表。** + +**如果发现缺少新模型,请在`后台-模型价格-更新价格`中更新新增的模型** + +[演示网站](https://one-api-martialbe.vercel.app/) + +
+ +> [!WARNING] +> 本项目为个人学习使用,不保证稳定性,且不提供任何技术支持,使用者必须在遵循 OpenAI 的使用条款以及法律法规的情况下使用,不得用于非法用途。 +> 根据[《生成式人工智能服务管理暂行办法》](http://www.cac.gov.cn/2023-07/13/c_1690898327029107.htm)的要求,请勿对中国地区公众提供一切未经备案的生成式人工智能服务。 + +## 功能变化 + +- 全新的 UI 界面 +- 新增用户仪表盘 +- 新增管理员分析数据统计界面 +- 重构了中转`供应商`模块 +- 支持使用`Azure Speech`模拟`TTS`功能 +- 渠道可配置单独的 http/socks5 代理 +- 支持动态返回用户模型列表 +- 支持自定义测速模型 +- 日志增加请求耗时 +- 支持和优化非 OpenAI 模型的函数调用(支持的模型可以在 lobe-chat 直接使用) +- 支持完成倍率自定义 +- 支持完整的分页和排序 +- 支持`Telegram bot` +- 支持模型按次收费 +- 支持模型通配符 +- 支持使用配置文件启动程序 +- 支持模型价格更新 +- 支持自动获取供应商模型 +- 支持仅聊天,开启后如果有传入`function call`参数会跳过该渠道 +- 支持支付 +- 支持配置用户组 RPM +- 支持`Prometheus`监控 + +## 文档 + +请查看[文档](https://github.com/MartialBE/one-hub/wiki) + +## 当前支持的供应商 + +| 供应商 | Chat | Embeddings | Audio | Images | 其他 | +| --------------------------------------------------------------------- | ------------------------ | ---------- | ------ | ----------- | ---------------------------------------------------------------- | +| [OpenAI](https://platform.openai.com/docs/api-reference/introduction) | ✅ | ✅ | ✅ | ✅ | - | +| [Azure OpenAI](https://oai.azure.com/) | ✅ | ✅ | ✅ | ✅ | - | +| [Azure Speech](https://portal.azure.com/) | - | - | ⚠️ tts | - | - | +| [Anthropic](https://www.anthropic.com/) | ✅ | - | - | - | - | +| [Gemini](https://aistudio.google.com/) | ✅ | - | - | - | - | +| [百度文心](https://console.bce.baidu.com/qianfan/overview) | ✅ | ✅ | - | - | - | +| [通义千问](https://dashscope.console.aliyun.com/overview) | ✅ | ✅ | - | - | - | +| [讯飞星火](https://console.xfyun.cn/) | ✅ | - | - | - | - | +| [智谱](https://open.bigmodel.cn/overview) | ✅ | ✅ | - | ⚠️ 图片生成 | - | +| [腾讯混元](https://cloud.tencent.com/product/hunyuan) | ✅ | - | - | - | - | +| [百川](https://platform.baichuan-ai.com/console/apikey) | ✅ | ✅ | - | - | - | +| [MiniMax](https://www.minimaxi.com/user-center/basic-information) | ✅ | ✅ | - | - | - | +| [Deepseek](https://platform.deepseek.com/usage) | ✅ | - | - | - | - | +| [Moonshot](https://moonshot.ai/) | ✅ | - | - | - | - | +| [Mistral](https://mistral.ai/) | ✅ | ✅ | - | - | - | +| [Groq](https://console.groq.com/keys) | ✅ | - | - | - | - | +| [Amazon Bedrock](https://console.aws.amazon.com/bedrock/home) | ⚠️ 仅支持 Anthropic 模型 | - | - | - | - | +| [零一万物](https://platform.lingyiwanwu.com/details) | ✅ | - | - | - | - | +| [Cloudflare AI](https://ai.cloudflare.com/) | ✅ | - | ⚠️ stt | ⚠️ 图片生成 | - | +| [Midjourney](https://www.midjourney.com/) | - | - | - | - | [midjourney-proxy](https://github.com/novicezk/midjourney-proxy) | +| [Cohere](https://cohere.com/) | ✅ | - | - | - | - | +| [Stability AI](https://platform.stability.ai/account/credits) | - | - | - | ⚠️ 图片生成 | - | +| [Coze](https://www.coze.com/open/docs/chat?_lang=zh) | ✅ | - | - | - | - | +| [Ollama](https://github.com/ollama/ollama) | ✅ | ✅ | - | - | - | +| [Suno](https://suno.com/) | - | - | - | - | [Suno-API](https://github.com/Suno-API/Suno-API) | + +## 感谢 + +- 本程序使用了以下开源项目 + - [one-api](https://github.com/songquanpeng/one-api)为本项目的基础 + - [Berry Free React Admin Template](https://github.com/codedthemes/berry-free-react-admin-template)为本项目的前端界面 + - [minimal-ui-kit](https://github.com/minimal-ui-kit/material-kit-react),使用了其中的部分样式 + - [new api](https://github.com/Calcium-Ion/new-api),Midjourney/Suno 模块的代码来源于此 + - [go-zero](https://github.com/zeromicro/go-zero) - Token 限流器的实现 + +感谢以上项目的作者和贡献者 + +## 交流群 + + + +## 其他 + + + + + Star History of MartialBE/one-api + + \ No newline at end of file diff --git a/one-hub/data.yml b/one-hub/data.yml new file mode 100644 index 000000000..ce1a9c98e --- /dev/null +++ b/one-hub/data.yml @@ -0,0 +1,19 @@ +name: one hub +tags: + - AI / 大模型 +title: OpenAI 接口管理 & 分发系统 +description: OpenAI 接口管理 & 分发系统 +additionalProperties: + key: one-hub + name: one-hub + tags: + - AI + shortDescZh: AI模型接口管理与分发系统,支持将多种大模型转为OpenAI格式调用、支持Midjourney Proxy、Suno、Rerank,兼容易支付协议,可供个人或者企业内部管理与分发渠道使用,本项目基于One API二次开发。 + shortDescEn: Access all LLM through the standard OpenAI API format, easy to deploy & use + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://one-hub.xiao5.info/ + github: https://github.com/MartialBE/one-hub + document: https://github.com/MartialBE/one-hub/blob/main/README.md diff --git a/one-hub/latest/data.yml b/one-hub/latest/data.yml new file mode 100644 index 000000000..6394e946c --- /dev/null +++ b/one-hub/latest/data.yml @@ -0,0 +1,56 @@ +additionalProperties: + formFields: + - default: "" + envKey: PANEL_DB_HOST + key: mysql + labelEn: Database Service + labelZh: 数据库服务 + required: true + type: service + - default: onehub + envKey: PANEL_DB_NAME + labelEn: Database + labelZh: 数据库名 + random: true + required: true + rule: paramCommon + type: text + - default: onehub + envKey: PANEL_DB_USER + labelEn: User + labelZh: 数据库用户 + random: true + required: true + rule: paramCommon + type: text + - default: onehub + envKey: PANEL_DB_USER_PASSWORD + labelEn: Password + labelZh: 数据库用户密码 + random: true + required: true + rule: paramComplexity + type: password + - default: 4000 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: Asia/Shanghai + edit: true + envKey: TZ + labelEn: Time Zone + labelZh: 时区 + required: true + type: text + - default: onehub + envKey: USER_TOKEN_SECRET + labelEn: USER_TOKEN_SECRET + labelZh: SECRET随机字符串 + random: true + required: true + rule: paramComplexity + type: password \ No newline at end of file diff --git a/one-hub/latest/docker-compose.yml b/one-hub/latest/docker-compose.yml new file mode 100644 index 000000000..bf43b29a7 --- /dev/null +++ b/one-hub/latest/docker-compose.yml @@ -0,0 +1,28 @@ +services: + one-hub: + image: ghcr.io/martialbe/one-api:latest + container_name: ${CONTAINER_NAME} + restart: always + ports: + - ${PANEL_APP_PORT_HTTP}:3000 + networks: + - 1panel-network + command: --log-dir /app/logs + volumes: + - ./data:/data + - ./logs:/app/logs + environment: + - SQL_DSN=${PANEL_DB_USER}:${PANEL_DB_USER_PASSWORD}@tcp(${PANEL_DB_HOST}:3306)/${PANEL_DB_NAME} # 修改此行,或注释掉以使用 SQLite 作为数据库 + - TZ=${TZ} + - USER_TOKEN_SECRET=${USER_TOKEN_SECRET} # 必填,否则无法启动,修改为随机字符串,32位以上 + # - REDIS_CONN_STRING=redis://redis + # - SESSION_SECRET=random_string # 推荐填写,否则每次重启后已登录用户的 cookie 将失效。 + # - HASHIDS_SALT=random_string # 可空,建议设置,字符串元素不能重复 + # - NODE_TYPE=slave # 多机部署时从节点取消注释该行 + # - SYNC_FREQUENCY=60 # 需要定期从数据库加载数据时取消注释该行 + # - FRONTEND_BASE_URL=https://openai.justsong.cn # 多机部署时从节点取消注释该行 + labels: + createdBy: "Apps" +networks: + 1panel-network: + external: true diff --git a/one-hub/logo.png b/one-hub/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..da6602d6b6499ea9856e1e240fba957119342e07 GIT binary patch literal 18577 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 Date: Tue, 25 Feb 2025 18:09:48 +0800 Subject: [PATCH 02/27] add lobe-chat image: lobehub/lobe-chat-pglite --- lobe-chat/pglite/.env.sample | 7 +++++ lobe-chat/pglite/data.yml | 47 +++++++++++++++++++++++++++++ lobe-chat/pglite/docker-compose.yml | 21 +++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 lobe-chat/pglite/.env.sample create mode 100644 lobe-chat/pglite/data.yml create mode 100644 lobe-chat/pglite/docker-compose.yml diff --git a/lobe-chat/pglite/.env.sample b/lobe-chat/pglite/.env.sample new file mode 100644 index 000000000..f31c58e39 --- /dev/null +++ b/lobe-chat/pglite/.env.sample @@ -0,0 +1,7 @@ +ACCESS_CODE="access_password" +CONTAINER_NAME="lobe-chat" +OPENAI_API_KEY="sk-xxx" +OPENAI_MODEL_LIST="" +OPENAI_PROXY_URL="https://api.openai.com/v1" +PANEL_APP_PORT_HTTP="40247" +SEARXNG_URL="https://searxng-instance.com" \ No newline at end of file diff --git a/lobe-chat/pglite/data.yml b/lobe-chat/pglite/data.yml new file mode 100644 index 000000000..7aa3f8b2a --- /dev/null +++ b/lobe-chat/pglite/data.yml @@ -0,0 +1,47 @@ +additionalProperties: + formFields: + - default: 40247 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: "password" + edit: true + envKey: OPENAI_API_KEY + labelEn: OpenAI API Key + labelZh: OpenAI API 密钥 + required: false + type: password + - default: "https://api.openai.com/v1" + edit: true + envKey: OPENAI_PROXY_URL + labelEn: OpenAI Proxy URL + labelZh: OpenAI 代理 URL + required: false + type: text + - default: "" + edit: true + envKey: ACCESS_CODE + labelEn: Access Code + labelZh: 访问密码 + random: true + required: false + rule: paramComplexity + type: password + - default: "" + edit: true + envKey: OPENAI_MODEL_LIST + labelEn: OpenAI Model List + labelZh: OpenAI 模型列表 + required: false + type: text + - default: "" + edit: true + envKey: SEARXNG_URL + labelEn: SEARXNG_URL + labelZh: searxng地址 + required: false + type: text diff --git a/lobe-chat/pglite/docker-compose.yml b/lobe-chat/pglite/docker-compose.yml new file mode 100644 index 000000000..5d5ab25a8 --- /dev/null +++ b/lobe-chat/pglite/docker-compose.yml @@ -0,0 +1,21 @@ +services: + lobe-chat: + image: lobehub/lobe-chat-pglite:latest + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:3210" + environment: + - OPENAI_API_KEY=${OPENAI_API_KEY} + - OPENAI_PROXY_URL=${OPENAI_PROXY_URL} + - ACCESS_CODE=${ACCESS_CODE} + - OPENAI_MODEL_LIST=${OPENAI_MODEL_LIST} + - SEARXNG_URL=${SEARXNG_URL} + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true From 2fd3631d89291ff0cc96ba2f5561d4e935065240 Mon Sep 17 00:00:00 2001 From: sephiroth <102894885+sephiroth233@users.noreply.github.com> Date: Thu, 27 Feb 2025 13:16:09 +0800 Subject: [PATCH 03/27] =?UTF-8?q?=E8=A1=A5=E5=85=85kirara=20logo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kirara/logo.png | Bin 0 -> 4768 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 kirara/logo.png diff --git a/kirara/logo.png b/kirara/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..9cec3e62d1817bf3fe702d0d21ccdd15beb049a2 GIT binary patch literal 4768 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

!}0k@$uIak@e=yjlY=N3BnWaKW~gk*dW)%cD3KH zwneSf(5a7)G8=QG9&G%o^pIm^L|i@bbY{D?PdIy50b`l(y!p* u)zeQLhv-{v{-Yu3Xm({aFaH6 Date: Wed, 5 Mar 2025 13:26:50 +0800 Subject: [PATCH 04/27] add one-api latest version --- one-api/0.6.8/data.yml | 48 ++++++++++++++++++++++++++++ one-api/0.6.8/docker-compose.yml | 24 ++++++++++++++ one-api/README.md | 51 ++++++++++++++++++++++++++++++ one-api/data.yml | 19 +++++++++++ one-api/latest/data.yml | 48 ++++++++++++++++++++++++++++ one-api/latest/docker-compose.yml | 24 ++++++++++++++ one-api/logo.png | Bin 0 -> 8085 bytes 7 files changed, 214 insertions(+) create mode 100644 one-api/0.6.8/data.yml create mode 100644 one-api/0.6.8/docker-compose.yml create mode 100644 one-api/README.md create mode 100644 one-api/data.yml create mode 100644 one-api/latest/data.yml create mode 100644 one-api/latest/docker-compose.yml create mode 100644 one-api/logo.png diff --git a/one-api/0.6.8/data.yml b/one-api/0.6.8/data.yml new file mode 100644 index 000000000..8e1f8ecbe --- /dev/null +++ b/one-api/0.6.8/data.yml @@ -0,0 +1,48 @@ +additionalProperties: + formFields: + - default: "" + envKey: PANEL_DB_HOST + key: mysql + labelEn: Database Service + labelZh: 数据库服务 + required: true + type: service + - default: oneapi + envKey: PANEL_DB_NAME + labelEn: Database + labelZh: 数据库名 + random: true + required: true + rule: paramCommon + type: text + - default: oneapi + envKey: PANEL_DB_USER + labelEn: User + labelZh: 数据库用户 + random: true + required: true + rule: paramCommon + type: text + - default: oneapi + envKey: PANEL_DB_USER_PASSWORD + labelEn: Password + labelZh: 数据库用户密码 + random: true + required: true + rule: paramComplexity + type: password + - default: 3000 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: Asia/Shanghai + edit: true + envKey: TZ + labelEn: Time Zone + labelZh: 时区 + required: true + type: text \ No newline at end of file diff --git a/one-api/0.6.8/docker-compose.yml b/one-api/0.6.8/docker-compose.yml new file mode 100644 index 000000000..41fd430a9 --- /dev/null +++ b/one-api/0.6.8/docker-compose.yml @@ -0,0 +1,24 @@ +services: + one-api: + image: justsong/one-api:v0.6.8 + container_name: ${CONTAINER_NAME} + restart: always + ports: + - ${PANEL_APP_PORT_HTTP}:3000 + networks: + - 1panel-network + volumes: + - ./data:/data + environment: + - SQL_DSN=${PANEL_DB_USER}:${PANEL_DB_USER_PASSWORD}@tcp(${PANEL_DB_HOST}:3306)/${PANEL_DB_NAME} # 修改此行,或注释掉以使用 SQLite 作为数据库 + - TZ=${TZ} +# - REDIS_CONN_STRING=redis://redis +# - SESSION_SECRET=random_string # 修改为随机字符串 +# - NODE_TYPE=slave # 多机部署时从节点取消注释该行 +# - SYNC_FREQUENCY=60 # 需要定期从数据库加载数据时取消注释该行 +# - FRONTEND_BASE_URL=https://openai.justsong.cn # 多机部署时从节点取消注释该行 + labels: + createdBy: "Apps" +networks: + 1panel-network: + external: true \ No newline at end of file diff --git a/one-api/README.md b/one-api/README.md new file mode 100644 index 000000000..14958b1a7 --- /dev/null +++ b/one-api/README.md @@ -0,0 +1,51 @@ +# 使用说明 + +- 默认账户密码 + +``` +username:root +password:123456 +``` + +# One API + +**One API** 是一个通过标准的 OpenAI API 格式访问所有的大模型,开箱即用。 + +## 主要功能: + +- 支持多种大模型: + + [x] [OpenAI ChatGPT 系列模型](https://platform.openai.com/docs/guides/gpt/chat-completions-api)(支持 [Azure OpenAI API](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference)) + + [x] [Anthropic Claude 系列模型](https://anthropic.com) + + [x] [Google PaLM2/Gemini 系列模型](https://developers.generativeai.google) + + [x] [百度文心一言系列模型](https://cloud.baidu.com/doc/WENXINWORKSHOP/index.html) + + [x] [阿里通义千问系列模型](https://help.aliyun.com/document_detail/2400395.html) + + [x] [讯飞星火认知大模型](https://www.xfyun.cn/doc/spark/Web.html) + + [x] [智谱 ChatGLM 系列模型](https://bigmodel.cn) + + [x] [360 智脑](https://ai.360.cn) + + [x] [腾讯混元大模型](https://cloud.tencent.com/document/product/1729) +- 支持配置镜像以及众多第三方代理服务。 +- 支持通过**负载均衡**的方式访问多个渠道。 +- 支持 **stream 模式**,可以通过流式传输实现打字机效果。 +- 支持**多机部署**。 +- 支持**令牌管理**,设置令牌的过期时间和额度。 +- 支持**兑换码管理**,支持批量生成和导出兑换码,可使用兑换码为账户进行充值。 +- 支持**通道管理**,批量创建通道。 +- 支持**用户分组**以及**渠道分组**,支持为不同分组设置不同的倍率。 +- 支持渠道**设置模型列表**。 +- 支持**查看额度明细**。 +- 支持**用户邀请奖励**。 +- 支持以美元为单位显示额度。 +- 支持发布公告,设置充值链接,设置新用户初始额度。 +- 支持模型映射,重定向用户的请求模型,如无必要请不要设置,设置之后会导致请求体被重新构造而非直接透传,会导致部分还未正式支持的字段无法传递成功。 +- 支持失败自动重试。 +- 支持绘图接口。 +- 支持 [Cloudflare AI Gateway](https://developers.cloudflare.com/ai-gateway/providers/openai/),渠道设置的代理部分填写 `https://gateway.ai.cloudflare.com/v1/ACCOUNT_TAG/GATEWAY/openai` 即可。 +- 持丰富的**自定义**设置, + 1. 支持自定义系统名称,logo 以及页脚。 + 2. 支持自定义首页和关于页面,可以选择使用 HTML & Markdown 代码进行自定义,或者使用一个单独的网页通过 iframe 嵌入。 +- 支持通过系统访问令牌访问管理 API(bearer token,用以替代 cookie,你可以自行抓包来查看 API 的用法)。 +- 支持 Cloudflare Turnstile 用户校验。 +- 支持用户管理,支持**多种用户登录注册方式**: + + 邮箱登录注册(支持注册邮箱白名单)以及通过邮箱进行密码重置。 + + [GitHub 开放授权](https://github.com/settings/applications/new)。 + + 微信公众号授权(需要额外部署 [WeChat Server](https://github.com/songquanpeng/wechat-server))。 \ No newline at end of file diff --git a/one-api/data.yml b/one-api/data.yml new file mode 100644 index 000000000..30156c8a7 --- /dev/null +++ b/one-api/data.yml @@ -0,0 +1,19 @@ +name: One API +tags: + - AI / 大模型 +title: OpenAI 接口管理 & 分发系统 +description: OpenAI 接口管理 & 分发系统 +additionalProperties: + key: one-api + name: One API + tags: + - AI + shortDescZh: 通过标准的 OpenAI API 格式访问所有的大模型,开箱即用 + shortDescEn: Access all LLM through the standard OpenAI API format, easy to deploy & use + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://openai.justsong.cn/ + github: https://github.com/songquanpeng/one-api + document: https://github.com/songquanpeng/one-api diff --git a/one-api/latest/data.yml b/one-api/latest/data.yml new file mode 100644 index 000000000..8e1f8ecbe --- /dev/null +++ b/one-api/latest/data.yml @@ -0,0 +1,48 @@ +additionalProperties: + formFields: + - default: "" + envKey: PANEL_DB_HOST + key: mysql + labelEn: Database Service + labelZh: 数据库服务 + required: true + type: service + - default: oneapi + envKey: PANEL_DB_NAME + labelEn: Database + labelZh: 数据库名 + random: true + required: true + rule: paramCommon + type: text + - default: oneapi + envKey: PANEL_DB_USER + labelEn: User + labelZh: 数据库用户 + random: true + required: true + rule: paramCommon + type: text + - default: oneapi + envKey: PANEL_DB_USER_PASSWORD + labelEn: Password + labelZh: 数据库用户密码 + random: true + required: true + rule: paramComplexity + type: password + - default: 3000 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: Asia/Shanghai + edit: true + envKey: TZ + labelEn: Time Zone + labelZh: 时区 + required: true + type: text \ No newline at end of file diff --git a/one-api/latest/docker-compose.yml b/one-api/latest/docker-compose.yml new file mode 100644 index 000000000..30d1e51bf --- /dev/null +++ b/one-api/latest/docker-compose.yml @@ -0,0 +1,24 @@ +services: + one-api: + image: justsong/one-api:latest + container_name: ${CONTAINER_NAME} + restart: always + ports: + - ${PANEL_APP_PORT_HTTP}:3000 + networks: + - 1panel-network + volumes: + - ./data:/data + environment: + - SQL_DSN=${PANEL_DB_USER}:${PANEL_DB_USER_PASSWORD}@tcp(${PANEL_DB_HOST}:3306)/${PANEL_DB_NAME} # 修改此行,或注释掉以使用 SQLite 作为数据库 + - TZ=${TZ} +# - REDIS_CONN_STRING=redis://redis +# - SESSION_SECRET=random_string # 修改为随机字符串 +# - NODE_TYPE=slave # 多机部署时从节点取消注释该行 +# - SYNC_FREQUENCY=60 # 需要定期从数据库加载数据时取消注释该行 +# - FRONTEND_BASE_URL=https://openai.justsong.cn # 多机部署时从节点取消注释该行 + labels: + createdBy: "Apps" +networks: + 1panel-network: + external: true \ No newline at end of file diff --git a/one-api/logo.png b/one-api/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..0f237a226583e08f89f14a15d86aa330a11151ae GIT binary patch literal 8085 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 literal 0 HcmV?d00001 From 9baffe9d0f3ee316a28fd07d6c94a4cf91d8cd87 Mon Sep 17 00:00:00 2001 From: TGY Date: Mon, 10 Mar 2025 11:12:37 +0800 Subject: [PATCH 05/27] add neo-api --- neo-api/README.md | 5 +++ neo-api/data.yml | 19 +++++++++++ neo-api/latest/data.yml | 52 +++++++++++++++++++++++++++++ neo-api/latest/docker-compose.yml | 26 +++++++++++++++ neo-api/logo.png | Bin 0 -> 8085 bytes neo-api/sqllite/data.yml | 17 ++++++++++ neo-api/sqllite/docker-compose.yml | 25 ++++++++++++++ new-api/sqllite/data.yml | 17 ++++++++++ new-api/sqllite/docker-compose.yml | 25 ++++++++++++++ 9 files changed, 186 insertions(+) create mode 100644 neo-api/README.md create mode 100644 neo-api/data.yml create mode 100644 neo-api/latest/data.yml create mode 100644 neo-api/latest/docker-compose.yml create mode 100644 neo-api/logo.png create mode 100644 neo-api/sqllite/data.yml create mode 100644 neo-api/sqllite/docker-compose.yml create mode 100644 new-api/sqllite/data.yml create mode 100644 new-api/sqllite/docker-compose.yml diff --git a/neo-api/README.md b/neo-api/README.md new file mode 100644 index 000000000..ce2092743 --- /dev/null +++ b/neo-api/README.md @@ -0,0 +1,5 @@ +# neo-api + +基于new-api的魔改版,部署流程请参考 new-api 教程 +[README.md]( +https://github.com/Calcium-Ion/new-api/blob/main/README.md) \ No newline at end of file diff --git a/neo-api/data.yml b/neo-api/data.yml new file mode 100644 index 000000000..85789f2da --- /dev/null +++ b/neo-api/data.yml @@ -0,0 +1,19 @@ +name: neo api +tags: + - AI / 大模型 +title: OpenAI 接口管理 & 分发系统 new-api魔改版 +description: OpenAI 接口管理 & 分发系统 ,new-api魔改版 +additionalProperties: + key: neo-api + name: neo api + tags: + - AI + shortDescZh: AI模型接口管理与分发系统,支持将多种大模型转为OpenAI格式调用、支持Midjourney Proxy、Suno、Rerank,兼容易支付协议,可供个人或者企业内部管理与分发渠道使用,本项目基于One API二次开发。 + shortDescEn: Access all LLM through the standard OpenAI API format, easy to deploy & use + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://github.com/wozulong/neo-api + github: https://github.com/wozulong/neo-api + document: https://github.com/wozulong/neo-api diff --git a/neo-api/latest/data.yml b/neo-api/latest/data.yml new file mode 100644 index 000000000..e5d51ca3e --- /dev/null +++ b/neo-api/latest/data.yml @@ -0,0 +1,52 @@ +additionalProperties: + formFields: + - default: "" + edit: true + envKey: PANEL_DB_HOST + key: mysql + labelEn: Database Service + labelZh: 数据库服务 + required: true + type: service + - default: neoapi + edit: true + envKey: PANEL_DB_NAME + labelEn: Database + labelZh: 数据库名 + random: true + required: true + rule: paramCommon + type: text + - default: neoapi + edit: true + envKey: PANEL_DB_USER + labelEn: User + labelZh: 数据库用户 + random: true + required: true + rule: paramCommon + type: text + - default: neoapi + edit: true + envKey: PANEL_DB_USER_PASSWORD + labelEn: Password + labelZh: 数据库用户密码 + random: true + required: true + rule: paramComplexity + type: password + - default: 3000 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: Asia/Shanghai + edit: true + envKey: TZ + labelEn: Time Zone + labelZh: 时区 + required: true + type: text diff --git a/neo-api/latest/docker-compose.yml b/neo-api/latest/docker-compose.yml new file mode 100644 index 000000000..145a8ea2d --- /dev/null +++ b/neo-api/latest/docker-compose.yml @@ -0,0 +1,26 @@ +services: + neo-api: + image: pengzhile/new-api:latest + container_name: ${CONTAINER_NAME} + restart: always + ports: + - ${PANEL_APP_PORT_HTTP}:3000 + networks: + - 1panel-network + command: --log-dir /app/logs + volumes: + - ./data:/data + - ./logs:/app/logs + environment: + - SQL_DSN=${PANEL_DB_USER}:${PANEL_DB_USER_PASSWORD}@tcp(${PANEL_DB_HOST}:3306)/${PANEL_DB_NAME} # 修改此行,或注释掉以使用 SQLite 作为数据库 + - TZ=${TZ} +# - SESSION_SECRET=${SESSION_SECRET} +# - REDIS_CONN_STRING=redis://redis +# - NODE_TYPE=slave # 多机部署时从节点取消注释该行 +# - SYNC_FREQUENCY=60 # 需要定期从数据库加载数据时取消注释该行 +# - FRONTEND_BASE_URL=https://openai.justsong.cn # 多机部署时从节点取消注释该行 + labels: + createdBy: "Apps" +networks: + 1panel-network: + external: true diff --git a/neo-api/logo.png b/neo-api/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..0f237a226583e08f89f14a15d86aa330a11151ae GIT binary patch literal 8085 zcmeHM_cI(0u-AKu8cvOb-09`??(`_vkSG!T^dwG#J`k%+d z^oKSD1=Sy@1=7gmp~XMX|I7b(;QwF;?g zFp=Y7pcjiS>)$xPI-Py_P@7uHrD$lYE7Mw-Nk3)acbfvO-qgjX5Q*^7<7?#yb8)w+ z;O`4$mxJa9D>2iPnhs@|Vi+av`&U!U3aQuY;@tl*UOYpQcj zbZ1XqOs_Y3dz0V%>GiOYai|Ag?cJbIwUR~Dd_?mjR2q4wvY;U_*0J{I-F9x?CpTca z|9uB7#gA#`V|%{Pp-Y@TPcLY^dEtL=g`+C<$jaS+_=;&G53F)>1^8}a4*-6b_sc(?&dEa!Rl zt3~!IGs`=bOp4O}N;hsW-kV0+SOo}|-RLUG@cAs86idVX0_tBL?QzX9lvcU4o&=z( zt}6epWoiNfWlgmtmmPaDREg*1^L}GmFl^|99?dX|@?Eg`n0RR$a*i1JGj7Jq3sw`2 zoV2eQ`pPv{vm307lr*ujE$j-gRh*`#EY=DLRJuw?R91L-uC0E7>pB4U?m61uzgHeJ z34hdFa~npPBPCEU=kWbk*7$nbLBo_RPX;2kZ7}{Yc*lQod+AEd9>6XMvb%69QY_Uf z%B8Hy*pv6S{7dHOR2SA(FVxj!Z)wp=Z?Erq>df9e8w(#eeOST5blCPd!f=}NWc2s1 z#Lx4e#=V3uK^viq-O2ofT%TFnqor)``4wO`>}XTjBW!$O_zF{?^=CJNI-odxXYQ$9 z?!?vA!SxyP8`kLf_PX>I9xlkE1w$pcBcD;4;$R}iRh$!)k69{eIkTO$MM~ta4CZ2z z-w)|@P3&r{wGO}E+v*H>`*Ue;6%qYi>BsFr$suqdKdaL_iF7>1^D79+b;kR18q9Ho z1~@95`L{~p2iq}KHizN)cjYN+C1H610!ooCy0bTVVYN%HEiRwoGY_T@)n=KEVF7)j zEnXf{GopSr1%@HtH<1Hz;P~&87G*LTtOt)tA7`>RT6mwlWqAT35YL0|N@X|be zeHjH1tK^sZgd{FKy~G0 z>AlJ*C-_+nN-Mj5z;A;N*W$0ehtMi|?Dk)eTloDS6G>D#C4nYKY{(Hj)~sc>Z4Y$T z3kdm`-nN=efF?f~nQ;H9K>Ef@-%KNtUP)&9CabWUX72Fo0HLy!aLDz+;6N;=~i?4uO)-bZt0K8EUNa=0@wx z+P+$k3@n8ugXoE+_wSjUir)U7y>YBy&m=+ z<)&lfKBPsT?!a%H=|3{HY_!QQ!ld+ej}EFozbyE$=TXuvr|8;y{#8{f7PoY;DU#SQ z>R~mzI5A8KXjd`V3Fo+#NJ<8!sq-60f65;j>mb%>p5vv6B}vjn4s?onN#~j9 z38)6=D8uNlkLP%pvq!@u=s*=rPrV)!kl`&KpF8j>u682pH2tgE+n^t?mQ{dJ(MXqm zO_i*>&&a^;)=1;(x%Z__ax+^mkELwe8KaBGts1nXpmFS;Xy&(s)e7wV=xxplEp4cL-rPRPm-$V+#vy6xgiOdQDyqIBX8#c027 zBs*H9!4h$K1D%m zm2b_!Q3CC}o1c200^dDi_*=aEG#_sCTmKX73xa;~&9E+fe(jkp@!8ojqjBU9nyw?8 zc1*h{n_^-g>e^#&*FNC$<6G_AB#gp9oKqpL>o-c*hUOSh6*P*ai(|S4bLVL1BFzh$ z5A8)q{{F>jtu;R?@)Jn$1(VTTupDvBkEiS!8I z|7$F@s6g9QFE5*tP)H7Afo#>F;)+k8kQ>M=#q7i@59Q_mux30)Qv42G280{eP>MNJ zH6%5W&Gm_EQ|S!43I&p$B4~ATHFqeLRYFoNIYtp7k`k4Z9gH9@e&Lsm56h;C_^K{M z`ffacyx5dLzQ$%tQf>CzN2CL22{#e9y6}Rm6HAdmWd%88PK^mq|0-?X6&b^0+z5mY ze;tKtTJR$BCva)_7geQ~PM5pfsbNIyN?}4Q{<2nxKpr0zFZft zrsra-j*wk3uQaGRUu2WP724NC4sTP~EDtBHD}YVU5CsCye}2t_>hB4aJSPW(M$pSo zM0seWXShqzkfT*rfMxtme9^X{M})7w-K->u!4y6t`NKSV!72{mm}B2G6jf{geIvhe z!YU{w?KGSyo^DB~_#l_2hj{ok9BqW*+b$oy*hdpTy1W2o$;B%2J3;VO(RUzd=lE`Z zK;aphNaX>{I!1l&Wlumr*G! zA1vGVJh0_sRZI^7lj}XQ-)l*8bV)ukivV^19X-f$*$1R*h=(a=JN875?jy2pW5(15TaiRaH zB`^s`!2$rcY|v`t3%TBprdejuT=aTV)Lz~m$1Z$4`0fUww0Mm+MqaDoN{e5mH%HLB z2h#Z%0jde_jNotGP{I`#lW*{tWq_CdlxgyK8a-VvN|JRfR*0FWRO6mf7z8#z-ePld zvl|`Uej<-DkDaS2WNLJk&aU|@o}!p;8&_+88&#Sj@)z_OgI8gT&Xsx(L^M3|MYX;M z$2~qdu;yy#@iAXQtplFsDYmg2*q!NQ3nWFhY!~jqT>bWdbQET`OsX-IeSNfTZfpt@C^=NSiAvl zzik{$`f=+b&ef^p^n#8)0B`E!Ch{hpYM`ln z&}+0VBbkbMaG3TTmo#_D-S?^;0!;ej1#nj{vB4U!P@;pvD`T@>7rc_V&ep;NRIjU< z1oKmnZa0j6R55;IphbsDW!{I{1j0WwXNDIEf3VA#Uno&*mAP97t>^cs2p^vrg&KGGSA24S&NuJTdDNdO zAGi|h!C}0%fN@}uHugx=NNlOZb$JIk;CH3oh6}qdr_j0)TCeBAc^Xfb;oBzu7t_ssh-1*PbYdCvy z9ElLx1I)@!HArQ^>vvB6Dzrv0`CG@@+dAGr8(^VqHTQf=i!*;xSHvpsfF8etqb;Mx+mDI%y1O^Rj4|uK zQIzGKgN!noN%Uh5_?~@ho8My}m6Y+mpPont`sN*|2Jou!Nix&%1de=cFb9n+2iDup zK7w-*LmRa=kVFXhB@+Q&1rA!&Kr74h=gfL>b1&~$YFsnNy1s4=Pqdb`V_yeo76&+* zT2#YQ+2VaV3h0)2PJgCqw6{^W{+PAQBg)Nm8;%@bmSy4D4rK^k>A;FA4SZ3ipt23iPV@%$R}xUGh2RkQUYc{Z?Y1`{!Ql>$M!!Ew43GMpBc9le5DZw3TN504n3%z($w6@x08K z7VnGj_W2y9#a+a1bC@>6-jT3T`f_}9WcjMt4ap1DqMz3z_9g9U+Li0W_qdP>SV8m- z>PNH>HlI?B(?=jRNt_gc>wI*S{E!437isl;T^ch0q3|;3vqfMsM)zn~HNX`2|0YTr z9A?MW#x8lgn7fIn@%U6MCR|}vQ5lUi6rDSFcn|=&=!*5g!+wP9e5O#88@{u0l-rpv zg{4e?!<|B}Zn60X*IY^UFdt4qDlJYjqwH6GPr3{E7fV-SjfftPRFgsfr|;vyEUeH& zMY13h3vQI>sO0tpze!Yed`&2}+! zkhgU|v|=MR@u3#dh6%k*A6>kHUk+Rzxc*=!ujtDc>%5nh?9^!q8vNGLzpqV`p76`R zg-Ve=g~;)9(ptFgff&?8BoC;WKK6qWW~idYi!BIAO1(GgXWX|oFWRD14R%UD-2f)o zQ{cNX#4^%Bv&mMl5ojFkd99suv#OMvzZA<+CVZ>)Iw2|U4QW1b^SIoi%mp*|7U~Rl zcT6e$WNrPKU7@g4oA1+8js=oC8?Wet}kF=qevlbY{?VnC-#WknUEa&`3;Ary0U zZw2OupnSF*6T5L&Kx91+S8MO1Yj7o0){Bf?%?=5@PwIC=T*q>rAwLg=}2yKhnk9jrdFs zn2EezAv;1e72_@(v<#Nf>0q>6t4)>gXK8f5?IF=Ss|jY}qwsLvt0?u7G?>a7GS!5z zwj1W9g5=MPwNe2Pr!6~sXm?&~M%EjX(J6UHF@_uD$;5+HVy(-3$33e`J?UY|t z7h*=7EYGh?dFoC1zW1(O=cs{F^9m8(N1Z|^o>N6!E+n0Ny~_LpXIu~4L~_b3PloM? zDkjnpz0K)q_TTqQO@Fb3-2dT# z9K~a$Eo{{FWGWYuG`P**P_ZBFa9Z&=pGM)jqsj8YGLD?+cmvEl>~le6o&U``Hs$Tl zl-DQ9ztM$^%hfdjnXZzi6mLM(BQX*?NIgsQ40wI%AWeoTwK&=9jC&p#FZ*%ue(>HFFf(UL8+>pLfP%Vs2aFlXk>Qq~0>%28N~`xr7ze z;vWZjcC-HDER)=(hV{SOGo=Wte4rN|FOo=;iLcg~dDHT;o?7--6xEjnSn-&}mz;-2 zX>z4RS0k&IMOmZHSg)P(s=`MjIg>|xHhzLsQ{j5i18ej5{z{=FAG_XLe^xV+EeTgG z`=AT~9)h%Fev8`^o8?)PnpBEQ)!N;89l5m%s9?$qk2;4?D<773|JET7X7X-Hs*`{2 z?vXkcqHfBK+P`0HoY9v>ZMeWt4{cH;VBYz(mtjFPBE(J0)SacSaXyDv?qq~_1 z+PErdYAT=4trr50kr-b+|As4ip`gtl;QgZ5VDE!|0Rg4dEe}7VS*d`A$-hEw(ua-J zP(HK^N@`4a=Nehs|4N3k*}vp&C4*Xx7q|A}w{~cY|Mk9}`>{t&PfGt#ZSF-~$i_qc z*`kGp5uU*I)i8}6c!vSgcHJ{Y-R|U4DZvsM zgZOT?JF8I79_f&Yh5szQ6TFY+J1JiPZRmeY?uDz*;Ey<3s-P0(xl6(sinYT2@@=xS z9N(WkF1&mcxbA$#H)l6{T^92Wv|=pMr+w2ONf<>>kqtN=n$1e)GZ2$81DSzuik?+s zW^@=M-UTF#4{Elo#bJ*h5Z<|=JS~*-^PR7U6>UB@M<_oGWCDQ0;R}xMDi4ZDjgsT< z59ai>lg1otPeD-LGgFD7!X9lI@hAHOTTW6oq{x%aiKo_f`R9fO?e9ttt{lDfnP2!W z$=o24@gdhJwo2z(IWM4EuW%f4!3t;nwO&J7CoGe4Do@N ze0?Ll3dwo@{iYp#v(Ab@iu1V*Nd0WW%y%7Ycgm%TI%dE*^Zlzb;Uhg0A6&3A; z3$@v&ySaopv0}FWB8WeaG8=5Zylt^Q`DAnG#Ewv+qf_R=MT~yt>(o&FW*9<9bP;$PZo3SFV)wKG!23>VdH*S2$tpd9+h8 vm{h2v9Dij;CQqNNYK7N)pA@v57rGMY^ijcdQjk#p`&BhFvNEhSco6eHk%;zp literal 0 HcmV?d00001 diff --git a/neo-api/sqllite/data.yml b/neo-api/sqllite/data.yml new file mode 100644 index 000000000..47b7d314b --- /dev/null +++ b/neo-api/sqllite/data.yml @@ -0,0 +1,17 @@ +additionalProperties: + formFields: + - default: 3000 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: Asia/Shanghai + edit: true + envKey: TZ + labelEn: Time Zone + labelZh: 时区 + required: true + type: text diff --git a/neo-api/sqllite/docker-compose.yml b/neo-api/sqllite/docker-compose.yml new file mode 100644 index 000000000..b82b5456a --- /dev/null +++ b/neo-api/sqllite/docker-compose.yml @@ -0,0 +1,25 @@ +services: + neo-api: + image: pengzhile/new-api:latest + container_name: ${CONTAINER_NAME} + restart: always + ports: + - ${PANEL_APP_PORT_HTTP}:3000 + networks: + - 1panel-network + command: --log-dir /app/logs + volumes: + - ./data:/data + - ./logs:/app/logs + environment: + - TZ=${TZ} +# - SESSION_SECRET=${SESSION_SECRET} +# - REDIS_CONN_STRING=redis://redis +# - NODE_TYPE=slave # 多机部署时从节点取消注释该行 +# - SYNC_FREQUENCY=60 # 需要定期从数据库加载数据时取消注释该行 +# - FRONTEND_BASE_URL=https://openai.justsong.cn # 多机部署时从节点取消注释该行 + labels: + createdBy: "Apps" +networks: + 1panel-network: + external: true diff --git a/new-api/sqllite/data.yml b/new-api/sqllite/data.yml new file mode 100644 index 000000000..47b7d314b --- /dev/null +++ b/new-api/sqllite/data.yml @@ -0,0 +1,17 @@ +additionalProperties: + formFields: + - default: 3000 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: Asia/Shanghai + edit: true + envKey: TZ + labelEn: Time Zone + labelZh: 时区 + required: true + type: text diff --git a/new-api/sqllite/docker-compose.yml b/new-api/sqllite/docker-compose.yml new file mode 100644 index 000000000..04c9b34bd --- /dev/null +++ b/new-api/sqllite/docker-compose.yml @@ -0,0 +1,25 @@ +services: + one-api: + image: calciumion/new-api:latest + container_name: ${CONTAINER_NAME} + restart: always + ports: + - ${PANEL_APP_PORT_HTTP}:3000 + networks: + - 1panel-network + command: --log-dir /app/logs + volumes: + - ./data:/data + - ./logs:/app/logs + environment: + - TZ=${TZ} +# - SESSION_SECRET=${SESSION_SECRET} +# - REDIS_CONN_STRING=redis://redis +# - NODE_TYPE=slave # 多机部署时从节点取消注释该行 +# - SYNC_FREQUENCY=60 # 需要定期从数据库加载数据时取消注释该行 +# - FRONTEND_BASE_URL=https://openai.justsong.cn # 多机部署时从节点取消注释该行 + labels: + createdBy: "Apps" +networks: + 1panel-network: + external: true From 7ffb0e2e195901c0991964273aee3b5bdd2356b7 Mon Sep 17 00:00:00 2001 From: TGY Date: Thu, 20 Mar 2025 17:01:15 +0800 Subject: [PATCH 06/27] add uni-api --- uni-api/README.md | 507 ++++++++++++++++++++++++++++++ uni-api/data.yml | 19 ++ uni-api/latest/data.yml | 35 +++ uni-api/latest/docker-compose.yml | 21 ++ uni-api/logo.png | Bin 0 -> 43853 bytes 5 files changed, 582 insertions(+) create mode 100644 uni-api/README.md create mode 100644 uni-api/data.yml create mode 100644 uni-api/latest/data.yml create mode 100644 uni-api/latest/docker-compose.yml create mode 100644 uni-api/logo.png diff --git a/uni-api/README.md b/uni-api/README.md new file mode 100644 index 000000000..f795b5636 --- /dev/null +++ b/uni-api/README.md @@ -0,0 +1,507 @@ +# uni-api + +

+ + + + + docker pull + +

+ +[英文](./README.md) | [中文](./README_CN.md) + +## 介绍 + +如果个人使用的话,one/new-api 过于复杂,有很多个人不需要使用的商用功能,如果你不想要复杂的前端界面,又想要支持的模型多一点,可以试试 uni-api。这是一个统一管理大模型 API 的项目,可以通过一个统一的API 接口调用多种不同提供商的服务,统一转换为 OpenAI 格式,支持负载均衡。目前支持的后端服务有:OpenAI、Anthropic、Gemini、Vertex、Azure、xai、Cohere、Groq、Cloudflare、OpenRouter 等。 + +## ✨ 特性 + +- 无前端,纯配置文件配置 API 渠道。只要写一个文件就能运行起一个属于自己的 API 站,文档有详细的配置指南,小白友好。 +- 统一管理多个后端服务,支持 OpenAI、Deepseek、OpenRouter 等其他 API 是 OpenAI 格式的提供商。支持 OpenAI Dalle-3 图像生成。 +- 同时支持 Anthropic、Gemini、Vertex AI、Azure、xai、Cohere、Groq、Cloudflare。Vertex 同时支持 Claude 和 Gemini API。 +- 支持 OpenAI、 Anthropic、Gemini、Vertex、Azure、xai 原生 tool use 函数调用。 +- 支持 OpenAI、Anthropic、Gemini、Vertex、Azure、xai 原生识图 API。 +- 支持四种负载均衡。 + 1. 支持渠道级加权负载均衡,可以根据不同的渠道权重分配请求。默认不开启,需要配置渠道权重。 + 2. 支持 Vertex 区域级负载均衡,支持 Vertex 高并发,最高可将 Gemini,Claude 并发提高 (API数量 * 区域数量) 倍。自动开启不需要额外配置。 + 3. 除了 Vertex 区域级负载均衡,所有 API 均支持渠道级顺序负载均衡,提高沉浸式翻译体验。默认不开启,需要配置 `SCHEDULING_ALGORITHM` 为 `round_robin`。 + 4. 支持单个渠道多个 API Key 自动开启 API key 级别的轮训负载均衡。 +- 支持自动重试,当一个 API 渠道响应失败时,自动重试下一个 API 渠道。 +- 支持渠道冷却,当一个 API 渠道响应失败时,会自动将该渠道排除冷却一段时间,不再请求该渠道,冷却时间结束后,会自动将该模型恢复,直到再次请求失败,会重新冷却。 +- 支持细粒度的模型超时时间设置,可以为每个模型设置不同的超时时间。 +- 支持细粒度的权限控制。支持使用通配符设置 API key 可用渠道的特定模型。 +- 支持限流,可以设置每分钟最多请求次数,可以设置为整数,如 2/min,2 次每分钟、5/hour,5 次每小时、10/day,10 次每天,10/month,10 次每月,10/year,10 次每年。默认60/min。 +- 支持多个标准 OpenAI 格式的接口:`/v1/chat/completions`,`/v1/images/generations`,`/v1/audio/transcriptions`,`/v1/moderations`,`/v1/models`。 +- 支持 OpenAI moderation 道德审查,可以对用户的消息进行道德审查,如果发现不当的消息,会返回错误信息。降低后台 API 被提供商封禁的风险。 + +## 使用方法 + +启动 uni-api 必须使用配置文件,有两种方式可以启动配置文件: + +1. 第一种是使用 `CONFIG_URL` 环境变量填写配置文件 URL,uni-api启动时会自动下载。 +2. 第二种就是挂载名为 `api.yaml` 的配置文件到容器内。 + +### 方法一:挂载 `api.yaml` 配置文件启动 uni-api + +必须事先填写完成配置文件才能启动 `uni-api`,必须使用名为 `api.yaml` 的配置文件才能启动 `uni-api`,可以配置多个模型,每个模型可以配置多个后端服务,支持负载均衡。下面是最小可运行的 `api.yaml` 配置文件的示例: + +```yaml +providers: + - provider: provider_name # 服务提供商名称, 如 openai、anthropic、gemini、openrouter,随便取名字,必填 + base_url: https://api.your.com/v1/chat/completions # 后端服务的API地址,必填 + api: sk-YgS6GTi0b4bEabc4C # 提供商的API Key,必填,自动使用 base_url 和 api 通过 /v1/models 端点获取可用的所有模型。 + # 这里可以配置多个提供商,每个提供商可以配置多个 API Key,每个提供商可以配置多个模型。 +api_keys: + - api: sk-Pkj60Yf8JFWxfgRmXQFWyGtWUddGZnmi3KlvowmRWpWpQxx # API Key,用户请求 uni-api 需要 API key,必填 + # 该 API Key 可以使用所有模型,即可以使用 providers 下面设置的所有渠道里面的所有模型,不需要一个个添加可用渠道。 +``` + +`api.yaml` 详细的高级配置: + +```yaml +providers: + - provider: provider_name # 服务提供商名称, 如 openai、anthropic、gemini、openrouter,随便取名字,必填 + base_url: https://api.your.com/v1/chat/completions # 后端服务的API地址,必填 + api: sk-YgS6GTi0b4bEabc4C # 提供商的API Key,必填 + model: # 选填,如果不配置 model,会自动通过 base_url 和 api 通过 /v1/models 端点获取可用的所有模型。 + - gpt-4o # 可以使用的模型名称,必填 + - claude-3-5-sonnet-20240620: claude-3-5-sonnet # 重命名模型,claude-3-5-sonnet-20240620 是服务商的模型名称,claude-3-5-sonnet 是重命名后的名字,可以使用简洁的名字代替原来复杂的名称,选填 + - dall-e-3 + + - provider: anthropic + base_url: https://api.anthropic.com/v1/messages + api: # 支持多个 API Key,多个 key 自动开启轮训负载均衡,至少一个 key,必填 + - sk-ant-api03-bNnAOJyA-xQw_twAA + - sk-ant-api02-bNnxxxx + model: + - claude-3-7-sonnet-20240620: claude-3-7-sonnet # 重命名模型,claude-3-7-sonnet-20240620 是服务商的模型名称,claude-3-7-sonnet 是重命名后的名字,可以使用简洁的名字代替原来复杂的名称,选填 + - claude-3-7-sonnet-20250219: claude-3-7-sonnet-think # 重命名模型,claude-3-7-sonnet-20250219 是服务商的模型名称,claude-3-7-sonnet-think 是重命名后的名字,可以使用简洁的名字代替原来复杂的名称,如果重命名后的名字里面有think,则自动转换为 claude 思考模型,默认思考 token 限制为 4096。选填 + tools: true # 是否支持工具,如生成代码、生成文档等,默认是 true,选填 + + - provider: gemini + base_url: https://generativelanguage.googleapis.com/v1beta # base_url 支持 v1beta/v1, 仅供 Gemini 模型使用,必填 + api: # 支持多个 API Key,多个 key 自动开启轮训负载均衡,至少一个 key,必填 + - AIzaSyAN2k6IRdgw123 + - AIzaSyAN2k6IRdgw456 + - AIzaSyAN2k6IRdgw789 + model: + - gemini-1.5-pro + - gemini-1.5-flash-exp-0827: gemini-1.5-flash # 重命名后,原来的模型名字 gemini-1.5-flash-exp-0827 无法使用,如果要使用原来的名字,可以在 model 中添加原来的名字,只要加上下面一行就可以使用原来的名字了 + - gemini-1.5-flash-exp-0827 # 加上这一行,gemini-1.5-flash-exp-0827 和 gemini-1.5-flash 都可以被请求 + - gemini-1.5-pro: gemini-1.5-pro-search # 支持以 -search 后缀重命名模型启用搜索,使用 gemini-1.5-pro-search 模型请求 uni-api 时,表示 gemini-1.5-pro 模型自动使用 Google 官方搜索工具,支持全部 1.5/2.0 系列模型。 + tools: true + preferences: + api_key_rate_limit: 15/min # 每个 API Key 每分钟最多请求次数,选填。默认为 999999/min。支持多个频率约束条件:15/min,10/day + # api_key_rate_limit: # 可以为每个模型设置不同的频率限制 + # gemini-1.5-flash: 15/min,1500/day + # gemini-1.5-pro: 2/min,50/day + # default: 4/min # 如果模型没有设置频率限制,使用 default 的频率限制 + api_key_cooldown_period: 60 # 每个 API Key 遭遇 429 错误后的冷却时间,单位为秒,选填。默认为 0 秒, 当设置为 0 秒时,不启用冷却机制。当存在多个 API key 时才会生效。 + api_key_schedule_algorithm: round_robin # 设置多个 API Key 的请求顺序,选填。默认为 round_robin,可选值有:round_robin,random,fixed_priority。当存在多个 API key 时才会生效。round_robin 是轮询负载均衡,random 是随机负载均衡,fixed_priority 是固定优先级调度,永远使用第一个可用的 API key。 + model_timeout: # 模型超时时间,单位为秒,默认 100 秒,选填 + gemini-1.5-pro: 10 # 模型 gemini-1.5-pro 的超时时间为 10 秒 + gemini-1.5-flash: 10 # 模型 gemini-1.5-flash 的超时时间为 10 秒 + default: 10 # 模型没有设置超时时间,使用默认的超时时间 10 秒,当请求的不在 model_timeout 里面的模型时,超时时间默认是 10 秒,不设置 default,uni-api 会使用全局配置的模型超时时间。 + proxy: socks5://[用户名]:[密码]@[IP地址]:[端口] # 代理地址,选填。支持 socks5 和 http 代理,默认不使用代理。 + headers: # 额外附加自定义HTTP请求头,选填。 + Custom-Header-1: Value-1 + Custom-Header-2: Value-2 + + - provider: vertex + project_id: gen-lang-client-xxxxxxxxxxxxxx # 描述: 您的Google Cloud项目ID。格式: 字符串,通常由小写字母、数字和连字符组成。获取方式: 在Google Cloud Console的项目选择器中可以找到您的项目ID。 + private_key: "-----BEGIN PRIVATE KEY-----\nxxxxx\n-----END PRIVATE" # 描述: Google Cloud Vertex AI服务账号的私钥。格式: 一个 JSON 格式的字符串,包含服务账号的私钥信息。获取方式: 在 Google Cloud Console 中创建服务账号,生成JSON格式的密钥文件,然后将其内容设置为此环境变量的值。 + client_email: xxxxxxxxxx@xxxxxxx.gserviceaccount.com # 描述: Google Cloud Vertex AI 服务账号的电子邮件地址。格式: 通常是形如 "service-account-name@project-id.iam.gserviceaccount.com" 的字符串。获取方式: 在创建服务账号时生成,也可以在 Google Cloud Console 的"IAM与管理"部分查看服务账号详情获得。 + model: + - gemini-1.5-pro + - gemini-1.5-flash + - gemini-1.5-pro: gemini-1.5-pro-search # 仅支持在 vertex Gemini API 中,以 -search 后缀重命名模型后,使用 gemini-1.5-pro-search 模型请求 uni-api 时,表示 gemini-1.5-pro 模型自动使用 Google 官方搜索工具。 + - claude-3-5-sonnet@20240620: claude-3-5-sonnet + - claude-3-opus@20240229: claude-3-opus + - claude-3-sonnet@20240229: claude-3-sonnet + - claude-3-haiku@20240307: claude-3-haiku + tools: true + notes: https://xxxxx.com/ # 可以放服务商的网址,备注信息,官方文档,选填 + + - provider: cloudflare + api: f42b3xxxxxxxxxxq4aoGAh # Cloudflare API Key,必填 + cf_account_id: 8ec0xxxxxxxxxxxxe721 # Cloudflare Account ID,必填 + model: + - '@cf/meta/llama-3.1-8b-instruct': llama-3.1-8b # 重命名模型,@cf/meta/llama-3.1-8b-instruct 是服务商的原始的模型名称,必须使用引号包裹模型名,否则yaml语法错误,llama-3.1-8b 是重命名后的名字,可以使用简洁的名字代替原来复杂的名称,选填 + - '@cf/meta/llama-3.1-8b-instruct' # 必须使用引号包裹模型名,否则yaml语法错误 + + - provider: azure + base_url: https://your-endpoint.openai.azure.com + api: your-api-key + model: + - gpt-4o + + - provider: other-provider + base_url: https://api.xxx.com/v1/messages + api: sk-bNnAOJyA-xQw_twAA + model: + - causallm-35b-beta2ep-q6k: causallm-35b + - anthropic/claude-3-5-sonnet + tools: false + engine: openrouter # 强制使用某个消息格式,目前支持 gpt,claude,gemini,openrouter 原生格式,选填 + +api_keys: + - api: sk-KjjI60Yf0JFWxfgRmXqFWyGtWUd9GZnmi3KlvowmRWpWpQRo # API Key,用户使用本服务需要 API key,必填 + model: # 该 API Key 可以使用的模型,必填。默认开启渠道级轮询负载均衡,每次请求模型按照 model 配置的顺序依次请求。与 providers 里面原始的渠道顺序无关。因此你可以设置每个 API key 请求顺序不一样。 + - gpt-4o # 可以使用的模型名称,可以使用所有提供商提供的 gpt-4o 模型 + - claude-3-5-sonnet # 可以使用的模型名称,可以使用所有提供商提供的 claude-3-5-sonnet 模型 + - gemini/* # 可以使用的模型名称,仅可以使用名为 gemini 提供商提供的所有模型,其中 gemini 是 provider 名称,* 代表所有模型 + role: admin # 设置 API key 的别名,选填。请求日志会显示该 API key 的别名。如果 role 为 admin,则仅有此 API key 可以请求 v1/stats,/v1/generate-api-key 端点。如果所有 API key 都没有设置 role 为 admin,则默认第一个 API key 为 admin 拥有请求 v1/stats,/v1/generate-api-key 端点的权限。 + + - api: sk-pkhf60Yf0JGyJxgRmXqFQyTgWUd9GZnmi3KlvowmRWpWqrhy + model: + - anthropic/claude-3-5-sonnet # 可以使用的模型名称,仅可以使用名为 anthropic 提供商提供的 claude-3-5-sonnet 模型。其他提供商的 claude-3-5-sonnet 模型不可以使用。这种写法不会匹配到other-provider提供的名为anthropic/claude-3-5-sonnet的模型。 + - # 通过在模型名两侧加上尖括号,这样就不会去名为anthropic的渠道下去寻找claude-3-5-sonnet模型,而是将整个 anthropic/claude-3-5-sonnet 作为模型名称。这种写法可以匹配到other-provider提供的名为 anthropic/claude-3-5-sonnet 的模型。但不会匹配到anthropic下面的claude-3-5-sonnet模型。 + - openai-test/text-moderation-latest # 当开启消息道德审查后,可以使用名为 openai-test 渠道下的 text-moderation-latest 模型进行道德审查。 + - sk-KjjI60Yd0JFWtxxxxxxxxxxxxxxwmRWpWpQRo/* # 支持将其他 api key 当作渠道 + preferences: + SCHEDULING_ALGORITHM: fixed_priority # 当 SCHEDULING_ALGORITHM 为 fixed_priority 时,使用固定优先级调度,永远执行第一个拥有请求的模型的渠道。默认开启,SCHEDULING_ALGORITHM 缺省值为 fixed_priority。SCHEDULING_ALGORITHM 可选值有:fixed_priority,round_robin,weighted_round_robin, lottery, random。 + # 当 SCHEDULING_ALGORITHM 为 random 时,使用随机轮训负载均衡,随机请求拥有请求的模型的渠道。 + # 当 SCHEDULING_ALGORITHM 为 round_robin 时,使用轮训负载均衡,按照顺序请求用户使用的模型的渠道。 + AUTO_RETRY: true # 是否自动重试,自动重试下一个提供商,true 为自动重试,false 为不自动重试,默认为 true。也可以设置为数字,表示重试次数。 + rate_limit: 15/min # 支持限流,每分钟最多请求次数,可以设置为整数,如 2/min,2 次每分钟、5/hour,5 次每小时、10/day,10 次每天,10/month,10 次每月,10/year,10 次每年。默认999999/min,选填。支持多个频率约束条件:15/min,10/day + # rate_limit: # 可以为每个模型设置不同的频率限制 + # gemini-1.5-flash: 15/min,1500/day + # gemini-1.5-pro: 2/min,50/day + # default: 4/min # 如果模型没有设置频率限制,使用 default 的频率限制 + ENABLE_MODERATION: true # 是否开启消息道德审查,true 为开启,false 为不开启,默认为 false,当开启后,会对用户的消息进行道德审查,如果发现不当的消息,会返回错误信息。 + + # 渠道级加权负载均衡配置示例 + - api: sk-KjjI60Yd0JFWtxxxxxxxxxxxxxxwmRWpWpQRo + model: + - gcp1/*: 5 # 冒号后面就是权重,权重仅支持正整数。 + - gcp2/*: 3 # 数字的大小代表权重,数字越大,请求的概率越大。 + - gcp3/*: 2 # 在该示例中,所有渠道加起来一共有 10 个权重,及 10 个请求里面有 5 个请求会请求 gcp1/* 模型,2 个请求会请求 gcp2/* 模型,3 个请求会请求 gcp3/* 模型。 + + preferences: + SCHEDULING_ALGORITHM: weighted_round_robin # 仅当 SCHEDULING_ALGORITHM 为 weighted_round_robin 并且上面的渠道如果有权重,会按照加权后的顺序请求。使用加权轮训负载均衡,按照权重顺序请求拥有请求的模型的渠道。当 SCHEDULING_ALGORITHM 为 lottery 时,使用抽奖轮训负载均衡,按照权重随机请求拥有请求的模型的渠道。没设置权重的渠道自动回退到 round_robin 轮训负载均衡。 + AUTO_RETRY: true + +preferences: # 全局配置 + model_timeout: # 模型超时时间,单位为秒,默认 100 秒,选填 + gpt-4o: 10 # 模型 gpt-4o 的超时时间为 10 秒,gpt-4o 是模型名称,当请求 gpt-4o-2024-08-06 等模型时,超时时间也是 10 秒 + claude-3-5-sonnet: 10 # 模型 claude-3-5-sonnet 的超时时间为 10 秒,当请求 claude-3-5-sonnet-20240620 等模型时,超时时间也是 10 秒 + default: 10 # 模型没有设置超时时间,使用默认的超时时间 10 秒,当请求的不在 model_timeout 里面的模型时,超时时间默认是 10 秒,不设置 default,uni-api 会使用 环境变量 TIMEOUT 设置的默认超时时间,默认超时时间是 100 秒 + o1-mini: 30 # 模型 o1-mini 的超时时间为 30 秒,当请求名字是 o1-mini 开头的模型时,超时时间是 30 秒 + o1-preview: 100 # 模型 o1-preview 的超时时间为 100 秒,当请求名字是 o1-preview 开头的模型时,超时时间是 100 秒 + cooldown_period: 300 # 渠道冷却时间,单位为秒,默认 300 秒,选填。当模型请求失败时,会自动将该渠道排除冷却一段时间,不再请求该渠道,冷却时间结束后,会自动将该模型恢复,直到再次请求失败,会重新冷却。当 cooldown_period 设置为 0 时,不启用冷却机制。 + rate_limit: 999999/min # uni-api 全局速率限制,单位为次数/分钟,支持多个频率约束条件,例如:15/min,10/day。默认 999999/min,选填。 + error_triggers: # 错误触发器,当模型返回的消息包含错误触发器中的任意一个字符串时,该渠道会自动返回报错。选填 + - The bot's usage is covered by the developer + - process this request due to overload or policy + proxy: socks5://[username]:[password]@[ip]:[port] # 全局代理地址,选填。 +``` + +挂载配置文件并启动 uni-api docker 容器: + +```bash +docker run --user root -p 8001:8000 --name uni-api -dit \ +-v ./api.yaml:/home/api.yaml \ +yym68686/uni-api:latest +``` + +### 方法二:使用 `CONFIG_URL` 环境变量启动 uni-api + +按照方法一写完配置文件后,上传到云端硬盘,获取文件的直链,然后使用 `CONFIG_URL` 环境变量启动 uni-api docker 容器: + +```bash +docker run --user root -p 8001:8000 --name uni-api -dit \ +-e CONFIG_URL=http://file_url/api.yaml \ +yym68686/uni-api:latest +``` + +## 环境变量 + +- CONFIG_URL: 配置文件的下载地址,可以是本地文件,也可以是远程文件,选填 +- TIMEOUT: 请求超时时间,默认为 100 秒,超时时间可以控制当一个渠道没有响应时,切换下一个渠道需要的时间。选填 +- DISABLE_DATABASE: 是否禁用数据库,默认为 false,选填 + +## Vercel 部署 + +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fyym68686%2Funi-api%2Ftree%2Fmain&env=CONFIG_URL,DISABLE_DATABASE&project-name=uni-api-vercel&repository-name=uni-api-vercel) + +点击上面的一键部署按钮后,设置环境变量 `CONFIG_URL` 为配置文件的直链, `DISABLE_DATABASE` 为 true,然后点击 Create 创建项目。部署完之后需要手动在 vercel 项目面板的 Settings -> Funcitons -> Function Max Duration 设置为 60 秒,然后点击 Deployments 菜单点击 Redeploy 重新部署,即可将超时时间设置为 60 秒,如果不重新部署,默认超时时间将是原来的 10 秒。注意不是删掉 vercel 项目重建,而是在当前部署好的 vercel 项目里面的 Deployments 菜单里面点 redeploy,这样才能让 Function Max Duration 的修改生效。 + +## Ubuntu 部署 + +在仓库 Releases 找到对应的二进制文件最新版本,例如名为 uni-api-linux-x86_64-0.0.99.pex 的文件。在服务器下载二进制文件并运行: + +```bash +wget https://github.com/yym68686/uni-api/releases/download/v0.0.99/uni-api-linux-x86_64-0.0.99.pex +chmod +x uni-api-linux-x86_64-0.0.99.pex +./uni-api-linux-x86_64-0.0.99.pex +``` + +## serv00 远程部署(FreeBSD 14.0) + +首先登录面板,Additional services 里面点击选项卡 Run your own applications 开启允许运行自己的程序,然后到面板 Port reservation 去随便开一个端口。 + +如果没有自己的域名,去面板 WWW websites 删掉默认给的域名,再新建一个域名 Domain 为刚才删掉的域名,点击 Advanced settings 后设置 Website type 为 Proxy 域名,Proxy port 指向你刚才开的端口,不要选中 Use HTTPS。 + +ssh 登陆到 serv00 服务器,执行下面的命令: + +```bash +git clone --depth 1 -b main --quiet https://github.com/yym68686/uni-api.git +cd uni-api +python -m venv uni-api +tmux new -A -s uni-api +source uni-api/bin/activate +export CFLAGS="-I/usr/local/include" +export CXXFLAGS="-I/usr/local/include" +export CC=gcc +export CXX=g++ +export MAX_CONCURRENCY=1 +export CPUCOUNT=1 +export MAKEFLAGS="-j1" +CMAKE_BUILD_PARALLEL_LEVEL=1 cpuset -l 0 pip install -vv -r requirements.txt +cpuset -l 0 pip install -r -vv requirements.txt +``` + +ctrl+b d 退出 tmux 等待几个小时安装完成,安装完成后执行下面的命令: + +```bash +tmux new -A -s uni-api +source uni-api/bin/activate +export CONFIG_URL=http://file_url/api.yaml +export DISABLE_DATABASE=true +# 修改端口,xxx 为端口,自行修改,对应刚刚在面板 Port reservation 开的端口 +sed -i '' 's/port=8000/port=xxx/' main.py +sed -i '' 's/reload=True/reload=False/' main.py +python main.py +``` + +使用 ctrl+b d 退出 tmux,即可让程序后台运行。此时就可以在其他聊天客户端使用 uni-api 了。curl 测试脚本: + +```bash +curl -X POST https://xxx.serv00.net/v1/chat/completions \ +-H 'Content-Type: application/json' \ +-H 'Authorization: Bearer sk-xxx' \ +-d '{"model": "gpt-4o","messages": [{"role": "user","content": "你好"}]}' +``` + +参考文档: + +https://docs.serv00.com/Python/ + +https://linux.do/t/topic/201181 + +https://linux.do/t/topic/218738 + +## Docker 本地部署 + +Start the container + +```bash +docker run --user root -p 8001:8000 --name uni-api -dit \ +-e CONFIG_URL=http://file_url/api.yaml \ # 如果已经挂载了本地配置文件,不需要设置 CONFIG_URL +-v ./api.yaml:/home/api.yaml \ # 如果已经设置 CONFIG_URL,不需要挂载配置文件 +-v ./uniapi_db:/home/data \ # 如果不想保存统计数据,不需要挂载该文件夹 +yym68686/uni-api:latest +``` + +Or if you want to use Docker Compose, here is a docker-compose.yml example: + +```yaml +services: + uni-api: + container_name: uni-api + image: yym68686/uni-api:latest + environment: + - CONFIG_URL=http://file_url/api.yaml # 如果已经挂载了本地配置文件,不需要设置 CONFIG_URL + ports: + - 8001:8000 + volumes: + - ./api.yaml:/home/api.yaml # 如果已经设置 CONFIG_URL,不需要挂载配置文件 + - ./uniapi_db:/home/data # 如果不想保存统计数据,不需要挂载该文件夹 +``` + +CONFIG_URL 就是可以自动下载远程的配置文件。比如你在某个平台不方便修改配置文件,可以把配置文件传到某个托管服务,可以提供直链给 uni-api 下载,CONFIG_URL 就是这个直链。如果使用本地挂载的配置文件,不需要设置 CONFIG_URL。CONFIG_URL 是在不方便挂载配置文件的情况下使用。 + +Run Docker Compose container in the background + +```bash +docker-compose pull +docker-compose up -d +``` + +Docker build + +```bash +docker build --no-cache -t uni-api:latest -f Dockerfile --platform linux/amd64 . +docker tag uni-api:latest yym68686/uni-api:latest +docker push yym68686/uni-api:latest +``` + +One-Click Restart Docker Image + +```bash +set -eu +docker pull yym68686/uni-api:latest +docker rm -f uni-api +docker run --user root -p 8001:8000 -dit --name uni-api \ +-e CONFIG_URL=http://file_url/api.yaml \ +-v ./api.yaml:/home/api.yaml \ +-v ./uniapi_db:/home/data \ +yym68686/uni-api:latest +docker logs -f uni-api +``` + +RESTful curl test + +```bash +curl -X POST http://127.0.0.1:8000/v1/chat/completions \ +-H "Content-Type: application/json" \ +-H "Authorization: Bearer ${API}" \ +-d '{"model": "gpt-4o","messages": [{"role": "user", "content": "Hello"}],"stream": true}' +``` + +pex linux 打包: + +```bash +VERSION=$(cat VERSION) +pex -D . -r requirements.txt \ + -c uvicorn \ + --inject-args 'main:app --host 0.0.0.0 --port 8000' \ + --platform linux_x86_64-cp-3.10.12-cp310 \ + --interpreter-constraint '==3.10.*' \ + --no-strip-pex-env \ + -o uni-api-linux-x86_64-${VERSION}.pex +``` + +macos 打包: + +```bash +VERSION=$(cat VERSION) +pex -r requirements.txt \ + -c uvicorn \ + --inject-args 'main:app --host 0.0.0.0 --port 8000' \ + -o uni-api-macos-arm64-${VERSION}.pex +``` + +## 赞助商 + +我们感谢以下赞助商的支持: + +- @PowerHunter:¥2000 +- @IM4O4: ¥100 +- @ioi:¥50 + +## 如何赞助我们 + +如果您想支持我们的项目,您可以通过以下方式赞助我们: + +1. [PayPal](https://www.paypal.me/yym68686) + +2. [USDT-TRC20](https://pb.yym68686.top/~USDT-TRC20),USDT-TRC20 钱包地址:`TLFbqSv5pDu5he43mVmK1dNx7yBMFeN7d8` + +3. [微信](https://pb.yym68686.top/~wechat) + +4. [支付宝](https://pb.yym68686.top/~alipay) + +感谢您的支持! + +## 常见问题 + +- 为什么总是出现 `Error processing request or performing moral check: 404: No matching model found` 错误? + +将 ENABLE_MODERATION 设置为 false 将修复这个问题。当 ENABLE_MODERATION 为 true 时,API 必须能够使用 text-moderation-latest 模型,如果你没有在提供商模型设置里面提供 text-moderation-latest,将会报错找不到模型。 + +- 怎么优先请求某个渠道,怎么设置渠道的优先级? + +直接在api_keys里面通过设置渠道顺序即可。不需要做其他设置,示例配置文件: + +```yaml +providers: + - provider: ai1 + base_url: https://xxx/v1/chat/completions + api: sk-xxx + + - provider: ai2 + base_url: https://xxx/v1/chat/completions + api: sk-xxx + +api_keys: + - api: sk-1234 + model: + - ai2/* + - ai1/* +``` + +这样设置则先请求 ai2,失败后请求 ai1。 + +- 各种调度算法背后的行为是怎样的?比如 fixed_priority,weighted_round_robin,lottery,random,round_robin? + +所有调度算法需要通过在配置文件的 api_keys.(api).preferences.SCHEDULING_ALGORITHM 设置为 fixed_priority,weighted_round_robin,lottery,random,round_robin 中的任意值来开启。 + +1. fixed_priority:固定优先级调度。所有请求永远执行第一个拥有用户请求的模型的渠道。报错时,会切换下一个渠道。这是默认的调度算法。 + +2. weighted_round_robin:加权轮训负载均衡,按照配置文件 api_keys.(api).model 设定的权重顺序请求拥有用户请求的模型的渠道。 + +3. lottery:抽奖轮训负载均衡,按照配置文件 api_keys.(api).model 设置的权重随机请求拥有用户请求的模型的渠道。 + +4. round_robin:轮训负载均衡,按照配置文件 api_keys.(api).model 的配置顺序请求拥有用户请求的模型的渠道。可以查看上一个问题,如何设置渠道的优先级。 + +- 应该怎么正确填写 base_url? + +除了高级配置里面所展示的一些特殊的渠道,所有 OpenAI 格式的提供商需要把 base_url 填完整,也就是说 base_url 必须以 /v1/chat/completions 结尾。如果你使用的 GitHub models,base_url 应该填写为 https://models.inference.ai.azure.com/chat/completions,而不是 Azure 的 URL。 + +对于 Azure 渠道,base_url 兼容以下几种写法:https://your-endpoint.services.ai.azure.com/models/chat/completions?api-version=2024-05-01-preview 和 https://your-endpoint.services.ai.azure.com/models/chat/completions,https://your-endpoint.openai.azure.com,推荐使用第一种写法。如果不显式指定 api-version,默认使用 2024-10-21 版本。 + +- 模型超时时间是如何确认的?渠道级别的超时设置和全局模型超时设置的优先级是什么? + +渠道级别的超时设置优先级高于全局模型超时设置。优先级顺序:渠道级别模型超时设置 > 渠道级别默认超时设置 > 全局模型超时设置 > 全局默认超时设置 > 环境变量 TIMEOUT。 + +通过调整模型超时时间,可以避免出现某些渠道请求超时报错的情况。如果你遇到 `{'error': '500', 'details': 'fetch_response_stream Read Response Timeout'}` 错误,请尝试增加模型超时时间。 + +- api_key_rate_limit 是怎么工作的?我如何给多个模型设置相同的频率限制? + +如果你想同时给 gemini-1.5-pro-latest,gemini-1.5-pro,gemini-1.5-pro-001,gemini-1.5-pro-002 这四个模型设置相同的频率限制,可以这样设置: + +```yaml +api_key_rate_limit: + gemini-1.5-pro: 1000/min +``` + +这会匹配所有含有 gemini-1.5-pro 字符串的模型。gemini-1.5-pro-latest,gemini-1.5-pro,gemini-1.5-pro-001,gemini-1.5-pro-002 这四个模型频率限制都会设置为 1000/min。api_key_rate_limit 字段配置的逻辑如下,这是一个示例配置文件: + +```yaml +api_key_rate_limit: + gemini-1.5-pro: 1000/min + gemini-1.5-pro-002: 500/min +``` + +此时如果有一个使用模型 gemini-1.5-pro-002 的请求。 + +首先,uni-api 会尝试精确匹配 api_key_rate_limit 的模型。如果刚好设置了 gemini-1.5-pro-002 的频率限制,则 gemini-1.5-pro-002 的频率限制则为 500/min,如果此时请求的模型不是 gemini-1.5-pro-002,而是 gemini-1.5-pro-latest,由于 api_key_rate_limit 没有设置 gemini-1.5-pro-latest 的频率限制,因此会寻找有没有前缀和 gemini-1.5-pro-latest 相同的模型被设置了,因此 gemini-1.5-pro-latest 的频率限制会被设置为 1000/min。 + +- 我想设置渠道1和渠道2为随机轮训,uni-api 在渠道1和渠道2请求失败后才自动重试渠道3,怎么设置? + +uni-api 支持将 api key 本身作为渠道,可以通过这一特性对渠道进行分组管理。 + +```yaml +api_keys: + - api: sk-xxx1 + model: + - sk-xxx2/* # 渠道 1 2 采用随机轮训,失败后请求渠道3 + - aws/* # 渠道3 + preferences: + SCHEDULING_ALGORITHM: fixed_priority # 表示始终优先请求 api key:sk-xxx2 里面的渠道 1 2,失败后自动请求渠道 3 + + - api: sk-xxx2 + model: + - anthropic/claude-3-7-sonnet # 渠道1 + - openrouter/claude-3-7-sonnet # 渠道2 + preferences: + SCHEDULING_ALGORITHM: random # 渠道 1 2 采用随机轮训 +``` + +## ⭐ Star 历史 + + + Star History Chart + \ No newline at end of file diff --git a/uni-api/data.yml b/uni-api/data.yml new file mode 100644 index 000000000..461ac09b8 --- /dev/null +++ b/uni-api/data.yml @@ -0,0 +1,19 @@ +name: uni-api +tags: + - AI / 大模型 +title: 统一管理大模型 API 的项目,可以通过一个统一的API 接口调用多种不同提供商的服务,统一转换为 OpenAI 格式。 +description: 如果个人使用的话,one/new-api 过于复杂,有很多个人不需要使用的商用功能,如果你不想要复杂的前端界面,又想要支持的模型多一点,可以试试 uni-api。这是一个统一管理大模型 API 的项目,可以通过一个统一的API 接口调用多种不同提供商的服务,统一转换为 OpenAI 格式,支持负载均衡。目前支持的后端服务有:OpenAI、Anthropic、Gemini、Vertex、Azure、xai、Cohere、Groq、Cloudflare、OpenRouter 等。 +additionalProperties: + key: uni-api + name: uni api + tags: + - AI + shortDescZh: 这是一个统一管理大模型 API 的项目,可以通过一个统一的API 接口调用多种不同提供商的服务,统一转换为 OpenAI 格式,支持负载均衡。目前支持的后端服务有:OpenAI、Anthropic、Gemini、Vertex、Azure、xai、Cohere、Groq、Cloudflare、OpenRouter 等。 + shortDescEn: This is a project that unifies the management of LLM APIs. It can call multiple backend services through a unified API interface, convert them to the OpenAI format uniformly, and support load balancing. + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://github.com/yym68686/uni-api + github: https://github.com/yym68686/uni-api + document: https://github.com/yym68686/uni-api/blob/main/README_CN.md diff --git a/uni-api/latest/data.yml b/uni-api/latest/data.yml new file mode 100644 index 000000000..a030dceae --- /dev/null +++ b/uni-api/latest/data.yml @@ -0,0 +1,35 @@ +additionalProperties: + formFields: + - default: "" + edit: true + envKey: CONFIG_URL + labelEn: CONFIG_URL + labelZh: 远程配置文件地址(若配置,则首先拉取远程配置到本地) + required: false + rule: paramCommon + type: text + - default: "./api.yaml" + edit: true + envKey: LOCAL_CONFIG_PATH + labelEn: local config file path + labelZh: 本地配置文件地址 + required: true + rule: paramCommon + type: text + - default: "./data" + edit: true + envKey: DATA_PATH + labelEn: uni-api data path + labelZh: uni-api数据存储路径 + required: true + rule: paramCommon + type: text + - default: 48000 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + diff --git a/uni-api/latest/docker-compose.yml b/uni-api/latest/docker-compose.yml new file mode 100644 index 000000000..6b922efbe --- /dev/null +++ b/uni-api/latest/docker-compose.yml @@ -0,0 +1,21 @@ +services: + uni-api: + image: yym68686/uni-api:latest + container_name: ${CONTAINER_NAME} + restart: always + ports: + - ${PANEL_APP_PORT_HTTP}:8000 + volumes: + - "${DATA_PATH}:/home/data" + - "${LOCAL_CONFIG_PATH}:/home/api.yaml" + environment: + - CONFIG_URL=${CONFIG_URL} + networks: + - 1panel-network + labels: + createdBy: "Apps" + + +networks: + 1panel-network: + external: true diff --git a/uni-api/logo.png b/uni-api/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..54a5336357ae91659ba3f8ab5a0394889cf1670d GIT binary patch literal 43853 zcmeFa`9IX}_douaY1AMYOSCBSEM;lYPT8hXRJM>U(V}E2d$MF^+GwR!*%J|>>_j9* z8zuXmEFnwweZJ>s)6)_j4YP=M^mt6&|idTo{J&>`_(L z#xN56lZ26H!~fBjthxaIM{v+q*@49th_qrD72Bh{UH7cXuNuw=_nIDxk4aSs9=DS; zz7j7%Rwf^%5S|{rLOsGa_ce$1ipytis}+XH)%j|qZ@jq2xoBAN<+pF&-j^%K@N04I zH@mgVa9+O9GJY+Zme71Vg1**W^(P;5H%a9`jT#Jats5LJaq8d9-Q^NAI#J_YR?@-> z*ml66-V{{H!$|blQ(6X<4>(?7v}JqoE_@^-aBupyn*A-FOL%DE!kGw_~p^g z8}meDzjVVtB9_RXeg69Og*oj@wmC+2KHBNoCL({f`|eK9d4cw@GzT^l7TIba)}4QA zIftmn(2>_)AFCXzNogQcs5Az~tmYIH5)ulq{~*cX)K>g-Ecmfgd+D0UgDIU~UHjY4 z8Dx2k^R|~nJBOKMx_Y*k#nB@@#z*F~l|&DET$s%>P!_FkW18vOU;9))uGYW5y{t|r z<#dfc{4gsTR>-xLK6`m8=OSlZW31&W0jib`GskajeLsn;Yg#{0Ws}u&fmboL0siNt zLwz<=s4I&#aS8s%@#eC%CiLxO&EIj6fs-^*(c$vw0Q? zZn7w9RQ>VphLY@$>lYxqk!?pJVK+ILB3#!O%fxo>lg=!*Voi+eXAai7b=1M(_q$$=c5-xO^cEP}yc$07 zM!{{M*hwJx4Z*;VeZJQ{T9Y{M)vH(M1v`}*j{0x1=xJVP9`L)TH6r*GP@!2@{`|-r z@wMqcL&JaMc`J!ThtA(g-9;oa1bK8;C5f*)U7b22ozb1+G&!|x{ z4k~W*7#q6qzEwG#)F4U4yjqNP=O1In$HzC%;a&QRRqNJuD8ad_b^vbFEPSS`_FU;l z=`3UEcgI)V_;ZE&dUtb4RX0d*L9$KVD-)Zn@iP%JwP%0a);Do!`h?iFM?+X@1?USdcPi%+&bjR@Ly4m4%-TiLUlWaZ^R{=2VIl6(@YR#^>B zjCS#!YYB9A&G`LpaR+RCulG!6bp>@rhsA|Ilv^^JKl_Wyvc`H%6-Iw0$ZWPKG8?vt z2;A~GBg0)M%D+^EDMcn@QH-XqeVo@9ZfxGy1=4;Fv_5VLQgEw$)mOByC1YZw{q*2B z8OtSn$UF!{0#|@T!B!O{#t0 za1g1^!8(_gz}lD2U7g(x*QA9qf#llmIZj-g_OW?zQOb6p!d!GXNBGtA2*ZREi~TlP z#1DbS1UI;mb|~;18CZjn9Xhu=DOeUq-a;zq18g)-a%d@Nmd@V=u3n}2agZ>Jpwl6lHFkMRgkOyhRHbCX{Y-&<`js{{ z>HVK(&6!7vdUOi6C*%#RNnkNrU(%i0Qwo$=V>eph^2gNuw`8`&zU-{L_t{EeCsh(8 zAEvf9FnE=gk&$c3t8=5fL2qB0wG;$C3!+a9>)e`T9T;h3Z1xIYJLTWpgPsbLui`J-6z{^QJ|qN0YBIuEyEtGLWktI>fD;jDp5E2roTFJatI z;U+J8B|EJp$Sw8w$NSO&Zk=iS{I{IimKGX%lyehtk01pTv$G_WxsP_F=zAQbS9I3A zbURg*+|f|;(s`7a#VEW`$~n2$u#kk5)V3nHrm){;tK`JU$jC7;K$H7ji+-tuq{9W< zKDZpJCB3`8@Z0y#GIbfp20LrUlTX)F7OB%~f1Xli3z9@F=Rp3EB zy>%PxbXq%0k=IE4kAdzA*>h*5N>%cy(VR=dCPM~yR;o|vySNNLN$h*#ZN_!>@x4!J z;h}B*r_)=d2YyvJv=4Mt$${l(9+C1ZBK;-h2RYHY!k+%|{+cq-OLdoe=A4No{LD%U z1uMSnn(cP~-o4FrU?hX4uC3urkYxJVx>x544rjM)Z%6JOUFQpF(Pm4>#6vI7NEA9apI4#Nn{a~ z5KsiSgNY|!G=M@6DBUiZ(m$x zf_Y&bV#?qXb$`Fv1&_}Cv2+6Q7ALMMLTijxua%M-$%9BHzU*N6j_q7z?7WEECUx(n z3h8ErK?-$MU?)isc&ZnEjj^2ncL$Q<8r#-z-&g2)9{9%2fK3+KmnqCPA8NJ6zdA@4B+%-ro+kL$!I}i(5y*D$<}FEAkuvWa$Om832AB5h5k8${QE$r ztMmB1Ly`F(0n7h^oW2LBhJ~Pal1Sj|aIAg#EB+iX9$pGlVn+9SqdRzFq2bYWk%5Tr~?nB zfrM9K0`Y}6WNL>Bt5R%4)6R5M_6lgnZ}_X$l%cyc@B^k674c2Qb41;{XPV`4&KCvryJCZ(Xa4e^q__%&F?#unV|klRhjN5HO!n_z zAGkji_)jxueYWxFjrTS67-rQaTIgggkvkJ0Byl16FZHD5TEh{us*d$kp9in@T zx0@<0R{ODNJb{5xv)|bMxFIvq0RH}^3uGRjiPokc|FZ79(9iN0KTz7%H-T>ca{EqF zc?L!ec~ocraZL)kIK4ktKr>Ovww^`{w7NIt?#DP#j2j-u7E8YxYM{SDiQXfD%Wx=T ztM?MQ&l$!7n2$#ChNWjfX%ENlWk=^lNHt%H#CZ`JeQ zOgNXCYze1#SecGiK&GY-0VCZZ!KHTNl=T)O|DE2K^lNw#2OY%kur4n@(2`o%CIMNQz~Y?Y&A$s(E)(tW(4C z`Wr{wPw*M8fUG}r^r3msa3v&zi&T;$FR>jd?v=?qLO|Euq_f6)>IxpL|1m&aG%s=w zfp+z>f@|N;gU-Loe_yz_NSTIs2LgV%3GUJ4&yRHc-L9$zP z*S+&pTs0>dvp4roxtDiivGWJfiEht5i?>*(9)SSP)0_O_#+2h#lV}hN2AzL?`Tkw{ zTuSPX$;c%lO67xAQ&9l$f)0H~f2D=0z@D4;dQReXwOoR0#|GLh!>cTh6aJ zi1|GK%DZ^WFH@OQm7824r%~tEOSk{4(iGJzG@zr-qAa#1to2(2>-b(Hu23EVZO1$L z6Q3SPBei6uLs``c{Mndt@ss+)znW1b^(EEr$79op9$$T9_up^nTkRThmBNw=H}yB& zFe5&3>HRE2w}C_JARKmZa7yT3`Ma1*68nHz`(X6sVo-dlBSvgvUYsFL!c22GI!43TCOtj6RBbx z)PmAikGSkz_V-vuHYdlnGrv+>dOk|C>Oi%|IiH+G3pab8|KL3qcj)E7Ww>R@HA9OJ z|4dm%(<2I-oc;c&AW%-}mp(DR;X~C7Z?a=+(JG~}?l%u~!{<&> zBC@V#h(_SHds+P5jVRd)gn(Cfz-E5jRc*+R!cS~2OK-Y=@KvTuZ?mZ4aO0g&ipFBEa%+m-tC+D5?%Z#_DzO2(#E{`6*_v>?L>w=&zXFmf9^oA-e?bjrN1XJ{L~cxK&4nQxuG7`0{8Z$AYiM5V+^3@; zf;FC82Rb#5LO=abntfCF*2H}UM|61j;nD2Z7v6rPr+;KDC{S-$)F&~RmvRaPeCir61D=Gb_>R_k)KggR-RrbAs!mTi1qj|wP zT8S_P)2)j=oXsFO_^viAVvP^hwHVA&k^TcGpmo{rNg8q;iI3mDecRje+248meNcZ_ zo^bcOBtP-Tbk+p7u(U~aOa1E$CC0BmPE|Nsh!nBEtz^~DZxMx|!@Vto&px!vkE(!O z&ezNVU)&aJoM!($=MuNu5(U@9t8oLeQ{5lASUKeR^XDN@`s|BKYxaAEKpx{eNju!0 zVIf=sqH<@f-*i-^D2<4AO}OcPKfZJ-%^1^*V`QM?Wd>MfnL0A&+y8%Hy?85v8xoSoEd>8q;bz?0!8lf^Bmk6!-Y8?mrs>@ zzAp{%JH5n{Uw4pwI8w2CG1Yrny;(=!UcK%;Zf@r{wV=S5MwG}gCkAlecSwU#m?w+{ zG};cdm)X3By;oL&2B?@|eQ$+DPziG%-LVdZ= zq50Fo`yuhY+EFs8!AF-ObTm(tKK2CQhS9qjYS}BNa*RrON&}~*lmY02=mW5fXSdb{ zbiXBGd2_ojgSA)<_cWz+RU|}cWN=L3Q zSl`eBiO5J7c=?zvTU^)waFW);;U{C`@%&)QY1RfPBf7-1{QaD%n1qDHg01$AgJm&> zy^kSP4>EDkUNwECG07<9^tcIFr^g0J--GkQpHxOIAHwSIA3U9QswUmZ8P%hoDi@tU zHsxuMvk{%6Vx9%lMe&5%u{cXDSCl->Jn8?!6RB$Q;M^fm`iqut|;wA~ilKDTY z(|T9w8{54-1z=8Z^vm5vroz^kmY!beX~^w1>ctwnSQL3idQ24sMK+D?Cm|?&f!bYN zoWAXxCTSsd_x}B$k+I%FY14SK_xD;CKfO84IO~;(V9}Z;_U~6HNJ&X4lGP>iu@JCl z?}A_@)~ZK52eYOLPD|@c7M+#XTo_D0bW-Rw2e$L_+=rm~p$F^0$JV>@cG$N2PBo`I z0fZRe9BBP!{sHns6;Cn2V*h%+<-5lm-(HDN4U{1z3q-(C;42)eoLVo9$8NmQ$6#GTWk}CtN?=m2~#37gWY< zt4^i#p9NrgsR6*PyZ)JbzZ;S}C~}(*UTsvoH-aH_fCsADc>C6( z@FjQTR^I!IRDeUI#gZV$OnL>`ewiBbEwKY$Z_=OgVzcKiSm#`u;WDd%@oe_AYk5Uv z_m`O}*+76O%S%W<8MW65TW4MV-1NkThjO)WJDt$)@lz`TKyvrvImz>|u*O(Cskt$J zVBl^gu71M<&>*0{LZRr}Hu-Z?vkC^ykqG+i5oc8vTbBju=drLR>bIffJp#?bqO}CY zzMYzoe{uYNq{sQkN^r5|9;*MaD$afQ8q{9hD0zFESsGR9`vD6H3o}z+c_%GCYC+Jn zfI=XySg}GAuCUhPj_M(7-N`Q@bs%Z;Tu)Jt2g!!5o>SF<)I+uXAQ>Tuf>hnTwoY5z_WLE_rEL`nEt*d>0!Qv7Zu0fR4u5*E z{v6~wz1buE?bnJnh@6{ly&as6zsl`2LBOXGU>I5%y(~RYM*!<Y9q=jM`S|qI`(Kp!0^sLkzyd~7@Y;%h zRI|~)1)3ZGfOAcEM&;OTuh)TSa%LwOZsNcnw872$g!U+NT6AOIdv$G1Ygt%-#wLCq-8!~rW~ru z*cU(zZ-76y63!p~x^kMZ#Z*Jg3xoVYi%JzcSL7*T3!qV11HWJT;~?vY$K7I;DI_!3 zaY(VGvO~6CSc&5evfR1bFo`v5GCfM74)B8e3bza3E16PZ0r^L`0Y*Dv1BvzNsL03% zi}kM<%)y}epBQg=doAwjs-W~~L4uK;M}(&yM}IfGHN6?FYCVe)cdo-q$zO>+F*w*! zC0w=W$2MK3=?-Xu14or1lqj(}Z0MsG#=1OumK+;yb_KtBiq0CXlScJ&nz+qtfoV2H zqb?-|ZgX<&_-Hy||NA1Rz?Qtnp{$r?_X)^*vhu6b9Ok^^*{3jlQN0-vfzts{pL_J1 z6*i659TUdz5&;sqU-|$-9lhXwtlWE=@W{ow_1u7}F`+Z%(GEfSWyBM!UBe^g92lTA z<^5j~PZKC5 z@-_|nxLnXl?UUwJ9IAJY?#mHT6!FLE{p-e>k7u#QyL_LSX1y|;H=49*`qKPsw7i>3 zoaw_KO*@C%O<5xq8P;cSs~;7>kPmH!5^i=LVHeMIZcw?H%vo~^{2;&gktmI7UG##C z;aDRiRyt4$+Zm}Z?s1)}mlP^RmiIBj8v=Qc0H#|BVKIxO_AZuyrpixT2T8_^1zzf-WjBI5V7^j&QdKZd~dHxQ{s>!4Hp@IP0;)WP>>fWMo_0UE_KT$`mwWPtn>H<=d%92q`c z>M@;#A;}!Gp-q1d>i0Ljhg523F~C1tL0-5OHG*#R)WnQWw_n;RZsRi*$4AqlEu95@ z+T)5=@7*w{2N+wyp}$lNR7xdNS*RH#cp@7HmAB7Ob{%BkCIR^j3sr z&Nv}}WRzr?lm&_T1=R4}H5|1njz9yciUxw0(C;Y;I5%U3F~`VY7pr`1xHs;j{y7(J z3^g)PMA!&X%fslEUjpxROYn-OLF=xzt0cP22Qm|m;mGwi1V$Ch{rb11(-`C<#&q}K zqDm98e|~+u@4mFDVqORR_RU8|(?mrr!}}tL_ca+g4X~!0zOJtPt!M?Qvd=Eq zI@|he&t}MqR{N?OOpnrJF~h^C$ZCP7^1cdMyXet$aKJdGAT6iW9E%*>vX$8rBn%UUUZ_&okhyV@@^(O+6`!a0_J!!>1 zJwk8dsy_SU2CJ|B0p6=u|ITesp||*br7Ke`TCLKxskcS z@-98UB;0PuV+&B_3}rEoSG=m#v?zx$eMl(Zw}E`WOr^phj6j3-Z|{LGRLdiH~e9djw{1Ci8MFk@tf5@Mc5N;Hd&xD(fi6H^YqA*ynTpJYJDLYZ1u&Uv z+c#MXfTh&M7CbT8IVH11+|WIA80Oou+#zbd(&^V164aH$P=b7a{wh6Vy+HNMX;3Cy zEHWMM>7WLae^geyA0fLVrLNWiQlo38kn*ROR1{lHS8$9O#f|1nJm>H%Dn^jMiC&4m ze!BpI7ShbYX&ygN^JzvB!JvI6LB*i02(VLCRQlc|A_KaBrw%4r9{3n_x_K&SjSdSr zK?J0x>J@;gdIt`Le?V2R#cxO?g*#!UM&p1?ulx+rYi(qPhK4SO$(>&ZpA2qHd(Lb|N8MnU-a;^=%c#f z2ovgy0tfS~uY+~qpMllWiSg14>4_tNm#Ozd;{)-B()JRvA<{%&lGsnEn=b=ul2mxcu5h{wBM{U0AWr7JgOKB#f2KcX7DKKx^+yh1 zwKnG_hFdg0|L2m_#@qW8f7WHu+X0NU(%&LywgkHlz`6=*GzC|zZd*80YX^zTRc?-n zqUU?I$Q@sT^>tJ^S0LoqEFsc-rczXM_W>$8j8M@N2|A?&8YCWdF#qx6;eYRq&^9ZW zP&7ZDprc2~hAMV9f{q}KnrD{qp$R+;m z*z^J%CLv9kkoRc@0$iysUbQ(I3jsLsp#C$Xk~Xtz!_G5rn}w@fGN@dscvb&oVBp{u zvOWjX9BskY>sf#1lKwc?M*aHGYiqZa1KwK-EfP5;o0dDXG1PN-4dt4LUtLef^fHb_ zHd|%;OlCckl_s?B*zx1XJ5Ce^jTg7aWpxg+ zqN6%zxCkF}CYlDzhcY@ATG4fm8P7Bq;M98}>OJMltmI}=?}zJi72pyRiC~co!mQ>3 zm^Y$r9_-sN`xB#016qtu%@mWaP6%K?(lI8PBe%g8p`o@V z02cZqJW1=bLgw^t1(}kcfFnxCKg2+l@{841nm0ZV2S>J96otKaiT!qFhNq(OaO{Qx z*0LyUk4`)n2JNZKrU*_?DYMm_-Yo*P=vi(1hDWA)y!#C=eIsZ+K#^C}R(@MixVds# z+YCAXM>NRA{M1%D8~_uXuW$UK1r3}=Ty}HaI#a>SnW%T!9}(ml^>flXRF=A!tN^j=-X?;^yZI5%hVL#=>;W$=)(WA z=H;LODvWztW@8AiaDoui()@H~)%5g=K;+~8R~?-pR)Y`gr^6Ud)+qGl%dVZZ`8d-b zyYQ#Nw9dS9z5aFb#~}Tlqg2}?U`jMFGTIgibC`NTZ7+CcvU52T93BsNvYuZ**iNGr zISrr3nQJBoV*e$paSxu3z%XDXulHiim_FX0025B5CGsUl7td5&6&zMs4t4Mn$7(DD ziY0$2s61S54kXVAQ&b;u=28V$`2;{s&gAi6fLV3Fg8`p{4?1g-XQZhldof7jJ!NF9 z%WVhDi440R?@BVkdDYTk(4npQq|L|a)dga>>|nJ6Zyn6oM%)lpny_uUPoG$Yfw)>X zLOyfJCF;$VnIgT(f#xfm8*;B)Q{=;{9lxp5d$VWpj;+pfI~X**-lgQ<$yS%C>ANsz z>DhWwB|cP6Ircy#KmA#U=YOeRy$(ut$&DvIE$F|3g+KfWE=L9^DJm`ts1gV~TM9aSSO#01(3LjPn+o+G^SVBp1!V44$sd zNP90%WSscyx1=)DEk%j&AmX3$897;_Q3#+Bo{$zF>MF$ZF^?vIkjq3ATsM`u9h?E` z04HcijvRRn)na-z^mH_Z^g3Oj@p51N;fAIl`3{@^Q4vjI3N$ZH={!-BWJzGD5F%K= zU(XR8^9UM9{vSORXD+tM_}zl4$U1jHZ0@2>KV=ZIc`G9G)Xd})6cxs5z9Glm?@h#! zZqroT?<#cRFEgM4s?Sm;q_(jJ2ndItLVMN55XO#^YeuI}Sf=3}(LZR#o>71);x>51WOQDB@Fox#(PK7{&_XfVB zdHmN?#z=8p3)_beX;mY#(Zd8=G_kxAFgwY>HEq+zMBwhIF#4Gj2QG&W4rQ#_Ty|!>bmVde zf5h7U9VL}bk35%-*tA;j*PqEZ^i=;lM95BmxZvmi*ak^+B4=WJv=E?S50+zcxkvk26YQZ3ubJMah1<0XqB()692ig^XoUuH#?EaAi|5a9c4!*vw8SqcgOgFA zn>(}E48tR66*ol8u^!ZA)il4BK6Nk(u@Oxf>2t~baZ)+|u?c`CHbTjOly{*)zwm@z zhh}I8wHPl9KL@TuX%OP4Nj+{+s6s-f?lGj-?^k*ftS)7Z|Nz9WrFR3uRHLz1S$ zM@P8HSWZw@=QMnXN`avg>V?wj&6JC4V65M5B7IuVl1YQvVdh*T|7mQZB*S>>ui^IT zv4O}(!AKiUo|+bsXyq_$^SmX_ZQ2#d$}r^i{}cO{v(&xJhK2?uY5ie3z_$9Yq2;Rd z;w|7OTvDvONgqz(1+mFDhj8Jnq_{D?>-xOmb+P(#tlsRBH^lnKDjs7$M1z0r|5GwG zYSA#CoyPm{tc;XljUbCLAE(bs&34D!^40Nx*kf9$nMb?d_Fmh)E!JDVi8QX`yIMSYf|Z3 zrPLD~CmK9E-!~CQwyBPAji2H)7QS2k0;YS`Fzaml2TkJ8HNwqhxM#?J1`3w)N{_9J zSNI~I$*^`Xaz*$qA?2dwaKLc0Xh;vP)ign3(s;8enetZf8QV80n!?oiMLbe4vpITx zU!qs=j~>mo4wq+_5K(KXSY-M`efBSOIdwg%=*P(vUr|%81-^SCalcXoFS)2zDfhEO zZ4{N_>pekFH#6ljxb%s|}lQetw7egDkLTmIV$V=mF?zeZoU8eN1m|mWg!o?7h?K>pRqiBl7oE>GBd1Zf*a$vixI@#5hq+y?4-e7 zHh5k#U$w!X^}%F(1*1))x*gvk+Z@Q$;J}4Xrco_K$605^hzx9Agb)%kyqbXqYpd9! z4#hWV+BU3n#E>%u*AC&2GvRSxfu1>ArIs_pYTbeLPkov%28xL+9iNVDux-M$!Mk#c-3OAm+EX?? zg`G)U#J)LtH;b6QhJABgqQ$H6xJ~?+vXgcU+bX%ZKxYWJ;8Y`Nm33pFa<1#{;nTD) z=7Y%2Y~o^1mj_Gxlmgq6t%9*`Q}zlk4Y*%m_&qj>wWJ-XY$>+Y9pEQ70o%30k9|LaeonR3CJ?gsT#;udCJoCe zMgDXG&AlLSFFK661h#hkv|kwgl;TB`K)N3AinPw>0{gi9YoL@xr7?Xtc4UkTV;9{U`f=?`1BN#4 zDDh(}>JAif&a15y_|UKBhF5Ss(S_Hw0%qY{pd4dTz}J-94b5jP5Y-6B+1db#ab@wt z^SIRtGQS`*rry01tBIE6`@-I)MFZ@M9}pyuBeuSs^}~+MR(=A3v7B8k9F?daV0rKS zy$V||AAryDL+_f5@yl(ygqx8ON5(L#@I4n+izq0ucJ11HvkinZ6T@r3MRBsX41|ks z+qa5+mL+%UxRPQZ7E-D5fg4wTh`6NVFY-TPlivlv=CM6x!W*~Q@G>oz2opa`A~C9*xF-A3)uFNphLS)?GoCKFCk3fJ?aC%g8lLb!C zREN{JXVT#`TBJByFUM5#M4a#|{08&LJvJ{2Sv3+y@QOni{oOWXbxbliQE$q|YvCl!km|z5RHh}pA==r(tfoN`GS<`1 zZd$0O00}j{B}XJzGyN!4J5_y#Hug3Ts$t4v{hDUxiDs2;7Wn zm$eh#zhPf7fomTp`b@%pe7)_IAfU0V{xiK}2_J#hQBj3|mZC@;me;8{;dcQI`AN?W zIbfiHX>qLfW}6de_H5idX#La}a!8y?Q}Hxhz9dNB4| zSWiJm!Yl*)P>^FrBI{aVnBYXhHuv^gvTqmzw&}w5B*FaM%}R>!RTxUJVI(eq+tP5u ziMdX=Pnfg;tLFh&$n3KwxL%MHR{#xSY#P>se1ABJkg(r=o|foO)C#zQS)nF;@&pv} z1zf>vyHzSIzsxYf&5CprG6>mu=rOHc6D@ZZgysHMuHwtnV0mMKM$;q*WWYjpr{2Y= zJJj~!@x2?K*L!0ax=Ey9_gB{0pjl9~wuDNdzoryT)=9u#{-8lMBjN~VEsa{ zIG^iVpW+sE8!`yhcLBP1q6Mr^pz~d5J_+vQ=3#d0fc>ue%O|iEAS6|+#!rxp2N*uZ z%f$u|oEPgl`y~cG2=U$vHhF&J#O%GS@EAo#`Dk_iW^gpj=b)P6Rufb1YXgL3v^>TK z9K5u${Xz436M^rVUvSKwNrmva{kkC@4YefeAG6-efmJnrR(p%H3vynXyZPe{hzYQ~ zgMRUWi}7B}N5%ReF19vs%TGmL%tlOrr}l-wr?do}|4m?)K~^BT{^U|$0j!a)N)K)B z;|iO%sl;rD%`dKjm-~!;-kas@R<#`@GDy6dtvCU4@S9(|L#a3c+Hk~OzhP5&YnJXH zhdWDGAfPqySpn=v$$;G9y%JKiLajOYYEeY~iAVhSYJ=?H@oNhbh3*UdTOCl7;Mc`B z^-w8JJ_x&SYlaH!KjS(|9aQET?E}tRa@OL_EuX!xy;NS5Bz^%<3WZ)_EX@4=Hrzxj z!6Oz=%++NZ93GTT%mt^LdziczkCw%d8ftIcdjokiS~$adBBC7}V$o*J$yxzoj%8V0 zCw>vO&o~wjl3RH}3->u;J3z&*uD8T1sp^S{-np=Nt3HmP(mG&o%e_()apRaAhMpTfPveiSvdH=0;+!rQI9B{ z!EH!w5${_Sft!wn`p)Q7AEY`Sne2x8q|(2$2BrTrJ5&V8Lls4}uRnCyc4s>pJTc6T z6)7ECg3EOR^l~^MSpW|QtAV#izbsfQj(L68x{LehD-f~8&Ny<31MkYg+q`*@^*4m| zfH%$ePB?^{H#^*3ABJ%IfLGN8r%eKA3w;-Efat)zjcoxFqXrnZ;}&NR7MGv-V#(xk z6wOy2hGsiV z{gYOC8GuFPhHxI#fH%gOlKAZIQ2=|r`p*giAclJzPX*S8P7bU9rTTF8l-iieX1rQA zF#bQy88M#Tf-+HjEp;m1LL-4pm($eV^D7d3Zg025Oa7zaN4?%I5X6)2JWxpIrHT+C zWx0_|Y1C~XRLA>zs13m+qxi^p5V`_NtVK`s(DRT|P}d|yA_vl4$Z_GVERKh2v&l>) zC|gBlBl4-!avUD8_%h0ukDR*OLpB&c9WzXKY*k^IH?c;4u(G69|G@JKRUgoW?QgWD z;0{HrA+7L>h)xmXye_KrDx@b%MG5WdqX?9ZoQPTuXNaN9XNA4>RgD+4E8;yEfOA zXnvK*NL14n1#(qGz!izxp4_{#Ta>;{i(J0|G4~<-z^p(WK{%=z5TbIuwPq2xbtjw{ zA1K*4&MdYMh=_4{dLM{*$_MuBx8G7si(oo;!O!|6bp|aI*needa08-14N~Oy0sc{( z?nc>hM7)Mky$_5u?A1mig8b5x(SX0s6Ot~8p`X&kp#zvWs!84>pn{D!(4;`h5l654 zQM=6v!9?2yh*KiKDf<)Q+K5vo5bqG7B*o?RI_%o_Hn;}Wf*4(}1bAT@DgpfY%~j|* za;sBfH9Sup*Bm2nrqy30PAp@*0lj0If%)EEFMa@-?{Cmi0i_*06xl}%(^9K~HJ{uu@i20s&9!I?!7EkLT z0}YmjG)(K`tmkN8vuG{EWQ*YE6Xdb|P(g_ySxmqNLxrlB&;~I`7B@A%lcH8b4Zh(a z`pguy3x1GsrwXaVcjTbVOShri4&|>DIuJN!9<~D!h~nw8yeB7#C16In{sjm$@R5NZ z)JC2HFUz!@%tX~>d5~wUBj6Prl>pn5=I%k?ZBX@t^TX8DGD((e>kF~c>MvaI*Zd@q zWm!%sa?Xc|wPSO(*mm#_-GTIUKhni9(1hQ?x46)05(LvR-$*;j`!q2kym>4gIhQqt z43w6Ee#B1U;72K}D~o)Oaw-G3?sdIr2Rh>^oDq>Bgw8NP0l+WiG^hLO`X8(U1j$a7 zV>wEi#=Qhpsp9ZMha5{}xsA%8t^#`3kRVqhABxtCKo!9@xG8Fss|PjkF}X#T_~1+# z)+8pr47{kahUIqH>f#EBPcbg-_t_@LvG4wBCXS16B3(7p`hYyGF?f?arwwh(d=A2G z()yFO0hRXP(ef`vp($*N7jO~>4)gfBKeKKk?BF)4N@_ppqSVfSJQ<}8ibKf=R)I6K zYR>>nNz(;+M2bBFY?GM{7J+kHc6WA1)(_+g%^;7sy;bG_)V3jdP?*IX@bDLiJOD%_ zeXv0hqgWNxZMmZKO4#ZF06)^7(%SvtqPS1L4gOwrU`!V>Yi0)Uu~06JhckCK;>bp> zOCYHbBRJjig$p0hn=>DL57gO9Q4-7U-4($NCle}W2IyiTcY-=O7b)KAyif@^U3U+h zzG5vekViE}atO>U00-!dl+|Y*=;F5KNQ9p?8pD|m8rHLjF9adMo@|vwfnG-n`3plb z3Q|mA9r=7Pg>-YigruaTLA)8KAS|4Q)Z4ECwjs@=Xu_|52V9GSW3&#zF-}bxXxNI0 z?8WR$rI@VA@0`;>k!FGfo=BtUcVfr0vsaQG4~z%1Y< zIKodw$}F2uDha=f=LgR`|Bfd)49Q?Jc^w0XQ@;+G9RPH2G=;-uxadi%>#wnhOJBj4?xvPEnp|ufSh$)*CLyRV`;pZ{ zj2Qx)+wN`J3lw(01hobHx_ZJ>{#>R2l@bbGBKK)KO2_E@z}1^XrY(AkgFTd3c#7YW zK;(EeRQL~-@&rVKbDj*K9u7*8b%9YK7s|FU&z~oXjyumqUKG`%$V_0{)2u*H8^mnK z?n)3O?KozvrDb~;|AyRD*8o36Xv{_MF=Xd~ZQ}6N8qoJyOEQu<$MQaVSJCrus0p$W zcH^C_1*rmutm7Ji?&i9MARLU4MPz&6|4Y@$29Qoo@=X)SKD)7OJ)m+xHQx0Pfh?n5 z1gSIyv>)%z-&_uyW&_lJ?yEeh;-sQyTR16z6?SCxqQi-z+(RTr0{jyPIp?f1Tf;BQ zWK_{r@azme6^0a%$OqQxv)$?r4nxTafl#QnF$f(&od?x4hV;a~VMdZlJqZGX+#>Y2 z+X8`=D7p%wi2K_%X?MLCfM8u-NU0_PM;Z;;)S_g)zcz(2e{cdt4rt|F5P)Xu;iO$u zZn)Yc>O=t7$4;tMvp}w`!7t`<1^|4Wm4K&^;((~gE=E*6Le-aTq|q{;OYpltt3eWM zUaCfbnL8F7&?m+7O}dsnTfALy%$W#HI1&;P)#o&v+!_?uNuGMfU;LT69d017X>~Y1 zB-X;LU2N>Njdqn3e_y?WmqMX8-|$MqstZ<8ChgMKabIfXMH zP(tl3S{?BGKJxs{&kh1@U>3mJ$SdF$SGt<)144|zb7u+tKBXRVA8fFUjcmbps-Pm; zCVLzl1-N)vbp#d5&DBmQ8I}O=vtPmpX_yOSw!!AMReWBz(Col#7;-qOdrKP>i1zQt zJmJ8}$VWvv=A~cPthq-_YfEfHL@K-8$$n%%Ob%EkZ7ekrq zV$g^w8Cy0xNd)d>kMJMg^wO0S8`$eljzWSR_@9KKSCPj&L5Xe>rZ^fJ6+s1e{Yt^t z(dL0Tw&o^nVlLo@d;a(?fk16e&=WE1!yi_lC|EZ(8AZJ(JQe6Q$b(KqT=ql z=i^O4u$V5W&zIMd{!r5azwsbC8F^?_Vc5<%(&!El$v5eLACmPGp*v$I{KpuoKkDLN z?-Wymjqp;D*$o?g|7@Ih1oV}cJsm__3pY1|s-;8)`%DtU#|KMlwOG5OPU90@oDSvaSi`aYumEi#%#+ z;AA0lBHJ`?o2LV}oCM~2Bq7;~NX`T{XsHwEv!5gM6&j(nW8#xJ+TZaI^3IT+LQKzt zAJsOk2#>_gA1Yjb@cgF*_M?*L=JM_zqO4RjZ)}Y_kt&wpyaW4yJTH`-KDn?T;V3uf zcPn58vzUFzL$MKRW-1s=!xp}NP+jnY9z5A!QIQDVV=_T72R;NuJl+DbfebJ`W#;3XAwB5cy5oFW~kI(OX1d zEKJuZa@234sCptt#%>`)>W)z@1azbc#Mj(I*Ra>31Wb|w!oceh5C#p1AbLJA10taK zGH1~2!Dz*u&q#^G=0&jip5TxX2+-P4!jZO~QIAjtUhkd#6txS)kXOroB#GkgJ>m|m zg+c29wH3EHA+-`#`+;&;_&qU!!dC-2seoPv9EMmZATJ*-K<%biz3i2J_F<#u(1Cc) zcyj#vP;0L9T*Ms|3KzHG-CgTQ%$yx}&!{~yFY34+=x9#9)2T7~>P$q0xSh42WQCYA zUnFfiO@d@bQ&!$i+cJxP%XXptq{efi0^in$>h3SJzb_r^9lScgp{}ey^E68~tG8H( zv}g#_lc(NQq-^R-b)n}WmL!L6Ce>+0x#>SO!6$yD)L>J z5z?|>#cuX7Z3GRHtsmOHT{wK3rlFysXJ@yb{e@Es8Kg*k7Xl>%sO5Q}l1oR;gtvA= zys&65{Asda7J0S($G*~?M>=2&t(x~}h%T#uiOr=P{B_iM5yM6RrpVEpLA$&+d3~cB&$%6e7 z6bNr{VfTPiZEqQ>nsb0E@|(NG_!*DDS}q<{lU!9)#kxC*s@)a?viZYccni-ksISaH zmO}+5EkFnv3RSAwH|TVz9Kn8E1WdR+>F8Vw$($-y;$>37JPc$1Hv-mGvHL&)0`q@vl zZ|L&PG5df@WxyOLZ=bf|Ga4JfMDodQl`{QbS&3|Pfi#nkBZ!Yb3k^Jxw#5ToAHJ2~ zZ$5<`fcxroUbk-Upzoff!3N0JJl7tE1_d@aHsq!rKmXHy208fZul!R-fbdbywzip+weae8=~| zEU^nl$ZkmukkotC{>mKpuEm>(Oj!_6173oF1ho;ZO`nF2)=rqaleqp{g4+@XyF~*H z+i;z-jgp?CxjVt;>#&M|ju$@{6-5`q{0(LsGr)dCMfKK*bbO)HYy(t){HFxOjAGs%*7-Bzv^i{Q{)z zzY+O=Y<$D4k7q}N362MG=~V*B7UC)Ypt~r8YEWw5k2GX;Pc{g(?BUe+&y4rrKIs)w z!h%^19dy~2CwQw<0_F=t`c8DR_ZJ31UFNo(g>y*_xb#{y!;@9dM*FBf2;**>94bJ= zg(Q0Y)~#C&0n2_Zt&0Fb&~y$sKrqAzZ#|;_d;)o(I&++Nz+G1b-S{csR$;Z}c%zmg z0NXvE({YV;UO}`3w;8;lHyL7bmEr2u+ucS*t1BY$m*Vg?d2mu7eoh0NQ$Me~idA2* z`#7#FIL9qmsMzZpOldYCU z;jOq&aPkJFS@Ut>D#K2%7lx&(P8psI8DI;3`wEj3@-DZKv1ZR&Jz5z%fN+J z=HOd;t6ehw;UHxs)Xax%_;B3@lnf|<|NN6%DYN5A8(Zg5fK*8Re?47;p0W{LvN9Mj zWqe^fo*fmTotGqfvWh1=f(^?dP83c~;z$DO9yYIBg{8x;;wfIY#>Y(JvI1$J#~ktcP1yG@EqY)LK)te$MY9sEne39{=`LS zGe{Bs%wO#RQHX7yIP!3k-HmH4@ewO3<1 zgj`Gt>$prJ9tJ5x+tA3_7Pb-I1}PuE(ARCcMadZ{KgPTUO0afiV;6EN3>qis+=`1M zejnZYvaCHiSK`r07)-!eEx(SvfFEpNFWHItF=IT-QO+58VT^ej{ZXok{gDV;J^~>- zT$Im-C0$bxh^(6y5(XsS-kXMJ0w__ipPezT$r-&1KQ>z*$eNtHRJ{!sy}PvN4ZZbq z^>%gug6L=a)V`BFZ%l`LTVniH{`>durC{K5{KjOABkf%S4>mtsjNdf-65J$QZei_& zZ^1{@k^>rIfQERkboMI)V~{;*r9TE}Z*NNzdpbx<59DXaQKN~U3dL$>xlz<3wF2JaIj zNA@FHsL8O|HSgLtthYCe*|*eQ0fuld#tHZCXa2wDuKSGW~hwgXwjl5m8YnP6iUh{qe-M~g@{UJCnMvW@B6wB4xaviuOE8JeeQE# z_jP@)&%WMo`f~AduCnbHQ6f%q{=~tL+8T`{5dmJ707y_Ke5sN&$x&pLXze06PvR@R zjQjBNrRr*MSlsR#(HinC1Xz2^sbqS!D6BxLr!drinU?~czuFAz;L|ybqSyNcA`Xl7 zSb?}T=Se~ca#4s^vumcvy41lxfS5G&94`W464BN5 zjvw5$8{Pj5-q&7N+STMc9g}nW+m%sds)X-gcv?p)Ygj(waip5dl#9c3X7YMiNDfjU zz3!PtM@0LVLLO94Aat+(tSKf$5n@L`mOb^pT;ob>C@7J?2ndeEaJL>RxlRTuu@t*4 zfxA{c{{U^Xzhg45&R)q&C>+7W!-H)V{@CT@VXD#vcoU>6>ElL~ZRZB;^`E|ko-wjn zbx5X(jL}ojVJM~Ekx}=sitcK73~Mi3N>{ePO(f;xMEM5<1Q=OZjCu27Y8O(L4xZiB z67Db0P8^75Px(Qa(gvTW9XD^xrj49CqkI(AdXLqxpkg8I%-a*EOhYS|zUsv&m!aSt zh7O3N>p^m43wQT}pOKfypx_db-ql6TFqBgwGcBOu zl|^P+Ku{XXFnK z@9npikf-PbFh2~S#JM{c>d+lt$nHYo!$`i6tgjY3auC(!GB%99MR%lnF^Nw!Y-AX% zN97s?*AB(QUw8a55TFM>^(GwNTi&%(=y9?nd>koKG@!dpXr*+o3Ee zIbHvAJONuP2KiBY&zm1obKKF@PwBsi9VtYiE&S1wtu|x^eVDJ^496@pwvG?W$aj%w1G^vOGDhymtrp{tTaaysuu(R1q)fe~Hi zwfPC-?24#>*HP~9F@sm~?1UF2M{t&~HLX-yg{~r7$%{yjvShl^Hd7JG+E3-_oimKb zaX&x;EGuXGuZdzV7hE69kgx%5G+ufqBE7{uM z$NG0J=zQd(&t0}w?}+GX6K2W@WA5ZuEuw9Pga}(@Am&}x_gVx`QT30k2mt4;r+xy5 zzWN~*e<5%oZ`B>K>MtDPc`&@0qUKngv?aWEDxU;Ro&V68{@=6_^I07CW3D={eqrZl zyj9?>{VI$>W%bHv`c3w+RXQd^+SyvmNIw&{(KKwMutT|5>B}a#EYp<`bFf$*#)CSP zFvmRZULNZ}<_+-o{;a{!0EVkec&Ki2t$0Fr#3eC{EytBX(MqgvlYtUF(>hl%)4u1= z@wTl9JCq}XWq37(w+som*p-EXlUA0Y#c{}MZKzlmf8a;Z>W-JJ^6lKtE}KFp4eGku z(x;6Oe&;8MhLqvrMZb7&%D^}zczqUf5^LC@9aB-JI@;I~Ne8*Y^5}Z^-@Ueqr`WZI zW$qO&`&{b4n+8TIaq7A{qn-&~5EZ~W?z?@Cw};0Qzn`u)K%Ll&hPAI0(C9eY_;1%Y zhoNBLzhZ+8&nMFQM<+viK-*)j44#7{k%*qB?js93N9g262uP;=RBrgD)ewR#CA|s^ z4$_llt9Tl9u!y{(aD7?G6@ia*0zvo?Op-)gS4Y{^DgMHOlC0-`vR38aQulq=D=s_9 z@-4KWV+;nb->j>%chNsO9nZaFGSR(Jt8Gky2Q<KG+ zzO|3@UQcU?=e@stO(-BOObdaF%BimK(^}&$?M1iu@n^(~$q-U7iE-C_0I1H8OYw&Du8o0pORm6V6o4i~j|kAk?OX z)qo=)6peOE{{u%bhrkj1-su7s06pO4-E^GuUzi8N_2qY$Q2JE>>*VGU-oZ-#wD?>n zTt|9aOMyEnOUN$nUHuC%0)ZRRaRGQ(3jlUGyZ$ngj|q0%2h|`8sRKg%>bpDsf?5Ii z8@0P2-E2-EteB%6_=Dh0%-i9Kcz)@t)QVGTmL8xSd7%9lpogTSq?>m!67zWb&yQ38 zgP*ZOlmMb_Y6g(hb?Ff!PWf#6FKPu4gy&3j14%8n4UA$O>A$=VV2s+*;?f!~)pg`3 z12#Bh*IeE7CdT)m!|usy`XW$9nmryf{3dtZ+O zhe|HttxJ6$q4!Uh?dZ`76DI55FbKZ|vZS;{E>~j#4{=!o^b<)wO_98_;XUGsga72J z8m|6%J-`ciI{y{}(nacyi9pY1c)v`T{04{{et?>^Y-*%J0jV=+-tGc@)y*2a`eMx^ z5~QyJWk|mcp9HKH!E1B&sK)88UJ?x}<0As-9p@s5zM1DZoMHYJV-dGiH~+80EG{lK zLKEGOX5hMRO!u+^+{Mu2DWde@5dODH%w!7;82D0Q`t*)hl>+I&#BJ9jM6_FmRjpOy zYf&;&a?OGu#I36!mrLEpQ75oBUPAaUpZwdm0_RCX1;8UOLIzQQ(b;$u*yhn{@I{_} z{6NRQ{8#gdWxBYyzvT zk*IGBM}`7u=g$IwpF}OcX;jktlbEtrQF65vS9iGsU=XAggyUw8uk!I%v?tZ0>Y4G3 zg|4*^-9Ue|I&C=h8`!wHz!|qYZhSMjpS(0k5m>F8fYqvP3#T>$7k3?jAXZ47j)o-K z>U59yt)$F+`!Yh)^wnb;l?Vhd&Nsq$yEEP_w;w)_Pi#7Hj9Ly>f>SaibvQ-npHE@Z zX8d)iU=s{h18!OnhD!RRJHXY^)BqU44u$j`Ip*{ssh*)oEMWu8>5@n5=c9^x=T$ye z2MKyTr|}D0M+6J|EfY+UF>P0GRBP4507Wp^1e_jA!WQQ7 z!l|A+e6A1($xo(9j@DIT11Z2{D_h*&_^4#&-nV=vHQJc?1QM)eR?5al-U8BtDZp+u z`vEnkZPDMpG#w}~o(paAZpm7zP?_1;qX{wL{=a^yrRAq|0Njnh2W7N8-JeB-c(#4P zwp7rLvdQTu5HccwR4jW5P)b8*Pz;CQ9-WR5X!oKtpw1ka>G+neE%NWepn)$q6bu+w zI3e?z!b=7HTaN?TG#ZRpKcY|nw3yvbJeLWAq~^dLf_s`elaj&Xz5vAVTSn&6oBcj% zAPDv(rSrf)KW{gff|?t55k#I(b(~{(u}sgJNK7P}&H*5Q9&Mv(9)>we)2A0Z1NGE# zX54>9e29tnc|Al%CG^La7XdBqTPXk5Y(i}M2D}0`%da}E=D!|UMz)MdF(7-6LP@T# zd~MFj3Zf<}A%C`i52!B2ZuxSJ&YkuwxE#V307S(oDk;4TNY2_s@X9=8hkzY1S1abno@k z5;B_Zt)+lFZ_dwoUqau9Og5TeZ(-tUdIeK6b>HGvR>r841O4T(FoXwgvCv zJO{)_aRG3Zp8+mCYX}nbB{y@JEFOrgh zbrs*9bFu0DEFsEI{g+M!I8SN_DVfZNWx2crYtIstD-Z$^y+K3A6qLW15>mYGIwj}e z1Ui-bv6d;x`z>ZRp>M9&SQy?4Z^BmwjRoGZt;3x*rM9t@FG06oEcs$M)zu5o+5u9k zBUZa-vUus?o`(sCnGhQ>8#cnV^qI?ywUmEQkg7WfVP1zo%r{s4>5I<v(FRsS)Gk6RGWfk|WV;366%o&};3*q@MKlK3<;GC~Y0Q8+CBqa1K+%)=w0CRJL zmivcL)1C7i`#(b8g{`z9x%y$CY))DjMeqk-BQkJZRhWIBm-p*=Upf6z>_rC$uD-11 zYI}n-JqEa(uRc2nb`lkrv@|2i@1af%#yHzAA1)Aoxt220OAK*!gkRV zUh<}?&-3x)%P6^2QY|O}Ju|EkSKscb4<&)~%HQ z?*%_{1=>+93E-eoTHwhNUJ9H)vw;?6A8leg!|w7iGGGNl$1W*g)gV5e2;3OGe*5uzH~YPSQLlCDQtyGQQv>V*jkj5 z3i0iTG!Ut+20#Pki!!zkL8-4zuX(>V3iUgv^rLEi>+^o&NYSpgUMX7+F z_c=7ZryBzI+yJ9cUWu#69x#gui-_|>0N<;wf$7$ZJD|6V@}C+7dTcRZpSMlA$*kg! zgor#Egn$zs8;Kv*toAhrXbVsVIx0^G=trqDrjewvxR?E7j$weA+Ws5Z$j6xJ>+7F? z=^22q=vX$KG7mUqH35IS1uYeM%I5cPEs1kmtxKtZnziorh1r!M5R|iLngUL4)aWZ2 z5)2yNxC3aJoC83i)mrJIG0lxxhbZY4iIP^kJj&zMRD0%aElvDK$51PmvZjeqwTKy~ zfQa{S+M1Bms$T{|F>Q&%>f30tXVW(I(aLYnC&B zu2W|j4O!ohGUw0+!htI50#4%!V9dIPMFrt5->Y>%9+yT2OiTW6_mssvsJ*Dc;&fcO zQ9bc14rY6DqCq!i)&@2J{dTF=~CD5SS!K z;gzborI1T4P-`?7a=_lJ4H#S|5~IM>D{ z3UrDCLSR6H)+Ocyom*o=`4<%0F?8~G)buq7i==e&Rk_@q+@0bC`Q3@6MMl^b-H$fY zA9O{jub}%Yuz{)0(FWIWJGShfT*DfNE6(r9jv}-v#{u}c0E_zf1|5Hs!(X z+x9z>ZC>b*UF%wb$+IGyH#vJ%cWd=~%rwI7IA%|2YG)0J)znJnZk4BW<}9!;OZSH1 zC<&=OQbTu;_3S6ctVt>m?Mg661cdl@&K^OX0IFm&Ov$_$WCDM#nqy1DbMeOoxK?;C z+?XvHr&PhS-C)14rE_!a3Ao^bWG}La>)rzG9_;(6hOXZ6pY?8n{*}dtZ^0kvtj3mX zy&1oIAA9wzQIz~oM61~Zr`9TH8r9w}WHJ;Z&L2p zG$_bg^6@ABW5_JZNeP;4aL(QC(e``)ZY+;p*yheNF&7$O7k0qM&YQj=Iewk)ahI`u z&5!VLCbtjwPdaxe6oYy`X(C%y^ey|rVT-1%sz0dR}BqAl8FeL;CgwSlz!Iu)P zc%hb~r6C0iGyQkH;c{GwRhLO^)Pb=zi_h52ZrAbcP&xRh1>g(#2Po!NW zL>YgMBk!Rnb|C)>gwzMX+W!JQ{o(0FgN*vF%G2c}Xnap676*?#I+?bd*2w4& zyvfUGVxRGAo70(NM<=Hu5WRlBtFm|0MU4MK>sl`mJ$1Ijq3oE-lvxurs<%0iSj+yF z6CCmrDAiW0F3g%#4?M)pj4NI|)pF`PVv)y?i+4VKl5|w;p0x$TdWBUBRat zh~(BM*?NOCLrWm5X*Ut+3no&Uv&q|-?*H#ms@hA+nv3j8TfyBLKg3-1%3z8RJnSIJ zDrB0%mldSv@@m-K;__K)M{ZQ^9VGutw5+oNlQvaN2*iP!{ou&s-rxG-Ox;*5PxW|> zLp8S}`$H0vg)JibX|i*!GR@puvmmK{m3 z{KTkEoVl{q&x^bUG0eikE!RB5CUOCn*k}A*+=jy;N zU6D@}N6J^|3BnNRvm<}>Es?#OstO7Us9+@M*AQypn^LE|!VB1mf zrt4Yj5>{?AKDCwd4;=%Y>PnckTVYgVGY3c0UAsNAC$~y)hFN@TBwQB1)ghXl(wm|l zgxy;{jnXtRCSXJfo_ICDuirgtd zsPp{^(5?r;-STk3sm=_@#b7mg7HPSDL7ej#`M~fzZ&p5?p?>=}NzFr_#{cNmOgVi(;qO8hX(dNxvR}e&DRw&-4#{Gpy3m zk?SH}C87AP(TGHuhI_-!3Wvi~+3RoW@P&7x>m;oXdFG&J6~f=?Ll)ht_^l)ov(LA~ zpWEjNy25K$b4?4Ahfx;kb%?Sqr@%dUgoJ4My8De^`%prM8HKJmt5E6W=m@=|#nLfT z9r|e7IQz71IwZM&8@9p|R$b(g%voMfO!xDo6bv)7a&l&XR{p1610yz_cfGXKA(!dU;ESVXQDOi7l|H;8M7TqqgD4jh@mH^s_JTuXvJyrs`K{q_T>si zOb}p-Y?}#6Oa($1k%LTG^0_j{pq_hZJ$I1-`)`8Kz4{gCtuC*4f9^`jGD`pP+ewSP zP=W5;25#iVUXmA+`p`4o7+zm*wQz#~bJ{~ry{^|%&oQCHcPRDFuroy&lCte~kO5gc z&dO7Y)YPQhN|VW{|CA9nZSHKZNg5q4UIyh!|MmzEez6{|<6gwFwXOYCWcy%7{_BpQ zq3bC9g|S+eC6M4r$e*NCpqLVr=v~yk9Q3?}&JiTb0{1S+s>x(jyjGGiW$$b6TLkr( zuo1z42ND|3?hHO<+k1@Z&lpjLHyl&Z)g*QtSs1HoGZt%;fOw3x`bbw~R;$r;GISwm zg{`eEvTFJ)ki7sK#ccOH(C;Rp14dTxJ2{#gWZROVh7!U2JxKgM5l8A)NhI5pcOtBN z+BtIisC_z>w&f*kBeYt>1LM$`ob|0G<3SzRS0nJ1s$hoEkP3+JIw;vSK@v7>=m^$F z5NEwW9{JsqJ4bX38p*kV$>&CrZHaUdx0cu>o$|P@HaXsynbi!l_#F*vQSxHVM0qr0 zbH4krQ3%LKx*&(|N6erfG{uc=XM*mNqxL;hyLtQ@6m+ktmh63Bff&(UeZ-K68_4a7 zhAt|wooYByw9FIErkr)lR6~5nq29yB5w7z$e9AnV`YtvjqTXuO{K=M zmL409-M>wPJ9babgh`}m;tCD=CkR<>v5C3snHPrvB|!pS&(0K>foV8&HP#^UWOyGH zd4P?B6Z!BxW*s2u#3iMxn4{5~*ca*KD zbX7=%dZ%7MdLR-(XV`!|lTF~a=sqNBY^LyDP+Z$V2TWcC3cw4@;ll$aFsP9-zXyn` zzu5!#OUo+NeSgv5-FD;{Y4@ZGZ(T+Bt?Uprbhy3NY_HBbAvNs%Ng-pX~JfUG0yW>io<4k0|wc5cDdM^@uRxN9gK`=C%cke|II!Z@sN`TJt z&ofA79rBXxQX`d~HTQb7gpMyEH`Yvs+YmzNbzIlQv6rqylls(Q>vk!RBEA%yhF?!W za-OnimunosXX+XGJ4M2#UmuPp;H5O+d~T2akwY&3xd|6pZHKSD{qwnFF9&=8Mi zQ)ZMwpOmiB>aw_OrR-#MFj?7wFs?;ZRFqQ}9$g+ogEQT@aOfU5ZtJr_g;d%I+FcW! z$ByTEJGRV^JnsX_U0G_x2+t`s!A12psRozt`f7^PZK)G8f*ve*S-ncqL0QvvFj|G2gPTO_MH@# zIqCrU|4dnP-dyL~^;P`!St~`yOz_cTlbb)(BXQzGd_0*=Xi)L+oKZX))>*|W%@UOtg{bkDIq(fHyS3LO)Ro-Xviz(>!j-+f z?p-YR21VC(gz{MoE_#X<_@1MB<(t_lE0oa zUq(7=?$#T|yc5HcPS~p?88WZ{i4$>4kEYzb)X{Q_59adPw8^5f=ZMLB=5g;A*%lSU zc@8;H6|${kxGj(+$J<^%2R@_v*^t6l2{0;V8tdj3^m0?tV@&i+D_9QeZ=z7EF7s-r zVW%@**5~p`1V9|pBEjl_6YH$*P=08^^1ZJ<^4hD(T>DRFBW-Xg4b}l^v7EVDN=S_O z-*S%rXN-XOkw+Jnu2A^XoRHS}9wEK!OL(C_!?zAN-pk*WI6(Nk$C8xxWbRLsw6;ax zgWsm-<0#B#`}t59`MXf=(R+yRPa@9b@Pp^>_42fsA`BAqw!!T+dj}71`II&PCWbQ- z66K%b1ti2{dH>>N!4c7kn z?)g&au9@l+i0&#xT(ayT^po?Jf>as_lo!iAH6x7HgJ7aHw~#EH-(2m%!P3-I`|rNz zWWi}&)q;vJmoU|}KoS))0v8qWMRfB-y2}&VKP3^#Q*O%Ysf}hWATaI4jm*Pv% zfaI?;;dD4fiDv6+FES*#?mO7kd(|DkWLnRxe8ZPLcBaUOD5I*oc*kg)g4>@fNP&NB z(!jZfoAF(~H?Deo_8B&DTnUt6BE-nj6{FpuN}uQN+A%XFB9X>5hJh%Bo&Q0&e$|Iz zy7$pXa(+!>L(6iq@fJrAYI1hX;lGFQp>?59e`z+j?Io#s#Xc@%N39!=Lq>;pW#*4T z&aVdTTUvLpm)K||b;g;!q%HQFO`Jc4;SS2Vg z_p6Ru;JEeigSylrH(12n@*APN10}QtdL*5Q0A0@l{@8Jw+^D&pSWLS?X`7|C;e@!q zNRxlf0>oTJ%}7=z;O?p2CwNQC!AtJhj#)6DdtfZ@ge!TqJ+j=Px;6%{*pqwfm-R+d=7hVEw}N_-!V^y{Ap(#Np4@X*x(I2bGZ za_VENOgI7;WuZ*!T=_m=uSo9IAQlzm!|rWzXuS79>b)bW*|iu9yz%`MC@FFU3fGoMv)QneP5NkcWN z9~~u!ME=nfad{Rc7VI_X?(Nmnw>F)UnOWYR)?QM#Y!95p>kvUBVbedrY3k0i_&c)E zGyLyPtctmbl}A%NWV&Pe*U=y8V~_=>G*eDie*HRRKAKQipvp7J$MPHM)z!N2(;*V- zY(!II?I7AwWMM-vE04>JBCmG6l2;21;`!$pezL6H&{VEu>wFBDqPOs%K*)t(J=W;V z6n!)~G~(+1Som*^Bsy*-O?2{h&WgiYw+V<_t!% z0Xx!VW8|I*!p~C6g>`DeM=m#aG`{A#9ZR^Y&K85p9CPA?7-&1MH^Dw}vXM+E^c(17Xugr-? z;z;p*M<3}xaE`YhAq~I3_SV`d^L0S@utazVT7pj|1S6b?Za3u$uQa^Q-STaBP%9LdM%#UT=M{!Jz#2zFy>`oYe z?WSxpT`AEGva#lH`ayBcf=)P)ThPp3um#_iKW^dPNDGDLJCl3tI$KNxS&m8z_^6+5 zB7^k{<%w0E-!5!7_Madz0_t`BtbVy0X=#z%=S-}zz~>6-PdF1WMk=+Lpr&Im(KVtnQ^7bu$Z&Wz(5GnWZ@L!ILLKdh9)3@FXVzN_D^Us%YmW*12==kc=*i%L5zEL7` zTr@L&w79nHr2kspKFyFSs3Qj$}*xBf8JO|9UVF7m)a ztwwlm@;-twLF>SfE>B57TIXSj-J8%yZxJom#F*awc0|D_YI<7vF~x19SZkQR(qtU_ z1hnj|Wp)*}MTrtJ$zWoY300Pjse43#-|kodS;_aFqKn`(5s%MNTgG19rb3WnE@ zcn}E)@=DPVbI*ii)9j%VJUz8C53VyWgC${)_Vs=|RRv1?7}7=6PLLxdlBE2Bs$33g zE@pM$NzElqa+)VJZglTQe_OgyJbJ@}<_09M#}Umcj1%2pir@-&l3{m<@)MWr;`pJ-Jo-~`tF#fL?= zlV6ez!dJ+W%Z4a4>jmQD>%&)^Jw<-e$6s1d7vgk^N-0z;pvCJHvW6TbLy2RP5J+;x Yv%?nK?>QseLg7bu=^E{r#T&i<2Z(>~BLDyZ literal 0 HcmV?d00001 From 63576ebab1f680323a840ba6bfc78bb11ff6f28b Mon Sep 17 00:00:00 2001 From: TGY Date: Thu, 20 Mar 2025 17:05:22 +0800 Subject: [PATCH 07/27] add uni-api --- uni-api/latest/data.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/uni-api/latest/data.yml b/uni-api/latest/data.yml index a030dceae..82c83bacc 100644 --- a/uni-api/latest/data.yml +++ b/uni-api/latest/data.yml @@ -6,25 +6,22 @@ additionalProperties: labelEn: CONFIG_URL labelZh: 远程配置文件地址(若配置,则首先拉取远程配置到本地) required: false - rule: paramCommon type: text - - default: "./api.yaml" + - default: ./api.yaml edit: true envKey: LOCAL_CONFIG_PATH labelEn: local config file path labelZh: 本地配置文件地址 required: true - rule: paramCommon type: text - - default: "./data" + - default: ./data edit: true envKey: DATA_PATH labelEn: uni-api data path labelZh: uni-api数据存储路径 required: true - rule: paramCommon type: text - - default: 48000 + - default: 38000 edit: true envKey: PANEL_APP_PORT_HTTP labelEn: Port From 0eec559aad2d2f0ffaf264ee741a585e9bf2b6c4 Mon Sep 17 00:00:00 2001 From: TGY Date: Thu, 20 Mar 2025 17:25:38 +0800 Subject: [PATCH 08/27] add uni-api --- uni-api/latest/data.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uni-api/latest/data.yml b/uni-api/latest/data.yml index 82c83bacc..b95c2f270 100644 --- a/uni-api/latest/data.yml +++ b/uni-api/latest/data.yml @@ -7,7 +7,7 @@ additionalProperties: labelZh: 远程配置文件地址(若配置,则首先拉取远程配置到本地) required: false type: text - - default: ./api.yaml + - default: ./config edit: true envKey: LOCAL_CONFIG_PATH labelEn: local config file path From 8c9ca3021b6155398c58fef34e66d8b65dff44ae Mon Sep 17 00:00:00 2001 From: sephiroth <102894885+sephiroth233@users.noreply.github.com> Date: Sat, 19 Apr 2025 13:13:17 +0800 Subject: [PATCH 09/27] add libretv --- libretv/README.md | 5 ++ libretv/data.yml | 19 ++++++ libretv/latest/data.yml | 102 ++++++++++++++++++++++++++++++ libretv/latest/docker-compose.yml | 26 ++++++++ libretv/logo.png | Bin 0 -> 4768 bytes 5 files changed, 152 insertions(+) create mode 100644 libretv/README.md create mode 100644 libretv/data.yml create mode 100644 libretv/latest/data.yml create mode 100644 libretv/latest/docker-compose.yml create mode 100644 libretv/logo.png diff --git a/libretv/README.md b/libretv/README.md new file mode 100644 index 000000000..60a149412 --- /dev/null +++ b/libretv/README.md @@ -0,0 +1,5 @@ +# LibreSpeed + +无 Flash、无 Java、无 Websocket、无废话。 + +这是一个用 Javascript 实现的非常轻量级的速度测试,使用 XMLHttpRequest 和 Web Workers。 \ No newline at end of file diff --git a/libretv/data.yml b/libretv/data.yml new file mode 100644 index 000000000..01379e746 --- /dev/null +++ b/libretv/data.yml @@ -0,0 +1,19 @@ +name: LibreSpeed +tags: + - 实用工具 +title: 开源速度测试工具 +description: 开源速度测试工具 +additionalProperties: + key: librespeed + name: LibreSpeed + tags: + - Tool + shortDescZh: 开源速度测试工具 + shortDescEn: Open-source speed test tool + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://librespeed.org/ + github: https://github.com/librespeed/speedtest + document: https://github.com/librespeed/speedtest diff --git a/libretv/latest/data.yml b/libretv/latest/data.yml new file mode 100644 index 000000000..44fc2baf4 --- /dev/null +++ b/libretv/latest/data.yml @@ -0,0 +1,102 @@ +additionalProperties: + formFields: + - default: 40262 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: "standalone" + edit: true + envKey: MODE + labelEn: Mode + labelZh: 模式 + required: true + type: text + - default: "LibreSpeed" + edit: true + envKey: TITLE + labelEn: Title + labelZh: 标题 + required: true + type: text + - default: "false" + edit: true + envKey: TELEMETRY + labelEn: Telemetry + labelZh: 遥测 + required: true + type: select + values: + - label: "false" + value: "false" + - label: "true" + value: "true" + - default: "true" + edit: true + envKey: ENABLE_ID_OBFUSCATION + labelEn: Enable ID Obfuscation + labelZh: 启用 ID 混淆 + required: true + type: select + values: + - label: "false" + value: "false" + - label: "true" + value: "true" + - default: "false" + edit: true + envKey: REDACT_IP_ADDRESSES + labelEn: Redact IP Addresses + labelZh: 隐藏 IP 地址 + required: true + type: select + values: + - label: "false" + value: "false" + - label: "true" + value: "true" + - default: "password" + edit: true + envKey: PASSWORD + labelEn: Password + labelZh: 密码 + random: true + required: false + rule: paramCommon + type: password + - default: "" + edit: true + envKey: EMAIL + labelEn: Email address for GDPR requests (must be specified when telemetry is enabled) + labelZh: GDPR 请求的电子邮件地址 (启用遥测时必须指定) + required: false + type: text + - default: "false" + edit: true + envKey: DISABLE_IPINFO + labelEn: Disable IPInfo + labelZh: 禁用 IPInfo + required: true + type: select + values: + - label: "false" + value: "false" + - label: "true" + value: "true" + - default: "km" + edit: true + envKey: DISTANCE + labelEn: Distance + labelZh: 距离 + required: false + type: select + values: + - label: "km" + value: "km" + - label: "mi" + value: "mi" + - label: "" + value: "" diff --git a/libretv/latest/docker-compose.yml b/libretv/latest/docker-compose.yml new file mode 100644 index 000000000..7e2e88740 --- /dev/null +++ b/libretv/latest/docker-compose.yml @@ -0,0 +1,26 @@ +services: + librespeed: + image: "ghcr.io/librespeed/speedtest:latest" + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:${PANEL_APP_PORT_HTTP}" + environment: + - MODE=${MODE} + - TITLE=${TITLE} + - TELEMETRY=${TELEMETRY} + - ENABLE_ID_OBFUSCATION=${ENABLE_ID_OBFUSCATION} + - REDACT_IP_ADDRESSES=${REDACT_IP_ADDRESSES} + - PASSWORD=${PASSWORD} + - EMAIL=${EMAIL} + - DISABLE_IPINFO=${DISABLE_IPINFO} + - DISTANCE=${DISTANCE} + - WEBPORT=${PANEL_APP_PORT_HTTP} + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/libretv/logo.png b/libretv/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..9cec3e62d1817bf3fe702d0d21ccdd15beb049a2 GIT binary patch literal 4768 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

!}0k@$uIak@e=yjlY=N3BnWaKW~gk*dW)%cD3KH zwneSf(5a7)G8=QG9&G%o^pIm^L|i@bbY{D?PdIy50b`l(y!p* u)zeQLhv-{v{-Yu3Xm({aFaH6 Date: Sat, 19 Apr 2025 13:16:10 +0800 Subject: [PATCH 10/27] update --- libretv/README.md | 212 +++++++++++++++++++++++++++++- libretv/data.yml | 20 +-- libretv/latest/data.yml | 95 +------------ libretv/latest/docker-compose.yml | 15 +-- 4 files changed, 223 insertions(+), 119 deletions(-) diff --git a/libretv/README.md b/libretv/README.md index 60a149412..2909824a6 100644 --- a/libretv/README.md +++ b/libretv/README.md @@ -1,5 +1,211 @@ -# LibreSpeed +# LibreTV - 免费在线视频搜索与观看平台 -无 Flash、无 Java、无 Websocket、无废话。 +## 📺 项目简介 -这是一个用 Javascript 实现的非常轻量级的速度测试,使用 XMLHttpRequest 和 Web Workers。 \ No newline at end of file +LibreTV是一个轻量级、免费的在线视频搜索与观看平台,提供来自多个视频源的内容搜索与播放服务。无需注册,即开即用,支持多种设备访问。项目结合了前端技术和后端代理功能,可部署在支持服务端功能的各类网站托管服务上。 + +本项目基于 https://github.com/bestK/tv + +演示站:(请自行部署,不再提供演示站) + +image-20250406231222216 + +**感谢 [NodeSupport](https://www.nodeseek.com/post-305185-1) 友情赞助** + +## ✨ 主要特性 + +- 🔍 多源视频搜索功能,覆盖电影、电视剧等内容 +- 📱 响应式设计,完美支持电脑、平板和手机 +- 🌐 聚合多个视频源,自动提取播放链接 +- 🔄 支持自定义API接口,灵活扩展 +- 💾 本地存储搜索历史,提升使用体验 +- 🚫 内置视频代理功能,解决跨域问题 +- 🛡️ 内置广告过滤功能,提供更干净的观影体验 +- 🎬 自定义视频播放器,支持HLS流媒体格式 +- 🔒 可选密码保护,增强访问控制 +- ⌨️ 键盘快捷键支持,提高观影体验 + +## ⌨️ 键盘快捷键 + +LibreTV播放器支持以下键盘快捷键: + +- **Alt + 左箭头**:播放上一集 +- **Alt + 右箭头**:播放下一集 +- **空格键**:暂停/播放 +- **左/右箭头**:快退/快进5秒 +- **上/下箭头**:调整音量 +- **F**:全屏/退出全屏 + +### CMS采集站源兼容性 + +本项目支持标准的苹果CMS V10 API格式。自定义API需遵循以下格式: +- 搜索接口: `https://example.com/api.php/provide/vod/?ac=videolist&wd=关键词` +- 详情接口: `https://example.com/api.php/provide/vod/?ac=detail&ids=视频ID` + +**重要提示**: 像 `https://360zy.com/api.php/provide/vod` 这样的CMS源需要按照以下格式添加: +1. 在设置面板中选择"自定义接口" +2. 接口地址只填写到域名部分: `https://360zy.com`(不要包含`/api.php/provide/vod`部分) +3. 项目会自动补全正确的路径格式 + +如果CMS接口非标准格式,可能需要修改项目中的`config.js`文件中的`API_CONFIG.search.path`和`API_CONFIG.detail.path`配置。 + +## 🛠️ 技术栈 + +- HTML5 + CSS3 + JavaScript (ES6+) +- Tailwind CSS (通过CDN引入) +- HLS.js 用于HLS流处理和广告过滤 +- DPlayer 视频播放器核心 +- Cloudflare/Vercel/Netlify Serverless Functions +- 服务端HLS代理和处理技术 +- 前端API请求拦截技术 +- localStorage本地存储 + +## 🚀 一键部署 + +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FLibreSpark%2FLibreTV) + +## 🚀 部署指南 + +### Cloudflare Pages部署 + +1. Fork或克隆本仓库到你的GitHub账户 +2. 登录Cloudflare Dashboard,进入Pages服务 +3. 点击"创建项目",连接GitHub仓库 +4. 使用以下设置: + - 构建命令:留空(无需构建) + - 输出目录:留空(默认为根目录) + - 部署命令:留空 +5. 点击"保存并部署" + +### Vercel/Netlify部署 + +类似Cloudflare Pages,只需连接仓库并部署即可,无需特殊配置。 + +### 本地测试 + +项目现在包含后端代理功能,需要支持服务器端功能的环境: + +```bash +# 使用 Node.js 启动(推荐) +# 先安装依赖 +npm install +# 启动开发服务器 +npm run dev + +# 如果仍想使用简单的静态服务器测试前端部分 +# 注意:视频代理功能将不可用,会导致视频无法播放 +python -m http.server 8080 +# 或 +npx http-server -p 8080 +``` + +> ⚠️ 注意:使用简单静态服务器时,视频代理功能将不可用,视频播放功能会受到影响。完整功能测试请使用 Vercel CLI 或正确配置的开发服务器。 + +### Docker 部署 + +```bash +docker pull bestzwei/libretv:latest +docker run -d --name libretv -p 8899:80 bestzwei/libretv:latest +``` + +访问 http://localhost:8899 查看效果。 + +### Docker Compose 部署 + +你也可以通过 Docker Compose 部署本项目。新建一个名为 `docker-compose.yaml` 的文件,内容如下: + +```yaml +version: '3' +services: + libretv: + image: bestzwei/libretv:latest + container_name: libretv + ports: + - "8899:80" + restart: unless-stopped +``` + +## 🔧 自定义配置 + +### 密码保护功能 + +LibreTV 现在支持密码保护功能,可以通过环境变量设置访问密码。当设置了 `PASSWORD` 环境变量后,用户首次访问网站时需要输入密码才能继续使用。 + +- 如果 `PASSWORD` 环境变量为空或未设置,将不启用密码保护。 +- 密码验证状态会保存在浏览器本地存储中,有效期默认为三个月。 + +不同部署平台设置密码的方法: + +#### Cloudflare Pages + +1. 进入 Cloudflare Dashboard > Pages > 你的项目 +2. 点击"设置" > "环境变量" +3. 添加新的变量: + - 变量名: `PASSWORD` + - 值: 你想设置的密码 +4. 选择应用于"生产环境"或同时包括"预览环境" +5. 保存并重新部署项目 + +#### Vercel + +1. 进入 Vercel Dashboard > 你的项目 +2. 点击"设置" > "环境变量" +3. 添加新的环境变量: + - 名称: `PASSWORD` + - 值: 你想设置的密码 +4. 选择作用范围(生产/预览/开发环境) +5. 点击"保存"并重新部署项目 + +#### Docker/Docker Compose + +使用 Docker 运行时,可以通过环境变量传递密码: + +```bash +# 使用 Docker 命令 +docker run -d --name libretv -p 8899:80 -e PASSWORD=your_password_here bestzwei/libretv:latest +``` + +使用 Docker Compose,在 `docker-compose.yml` 文件中设置: + +```yaml +version: '3' +services: + libretv: + image: bestzwei/libretv:latest + container_name: libretv + ports: + - "8899:80" + environment: + - PASSWORD=your_password_here # 留空则不启用密码保护 + restart: unless-stopped +``` + +#### 本地测试环境 + +对于本地测试,你可以在启动服务器之前设置环境变量: + +```bash +# Linux/MacOS +export PASSWORD=your_password_here +python -m http.server 8080 + +# Windows +set PASSWORD=your_password_here +python -m http.server 8080 +``` + +## Star History + +[![Star History Chart](https://api.star-history.com/svg?repos=LibreSpark/LibreTV&type=Date)](https://www.star-history.com/#LibreSpark/LibreTV&Date) + +## ⚠️ 免责声明 + +LibreTV 仅作为视频搜索工具,不存储、上传或分发任何视频内容。所有视频均来自第三方API接口提供的搜索结果。如有侵权内容,请联系相应的内容提供方。 + +## 🔄 更新日志 + +- 1.0.0 (2025-04-06): 初始版本发布 +- 1.0.1 (2025-04-07): 添加广告过滤功能,优化播放器性能 +- 1.0.2 (2025-04-08): 分离了播放页面,优化视频源API兼容性 +- 1.0.3 (2025-04-13): 性能优化、UI优化、更新设置功能 +- 1.1.0 (2025-04-17): 添加服务端代理功能,支持HLS流处理和解析,支持环境变量设置访问密码 \ No newline at end of file diff --git a/libretv/data.yml b/libretv/data.yml index 01379e746..7b1ca5db6 100644 --- a/libretv/data.yml +++ b/libretv/data.yml @@ -1,19 +1,19 @@ -name: LibreSpeed +name: libretv tags: - 实用工具 -title: 开源速度测试工具 -description: 开源速度测试工具 +title: LibreTV - 免费在线视频搜索与观看平台 +description: LibreTV是一个轻量级、免费的在线视频搜索与观看平台,提供来自多个视频源的内容搜索与播放服务。无需注册,即开即用,支持多种设备访问。项目结合了前端技术和后端代理功能,可部署在支持服务端功能的各类网站托管服务上。 additionalProperties: - key: librespeed - name: LibreSpeed + key: libretv + name: LibreTV tags: - Tool - shortDescZh: 开源速度测试工具 - shortDescEn: Open-source speed test tool + shortDescZh: LibreTV - 免费在线视频搜索与观看平台 + shortDescEn: LibreTV - Free Online Video Search and Viewing Platform type: tool crossVersionUpdate: true limit: 0 recommend: 0 - website: https://librespeed.org/ - github: https://github.com/librespeed/speedtest - document: https://github.com/librespeed/speedtest + website: https://github.com/LibreSpark/LibreTV + github: https://github.com/LibreSpark/LibreTV + document: https://github.com/LibreSpark/LibreTV/blob/main/readme.md diff --git a/libretv/latest/data.yml b/libretv/latest/data.yml index 44fc2baf4..5e6ff6ab8 100644 --- a/libretv/latest/data.yml +++ b/libretv/latest/data.yml @@ -1,6 +1,6 @@ additionalProperties: formFields: - - default: 40262 + - default: 40248 edit: true envKey: PANEL_APP_PORT_HTTP labelEn: Port @@ -8,95 +8,4 @@ additionalProperties: required: true rule: paramPort type: number - - default: "standalone" - edit: true - envKey: MODE - labelEn: Mode - labelZh: 模式 - required: true - type: text - - default: "LibreSpeed" - edit: true - envKey: TITLE - labelEn: Title - labelZh: 标题 - required: true - type: text - - default: "false" - edit: true - envKey: TELEMETRY - labelEn: Telemetry - labelZh: 遥测 - required: true - type: select - values: - - label: "false" - value: "false" - - label: "true" - value: "true" - - default: "true" - edit: true - envKey: ENABLE_ID_OBFUSCATION - labelEn: Enable ID Obfuscation - labelZh: 启用 ID 混淆 - required: true - type: select - values: - - label: "false" - value: "false" - - label: "true" - value: "true" - - default: "false" - edit: true - envKey: REDACT_IP_ADDRESSES - labelEn: Redact IP Addresses - labelZh: 隐藏 IP 地址 - required: true - type: select - values: - - label: "false" - value: "false" - - label: "true" - value: "true" - - default: "password" - edit: true - envKey: PASSWORD - labelEn: Password - labelZh: 密码 - random: true - required: false - rule: paramCommon - type: password - - default: "" - edit: true - envKey: EMAIL - labelEn: Email address for GDPR requests (must be specified when telemetry is enabled) - labelZh: GDPR 请求的电子邮件地址 (启用遥测时必须指定) - required: false - type: text - - default: "false" - edit: true - envKey: DISABLE_IPINFO - labelEn: Disable IPInfo - labelZh: 禁用 IPInfo - required: true - type: select - values: - - label: "false" - value: "false" - - label: "true" - value: "true" - - default: "km" - edit: true - envKey: DISTANCE - labelEn: Distance - labelZh: 距离 - required: false - type: select - values: - - label: "km" - value: "km" - - label: "mi" - value: "mi" - - label: "" - value: "" + \ No newline at end of file diff --git a/libretv/latest/docker-compose.yml b/libretv/latest/docker-compose.yml index 7e2e88740..a6e124c90 100644 --- a/libretv/latest/docker-compose.yml +++ b/libretv/latest/docker-compose.yml @@ -1,23 +1,12 @@ services: - librespeed: - image: "ghcr.io/librespeed/speedtest:latest" + libretv: + image: "bestzwei/libretv:latest" container_name: ${CONTAINER_NAME} restart: always networks: - 1panel-network ports: - "${PANEL_APP_PORT_HTTP}:${PANEL_APP_PORT_HTTP}" - environment: - - MODE=${MODE} - - TITLE=${TITLE} - - TELEMETRY=${TELEMETRY} - - ENABLE_ID_OBFUSCATION=${ENABLE_ID_OBFUSCATION} - - REDACT_IP_ADDRESSES=${REDACT_IP_ADDRESSES} - - PASSWORD=${PASSWORD} - - EMAIL=${EMAIL} - - DISABLE_IPINFO=${DISABLE_IPINFO} - - DISTANCE=${DISTANCE} - - WEBPORT=${PANEL_APP_PORT_HTTP} labels: createdBy: "Apps" From 3fba535d84604e12aba120ab2d10ea5c024b5fac Mon Sep 17 00:00:00 2001 From: sephiroth <102894885+sephiroth233@users.noreply.github.com> Date: Sat, 19 Apr 2025 13:53:41 +0800 Subject: [PATCH 11/27] update --- libretv/latest/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretv/latest/docker-compose.yml b/libretv/latest/docker-compose.yml index a6e124c90..746d08191 100644 --- a/libretv/latest/docker-compose.yml +++ b/libretv/latest/docker-compose.yml @@ -6,7 +6,7 @@ services: networks: - 1panel-network ports: - - "${PANEL_APP_PORT_HTTP}:${PANEL_APP_PORT_HTTP}" + - "${PANEL_APP_PORT_HTTP}:80" labels: createdBy: "Apps" From ccaf487df38410b73d216854566c4a75795d12fb Mon Sep 17 00:00:00 2001 From: sephiroth <102894885+sephiroth233@users.noreply.github.com> Date: Sat, 19 Apr 2025 15:02:11 +0800 Subject: [PATCH 12/27] update new-api --- new-api/latest/docker-compose.yml | 2 +- new-api/sqllite/docker-compose.yml | 2 +- new-api/veloera/data.yml | 17 +++++++++++++++++ new-api/veloera/docker-compose.yml | 25 +++++++++++++++++++++++++ 4 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 new-api/veloera/data.yml create mode 100644 new-api/veloera/docker-compose.yml diff --git a/new-api/latest/docker-compose.yml b/new-api/latest/docker-compose.yml index 1e361775b..d7c4d56a5 100644 --- a/new-api/latest/docker-compose.yml +++ b/new-api/latest/docker-compose.yml @@ -1,5 +1,5 @@ services: - one-api: + new-api: image: calciumion/new-api:latest container_name: ${CONTAINER_NAME} restart: always diff --git a/new-api/sqllite/docker-compose.yml b/new-api/sqllite/docker-compose.yml index 04c9b34bd..c6fff4d5f 100644 --- a/new-api/sqllite/docker-compose.yml +++ b/new-api/sqllite/docker-compose.yml @@ -1,5 +1,5 @@ services: - one-api: + new-api: image: calciumion/new-api:latest container_name: ${CONTAINER_NAME} restart: always diff --git a/new-api/veloera/data.yml b/new-api/veloera/data.yml new file mode 100644 index 000000000..47b7d314b --- /dev/null +++ b/new-api/veloera/data.yml @@ -0,0 +1,17 @@ +additionalProperties: + formFields: + - default: 3000 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: Asia/Shanghai + edit: true + envKey: TZ + labelEn: Time Zone + labelZh: 时区 + required: true + type: text diff --git a/new-api/veloera/docker-compose.yml b/new-api/veloera/docker-compose.yml new file mode 100644 index 000000000..8471ec549 --- /dev/null +++ b/new-api/veloera/docker-compose.yml @@ -0,0 +1,25 @@ +services: + new-api: + image: ghcr.io/veloera/veloera:latest + container_name: ${CONTAINER_NAME} + restart: always + ports: + - ${PANEL_APP_PORT_HTTP}:3000 + networks: + - 1panel-network + command: --log-dir /app/logs + volumes: + - ./data:/data + - ./logs:/app/logs + environment: + - TZ=${TZ} +# - SESSION_SECRET=${SESSION_SECRET} +# - REDIS_CONN_STRING=redis://redis +# - NODE_TYPE=slave # 多机部署时从节点取消注释该行 +# - SYNC_FREQUENCY=60 # 需要定期从数据库加载数据时取消注释该行 +# - FRONTEND_BASE_URL=https://openai.justsong.cn # 多机部署时从节点取消注释该行 + labels: + createdBy: "Apps" +networks: + 1panel-network: + external: true From 6b6dc8fde86b25c4c62efcd610c5b52f842b716f Mon Sep 17 00:00:00 2001 From: TGY Date: Sun, 4 May 2025 11:42:14 +0800 Subject: [PATCH 13/27] update libretv --- libretv/latest/data.yml | 9 ++++++++- libretv/latest/docker-compose.yml | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/libretv/latest/data.yml b/libretv/latest/data.yml index 5e6ff6ab8..5da2b0c0c 100644 --- a/libretv/latest/data.yml +++ b/libretv/latest/data.yml @@ -8,4 +8,11 @@ additionalProperties: required: true rule: paramPort type: number - \ No newline at end of file + - default: + edit: true + envKey: PASSWORD + labelEn: Password + labelZh: 密码 + random: true + required: false + rule: paramComplexity \ No newline at end of file diff --git a/libretv/latest/docker-compose.yml b/libretv/latest/docker-compose.yml index 746d08191..a6c0fa1e6 100644 --- a/libretv/latest/docker-compose.yml +++ b/libretv/latest/docker-compose.yml @@ -7,6 +7,7 @@ services: - 1panel-network ports: - "${PANEL_APP_PORT_HTTP}:80" + - "PASSWORD:${PASSWORD}" labels: createdBy: "Apps" From 751b0105dde21dcf8b1d40efe43dc3eb70483869 Mon Sep 17 00:00:00 2001 From: TGY Date: Sun, 4 May 2025 12:04:19 +0800 Subject: [PATCH 14/27] update magic-resume --- magic-resume/README.md | 131 +++++++++++++++++++++++++ magic-resume/data.yml | 19 ++++ magic-resume/latest/.env.sample | 2 + magic-resume/latest/data.yml | 10 ++ magic-resume/latest/docker-compose.yml | 17 ++++ magic-resume/logo.png | Bin 0 -> 5908 bytes 6 files changed, 179 insertions(+) create mode 100644 magic-resume/README.md create mode 100644 magic-resume/data.yml create mode 100644 magic-resume/latest/.env.sample create mode 100644 magic-resume/latest/data.yml create mode 100644 magic-resume/latest/docker-compose.yml create mode 100644 magic-resume/logo.png diff --git a/magic-resume/README.md b/magic-resume/README.md new file mode 100644 index 000000000..f26a8ce93 --- /dev/null +++ b/magic-resume/README.md @@ -0,0 +1,131 @@ +
+ +# ✨ Magic Resume ✨ + +[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +![Next.js](https://img.shields.io/badge/Next.js-14.0-black) +![Framer Motion](https://img.shields.io/badge/Framer_Motion-10.0-purple) + +简体中文 | [English](./README.en-US.md) + +
+ +Magic Resume 是一个现代化的在线简历编辑器,让创建专业简历变得简单有趣。基于 Next.js 和 Motion 构建,支持实时预览和自定义主题。 + +## 📸 项目截图 + +![782shots_so](https://github.com/user-attachments/assets/d59f7582-799c-468d-becf-59ee6453acfd) + +## ✨ 特性 + +- 🚀 基于 Next.js 14+ 构建 +- 💫 流畅的动画效果 (Motion) +- 🎨 自定义主题支持 +- 🌙 深色模式 +- 📤 导出为 PDF +- 🔄 实时预览 +- 💾 自动保存 +- 🔒 硬盘级存储 + +## 🛠️ 技术栈 + +- Next.js 14+ +- TypeScript +- Motion +- Tiptap +- Tailwind CSS +- Zustand +- Shadcn/ui +- Lucide Icons + +## 🚀 快速开始 + +1. 克隆项目 + +```bash +git clone git@github.com:JOYCEQL/magic-resume.git +cd magic-resume +``` + +2. 安装依赖 + +```bash +pnpm install +``` + +3. 启动开发服务器 + +```bash +pnpm dev +``` + +4. 打开浏览器访问 `http://localhost:3000` + +## 📦 构建打包 + +```bash +pnpm build +``` + +## ⚡ Vercel 部署 + +你可以一键部署自己的 Magic Resume 实例: + +[![使用 Vercel 部署](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FJOYCEQL%2Fmagic-resume) + +## 🐳 Docker 部署 + +### Docker Compose + +1. 确保你已经安装了 Docker 和 Docker Compose + +2. 在项目根目录运行: + +```bash +docker compose up -d +``` + +这将会: + +- 自动构建应用镜像 +- 在后台启动容器 + +### Docker Hub + +最新版本的 Magic Resume 已经发布在 Docker Hub: + +[Docker Hub](https://hub.docker.com/r/siyueqingchen/magic-resume/) + +```bash +docker pull siyueqingchen/magic-resume:main +``` + +## 📝 开源协议 + +本项目采用 Apache 2.0 协议,但有一些自定义的部分 - 查看 [LICENSE](LICENSE) 了解详情 + +## 🗺️ 路线图 + +- [x] AI 辅助编写 +- [x] 多语言支持 +- [ ] 支持更多简历模板 +- [ ] 更多格式导出 +- [ ] 自定义模型 +- [ ] 智能一页 +- [ ] 导入 PDF, Markdown 等 +- [ ] 在线简历托管 + +## 📞 联系方式 + +可以通过以下方式关注最新动态: + +- 作者:SiYue +- X: @GuangzhouY81070 +- Discord: 欢迎加入群组 https://discord.gg/9mWgZrW3VN +- 用户群:加微信 qingchensiyue +- 邮箱:18806723365@163.com +- 项目主页:https://github.com/JOYCEQL/magic-resume + +## 🌟 支持项目 + +如果这个项目对你有帮助,欢迎点个 star ⭐️ \ No newline at end of file diff --git a/magic-resume/data.yml b/magic-resume/data.yml new file mode 100644 index 000000000..534f041dc --- /dev/null +++ b/magic-resume/data.yml @@ -0,0 +1,19 @@ +name: Magic Resume +tags: + - 工具 +title: Magic Resume 是一个现代化的在线简历编辑器,让创建专业简历变得简单有趣。基于 Next.js 和 Motion 构建,支持实时预览和自定义主题。 +description: Magic Resume 是一个现代化的在线简历编辑器,让创建专业简历变得简单有趣。基于 Next.js 和 Motion 构建,支持实时预览和自定义主题。 +additionalProperties: + key: magic-resume + name: Magic Resume + tags: + - Tool + shortDescZh: Magic Resume 是一个现代化的在线简历编辑器,让创建专业简历变得简单有趣。基于 Next.js 和 Motion 构建,支持实时预览和自定义主题。 + shortDescEn: Magic Resume is a modern online resume editor that makes creating professional resumes simple and enjoyable. Built with Next.js and Framer Motion, it supports real-time preview and custom themes + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://magicv.art/zh + github: https://github.com/JOYCEQL/magic-resume + document: https://github.com/JOYCEQL/magic-resume/blob/main/README.md diff --git a/magic-resume/latest/.env.sample b/magic-resume/latest/.env.sample new file mode 100644 index 000000000..c72333b28 --- /dev/null +++ b/magic-resume/latest/.env.sample @@ -0,0 +1,2 @@ +CONTAINER_NAME="magic-resume" +PANEL_APP_PORT_HTTP="40250" diff --git a/magic-resume/latest/data.yml b/magic-resume/latest/data.yml new file mode 100644 index 000000000..179f5068f --- /dev/null +++ b/magic-resume/latest/data.yml @@ -0,0 +1,10 @@ +additionalProperties: + formFields: + - default: 40250 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number diff --git a/magic-resume/latest/docker-compose.yml b/magic-resume/latest/docker-compose.yml new file mode 100644 index 000000000..a505a0b49 --- /dev/null +++ b/magic-resume/latest/docker-compose.yml @@ -0,0 +1,17 @@ +services: + magic-resume: + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:3000" + environment: + - NODE_ENV=production + image: siyueqingchen/magic-resume:main + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/magic-resume/logo.png b/magic-resume/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..18ba2f0ba0873901b34c821679efad9157f45da4 GIT binary patch literal 5908 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 literal 0 HcmV?d00001 From 6a329675f4d021381141a7fca645c26f7b662c45 Mon Sep 17 00:00:00 2001 From: TGY Date: Sun, 4 May 2025 12:19:42 +0800 Subject: [PATCH 15/27] update LibreTV --- libretv/latest/docker-compose.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libretv/latest/docker-compose.yml b/libretv/latest/docker-compose.yml index a6c0fa1e6..5e6e7dea5 100644 --- a/libretv/latest/docker-compose.yml +++ b/libretv/latest/docker-compose.yml @@ -1,5 +1,5 @@ services: - libretv: + libreTV: image: "bestzwei/libretv:latest" container_name: ${CONTAINER_NAME} restart: always @@ -7,7 +7,8 @@ services: - 1panel-network ports: - "${PANEL_APP_PORT_HTTP}:80" - - "PASSWORD:${PASSWORD}" + environment: + - PASSWORD=${PASSWORD} labels: createdBy: "Apps" From 9e60a5dd5a0da9799f8a9cc6dd464a851639cbaf Mon Sep 17 00:00:00 2001 From: TGY Date: Sun, 4 May 2025 12:32:14 +0800 Subject: [PATCH 16/27] update LibreTV --- libretv/latest/data.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretv/latest/data.yml b/libretv/latest/data.yml index 5da2b0c0c..c37dbf6f8 100644 --- a/libretv/latest/data.yml +++ b/libretv/latest/data.yml @@ -8,7 +8,7 @@ additionalProperties: required: true rule: paramPort type: number - - default: + - default: "" edit: true envKey: PASSWORD labelEn: Password From 65be6373335667ab5e937a5d7af0fda1991c3437 Mon Sep 17 00:00:00 2001 From: TGY Date: Sun, 4 May 2025 12:33:55 +0800 Subject: [PATCH 17/27] update LibreTV --- libretv/latest/docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libretv/latest/docker-compose.yml b/libretv/latest/docker-compose.yml index 5e6e7dea5..d627c4a86 100644 --- a/libretv/latest/docker-compose.yml +++ b/libretv/latest/docker-compose.yml @@ -7,8 +7,8 @@ services: - 1panel-network ports: - "${PANEL_APP_PORT_HTTP}:80" - environment: - - PASSWORD=${PASSWORD} + # environment: + # - PASSWORD=${PASSWORD} # optional labels: createdBy: "Apps" From 5b0bbfe7fe23f4811e5e69a846aca174b0e5b0e3 Mon Sep 17 00:00:00 2001 From: TGY Date: Sun, 4 May 2025 12:34:48 +0800 Subject: [PATCH 18/27] update LibreTV --- libretv/latest/data.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libretv/latest/data.yml b/libretv/latest/data.yml index c37dbf6f8..dfb0a3640 100644 --- a/libretv/latest/data.yml +++ b/libretv/latest/data.yml @@ -8,11 +8,11 @@ additionalProperties: required: true rule: paramPort type: number - - default: "" - edit: true - envKey: PASSWORD - labelEn: Password - labelZh: 密码 - random: true - required: false - rule: paramComplexity \ No newline at end of file +# - default: "" +# edit: true +# envKey: PASSWORD +# labelEn: Password +# labelZh: 密码 +# random: true +# required: false +# rule: paramComplexity \ No newline at end of file From 3a8f6f770e5ca6943679ad942f0302c857887609 Mon Sep 17 00:00:00 2001 From: TGY Date: Sun, 18 May 2025 22:51:16 +0800 Subject: [PATCH 19/27] add better-sync --- obsidian-better-sync/README.md | 139 ++++++++++++++++++ obsidian-better-sync/data.yml | 19 +++ obsidian-better-sync/latest/data.yml | 26 ++++ .../latest/docker-compose.yml | 20 +++ obsidian-better-sync/logo.png | Bin 0 -> 6331 bytes 5 files changed, 204 insertions(+) create mode 100644 obsidian-better-sync/README.md create mode 100644 obsidian-better-sync/data.yml create mode 100644 obsidian-better-sync/latest/data.yml create mode 100644 obsidian-better-sync/latest/docker-compose.yml create mode 100644 obsidian-better-sync/logo.png diff --git a/obsidian-better-sync/README.md b/obsidian-better-sync/README.md new file mode 100644 index 000000000..786215695 --- /dev/null +++ b/obsidian-better-sync/README.md @@ -0,0 +1,139 @@ +[中文文档](readme-zh.md) / [English Document](README.md) + +# Better Sync Service + +

+ version + license +

+ +[BetterSync For Obsidian](https://github.com/haierkeys/obsidian-better-sync) 服务端,基于 Golang + Websocket +构建的高性能笔记实时同步服务 + +## 功能清单 + +- [x] 多端笔记实时同步 +- [ ] 笔记云存储同步备份 - s3 +- [ ] 笔记云存储同步备份 - 阿里云 +- [ ] 笔记云存储同步备份 - CF R2 +- [ ] 笔记云存储同步备份 - minio +- [ ] 笔记云存储同步备份 - webdav +- [ ] 笔记云存储同步备份 - 增加备份策略 +- [x] Web页面管理 +- [x] 目前仅支持 Sqlite 存储 +- [ ] 增加git维护版本 +- [ ] 基于 google-diff-match-patch 算法优化 + +## BUGLIST (已知问题) + +- webgui 除了登录/注册/复制配置之外的 界面无实际功能或点击异常 +- 部分用户连接ws后, 认证成功,但是不显示nickname + +## 更新日志 + +查看完整的更新内容,请访问 [Changelog](https://github.com/haierkeys/obsidian-better-sync-service/releases)。 + +## 价格 + +本软件是开源且免费的。如果您想表示感谢或帮助支持继续开发,可以通过以下方式为我提供支持: + +[BuyMeACoffee](https://ko-fi.com/haierkeys) + +## 私有部署 + +- 目录设置 + + ```bash + # 创建项目所需的目录 + mkdir -p /data/better-sync + cd /data/better-sync + + mkdir -p ./config && mkdir -p ./storage/logs && mkdir -p ./storage/uploads + ``` + + 首次启动如果不下载配置文件,程序会自动生成一个默认配置到 **config/config.yaml** + + 如果你想从网络下载一个默认配置 使用以下命令来下载 + + ```bash + # 从开源库下载默认配置文件到配置目录 + wget -P ./config/ https://raw.githubusercontent.com/haierkeys/obsidian-better-sync-service/main/config/config.yaml + ``` + +- 二进制安装 + + 从 [Releases](https://github.com/haierkeys/obsidian-better-sync-service/releases) 下载最新版本,解压后执行: + + ```bash + ./better-sync-service run -c config/config.yaml + ``` + + +- 容器化安装(Docker 方式) + + Docker 命令: + + ```bash + # 拉取最新的容器镜像 + docker pull haierkeys/obsidian-better-sync-service:latest + + # 创建并启动容器 + docker run -tid --name better-sync-service \ + -p 9000:9000 -p 9001:9001 \ + -v /data/better-sync/storage/:/better-sync/storage/ \ + -v /data/better-sync/config/:/better-sync/config/ \ + haierkeys/obsidian-better-sync-service:latest + ``` + + Docker Compose + 使用 *containrrr/watchtower* 来监听镜像实现自动更新项目 + **docker-compose.yaml** 内容如下 + + ```yaml + # docker-compose.yaml + services: + better-sync: + image: haierkeys/obsidian-better-sync-service:latest # 你的应用镜像 + container_name: better-sync + ports: + - "9000:9000" # 映射端口 9000 + - "9001:9001" # 映射端口 9001 + volumes: + - /data/better-sync/storage/:/better-sync/storage/ # 映射存储目录 + - /data/better-sync/config/:/better-sync/config/ # 映射配置目录 + + ``` + + 执行 **docker compose** + + 以服务方式注册 docker 容器 + + ```bash + docker compose up -d + ``` + + 注销并销毁 docker 容器 + + ```bash + docker compose down + ``` + +### 使用 + +访问 `WebGUI` 地址 `http://{IP:PORT}` + +点击在 复制 API 配置 获取配置信息, 到 `BetterSync For Obsidian` 插件中粘贴即可 + +首次访问需要进行用户注册,如需关闭注册, 请修改 `user.register-is-enable` 为 `false` + +### 配置说明 + +默认的配置文件名为 **config.yaml**,请将其放置在 **根目录** 或 **config** 目录下。 + +更多配置详情请参考: + +- [config/config.yaml](config/config.yaml) + +## 其他资源 + +- [Better Sync For Obsidian](https://github.com/haierkeys/obsidian-better-sync) \ No newline at end of file diff --git a/obsidian-better-sync/data.yml b/obsidian-better-sync/data.yml new file mode 100644 index 000000000..c5ec31daa --- /dev/null +++ b/obsidian-better-sync/data.yml @@ -0,0 +1,19 @@ +name: Obsidian BetterSync +tags: + - 实用工具 +title: Obsidian 在线同步插件 +description: Obsidian 在线同步插件 +additionalProperties: + key: better-sync-service + name: Obsidian BetterSync + tags: + - Tool + shortDescZh: Obsidian 在线同步插件 + shortDescEn: Obsidian BetterSync + type: website + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://github.com/haierkeys/obsidian-better-sync-service + github: https://github.com/haierkeys/obsidian-better-sync-service + document: https://github.com/haierkeys/obsidian-better-sync-service/blob/master/readme-zh.md diff --git a/obsidian-better-sync/latest/data.yml b/obsidian-better-sync/latest/data.yml new file mode 100644 index 000000000..e55a6a8dd --- /dev/null +++ b/obsidian-better-sync/latest/data.yml @@ -0,0 +1,26 @@ +additionalProperties: + formFields: + - default: 40166 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: HTTP Port + labelZh: HTTP端口 + required: true + rule: paramPort + type: number + - default: 40167 + edit: true + envKey: PRIVATE_HTTP_LISTEN + labelEn: private-http-listen + labelZh: 性能监控接口 + required: true + rule: paramPort + type: number + - default: ./data + edit: true + envKey: DATA_PATH + labelEn: Data folder path + labelZh: 数据文件夹路径 + required: true + type: text + diff --git a/obsidian-better-sync/latest/docker-compose.yml b/obsidian-better-sync/latest/docker-compose.yml new file mode 100644 index 000000000..b3dc07481 --- /dev/null +++ b/obsidian-better-sync/latest/docker-compose.yml @@ -0,0 +1,20 @@ +services: + better-sync: + container_name: ${CONTAINER_NAME} + restart: always + ports: + - "${PANEL_APP_PORT_HTTP}:9000" + - "${PRIVATE_HTTP_LISTEN}:9001" + volumes: + - ${DATA_PATH}/storage:/better-sync/storage/ + - ${DATA_PATH}/config:/better-sync/config/ + image: haierkeys/obsidian-better-sync-service:latest + labels: + createdBy: "Apps" + networks: + - 1panel-network + +networks: + 1panel-network: + external: true + diff --git a/obsidian-better-sync/logo.png b/obsidian-better-sync/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..affa745c47b782d22734f68ad242e3e2536a9d82 GIT binary patch literal 6331 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 literal 0 HcmV?d00001 From 2942b4d1b3208b2eb3163cd0943a27a116c3a630 Mon Sep 17 00:00:00 2001 From: sephiroth <102894885+sephiroth233@users.noreply.github.com> Date: Tue, 10 Jun 2025 19:21:33 +0800 Subject: [PATCH 20/27] update --- libretv/latest/data.yml | 23 +++++++++++++++-------- libretv/latest/docker-compose.yml | 8 +++++--- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/libretv/latest/data.yml b/libretv/latest/data.yml index dfb0a3640..f4fe06768 100644 --- a/libretv/latest/data.yml +++ b/libretv/latest/data.yml @@ -8,11 +8,18 @@ additionalProperties: required: true rule: paramPort type: number -# - default: "" -# edit: true -# envKey: PASSWORD -# labelEn: Password -# labelZh: 密码 -# random: true -# required: false -# rule: paramComplexity \ No newline at end of file + - default: "" + edit: true + envKey: PASSWORD + labelEn: Password + labelZh: 密码 + random: true + required: true + rule: paramComplexity + - default: "./data" + edit: true + envKey: DATA_PATH + labelEn: Data Path + labelZh: 数据路径 + required: true + type: text \ No newline at end of file diff --git a/libretv/latest/docker-compose.yml b/libretv/latest/docker-compose.yml index d627c4a86..576bb1d70 100644 --- a/libretv/latest/docker-compose.yml +++ b/libretv/latest/docker-compose.yml @@ -6,9 +6,11 @@ services: networks: - 1panel-network ports: - - "${PANEL_APP_PORT_HTTP}:80" - # environment: - # - PASSWORD=${PASSWORD} # optional + - "${PANEL_APP_PORT_HTTP}:8080" + environment: + - PASSWORD=${PASSWORD} + volumes: + - ${DATA_PATH}:/app labels: createdBy: "Apps" From ddae579d670d77f105685a16272384edf74292bc Mon Sep 17 00:00:00 2001 From: sephiroth <102894885+sephiroth233@users.noreply.github.com> Date: Tue, 10 Jun 2025 19:26:32 +0800 Subject: [PATCH 21/27] update --- libretv/latest/data.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libretv/latest/data.yml b/libretv/latest/data.yml index f4fe06768..189aa5d01 100644 --- a/libretv/latest/data.yml +++ b/libretv/latest/data.yml @@ -13,9 +13,8 @@ additionalProperties: envKey: PASSWORD labelEn: Password labelZh: 密码 - random: true required: true - rule: paramComplexity + type: text - default: "./data" edit: true envKey: DATA_PATH From 24f348e7b31d59d65e4ab163c792d244bf5f161e Mon Sep 17 00:00:00 2001 From: sephiroth <102894885+sephiroth233@users.noreply.github.com> Date: Tue, 10 Jun 2025 19:29:12 +0800 Subject: [PATCH 22/27] update --- libretv/latest/data.yml | 7 ------- libretv/latest/docker-compose.yml | 2 -- 2 files changed, 9 deletions(-) diff --git a/libretv/latest/data.yml b/libretv/latest/data.yml index 189aa5d01..90e04e6df 100644 --- a/libretv/latest/data.yml +++ b/libretv/latest/data.yml @@ -15,10 +15,3 @@ additionalProperties: labelZh: 密码 required: true type: text - - default: "./data" - edit: true - envKey: DATA_PATH - labelEn: Data Path - labelZh: 数据路径 - required: true - type: text \ No newline at end of file diff --git a/libretv/latest/docker-compose.yml b/libretv/latest/docker-compose.yml index 576bb1d70..1bd077477 100644 --- a/libretv/latest/docker-compose.yml +++ b/libretv/latest/docker-compose.yml @@ -9,8 +9,6 @@ services: - "${PANEL_APP_PORT_HTTP}:8080" environment: - PASSWORD=${PASSWORD} - volumes: - - ${DATA_PATH}:/app labels: createdBy: "Apps" From 8df53e62d228f390e363a73c0ed2fbb6dfdf4c96 Mon Sep 17 00:00:00 2001 From: TGY Date: Wed, 11 Jun 2025 10:14:29 +0800 Subject: [PATCH 23/27] update gh-proxy image --- gh-proxy/README.md | 162 ++++++++++++++++------------- gh-proxy/data.yml | 8 +- gh-proxy/latest/.env.sample | 1 + gh-proxy/latest/data.yml | 7 ++ gh-proxy/latest/docker-compose.yml | 7 +- 5 files changed, 105 insertions(+), 80 deletions(-) diff --git a/gh-proxy/README.md b/gh-proxy/README.md index 19c87cc47..3b1b17482 100644 --- a/gh-proxy/README.md +++ b/gh-proxy/README.md @@ -1,118 +1,132 @@ -# gh-proxy +# GHProxy -## 简介 +![GitHub Release](https://img.shields.io/github/v/release/WJQSERVER-STUDIO/ghproxy?display_name=tag&style=flat) +![pull](https://img.shields.io/docker/pulls/wjqserver/ghproxy.svg) +![Docker Image Size (tag)](https://img.shields.io/docker/image-size/wjqserver/ghproxy/latest) +![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/WJQSERVER-STUDIO/ghproxy) +[![Go Report Card](https://goreportcard.com/badge/github.com/WJQSERVER-STUDIO/ghproxy)](https://goreportcard.com/report/github.com/WJQSERVER-STUDIO/ghproxy) -github release、archive以及项目文件的加速项目,支持clone,有Cloudflare Workers无服务器版本以及Python版本 -## 演示 +支持 Git clone、raw、releases的 Github 加速项目, 支持自托管的同时带来卓越的性能与极低的资源占用(Golang和HertZ带来的优势), 同时支持多种额外功能 -[https://gh.api.99988866.xyz/](https://gh.api.99988866.xyz/) +## 项目说明 -演示站为公共服务,如有大规模使用需求请自行部署,演示站有点不堪重负 +### 项目特点 -![imagea272c95887343279.png](https://img.maocdn.cn/img/2021/04/24/imagea272c95887343279.png) +- ⚡ **基于 Go 语言实现,跨平台的同时提供高并发性能** +- 🌐 **使用字节旗下的 [HertZ](https://github.com/cloudwego/hertz) 作为 Web 框架** +- 📡 **使用 [Touka-HTTPC](https://github.com/satomitouka/touka-httpc) 作为 HTTP 客户端** +- 📥 **支持 Git clone、raw、releases 等文件拉取** +- 🐳 **支持反代Docker, GHCR等镜像仓库** +- 🎨 **支持多个前端主题** +- 🚫 **支持自定义黑名单/白名单** +- 🗄️ **支持 Git Clone 缓存(配合 [Smart-Git](https://github.com/WJQSERVER-STUDIO/smart-git))** +- 🐳 **支持自托管与Docker容器化部署** +- ⚡ **支持速率限制** +- ⚡ **支持带宽速率限制** +- 🔒 **支持用户鉴权** +- 🐚 **支持 shell 脚本多层嵌套加速** -当然也欢迎[捐赠](#捐赠)以支持作者 +### 项目相关 -## python版本和cf worker版本差异 +[DEMO](https://ghproxy.1888866.xyz) -- python版本支持进行文件大小限制,超过设定返回原地址 [issue #8](https://github.com/hunshcn/gh-proxy/issues/8) +[TG讨论群组](https://t.me/ghproxy_go) -- python版本支持特定user/repo 封禁/白名单 以及passby [issue #41](https://github.com/hunshcn/gh-proxy/issues/41) +[相关文章](https://blog.wjqserver.com/categories/my-program/) -## 使用 +[GHProxy项目文档](https://wjqserver-docs.pages.dev/docs/ghproxy/) 感谢 [@redbunnys](https://github.com/redbunnys)的维护 -直接在copy出来的url前加`https://gh.api.99988866.xyz/`即可 +### 使用示例 -也可以直接访问,在input输入 +```bash +# 下载文件 +https://ghproxy.1888866.xyz/raw.githubusercontent.com/WJQSERVER-STUDIO/tools-stable/main/tools-stable-ghproxy.sh +https://ghproxy.1888866.xyz/https://raw.githubusercontent.com/WJQSERVER-STUDIO/tools-stable/main/tools-stable-ghproxy.sh -***大量使用请自行部署,以上域名仅为演示使用。*** +# 克隆仓库 +git clone https://ghproxy.1888866.xyz/github.com/WJQSERVER-STUDIO/ghproxy.git +git clone https://ghproxy.1888866.xyz/https://github.com/WJQSERVER-STUDIO/ghproxy.git -访问私有仓库可以通过 +# Docker(OCI) 代理 +docker pull gh.example.com/wjqserver/ghproxy +docker pull gh.example.com/adguard/adguardhome -`git clone https://user:TOKEN@ghproxy.com/https://github.com/xxxx/xxxx` [#71](https://github.com/hunshcn/gh-proxy/issues/71) +docker pull gh.example.com/docker.io/wjqserver/ghproxy +docker pull gh.example.com/docker.io/adguard/adguardhome -以下都是合法输入(仅示例,文件不存在): +docker pull gh.example.com/ghcr.io/openfaas/queue-worker +``` -- 分支源码:https://github.com/hunshcn/project/archive/master.zip +## 部署说明 -- release源码:https://github.com/hunshcn/project/archive/v0.1.0.tar.gz - -- release文件:https://github.com/hunshcn/project/releases/download/v0.1.0/example.zip - -- 分支文件:https://github.com/hunshcn/project/blob/master/filename - -- commit文件:https://github.com/hunshcn/project/blob/1111111111111111111111111111/filename - -- gist:https://gist.githubusercontent.com/cielpy/351557e6e465c12986419ac5a4dd2568/raw/cmd.py - -## cf worker版本部署 - -首页:https://workers.cloudflare.com - -注册,登陆,`Start building`,取一个子域名,`Create a Worker`。 - -复制 [index.js](https://cdn.jsdelivr.net/gh/hunshcn/gh-proxy@master/index.js) 到左侧代码框,`Save and deploy`。如果正常,右侧应显示首页。 - -`ASSET_URL`是静态资源的url(实际上就是现在显示出来的那个输入框单页面) - -`PREFIX`是前缀,默认(根路径情况为"/"),如果自定义路由为example.com/gh/*,请将PREFIX改为 '/gh/',注意,少一个杠都会错! - -## Python版本部署 +可参考文章: https://blog.wjqserver.com/post/ghproxy-deploy-with-smart-git/ ### Docker部署 +- Docker-cli + ``` -docker run -d --name="gh-proxy-py" \ - -p 0.0.0.0:80:80 \ - --restart=always \ - hunsh/gh-proxy-py:latest +docker run -p 7210:8080 -v ./ghproxy/log/run:/data/ghproxy/log -v ./ghproxy/log/caddy:/data/caddy/log -v ./ghproxy/config:/data/ghproxy/config --restart always wjqserver/ghproxy ``` -第一个80是你要暴露出去的端口 +- Docker-Compose (建议使用) -### 直接部署 + 参看[docker-compose.yml](https://github.com/WJQSERVER-STUDIO/ghproxy/blob/main/docker/compose/docker-compose.yml) -安装依赖(请使用python3) +### 二进制文件部署(不推荐) -```pip install flask requests``` +一键部署脚本: -按需求修改`app/main.py`的前几项配置 - -*注意:* 可能需要在`return Response`前加两行 -```python3 -if 'Transfer-Encoding' in headers: - headers.pop('Transfer-Encoding') +```bash +wget -O install.sh https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/main/deploy/install.sh && chmod +x install.sh &&./install.sh ``` -### 注意 +Dev一键部署脚本: -python版本的机器如果无法正常访问github.io会启动报错,请自行修改静态文件url +```bash +wget -O install-dev.sh https://raw.githubusercontent.com/WJQSERVER-STUDIO/ghproxy/dev/deploy/install-dev.sh && chmod +x install-dev.sh && ./install-dev.sh +``` -python版本默认走服务器(2021.3.27更新) +## 配置说明 -## Cloudflare Workers计费 +参看[项目文档](https://github.com/WJQSERVER-STUDIO/ghproxy/blob/main/docs/config.md) -到 `overview` 页面可参看使用情况。免费版每天有 10 万次免费请求,并且有每分钟1000次请求的限制。 +### 前端页面 -如果不够用,可升级到 $5 的高级版本,每月可用 1000 万次请求(超出部分 $0.5/百万次请求)。 +参看[GHProxy-Frontend](https://github.com/WJQSERVER-STUDIO/GHProxy-Frontend) -## Changelog +## 项目简史 -* 2020.04.10 增加对`raw.githubusercontent.com`文件的支持 -* 2020.04.09 增加Python版本(使用Flask) -* 2020.03.23 新增了clone的支持 -* 2020.03.22 初始版本 +**本项目是[WJQSERVER-STUDIO/ghproxy-go](https://github.com/WJQSERVER-STUDIO/ghproxy-go)的重构版本,实现了原项目原定功能的同时,进一步优化了性能** +关于此项目的详细开发过程,请参看Commit记录与[CHANGELOG.md](https://github.com/WJQSERVER-STUDIO/ghproxy/blob/main/CHANGELOG.md) -## 链接 +- v3.0.0 迁移到HertZ框架, 进一步提升效率 +- v2.4.1 对路径匹配进行优化 +- v2.0.0 对`proxy`核心模块进行了重构,大幅优化内存占用 +- v1.0.0 迁移至本仓库,并再次重构内容实现 +- v0.2.0 重构项目实现 -[我的博客](https://hunsh.net) +## LICENSE -## 参考 +本项目使用WJQserver Studio License 2.0 [WJQserver Studio License 2.0](https://wjqserver-studio.github.io/LICENSE/LICENSE.html) -[jsproxy](https://github.com/EtherDream/jsproxy/) +在v2.3.0之前, 本项目使用WJQserver Studio License 1.2 -## 捐赠 +在v1.0.0版本之前,本项目继承于[WJQSERVER-STUDIO/ghproxy-go](https://github.com/WJQSERVER-STUDIO/ghproxy-go)的APACHE2.0 LICENSE VERSION -![wx.png](https://img.maocdn.cn/img/2021/04/24/image.md.png) -![ali.png](https://www.helloimg.com/images/2021/04/24/BK9vmb.md.png) \ No newline at end of file +## 赞助 + +如果您觉得本项目对您有帮助,欢迎赞助支持,您的赞助将用于Demo服务器开支及开发者时间成本支出,感谢您的支持! + +为爱发电,开源不易 + +爱发电: https://afdian.com/a/wjqserver + +USDT(TRC20): `TNfSYG6F2vkiibd6J6mhhHNWDgWgNdF5hN` + +### 捐赠列表 + +| 赞助人 |金额| +|--------|------| +| starry | 8 USDT (TRC20) | \ No newline at end of file diff --git a/gh-proxy/data.yml b/gh-proxy/data.yml index 69d3cb873..31d8db0fc 100644 --- a/gh-proxy/data.yml +++ b/gh-proxy/data.yml @@ -8,12 +8,12 @@ additionalProperties: name: gh-proxy tags: - Tool - shortDescZh: GitHub release、archive 以及项目文件的加速项目 + shortDescZh: 支持 Git clone、raw、releases的 Github 加速项目, 支持自托管的同时带来卓越的性能与极低的资源占用(Golang和HertZ带来的优势), 同时支持多种额外功能 shortDescEn: Acceleration project for GitHub releases, archives, and project files type: tool crossVersionUpdate: true limit: 0 recommend: 0 - website: https://github.com/hunshcn/gh-proxy - github: https://github.com/hunshcn/gh-proxy - document: https://github.com/hunshcn/gh-proxy + website: https://github.com/WJQSERVER-STUDIO/ghproxy + github: https://github.com/WJQSERVER-STUDIO/ghproxy + document: https://github.com/WJQSERVER-STUDIO/ghproxy/blob/main/README.md diff --git a/gh-proxy/latest/.env.sample b/gh-proxy/latest/.env.sample index c807743c2..426854da1 100644 --- a/gh-proxy/latest/.env.sample +++ b/gh-proxy/latest/.env.sample @@ -1,2 +1,3 @@ CONTAINER_NAME="gh-proxy" PANEL_APP_PORT_HTTP="40170" +DATA_PATH="./data" diff --git a/gh-proxy/latest/data.yml b/gh-proxy/latest/data.yml index e6fbca412..f93ba9d5a 100644 --- a/gh-proxy/latest/data.yml +++ b/gh-proxy/latest/data.yml @@ -8,3 +8,10 @@ additionalProperties: required: true rule: paramPort type: number + - default: "./data" + disabled: true + envKey: DATA_PATH + labelEn: Data Path + labelZh: 数据路径 + required: true + type: text diff --git a/gh-proxy/latest/docker-compose.yml b/gh-proxy/latest/docker-compose.yml index 13be61663..eb314929d 100644 --- a/gh-proxy/latest/docker-compose.yml +++ b/gh-proxy/latest/docker-compose.yml @@ -1,12 +1,15 @@ services: gh-proxy: + image: wjqserver/ghproxy:latest container_name: ${CONTAINER_NAME} restart: always networks: - 1panel-network ports: - - "${PANEL_APP_PORT_HTTP}:80" - image: stilleshan/gh-proxy:latest + - "${PANEL_APP_PORT_HTTP}:8080" + volumes: + - ${DATA_PATH}/log:/data/ghproxy/log + - ${DATA_PATH}/config:/data/ghproxy/config labels: createdBy: "Apps" From 7aa24af69f9921ef841f3512730d0188e6254f7b Mon Sep 17 00:00:00 2001 From: TGY Date: Wed, 11 Jun 2025 16:10:04 +0800 Subject: [PATCH 24/27] add ech0 --- ech0/README.md | 184 +++++++++++++++++++++++++++++++++ ech0/data.yml | 19 ++++ ech0/latest/.env.sample | 4 + ech0/latest/data.yml | 26 +++++ ech0/latest/docker-compose.yml | 15 +++ ech0/logo.png | Bin 0 -> 26132 bytes 6 files changed, 248 insertions(+) create mode 100644 ech0/README.md create mode 100644 ech0/data.yml create mode 100644 ech0/latest/.env.sample create mode 100644 ech0/latest/data.yml create mode 100644 ech0/latest/docker-compose.yml create mode 100644 ech0/logo.png diff --git a/ech0/README.md b/ech0/README.md new file mode 100644 index 000000000..c7edf7b05 --- /dev/null +++ b/ech0/README.md @@ -0,0 +1,184 @@ +# Ech0 - 开源、自托管、专注思想流动的轻量级发布平台 + +

+ Ech0 +

+ +Ech0 是一款专为轻量级分享而设计的开源自托管平台,支持快速发布与分享你的想法、文字与链接。简单直观的操作界面,轻松管理你的内容,让分享变得更加自由,确保数据完全掌控,随时随地与世界连接。 + +![界面预览](./docs/imgs/screenshot.png) + +[预览地址](https://memo.vaaat.com/) +[官网地址](https://echo.soopy.cn/) + +--- + +## 核心优势 + +☁️ **原子级轻量**:内存占用、可执行文件、镜像大小均不到**30MB**,单SQLite文件存储架构 +🚀 **极速部署**:无需配置,从安装到使用只需1条命令 +✍️ **零干扰写作**:纯净的在线Markdown编辑器,**支持丰富的Markdown插件与预览** +📦 **数据主权**:所有内容存储于本地SQLite文件,支持RSS订阅 +🎉 **永久免费**:MIT协议开源,无追踪/无订阅/无服务依赖 +🌍 **跨端适配**:完美兼容桌面/移动浏览器,支持手机、iPad、PC三端响应式布局 +👾 **WPA适配**:支持作为Web应用安装 +📝 **内置Todo管理**:轻松记录、管理每日待办事项,帮助你高效规划和追踪任务进度 +🔗 **Ech0 Connect**:全新内容聚合与互联功能,支持多实例间互通、内容订阅与同步,打造属于你的去中心化内容网络 +🎵 **无缝音乐集成**: 内置超低资源占用的音乐播放器,支持本地音频流解析,提供沉浸式背景音乐与专注模式 +🎥 **即时视频分享**: 原生支持哔哩哔哩视频智能解析,输入BV号/链接即可自动提取并嵌入 +🃏 **丰富的快捷卡片**:支持网站链接、GitHub项目等多种富媒体内容一键分享,让信息展示更加直观生动 +⚙️ **高级自定义功能**:为高级用户提供便捷自定义样式与脚本,分享更具表现力 + +--- + +## 3秒极速部署 + +### 🧙 脚本一键部署(推荐) +```shell +curl -fsSL "http://echo.soopy.cn/install.sh" -o install_ech0.sh && bash install_ech0.sh +``` + +### 🐳 docker部署(推荐) + +```shell +docker run -d \ + --name ech0 \ + -p 6277:6277 \ + -v /opt/ech0/data:/app/data \ + -e JWT_SECRET="Hello Echos!" \ + sn0wl1n/ech0:latest +``` + +> 💡 部署完成后访问 ip:6277 即可使用 +> 🚷 建议把`-e JWT_SECRET="Hello Echos!"`里的`Hello Echos!`改成别的内容以提高安全性 +> 📍 首次使用注册的账号会被设置为管理员(目前仅管理员支持发布内容) +> 🎈 数据存储在/opt/ech0/data下 + +### 🐋 docker-componse部署 + +创建一个新目录并将 `docker-compose.yml` 文件放入其中 + +在该目录下执行以下命令启动服务: + +```shell +docker-compose up -d +``` + +## 如何更新 + +### 🔄 Docker部署如何更新 + +```shell +# 停止当前的容器 +docker stop ech0 + +# 移除容器 +docker rm ech0 + +# 拉取最新的镜像 +docker pull sn0wl1n/ech0:latest + +# 启动新版本的容器 +docker run -d \ + --name ech0 \ + -p 6277:6277 \ + -v /opt/ech0/data:/app/data \ + -v /opt/ech0/config/config.yaml:/app/data/config/config.yaml \ + -e JWT_SECRET="Hello Echos!" \ + sn0wl1n/ech0:latest +``` + +### 💎 Docker Compose部署如何更新 + +```shell +# 进入 compose 文件目录 +cd /path/to/compose + +# 拉取最新镜像并重启 +docker-compose pull && \ +docker-compose up -d --force-recreate + +# 清理旧镜像 +docker image prune -f +``` + +--- + +# 🦖 未来目标 + +- [x] 使用裸Vue3重写整个前端 +- [x] 修复一个安全性的问题 +- [x] 重构后端,使其更加优雅高效 +- [ ] 优化各项画面细节 && 增加更多实用功能 +- [ ] 性能优化 && 美化界面 + +--- + +# ❓ 常见问题 + +1. **Ech0是什么?** + Ech0 是一款轻量级的开源自托管平台,专为快速发布与分享个人想法、文字和链接而设计。它提供简洁的界面,支持零干扰的写作体验,所有数据存储于本地,确保用户对内容的完全控制。 + +2. **Ech0 是免费的吗?** + 是的,Ech0 完全免费且开源,遵循 MIT 协议。它没有广告、追踪、订阅或服务依赖。 + +3. **如何进行备份和恢复数据?** + 由于所有内容都存储在本地 SQLite 文件中,您只需备份/opt/ech0/data目录中的文件即可(具体选择部署时的映射路径)。在需要恢复时,直接将备份文件还原即可。 + +4. **Ech0 支持 RSS 吗?** + 是的,Ech0 支持 RSS 订阅,您可以通过 RSS 阅读器订阅您的内容更新。 + +5. **为什么发布失败,提示联系管理员?** + 当前版本设计上,只有管理员可以发布内容。部署后,首个注册的用户会自动被设置为系统管理员,其他用户无法发布内容(可在设置中分配权限)。 + +6. **为什么没有明确的权限划分?** + Ech0 旨在保持简洁和轻量,因此在设计时没有复杂的权限系统。我们希望用户能够专注于分享内容,而不是被复杂的权限管理所困扰。为了保持流畅的使用体验,Ech0 尽量精简了功能,避免不必要的复杂性。(因此目前只有管理员与非管理员之分,所以请谨慎分配你的权限) + +--- + +# 🛠️ 开发 + +🔧 依赖环境 +📌 后端: `Go 1.24.3+` +📌 前端: `NodeJS v22.15.0, PNPM` + +🏗️ 启动 +在Ech0根目录下: + +后端: +```shell +go run cmd/ech0/main.go +``` + +前端(新终端): +```shell +cd web # 进入前端目录 + +pnpm install + +pnpm dev +``` + +--- + +# 🥰 致谢 + +- 感谢 [Gin](https://github.com/gin-gonic/gin) 提供高性能的后端框架支持 +- 感谢 [Md-Editor-V3](https://github.com/imzbf/md-editor-v3) 提供强大易用的 Markdown 编辑器 +- 感谢 [Figma](https://www.figma.com/) 提供便捷的 Logo 设计工具 +- 感谢舍友的 Logo 设计 +- 感谢所有开源社区的贡献者与支持者 + +--- + +# ☕ 支持 + + +🌟 如果你觉得 **Ech0** 不错,欢迎为项目点个 Star!🚀 + +Ech0 完全开源且免费,持续维护和优化离不开大家的支持。如果这个项目对你有所帮助,也欢迎通过赞助支持项目的持续发展。你的每一份鼓励和支持,都是我们前进的动力! +你可以向打赏二维码付款,然后备注你的github名称,将在首页 `README.md` 页面向所有展示你的贡献 + +| 支持平台 | 二维码 | +| :------: | :-------------: | +| [**爱发电**](https://afdian.com/a/l1nsn0w) | Pay | diff --git a/ech0/data.yml b/ech0/data.yml new file mode 100644 index 000000000..92ca12389 --- /dev/null +++ b/ech0/data.yml @@ -0,0 +1,19 @@ +name: ech0 +tags: + - 实用工具 +title: Ech0 - 开源、自托管、专注思想流动的轻量级发布平台 +description: Ech0 - 开源、自托管、专注思想流动的轻量级发布平台 +additionalProperties: + key: ech0 + name: ech0 + tags: + - Tool + shortDescZh: Ech0 是一款专为轻量级分享而设计的开源自托管平台,支持快速发布与分享你的想法、文字与链接。简单直观的操作界面,轻松管理你的内容,让分享变得更加自由,确保数据完全掌控,随时随地与世界连接。 + shortDescEn: Ech0 is an open source hosting platform designed for lightweight sharing, supporting the rapid publishing and sharing of your ideas, text and links. With a simple and intuitive interface, it's easy to manage your content, make sharing more free, ensure full control of your data, and connect with the world anytime, anywhere. + type: tool + crossVersionUpdate: true + limit: 1 + recommend: 0 + website: https://memo.vaaat.com/ + github: https://github.com/lin-snow/Ech0 + document: https://github.com/lin-snow/Ech0/blob/main/README.md diff --git a/ech0/latest/.env.sample b/ech0/latest/.env.sample new file mode 100644 index 000000000..b97016182 --- /dev/null +++ b/ech0/latest/.env.sample @@ -0,0 +1,4 @@ +CONTAINER_NAME="ech0" +DATA_PATH="./data" +PANEL_APP_PORT_HTTP="40120" +JWT_SECRET="secret" diff --git a/ech0/latest/data.yml b/ech0/latest/data.yml new file mode 100644 index 000000000..ecb3baf59 --- /dev/null +++ b/ech0/latest/data.yml @@ -0,0 +1,26 @@ +additionalProperties: + formFields: + - default: "./data" + edit: true + envKey: DATA_PATH + labelEn: Data Path + labelZh: 数据路径 + required: true + type: text + - default: 40120 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: "secret" + edit: true + envKey: JWT_SECRET + labelEn: JWT Secret + labelZh: JWT密钥 + random: true + required: true + rule: paramComplexity + type: password diff --git a/ech0/latest/docker-compose.yml b/ech0/latest/docker-compose.yml new file mode 100644 index 000000000..621c82293 --- /dev/null +++ b/ech0/latest/docker-compose.yml @@ -0,0 +1,15 @@ +services: + ech0: + image: sn0wl1n/ech0:latest + container_name: ${CONTAINER_NAME} + restart: always + ports: + - "${PANEL_APP_PORT_HTTP}:6277" + volumes: + - ${DATA_PATH}/data:/app/data + environment: + - JWT_SECRET="${JWT_SECRET}" + networks: + - 1panel-network + labels: + createdBy: "Apps" diff --git a/ech0/logo.png b/ech0/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8ea37192452137714aef53dcbacc4223c8bea68b GIT binary patch literal 26132 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 m=1EpEK Date: Wed, 11 Jun 2025 16:14:39 +0800 Subject: [PATCH 25/27] update ech0 --- ech0/latest/docker-compose.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ech0/latest/docker-compose.yml b/ech0/latest/docker-compose.yml index 621c82293..653f59ada 100644 --- a/ech0/latest/docker-compose.yml +++ b/ech0/latest/docker-compose.yml @@ -13,3 +13,8 @@ services: - 1panel-network labels: createdBy: "Apps" + + +networks: + 1panel-network: + external: true From 229604d8a36fbab8d7ef6dedb5d8042d7fab4053 Mon Sep 17 00:00:00 2001 From: TGY Date: Tue, 24 Jun 2025 14:02:40 +0800 Subject: [PATCH 26/27] add openlist --- openlist/README.md | 127 +++++++++++++++++++++++++++++ openlist/data.yml | 19 +++++ openlist/latest/.env.sample | 4 + openlist/latest/data.yml | 24 ++++++ openlist/latest/docker-compose.yml | 23 ++++++ openlist/logo.png | Bin 0 -> 3647 bytes 6 files changed, 197 insertions(+) create mode 100644 openlist/README.md create mode 100644 openlist/data.yml create mode 100644 openlist/latest/.env.sample create mode 100644 openlist/latest/data.yml create mode 100644 openlist/latest/docker-compose.yml create mode 100644 openlist/logo.png diff --git a/openlist/README.md b/openlist/README.md new file mode 100644 index 000000000..a66335c6c --- /dev/null +++ b/openlist/README.md @@ -0,0 +1,127 @@ +
+ logo +

🗂一个支持多存储的文件列表程序,使用 Gin 和 SolidJS,基于 AList 项目 fork 开发

+ + +
+ +--- + +> [!IMPORTANT] +> +> 一个更可信、可持续的 AList 开源替代方案,防范未来可能的闭源、黑箱或不可信变更。 +> +> 我们诚挚地感谢原项目 [AlistGo/alist](https://github.com/AlistGo/alist) 的作者 [Xhofe](https://github.com/Xhofe) 以及其他所有贡献者。 +> +> 本 Fork 尚未稳定, 具体迁移进度可在 [OpenList 迁移工作总结](https://github.com/OpenListTeam/OpenList/issues/6) 中查看。 + +[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] [分秒帧](https://www.mediatrack.cn/) + - [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 (详细文档待补充) +- [ ] Docker 部署(重建中) +- [x] Cloudflare workers 中转 +- [x] 文件/文件夹打包下载 +- [x] 网页上传(可以允许访客上传),删除,新建文件夹,重命名,移动,复制 +- [x] 离线下载 +- [x] 跨存储复制文件 +- [x] 单线程下载/串流的多线程下载加速 + +## 文档 + +- https://docs.oplist.org +- https://docs.openlist.team + +## Demo + +N/A(重建中) + +## 讨论 + +一般问题请到 [*Discussions*](https://github.com/OpenListTeam/OpenList/discussions) 讨论,***Issues* 仅针对错误报告和功能请求。** + +## 贡献者 + +感谢这些开源作者们: + +[![Contributors](https://contrib.rocks/image?repo=OpenListTeam/OpenList)](https://github.com/OpenListTeam/OpenList/graphs/contributors) + +## 许可 + +`OpenList` 是按 AGPL-3.0 许可证许可的开源软件。 + +## 免责声明 + +- 本程序为免费开源项目,旨在分享网盘文件,方便下载以及学习golang,使用时请遵守相关法律法规,请勿滥用; +- 本程序通过调用官方sdk/接口实现,无破坏官方接口行为; +- 本程序仅做302重定向/流量转发,不拦截、存储、篡改任何用户数据; +- 在使用本程序之前,你应了解并承担相应的风险,包括但不限于账号被ban,下载限速等,与本程序无关; +- 如有侵权,请联系[OpenListTeam](https://github.com/OpenListTeam),团队会及时处理。 + +--- + +> [@GitHub](https://github.com/OpenListTeam) · [Telegram 交流群](https://t.me/OpenListTeam) · [Telegram 频道](https://t.me/OpenListOfficial) \ No newline at end of file diff --git a/openlist/data.yml b/openlist/data.yml new file mode 100644 index 000000000..70209b3b4 --- /dev/null +++ b/openlist/data.yml @@ -0,0 +1,19 @@ +name: OpenList +tags: + - 工具 +title: 一个支持多存储的文件列表程序 +description: 一个支持多存储的文件列表程序,使用 Gin 和 SolidJS,基于 AList 项目 fork 开发 +additionalProperties: + key: openlist + name: OpenList + tags: + - Tool + shortDescZh: 一个支持多存储的文件列表程序,使用 Gin 和 SolidJS,基于 AList 项目 fork 开发 + shortDescEn: A file list program that supports multiple storage + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://github.com/OpenListTeam + github: https://github.com/OpenListTeam + document: https://docs.oplist.org/zh/ diff --git a/openlist/latest/.env.sample b/openlist/latest/.env.sample new file mode 100644 index 000000000..bc431768a --- /dev/null +++ b/openlist/latest/.env.sample @@ -0,0 +1,4 @@ +CONTAINER_NAME="openlist" +PANEL_APP_PORT_HTTP="40034" +DATA_PATH="./data/data" +MOUNT_PATH="./data/mnt" \ No newline at end of file diff --git a/openlist/latest/data.yml b/openlist/latest/data.yml new file mode 100644 index 000000000..926c16795 --- /dev/null +++ b/openlist/latest/data.yml @@ -0,0 +1,24 @@ +additionalProperties: + formFields: + - default: 40034 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: ./data/data + edit: true + envKey: DATA_PATH + labelEn: Data folder path + labelZh: 数据文件夹路径 + required: true + type: text + - default: ./data/mnt + edit: true + envKey: MOUNT_PATH + labelEn: Mount folder path + labelZh: 挂载文件夹路径 + required: true + type: text diff --git a/openlist/latest/docker-compose.yml b/openlist/latest/docker-compose.yml new file mode 100644 index 000000000..315d3a18a --- /dev/null +++ b/openlist/latest/docker-compose.yml @@ -0,0 +1,23 @@ +services: + alist: + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:5244" + volumes: + - "${DATA_PATH}:/opt/openlist/data" + - "${MOUNT_PATH}:/mnt/data" + environment: + - PUID=0 + - PGID=0 + - UMASK=022 + image: openlistteam/openlist:latest + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true + diff --git a/openlist/logo.png b/openlist/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..70282047f8dddb9f73ca9836554c73a95d46aa64 GIT binary patch literal 3647 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 RWcEY|urRYZ`x@g-`5%LJrKA7= literal 0 HcmV?d00001 From cddafd49b6352639cdbcb1788fc18ecd7e43071d Mon Sep 17 00:00:00 2001 From: TGY Date: Fri, 27 Jun 2025 09:54:59 +0800 Subject: [PATCH 27/27] add moontv --- moontv/README.md | 206 +++++++++++++++++++++++++++++++ moontv/data.yml | 19 +++ moontv/latest/data.yml | 17 +++ moontv/latest/docker-compose.yml | 18 +++ moontv/logo.png | Bin 0 -> 204479 bytes 5 files changed, 260 insertions(+) create mode 100644 moontv/README.md create mode 100644 moontv/data.yml create mode 100644 moontv/latest/data.yml create mode 100644 moontv/latest/docker-compose.yml create mode 100644 moontv/logo.png diff --git a/moontv/README.md b/moontv/README.md new file mode 100644 index 000000000..a608de9cc --- /dev/null +++ b/moontv/README.md @@ -0,0 +1,206 @@ +# MoonTV + +
+ LibreTV Logo +
+ +> 🎬 **MoonTV** 是一个开箱即用的、跨平台的影视聚合播放器。它基于 **Next.js 14** + **Tailwind CSS** + **TypeScript** 构建,支持多资源搜索、在线播放、收藏同步、播放记录、本地/云端存储,让你可以随时随地畅享海量免费影视内容。 + +
+ +![Next.js](https://img.shields.io/badge/Next.js-14-000?logo=nextdotjs) +![TailwindCSS](https://img.shields.io/badge/TailwindCSS-3-38bdf8?logo=tailwindcss) +![TypeScript](https://img.shields.io/badge/TypeScript-4.x-3178c6?logo=typescript) +![License](https://img.shields.io/badge/License-MIT-green) +![Docker Ready](https://img.shields.io/badge/Docker-ready-blue?logo=docker) + +
+ +--- + +## ✨ 功能特性 + +- 🔍 **多源聚合搜索**:内置数十个免费资源站点,一次搜索立刻返回全源结果。 +- 📄 **丰富详情页**:支持剧集列表、演员、年份、简介等完整信息展示。 +- ▶️ **流畅在线播放**:集成 HLS.js & VidStack。 +- ❤️ **收藏 + 继续观看**:LocalStorage 存储,后续扩展 DB 存储。 +- 📱 **PWA**:离线缓存、安装到桌面/主屏,移动端原生体验。 +- 🌗 **响应式布局**:桌面侧边栏 + 移动底部导航,自适应各种屏幕尺寸。 +- 🚀 **极简部署**:一条 Docker 命令即可将完整服务跑起来,或免费部署到 Vercel。 +- 👿 **智能去广告**:自动跳过视频中的切片广告(实验性) + +
+ 点击查看项目截图 + 项目截图 +
+ +## 🗺 目录 + +- [技术栈](#技术栈) +- [部署](#部署) +- [环境变量](#环境变量) +- [配置说明](#配置说明) +- [Roadmap](#roadmap) +- [安全与隐私提醒](#安全与隐私提醒) +- [License](#license) +- [致谢](#致谢) + +## 技术栈 + +| 分类 | 主要依赖 | +| --------- | --------------------------------------------------------------------------------- | +| 前端框架 | [Next.js 14](https://nextjs.org/) · App Router | +| UI & 样式 | [Tailwind CSS 3](https://tailwindcss.com/) | +| 语言 | TypeScript 4 | +| 播放器 | [VidStack](https://vidstack.io/) · [HLS.js](https://github.com/video-dev/hls.js/) | +| 代码质量 | ESLint · Prettier · Jest | +| 部署 | Docker · Vercel | + +## 部署 + +本项目支持 Vercel 和 Docker 部署,注意**不支持 Cloudflare**,后续亦无支持计划。 + +### Vercel 部署 + +> 推荐使用,零运维成本,免费额度足够个人使用。 + +1. **Fork** 本仓库到你的 GitHub 账户。 +2. 登陆 [Vercel](https://vercel.com/),点击 **Add New → Project**,选择 Fork 后的仓库。 +3. (强烈建议)设置 PASSWORD 环境变量。 +4. 保持默认设置完成首次部署。 +5. 如需自定义 `config.json`,请直接修改 Fork 后仓库中该文件。 +6. 每次 Push 到 `main` 分支将自动触发重新构建。 + +部署完成后即可通过分配的域名访问,也可以绑定自定义域名。 + +### Docker 部署 + +> 适用于自建服务器 / NAS / 群晖等场景。 + +#### 1. 直接运行(最简单) + +```bash +# 拉取预构建镜像 +docker pull ghcr.io/senshinya/moontv:latest + +# 运行容器 +# -d: 后台运行 -p: 映射端口 3000 -> 3000 +docker run -d --name moontv -p 3000:3000 ghcr.io/senshinya/moontv:latest +``` + +访问 `http://服务器 IP:3000` 即可。 + +#### 2. docker-compose 示例 + +```yaml +version: '3.9' +services: + moontv: + image: ghcr.io/senshinya/moontv:latest + container_name: moontv + restart: unless-stopped + ports: + - '3000:3000' + environment: + - PASSWORD=your_password + # 如需自定义配置,可挂载文件 + # volumes: + # - ./config.json:/app/config.json:ro +``` + +执行: + +```bash +docker compose up -d +``` + +随后同样访问 `http://服务器 IP:3000`。 + +### **请勿使用 Pull Bot 自动同步** + +Pull Bot 会反复触发无效的 PR 和垃圾邮件,严重干扰项目维护。作者可能会直接拉黑所有 Pull Bot 自动发起的同步请求的仓库所有者。 + +**推荐做法:** + +建议在 fork 的仓库中启用本仓库自带的 GitHub Actions 自动同步功能(见 `.github/workflows/sync.yml`)。 + +如需手动同步主仓库更新,也可以使用 GitHub 官方的 [Sync fork](https://docs.github.com/cn/github/collaborating-with-issues-and-pull-requests/syncing-a-fork) 功能。 + +## 环境变量 + +| 变量 | 说明 | 可选值 | 默认值 | +| ----------------------------------- | ---------------------------------- | ---------------------------------------------------------------- | ------------ | +| PASSWORD | 实例访问密码,留空则不启用密码保护 | 任意字符串 | (空) | +| NEXT_PUBLIC_STORAGE_TYPE | 播放记录/收藏的存储方式 | localstorage(本地浏览器存储)、database(后端数据库,暂不支持) | localstorage | +| NEXT_PUBLIC_ENABLE_BLOCKAD | 开启智能去广告功能(实验性) | true / false | false | +| NEXT_PUBLIC_SEARCH_MAX_PAGE | 搜索接口可拉取的最大页数 | 1-50 | 5 | +| NEXT_PUBLIC_AGGREGATE_SEARCH_RESULT | 搜索结果默认是否按标题和年份聚合 | true / false | true | + +## 配置说明 + +所有可自定义项集中在根目录的 `config.json` 中: + +```json +{ + "cache_time": 7200, + "api_site": { + "dyttzy": { + "api": "http://caiji.dyttzyapi.com/api.php/provide/vod", + "name": "电影天堂资源", + "detail": "http://caiji.dyttzyapi.com" + } + // ...更多站点 + } +} +``` + +- `cache_time`:接口缓存时间(秒)。 +- `api_site`:你可以增删或替换任何资源站,字段说明: + - `key`:唯一标识,保持小写字母/数字。 + - `api`:资源站提供的 `vod` JSON API 根地址。 + - `name`:在人机界面中展示的名称。 + - `detail`:(可选)部分无法通过 API 获取剧集详情的站点,需要提供网页详情根 URL,用于爬取。 + +MoonTV 支持标准的苹果 CMS V10 API 格式。 + +修改后 **无需重新构建**,服务会在启动时读取一次。 + +## Roadmap + +- [ ] DB 存储 +- [ ] 深色模式 + +## 安全与隐私提醒 + +### 强烈建议设置密码保护 + +为了您的安全和避免潜在的法律风险,我们**强烈建议**在部署时设置密码保护: + +- **避免公开访问**:不设置密码的实例任何人都可以访问,可能被恶意利用 +- **防范版权风险**:公开的视频搜索服务可能面临版权方的投诉举报 +- **保护个人隐私**:设置密码可以限制访问范围,保护您的使用记录 + +### 部署建议 + +1. **设置环境变量 `PASSWORD`**:为您的实例设置一个强密码 +2. **仅供个人使用**:请勿将您的实例链接公开分享或传播 +3. **遵守当地法律**:请确保您的使用行为符合当地法律法规 + +### 重要声明 + +- 本项目仅供学习和个人使用 +- 请勿将部署的实例用于商业用途或公开服务 +- 如因公开分享导致的任何法律问题,用户需自行承担责任 +- 项目开发者不对用户的使用行为承担任何法律责任 + +## License + +[MIT](LICENSE) © 2025 MoonTV & Contributors + +## 致谢 + +- [ts-nextjs-tailwind-starter](https://github.com/theodorusclarence/ts-nextjs-tailwind-starter) — 项目最初基于该脚手架。 +- [LibreTV](https://github.com/LibreSpark/LibreTV) — 由此启发,站在巨人的肩膀上。 +- [VidStack](https://vidstack.io/) — 提供强大的网页视频播放器。 +- [HLS.js](https://github.com/video-dev/hls.js) — 实现 HLS 流媒体在浏览器中的播放支持。 +- 感谢所有提供免费影视接口的站点。 \ No newline at end of file diff --git a/moontv/data.yml b/moontv/data.yml new file mode 100644 index 000000000..c043d93a1 --- /dev/null +++ b/moontv/data.yml @@ -0,0 +1,19 @@ +name: moontv +tags: + - 实用工具 +title: moontv - 免费在线视频搜索与观看平台 +description: 🎬 MoonTV 是一个开箱即用的、跨平台的影视聚合播放器。它基于 Next.js 14 + Tailwind CSS + TypeScript 构建,支持多资源搜索、在线播放、收藏同步、播放记录、本地/云端存储,让你可以随时随地畅享海量免费影视内容。 +additionalProperties: + key: moontv + name: moontv + tags: + - Tool + shortDescZh: moontv - 免费在线视频搜索与观看平台 + shortDescEn: moontv - Free Online Video Search and Viewing Platform + type: tool + crossVersionUpdate: true + limit: 0 + recommend: 0 + website: https://github.com/senshinya/MoonTV + github: https://github.com/senshinya/MoonTV + document: https://github.com/senshinya/MoonTV/blob/main/README.md diff --git a/moontv/latest/data.yml b/moontv/latest/data.yml new file mode 100644 index 000000000..3c113dfe7 --- /dev/null +++ b/moontv/latest/data.yml @@ -0,0 +1,17 @@ +additionalProperties: + formFields: + - default: 40249 + edit: true + envKey: PANEL_APP_PORT_HTTP + labelEn: Port + labelZh: 端口 + required: true + rule: paramPort + type: number + - default: "" + edit: true + envKey: PASSWORD + labelEn: Password + labelZh: 密码 + required: true + type: text diff --git a/moontv/latest/docker-compose.yml b/moontv/latest/docker-compose.yml new file mode 100644 index 000000000..3976ce7b8 --- /dev/null +++ b/moontv/latest/docker-compose.yml @@ -0,0 +1,18 @@ +services: + moontv: + image: ghcr.io/senshinya/moontv:latest + container_name: ${CONTAINER_NAME} + restart: always + networks: + - 1panel-network + ports: + - "${PANEL_APP_PORT_HTTP}:3000" + environment: + - PASSWORD=${PASSWORD} + - NEXT_PUBLIC_ENABLE_BLOCKAD=true + labels: + createdBy: "Apps" + +networks: + 1panel-network: + external: true diff --git a/moontv/logo.png b/moontv/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..184fdaca378382239f0692d1f48bd56b254d420f GIT binary patch literal 204479 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 literal 0 HcmV?d00001