Compare commits

...

40 Commits

Author SHA1 Message Date
e4d09a75af update wps302 worker url 2025-11-12 21:47:50 +08:00
ced865ae96 Update README 2025-11-10 10:49:26 +08:00
39d62d4790 update apt-ftparchive release 2025-11-09 22:37:43 +08:00
612536ca51 refactor: list page 2025-11-06 15:45:37 +08:00
a775745284 style: update 2025-11-05 11:08:32 +08:00
ced4424f7f add eudic 2025-11-04 15:17:41 +08:00
8c5f96e24c add remotedesktopmanager repo 2025-11-03 20:32:49 +08:00
88b986a35c fix: 修正 Packages 字段提取 2025-11-03 20:30:07 +08:00
cdc21a78f2 add wezterm repo 2025-11-03 20:21:06 +08:00
3a1b8e0c96 fix: 修改 Packages 分割方式 2025-11-03 20:16:26 +08:00
51fad100c8 add freedownloadmanager repo 2025-10-15 10:36:00 +08:00
714b0ff576 update mihomo 2025-10-15 10:29:22 +08:00
fd616b3ea4 fix sunloginclient 2025-10-15 10:28:50 +08:00
30b2f2e08f style: update merge-apt-repo.py 2025-10-09 17:35:51 +08:00
190f50bc95 add yesplaymusic 2025-10-09 17:19:26 +08:00
1678e35a07 revert: remove debiancn repo, restore wps-office 2025-10-06 19:14:47 +08:00
16d46f3c82 add simplenote 2025-10-06 18:37:38 +08:00
204d14c4a0 add fooyin 2025-10-06 18:33:51 +08:00
399261f4ad add spotify-client repo 2025-10-06 18:30:35 +08:00
5f6dac91cf add anydesk repo 2025-10-06 18:29:33 +08:00
2ba745fc2e add chrome-remote-desktop repo 2025-10-06 18:25:07 +08:00
43876bf6d3 add winboat 2025-09-29 18:30:08 +08:00
33b5e1d84f add splayer 2025-09-27 09:54:04 +08:00
fc5254f4cb update qqmusic 2025-09-26 10:22:47 +08:00
8f20346faa refactor: save packages info to file 2025-09-25 10:04:18 +08:00
dfc8f6d33c fix: limit the number of parameters 2025-09-26 10:09:37 +08:00
f3ae9e3036 add mqttx 2025-09-24 19:39:00 +08:00
9396a8f906 update linuxqq 2025-09-20 22:10:07 +08:00
50cf51934d add kali-undercover 2025-06-26 10:54:03 +08:00
21b15b8503 add tinyrdm 2025-06-26 10:46:05 +08:00
960790f38e add spark-store 2025-06-26 10:43:02 +08:00
47c3b40246 feat: Support for Git hosting sites like Github 2025-06-26 10:40:31 +08:00
e776e0b535 update bytedance-feishu-stable 2025-06-11 19:34:51 +08:00
e5fa6d8670 add joplin 2025-05-22 00:35:48 +08:00
4f021103db chore: add Dockerfile 2025-05-14 18:45:06 +08:00
0a1d12e2fd refactor: use apt_pkg replace dpkg for version comparison 2025-05-14 00:42:42 +08:00
d1bffe02dd add neovide, himalaya repo; remove black-desk repo 2025-05-09 12:12:21 +08:00
d1c2e4bbe7 add arm64 version of flclash 2025-05-01 10:18:34 +08:00
cd3410180f refactor: change repo format to official archive 2025-04-14 16:22:16 +08:00
5b70322258 feat: add archive packages 2025-04-14 16:15:18 +08:00
32 changed files with 574 additions and 211 deletions

4
.gitignore vendored
View File

@ -1,4 +1,6 @@
data/github-local.json data/github-local.json
data/deb.db data/deb.db
deb/ *.deb
*Packages
*Release*
__pycache__/ __pycache__/

17
Dockerfile Normal file
View File

@ -0,0 +1,17 @@
FROM debian:12-slim
RUN apt-get update && \
apt-get install -y --no-install-recommends \
apt-utils \
python3-apt \
python3-requests \
curl \
jq \
gpg \
gpg-agent && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
WORKDIR /mnt
CMD ["/bin/bash"]

View File

@ -1,29 +1,30 @@
# wcbing APT 软件源/仓库 # wcbing APT 软件源/仓库
适用于 Debian-based 发行版Debian/Ubuntu/Mint/...)的 APT 软件源/仓库,收集一些国内常用软件的二进制包。 适用于 Debian-based 发行版Debian/Ubuntu/Mint/...)的 APT 软件源/仓库,收集一些常用软件的二进制包。
本仓库仅提供链接重定向功能,致力于在不改动 APT 的情况下实现类似 WinGet、Homebrew Cask 等仅提供仓库索引的效果。 ## 特色功能
- 本仓库仅提供链接重定向功能,在不改动 APT 的情况下实现了类似 WinGet、Homebrew Cask 等仅提供仓库索引的效果,确保了来源的安全可靠并规避了分发二进制文件可能导致的版权风险。
- 添加国内常用软件,更适合中国用户使用。
- 支持 AppStream实验性可以与你喜欢的图形软件商店如 GNOME Software、KDE Plasma Discover结合使用。
## 使用现有仓库 ## 使用仓库
[现有仓库实例](https://packages.wcbing.top/deb/)查看使用方法。 点击 [现有仓库实例](https://packages.wcbing.top/deb/) 查看,里面有使用方法和[仓库内容列表](https://packages.wcbing.top/deb/list/)
## 收录的软件说明 ## 收录的软件说明
- 现主要服务 x86_64 用户,同时实验性支持 arm64。 - 现主要服务 x86_64 用户,同时实验性支持 arm64。
如有需要请参考最后一节自行建立仓库。 如有需要请参考最后一节自行建立仓库。
- 主要收录官方打包发布的文件,不接受第三方自行打包的商业软件 - 非开源、商业软件只收录官方打包发布的文件,不接受第三方自行打包的。
- 有固定的更新地址,如官网、官方仓库或 Github Releases。 - 有固定的更新地址,如官网、官方仓库或 Github Releases。
- 不收录打包的 wine 应用、Android 应用。 - 不收录打包的 wine 应用、Android 应用。
- 不收录图标、主题、字体等包,以后可能单独建一个相关仓库。 - 不收录图标、主题、字体等包,这些单独建一个相关仓库。
## 已收录软件 ## 部分已收录软件
> 部分应用长时间不更新,可能不会如下面一样编写脚本,最终请以 apt 查询到的为准。 ### 部分自行收集软件
### 自行收集
| 软件名 | 包名 | amd64 | arm64 | | 软件名 | 包名 | amd64 | arm64 |
| ----- | ---- | ----- | ----- | | ----- | ---- | ----- | ----- |
@ -31,9 +32,10 @@
| [QQ音乐](https://y.qq.com/download/download.html) | qqmusic | ✅ | | | [QQ音乐](https://y.qq.com/download/download.html) | qqmusic | ✅ | |
| [腾讯会议](https://meeting.tencent.com/download/) | wemeet | ✅ | ✅ | | [腾讯会议](https://meeting.tencent.com/download/) | wemeet | ✅ | ✅ |
| [腾讯文档](https://docs.qq.com/home/download) | tdappdesktop | ✅ | ✅ | | [腾讯文档](https://docs.qq.com/home/download) | tdappdesktop | ✅ | ✅ |
| [WPS Office](https://linux.wps.cn/) | wps-office | ✅ | |
| [百度网盘](https://pan.baidu.com/download) | baidunetdisk | ✅ | | | [百度网盘](https://pan.baidu.com/download) | baidunetdisk | ✅ | |
| [钉钉](https://www.dingtalk.com/download/) | com.alibabainc.dingtalk | ✅ | ✅ | | [钉钉](https://www.dingtalk.com/download/) | com.alibabainc.dingtalk | ✅ | ✅ |
| [飞书](https://www.feishu.cn/download) | bytedance-feishu-stable | ✅ | | | [飞书](https://www.feishu.cn/download) | bytedance-feishu-stable | ✅ | |
| [Xmind](https://xmind.cn/download/) | xmind-vana | ✅ | | | [Xmind](https://xmind.cn/download/) | xmind-vana | ✅ | |
| [uTools](https://u.tools/download/) | utools | ✅ | | | [uTools](https://u.tools/download/) | utools | ✅ | |
| [360安全浏览器](https://browser.360.net/gc/) | browser360-cn-stable | ✅ | | | [360安全浏览器](https://browser.360.net/gc/) | browser360-cn-stable | ✅ | |
@ -41,17 +43,18 @@
| [向日葵](https://sunlogin.oray.com/download/linux) | sunloginclient<br />提取自 Debian 12 的依赖:<br />gconf2-common<br />libgconf-2-4 | ✅ | | | [向日葵](https://sunlogin.oray.com/download/linux) | sunloginclient<br />提取自 Debian 12 的依赖:<br />gconf2-common<br />libgconf-2-4 | ✅ | |
| [ToDesk](https://www.todesk.com/linux.html) | todesk | ✅ | | | [ToDesk](https://www.todesk.com/linux.html) | todesk | ✅ | |
| [微信](https://linux.weixin.qq.com/) | wechat | ✅ | ✅ | | [微信](https://linux.weixin.qq.com/) | wechat | ✅ | ✅ |
| [kali-undercover](https://www.kali.org/docs/introduction/kali-undercover/) | kali-undercover | ✅ | ✅ |
| [欧路词典](https://www.eudic.net/v4/en/app/download) | eudic | ✅ | |
### Github Releses ### Github Releses
> 因服务器资源有限,本仓库可能无法收录部分大文件。 > 也可投稿至星火商店的 [Github Releases 更新配置仓库](https://gitee.com/spark-building-service/github),其和本部分内容是同源的。
> 有收录需求也可投稿至星火商店的 [Github Releases 更新配置仓库](https://gitee.com/spark-building-service/github),其和本部分内容是同源的。
| 软件名 | 包名 | amd64 | arm64 | | 软件名 | 包名 | amd64 | arm64 |
| ----- | ---- | ----- | ----- | | ----- | ---- | ----- | ----- |
| [Clash Verge Rev](https://github.com/clash-verge-rev/clash-verge-rev) | clash-verge | ✅ | ✅ | | [Clash Verge Rev](https://github.com/clash-verge-rev/clash-verge-rev) | clash-verge | ✅ | ✅ |
| [FlClash](https://github.com/chen08209/FlClash) | flclash | ✅ | | | [FlClash](https://github.com/chen08209/FlClash) | flclash | ✅ | |
| [mihomo](https://github.com/MetaCubeX/mihomo) | mihomo | ✅ | ✅ | | [mihomo](https://github.com/MetaCubeX/mihomo) | mihomo | ✅ | ✅ |
| [hugo](https://github.com/gohugoio/hugo) | hugo | ✅ | ✅ | | [hugo](https://github.com/gohugoio/hugo) | hugo | ✅ | ✅ |
| [RustDesk](https://github.com/rustdesk/rustdesk) | rustdesk | ✅ | ✅ | | [RustDesk](https://github.com/rustdesk/rustdesk) | rustdesk | ✅ | ✅ |
@ -68,14 +71,30 @@
| [Caddy](https://github.com/caddyserver/caddy) | caddy | ✅ | ✅ | | [Caddy](https://github.com/caddyserver/caddy) | caddy | ✅ | ✅ |
| [code-server](https://github.com/coder/code-server) | code-server | ✅ | ✅ | | [code-server](https://github.com/coder/code-server) | code-server | ✅ | ✅ |
| [DBeaver](https://github.com/dbeaver/dbeaver) | dbeaver-ce | ✅ | | | [DBeaver](https://github.com/dbeaver/dbeaver) | dbeaver-ce | ✅ | |
| [Joplin](https://github.com/laurent22/joplin) | joplin | ✅ | |
| [Tiny RDM](https://github.com/tiny-craft/tiny-rdm) | tinyrdm | ✅ | |
| [MQTTX](https://github.com/emqx/MQTTX) | mqttx | ✅ | ✅ |
| [SPlayer](https://github.com/imsyy/SPlayer) | splayer | ✅ | |
| [WinBoat](https://github.com/TibixDev/winboat) | winboat | ✅ | |
| [fooyin](https://github.com/fooyin/fooyin) | fooyin | ✅ | |
| [Simplenote](https://github.com/Automattic/simplenote-electron) | simplenote | ✅ | ✅ |
| [YesPlayMusic](https://github.com/qier222/YesPlayMusic) | yesplaymusic | ✅ | ✅ |
### 合并自现有 repo #### Gitee
| 软件名 | 包名 | amd64 | arm64 |
| ----- | --- | ----- | ----- |
| [星火应用商店](https://gitee.com/spark-store-project/spark-store) | spark-store | ✅ | ✅ |
### 合并自现有官方仓库
| 软件仓库 | 包名 | amd64 | arm64 | | 软件仓库 | 包名 | amd64 | arm64 |
| ------ | ---- | ----- | ----- | | ------ | ---- | ----- | ----- |
| [Mozilla Firefox](https://support.mozilla.org/zh-CN/kb/install-firefox-linux) | firefox<br />firefox_beta<br />firefox_devedition<br />firefox_nightly<br />firefox_esr<br />mozillavpn | ✅ | ✅ | | [Mozilla Firefox](https://support.mozilla.org/zh-CN/kb/install-firefox-linux) | firefox<br />firefox_beta<br />firefox_devedition<br />firefox_nightly<br />firefox_esr<br />mozillavpn | ✅ | ✅ |
| Google Chrome | google-chrome-stable<br />google-chrome-beta<br />google-chrome-unstable | ✅ | | | Google Chrome | google-chrome-stable<br />google-chrome-beta<br />google-chrome-unstable | ✅ | |
| Google Earth | google-earth-pro-stable<br />google-earth-ec-stable | ✅ | | | Google Earth | google-earth-pro-stable<br />google-earth-ec-stable | ✅ | |
| Chrome Remote Desktop | chrome-remote-desktop | ✅ | |
| Microsoft Edge | microsoft-edge-stable<br />microsoft-edge-beta<br />microsoft-edge-dev | ✅ | | | Microsoft Edge | microsoft-edge-stable<br />microsoft-edge-beta<br />microsoft-edge-dev | ✅ | |
| Opera | opera-stable<br />opera-beta<br />opera-developer | ✅ | | | Opera | opera-stable<br />opera-beta<br />opera-developer | ✅ | |
| Visual Studio Code | code<br />code-insiders<br />code-exploration | ✅ | ✅ | | Visual Studio Code | code<br />code-insiders<br />code-exploration | ✅ | ✅ |
@ -83,7 +102,8 @@
| [Sublime Text<br />Sublime Merge](https://www.sublimetext.com/docs/linux_repositories.html) | sublime-text<br />sublime-merge | ✅ | ✅ | | [Sublime Text<br />Sublime Merge](https://www.sublimetext.com/docs/linux_repositories.html) | sublime-text<br />sublime-merge | ✅ | ✅ |
| [Steam](https://repo.steampowered.com/steam/) | steam-launcher<br />steam-libs-amd64 | ✅ | | | [Steam](https://repo.steampowered.com/steam/) | steam-launcher<br />steam-libs-amd64 | ✅ | |
| [Tailscale](https://pkgs.tailscale.com/stable/) | tailscale<br />tailscale-nginx-auth | ✅ | ✅ | | [Tailscale](https://pkgs.tailscale.com/stable/) | tailscale<br />tailscale-nginx-auth | ✅ | ✅ |
| [black-desk 打包](https://github.com/black-desk/debs) | app.typst.typst<br />dev.neovide.neovide<br />dev.zed.zed<br />dev.zed.zed-pre<br />~~io.github.black-desk.debian-tweak<br />io.neovim.neovim<br />io.neovim.neovim-nightly<br />one.metacubex.clash-meta~~<br />org.pimalaya.himalaya | ✅ | | | [neovide: wcbing 打包](https://github.com/wcbing-build/neovide-debs) | neovide | ✅ | |
| [himalaya: wcbing 打包](https://github.com/wcbing-build/himalaya-debs) | himalaya | ✅ | ✅ |
| [Typora](https://typora.io/#linux) | typora | ✅ | ✅ | | [Typora](https://typora.io/#linux) | typora | ✅ | ✅ |
| [Zotero](https://zotero.retorque.re/file/apt-package-archive/index.html) | zotero<br />zotero-beta<br />zotero6 | ✅ | | | [Zotero](https://zotero.retorque.re/file/apt-package-archive/index.html) | zotero<br />zotero-beta<br />zotero6 | ✅ | |
| [Github CLI](https://cli.github.com/) | gh | ✅ | ✅ | | [Github CLI](https://cli.github.com/) | gh | ✅ | ✅ |
@ -92,8 +112,12 @@
| [lazydocker: wcbing 打包](https://github.com/wcbing-build/lazydocker-debs) | lazydocker | ✅ | ✅ | | [lazydocker: wcbing 打包](https://github.com/wcbing-build/lazydocker-debs) | lazydocker | ✅ | ✅ |
| [lazygit: wcbing 打包](https://github.com/wcbing-build/lazygit-debs) | lazygit | ✅ | ✅ | | [lazygit: wcbing 打包](https://github.com/wcbing-build/lazygit-debs) | lazygit | ✅ | ✅ |
| [NextTrace](https://github.com/nxtrace/nexttrace-debs) | nexttrace | ✅ | ✅ | | [NextTrace](https://github.com/nxtrace/nexttrace-debs) | nexttrace | ✅ | ✅ |
| [Debian 中文社区软件源](https://github.com/debiancn/repo)[镜像](https://help.mirrors.cernet.edu.cn/debiancn/) | anydesk<br />marktext<br />wps-office<br />[更多](https://github.com/debiancn/repo) | ✅ | |
| [Gitea](https://gitlab.com/packaging/gitea)[镜像](https://mirrors.ustc.edu.cn/help/packaging-gitea.html) | gitea | ✅ | ✅ | | [Gitea](https://gitlab.com/packaging/gitea)[镜像](https://mirrors.ustc.edu.cn/help/packaging-gitea.html) | gitea | ✅ | ✅ |
| [AnyDesk](https://deb.anydesk.com/howto.html) | anydesk | ✅ | ✅ |
| [Spotify](https://www.spotify.com/sg-zh/download/linux/) | spotify-client | ✅ | |
| [Free Download Manager](https://www.freedownloadmanager.org/zh/download-fdm-for-linux.htm) | freedownloadmanager | ✅ | |
| [WezTerm](https://wezterm.org/install/linux.html#using-the-apt-repo) | wezterm<br />wezterm-nightly | ✅ | ✅ |
| [Remote Desktop Manager](https://docs.devolutions.net/rdm/installation/client/?tab=linux) | remotedesktopmanager | ✅ | ✅ |
## 自建仓库 ## 自建仓库

View File

@ -4,11 +4,13 @@ import os
import sqlite3 import sqlite3
import sys import sys
import logging import logging
import re
from threading import Lock from threading import Lock
BASE_DIR = "deb" DEB_BASE_DIR = "deb"
PACKAGES_DIR = "packages"
DB_DIR = "data" DB_DIR = "data"
USER_AGENT = "Debian APT-HTTP/1.3 (2.6.1)" # from Debian 12 USER_AGENT = "Debian APT-HTTP/1.3 (3.0.3)" # from Debian 13
version_lock = Lock() version_lock = Lock()
@ -19,28 +21,66 @@ logging.basicConfig(
) )
def download(url: str) -> None: def download(url: str, file_path: str) -> bool:
"""Download file using curl with APT User-Agent.""" """Download file using curl with APT User-Agent."""
file_path = os.path.join(BASE_DIR, url.split("?")[0]) curl_process = subprocess.run(
os.makedirs(os.path.dirname(file_path), exist_ok=True) ["curl", "-H", f"User-Agent: {USER_AGENT}", "-fsLo", file_path, url]
subprocess.run(["curl", "-H", f"User-Agent: {USER_AGENT}", "-fsLo", file_path, url]) )
if curl_process.returncode or not os.path.exists(file_path):
logging.error(f"Failed to download {url}")
return False
return True
def check_download(name: str, version: str, url: str, arch: str="amd64") -> None: def scan(name, arch, url, file_path) -> bool:
scan_process = subprocess.run(
["apt-ftparchive", "packages", file_path], capture_output=True
)
package = scan_process.stdout.decode()
package = re.sub(
r"^(Filename: ).*", f"\\1{url}", package, flags=re.MULTILINE
) # 替换 Filename 开头的行
package_file_path = os.path.join(PACKAGES_DIR, arch, f"{name}.package")
try:
with open(package_file_path, "w") as f:
f.write(package)
return True
except IOError as e:
logging.error(f"Failed to write package file for {name}: {e}")
return False
def check_download(name: str, version: str, url: str, arch: str) -> None:
"""Check and handle package download/update.""" """Check and handle package download/update."""
logging.info("%s:%s = %s", name, arch, version) logging.info("%s:%s = %s", name, arch, version)
db_path = os.path.join("data", f"{BASE_DIR}.db") file_path = os.path.join(DEB_BASE_DIR, arch, f"{name}_{version}_{arch}.deb")
local_version = None
db_path = os.path.join(DB_DIR, f"{DEB_BASE_DIR}.db")
# get local version # get local version
with version_lock, sqlite3.connect(db_path) as conn: with version_lock, sqlite3.connect(db_path) as conn:
res = conn.execute( res = conn.execute(
f"SELECT version, url FROM '{arch}' WHERE name = ?", (name,) f"SELECT version FROM '{arch}' WHERE name = ?", (name,)
).fetchone() ).fetchone()
if res: if res:
local_version, local_url = res local_version = res[0]
if local_version != version: if local_version == version:
return
# download and scan
logging.info(f"Downloading {name}:{arch} ({version})")
os.makedirs(os.path.join(DEB_BASE_DIR, arch), exist_ok=True)
if not download(url, file_path):
return
logging.info(f"Downloaded {name}:{arch} ({version})")
os.makedirs(os.path.join(PACKAGES_DIR, arch), exist_ok=True)
if not scan(name, arch, url, file_path):
return
if res:
print(f"Update: {name}:{arch} ({local_version} -> {version})") print(f"Update: {name}:{arch} ({local_version} -> {version})")
download(url)
# update database # update database
with version_lock, sqlite3.connect(db_path) as conn: with version_lock, sqlite3.connect(db_path) as conn:
conn.execute( conn.execute(
@ -49,13 +89,11 @@ def check_download(name: str, version: str, url: str, arch: str="amd64") -> None
) )
conn.commit() conn.commit()
# remove old version # remove old version
if local_url != url: # 防止固定下载链接 old_file_path = os.path.join(DEB_BASE_DIR, arch, f"{name}_{local_version}_{arch}.deb")
old_file_path = os.path.join(BASE_DIR, local_url.split("?")[0])
if os.path.exists(old_file_path): if os.path.exists(old_file_path):
os.remove(old_file_path) os.remove(old_file_path)
else: else:
print(f"AddNew: {name}:{arch} ({version})") print(f"AddNew: {name}:{arch} ({version})")
download(url)
# update database # update database
with version_lock, sqlite3.connect(db_path) as conn: with version_lock, sqlite3.connect(db_path) as conn:
conn.execute( conn.execute(
@ -67,11 +105,11 @@ def check_download(name: str, version: str, url: str, arch: str="amd64") -> None
if __name__ == "__main__": if __name__ == "__main__":
args = sys.argv args = sys.argv
if len(args) in (4, 5): if len(args) == 5:
check_download(*args[1:]) check_download(*args[1:])
elif len(args) > 1: elif len(args) > 1:
logging.error(f"Unknown Args: {args[1:]}") logging.error(f"Unknown Args: {args[1:]}")
else: else:
print(f"Usage: {args[0]} <package_name> <version> <url> [arch]") print(f"Usage: {args[0]} <package_name> <version> <url> <arch>")
print("options:") print("options:")
print(" arch: amd64, arm64, all. default is amd64") print(" arch: amd64, arm64, all.")

View File

@ -9,14 +9,15 @@
"mihomo": { "mihomo": {
"repo": "MetaCubeX/mihomo", "repo": "MetaCubeX/mihomo",
"file_list": { "file_list": {
"amd64": "mihomo-linux-amd64-compatible-{releases_tag}.deb", "amd64": "mihomo-linux-amd64-{releases_tag}.deb",
"arm64": "mihomo-linux-arm64-{releases_tag}.deb" "arm64": "mihomo-linux-arm64-{releases_tag}.deb"
} }
}, },
"flclash": { "flclash": {
"repo": "chen08209/FlClash", "repo": "chen08209/FlClash",
"file_list": { "file_list": {
"amd64": "FlClash-{version}-linux-amd64.deb" "amd64": "FlClash-{version}-linux-amd64.deb",
"arm64": "FlClash-{version}-linux-arm64.deb"
} }
}, },
"hugo": { "hugo": {
@ -60,13 +61,6 @@
"arm64": "LocalSend-{version}-linux-arm-64.deb" "arm64": "LocalSend-{version}-linux-arm-64.deb"
} }
}, },
"motrix": {
"repo": "agalwood/Motrix",
"file_list": {
"amd64": "Motrix_{version}_amd64.deb",
"arm64": "Motrix_{version}_arm64.deb"
}
},
"peazip": { "peazip": {
"repo": "peazip/PeaZip", "repo": "peazip/PeaZip",
"file_list": { "file_list": {
@ -117,5 +111,64 @@
"file_list": { "file_list": {
"amd64": "dbeaver-ce_{version}_amd64.deb" "amd64": "dbeaver-ce_{version}_amd64.deb"
} }
},
"joplin": {
"repo": "laurent22/joplin",
"file_list": {
"amd64": "Joplin-{version}.deb"
}
},
"spark-store": {
"site": "https://gitee.com",
"repo": "spark-store-project/spark-store",
"file_list": {
"amd64": "spark-store_{releases_tag}_amd64.deb",
"arm64": "spark-store_{releases_tag}_arm64.deb"
}
},
"tinyrdm": {
"repo": "tiny-craft/tiny-rdm",
"file_list": {
"amd64": "tiny-rdm_{version}_linux_amd64_webkit2_41.deb"
}
},
"mqttx": {
"repo": "emqx/MQTTX",
"file_list": {
"amd64": "MQTTX_{version}_amd64.deb",
"arm64": "MQTTX_{version}_arm64.deb"
}
},
"splayer": {
"repo": "imsyy/SPlayer",
"file_list": {
"amd64": "splayer-{version}-amd64.deb"
}
},
"winboat": {
"repo": "TibixDev/winboat",
"file_list": {
"amd64": "winboat-{version}-amd64.deb"
}
},
"fooyin": {
"repo": "fooyin/fooyin",
"file_list": {
"amd64": "fooyin_{version}-trixie_amd64.deb"
}
},
"simplenote": {
"repo": "Automattic/simplenote-electron",
"file_list": {
"amd64": "Simplenote-linux-{version}-amd64.deb",
"arm64": "Simplenote-linux-{version}-arm64.deb"
}
},
"yesplaymusic": {
"repo": "qier222/YesPlayMusic",
"file_list": {
"amd64": "yesplaymusic_{version}_amd64.deb",
"arm64": "yesplaymusic_{version}_arm64.deb"
}
} }
} }

View File

@ -11,6 +11,12 @@
"amd64": "dists/stable/main/binary-amd64/Packages.gz" "amd64": "dists/stable/main/binary-amd64/Packages.gz"
} }
}, },
"chrome-remote-desktop": {
"repo": "https://dl.google.com/linux/chrome-remote-desktop/deb/",
"path": {
"amd64": "dists/stable/main/binary-amd64/Packages.gz"
}
},
"termius": { "termius": {
"repo": "https://deb.termius.com/", "repo": "https://deb.termius.com/",
"path": { "path": {
@ -62,12 +68,6 @@
"mix": "apt/stable/Packages.gz" "mix": "apt/stable/Packages.gz"
} }
}, },
"black-desk": {
"repo": "https://github.com/black-desk/debs/releases/latest/download/",
"path": {
"amd64": "Packages"
}
},
"typora": { "typora": {
"repo": "https://typoraio.cn/linux/", "repo": "https://typoraio.cn/linux/",
"path": { "path": {
@ -117,17 +117,55 @@
"mix": "Packages" "mix": "Packages"
} }
}, },
"debiancn": {
"repo": "https://mirrors.cernet.edu.cn/debiancn/",
"path": {
"amd64": "dists/bookworm/main/binary-amd64/Packages.gz"
}
},
"gitea": { "gitea": {
"repo": "https://mirrors.ustc.edu.cn/packaging-gitea/", "repo": "https://mirrors.ustc.edu.cn/packaging-gitea/",
"path": { "path": {
"amd64": "dists/gitea/main/binary-amd64/Packages", "amd64": "dists/gitea/main/binary-amd64/Packages",
"arm64": "dists/gitea/main/binary-arm64/Packages" "arm64": "dists/gitea/main/binary-arm64/Packages"
} }
},
"neovide": {
"repo": "https://github.com/wcbing-build/neovide-debs/releases/latest/download/",
"path": {
"mix": "Packages"
}
},
"himalaya": {
"repo": "https://github.com/wcbing-build/himalaya-debs/releases/latest/download/",
"path": {
"mix": "Packages"
}
},
"anydesk": {
"repo": "https://deb.anydesk.com/",
"path": {
"amd64": "dists/all/main/binary-amd64/Packages",
"arm64": "dists/all/main/binary-arm64/Packages"
}
},
"spotify-client": {
"repo": "https://repository.spotify.com/",
"path": {
"amd64": "dists/stable/non-free/binary-amd64/Packages"
}
},
"freedownloadmanager": {
"repo": "https://debrepo.freedownloadmanager.org/",
"path": {
"amd64": "dists/jammy/main/binary-amd64/Packages.gz"
}
},
"wezterm": {
"repo": "https://apt.fury.io/wez/",
"path": {
"mix": "Packages"
}
},
"remotedesktopmanager": {
"repo": "https://dl.cloudsmith.io/public/devolutions/rdm/deb/debian/",
"path": {
"amd64": "dists/trixie/main/binary-amd64/Packages.gz",
"arm64": "dists/trixie/main/binary-arm64/Packages.gz"
}
} }
} }

View File

@ -0,0 +1,9 @@
APT::FTPArchive::Release {
Origin "wcbing APT Repo";
Label "wcbing APT Repo";
Suite "wcbing";
Codename "wcbing";
Architectures "amd64 arm64";
Components "main";
Description "wcbing APT Repo || wcbing 的 APT 仓库";
}

View File

@ -7,7 +7,7 @@ import re
from concurrent.futures import ThreadPoolExecutor, wait from concurrent.futures import ThreadPoolExecutor, wait
from check_downloader import check_download from check_downloader import check_download
github_info_list = {} git_repo_list = {}
CONFIG = {"data_dir": "data", "proxy": "", "thread": 5} CONFIG = {"data_dir": "data", "proxy": "", "thread": 5}
@ -17,7 +17,7 @@ def read_args():
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("-d", "--data", default="data", help="从 <DATA> 读取仓库配置") parser.add_argument("-d", "--data", default="data", help="从 <DATA> 读取仓库配置")
parser.add_argument( parser.add_argument(
"-p", "--proxy", default="", help="Github 代理<PROXY> 必须以 / 结尾" "-p", "--proxy", default="", help="Github 代理"
) )
parser.add_argument( parser.add_argument(
"-t", "--thread", type=int, default=5, help="并发下载线程数量,默认为 5" "-t", "--thread", type=int, default=5, help="并发下载线程数量,默认为 5"
@ -31,28 +31,30 @@ if __name__ == "__main__":
# read all repo info 读取所有仓库配置 # read all repo info 读取所有仓库配置
with open(os.path.join(CONFIG["data_dir"], "github.json"), "r") as f: with open(os.path.join(CONFIG["data_dir"], "github.json"), "r") as f:
github_info_list = json.load(f) git_repo_list = json.load(f)
tasks = [] tasks = []
with ThreadPoolExecutor(max_workers=CONFIG["thread"]) as executor: with ThreadPoolExecutor(max_workers=CONFIG["thread"]) as executor:
for name, repo in github_info_list.items(): for name, repo in git_repo_list.items():
release_url = ( if "site" in repo:
f'{CONFIG["proxy"]}https://github.com/{repo["repo"]}/releases' repo_url = os.path.join(repo["site"], repo['repo'])
) else:
# 默认认为是 GitHub 仓库地址,同时使用代理
repo_url = os.path.join(CONFIG["proxy"], "https://github.com", repo["repo"])
# get latest releases tag 获取最新版本标签 # get latest releases tag 获取最新版本标签
location = requests.head(release_url + "/latest").headers.get("Location", "") location = requests.head(repo_url + "/releases/latest").headers.get("Location", "")
match = re.search(r".*releases/tag/([^/]+)", location) match = re.search(r".*releases/tag/(.*)", location)
if not match: if not match:
continue continue
releases_tag = match.group(1) releases_tag = match.group(1)
version = match.group() if (match := re.search("[0-9].*", releases_tag)) else "" version = match.group() if (match := re.search("[0-9][^_]*", releases_tag)) else ""
for arch, file_name in repo["file_list"].items(): for arch, file_name in repo["file_list"].items():
release_file = file_name.format( release_file = file_name.format(
releases_tag=releases_tag, version=version releases_tag=releases_tag, version=version
) )
file_url = f"{release_url}/download/{releases_tag}/{release_file}" file_url = f"{repo_url}/releases/download/{releases_tag}/{release_file}"
# 提交任务到线程池 # 提交任务到线程池
tasks.append( tasks.append(
executor.submit(check_download, name, version, file_url, arch) executor.submit(check_download, name, version, file_url, arch)

View File

@ -1,6 +1,6 @@
JSON=$(curl -s "https://pan.baidu.com/disk/cmsdata?do=client") JSON=$(curl -s "https://pan.baidu.com/disk/cmsdata?do=client")
VERSION=$(echo $JSON | jq -r ".linux.version" | cut -d "V" -f 2) VERSION=$(echo $JSON | jq -r ".linux.version" | cut -d "V" -f 2)
X64_URL=$(echo $JSON | jq -r ".linux.url_1") AMD64_URL=$(echo $JSON | jq -r ".linux.url_1")
./check_downloader.py baidunetdisk $VERSION $X64_URL ./check_downloader.py baidunetdisk $VERSION $AMD64_URL amd64

View File

@ -1,6 +1,6 @@
JSON=$(curl -s https://active.browser.360.net/api/v1/web-version) JSON=$(curl -s https://active.browser.360.net/api/v1/web-version)
VERSION=$(echo $JSON | jq -r ".data.web_version") VERSION=$(echo $JSON | jq -r ".data.web_version")
X64_URL="https://gedown.360safe.com/gc/browser360-cn-stable_"$VERSION"-1_amd64.deb" AMD64_URL="https://gedown.360safe.com/gc/browser360-cn-stable_"$VERSION"-1_amd64.deb"
./check_downloader.py browser360-cn-stable $VERSION $X64_URL ./check_downloader.py browser360-cn-stable $VERSION $AMD64_URL amd64

View File

@ -1,8 +1,12 @@
X64_JSON=$(curl -s "https://www.feishu.cn/api/package_info?platform=10") VERSIONS_JSON=$(curl -fs "https://www.feishu.cn/api/downloads")
# arm64 https://www.feishu.cn/api/package_info?platform=12
# AMD64
# "version_number": "Linux-x64-deb@V7.22.9" # "version_number": "Linux-x64-deb@V7.22.9"
VERSION=$(echo $X64_JSON | jq -r ".data.version_number" | cut -d '@' -f 2) AMD64_VERSION=$(echo $VERSIONS_JSON | jq -r ".versions.Linux_deb_x64.version_number" | cut -d 'V' -f 2)
X64_URL=$(echo $X64_JSON | jq -r ".data.download_link") AMD64_URL=$(echo $VERSIONS_JSON | jq -r ".versions.Linux_deb_x64.download_link")
./check_downloader.py bytedance-feishu-stable $AMD64_VERSION $AMD64_URL amd64
./check_downloader.py bytedance-feishu-stable $VERSION $X64_URL # ARM64
ARM64_VERSION=$(echo $VERSIONS_JSON | jq -r ".versions.Linux_deb_arm.version_number" | cut -d 'V' -f 2)
ARM64_URL=$(echo $VERSIONS_JSON | jq -r ".versions.Linux_deb_arm.download_link")
./check_downloader.py bytedance-feishu-stable $ARM64_VERSION $ARM64_URL arm64

View File

@ -1,6 +1,6 @@
X64_URL=$(curl -sw %{redirect_url} https://www.dingtalk.com/win/d/qd=linux_amd64) AMD64_URL=$(curl -sw %{redirect_url} https://www.dingtalk.com/win/d/qd=linux_amd64)
VERSION=$(echo $X64_URL | sed 's#.*/##g' | cut -d '_' -f 2) VERSION=$(echo $AMD64_URL | sed 's#.*/##g' | cut -d '_' -f 2)
./check_downloader.py com.alibabainc.dingtalk $VERSION $X64_URL ./check_downloader.py com.alibabainc.dingtalk $VERSION $AMD64_URL amd64
ARM64_URL=$(curl -sw %{redirect_url} https://www.dingtalk.com/win/d/qd=linux_arm64) ARM64_URL=$(curl -sw %{redirect_url} https://www.dingtalk.com/win/d/qd=linux_arm64)
VERSION=$(echo $ARM64_URL | sed 's#.*/##g' | cut -d '_' -f 2) VERSION=$(echo $ARM64_URL | sed 's#.*/##g' | cut -d '_' -f 2)

View File

@ -1,7 +1,7 @@
X64_URL=$(curl -sI "https://dida365.com/static/getApp/download?type=linux_deb_x64" | grep location | cut -d ' ' -f 2 | tr -d '\r') AMD64_URL=$(curl -sI "https://dida365.com/static/getApp/download?type=linux_deb_x64" | grep location | cut -d ' ' -f 2 | tr -d '\r')
# https://cdn.dida365.cn/download/linux/linux_deb_x64/dida-6.0.0-amd64.deb # https://cdn.dida365.cn/download/linux/linux_deb_x64/dida-6.0.0-amd64.deb
VERSION=$(echo $X64_URL | cut -d "-" -f 2) VERSION=$(echo $AMD64_URL | cut -d "-" -f 2)
./check_downloader.py dida $VERSION $X64_URL ./check_downloader.py dida $VERSION $AMD64_URL amd64
# ARM64 # ARM64
ARM64_URL=$(curl -sI "https://dida365.com/static/getApp/download?type=linux_deb_arm64" | grep location | cut -d ' ' -f 2 | tr -d '\r') ARM64_URL=$(curl -sI "https://dida365.com/static/getApp/download?type=linux_deb_arm64" | grep location | cut -d ' ' -f 2 | tr -d '\r')

7
get/eudic.sh Normal file
View File

@ -0,0 +1,7 @@
WEB_CONTENT=$(curl -s https://www.eudic.net/v4/en/app/download)
AMD64_URL=$(echo $WEB_CONTENT | grep -o 'https://[^"]*\.deb[^"]*')
# https://www.eudic.net/download/eudic.deb?v=2025-08-25
VERSION=$(echo $AMD64_URL | cut -d '=' -f 2)
./check_downloader.py eudic "$VERSION" "$AMD64_URL" amd64

View File

@ -1,8 +1,12 @@
JSON=$(curl -s https://im.qq.com/rainbow/linuxQQDownload | sed -nE 's/.*var params\s*=\s*(\{.*?\});.*/\1/p') # 正式版参考 https://github.com/flathub/com.qq.QQ/blob/master/com.qq.QQ.yaml
JSON=$(curl -s https://cdn-go.cn/qq-web/im.qq.com_new/latest/rainbow/linuxConfig.js | sed -nE 's/.*var params\s*=\s*(\{.*?\});.*/\1/p')
VERSION=$(echo $JSON | jq -r '.version + "_" + .updateDate') VERSION=$(echo $JSON | jq -r '.version + "_" + .updateDate')
X64_URL=$(echo $JSON | jq -r '.x64DownloadUrl.deb') # 测试版参考 https://bbs.deepin.org/post/279737?offset=1&limit=20&postId=1658175
./check_downloader.py linuxqq $VERSION $X64_URL
# AMD64
AMD64_URL=$(echo $JSON | jq -r '.x64DownloadUrl.deb')
./check_downloader.py linuxqq $VERSION $AMD64_URL amd64
# ARM64 # ARM64
ARM64_URL=$(echo $JSON | jq -r '.armDownloadUrl.deb') ARM64_URL=$(echo $JSON | jq -r '.armDownloadUrl.deb')

View File

@ -1,6 +1,6 @@
WEB_CONTENT=$(curl -s "https://y.qq.com/download/download.html") WEB_CONTENT=$(curl -s "https://y.qq.com/download/download.html")
VERSION=$(echo $WEB_CONTENT | grep -o "Linux <span class=\"product_list__version\">最新版:[0-9\.]*" | cut -d ':' -f 2) VERSION=$(echo $WEB_CONTENT | grep -o "Linux <span class=\"product_list__version\">最新版:[0-9\.]*" | cut -d ':' -f 2)
X64_URL=$(echo $WEB_CONTENT | grep -o "https://[0-9a-z/\._]*amd64\.deb" | head -n 1) AMD64_URL=$(echo $WEB_CONTENT | grep -o "https://[^\"]*amd64\.deb[^\"]*" | head -n 1)
./check_downloader.py qqmusic $VERSION $X64_URL ./check_downloader.py qqmusic $VERSION $AMD64_URL amd64

View File

@ -1,6 +1,6 @@
JSON=$(curl -fs "https://client-webapi.oray.com/softwares/SUNLOGIN_X_LINUX?x64=1") JSON=$(curl -fs "https://client-webapi.oray.com/softwares/SUNLOGIN_X_LINUX?x64=1")
VERSION=$(echo "$JSON" | jq -r '.versionno') VERSION=$(printf "%s" "$JSON" | jq -r '.versionno')
X64_URL=$(echo $JSON | jq -r '.downloadurl') AMD64_URL=$(printf "%s" "$JSON" | jq -r '.downloadurl')
./check_downloader.py sunloginclient $VERSION $X64_URL ./check_downloader.py sunloginclient $VERSION $AMD64_URL amd64

View File

@ -1,6 +1,6 @@
X64_URL=$(curl -s https://www.todesk.com/linux.html | grep -o "https://[0-9a-zA-Z_\/\.\-]*.deb" | head -n 1) AMD64_URL=$(curl -s https://www.todesk.com/linux.html | grep -o "https://[0-9a-zA-Z_\/\.\-]*.deb" | head -n 1)
# X64_URL=https:/ /dl.todesk.com/linux/todesk-v4.7.2.0-amd64.deb # AMD64_URL=https:/ /dl.todesk.com/linux/todesk-v4.7.2.0-amd64.deb
VERSION=$(echo $X64_URL | cut -d '-' -f 2) VERSION=$(echo $AMD64_URL | cut -d '-' -f 2)
./check_downloader.py todesk $VERSION $X64_URL ./check_downloader.py todesk $VERSION $AMD64_URL amd64

View File

@ -1,8 +1,8 @@
WEB_CONTENT=$(curl -s "https://www.u-tools.cn/download/") WEB_CONTENT=$(curl -s "https://www.u-tools.cn/download/")
X64_URL=$(echo $WEB_CONTENT | grep -o "https://[^ ]*amd64\.deb") AMD64_URL=$(echo $WEB_CONTENT | grep -o "https://[^ ]*amd64\.deb")
# https://open.u-tools.cn/download/utools_5.2.1_amd64.deb # https://open.u-tools.cn/download/utools_5.2.1_amd64.deb
VERSION=$(echo $X64_URL | cut -d '_' -f 2) VERSION=$(echo $AMD64_URL | cut -d '_' -f 2)
./check_downloader.py utools $VERSION $X64_URL ./check_downloader.py utools $VERSION $AMD64_URL amd64

View File

@ -1,13 +1,13 @@
WEB_CONTENT=$(curl -s "https://linux.weixin.qq.com/") WEB_CONTENT=$(curl -s "https://linux.weixin.qq.com/")
# X64 # AMD64
X64_URL=$(echo $WEB_CONTENT | grep -o 'https:[0-9a-zA-Z/\._]*x86_64\.deb') AMD64_URL=$(echo $WEB_CONTENT | grep -o 'https:[0-9a-zA-Z/\._]*x86_64\.deb')
Last_Modified=$(curl -sI $X64_URL | grep "Last-Modified") Last_Modified=$(curl -sI $AMD64_URL | grep "Last-Modified")
# Last-Modified: Wed, 06 Nov 2024 02:08:50 GMT # Last-Modified: Wed, 06 Nov 2024 02:08:50 GMT
VERSION=$(echo $Last_Modified | cut -d ' ' -f 3-6 | sed 's/ /-/g') VERSION=$(echo $Last_Modified | cut -d ' ' -f 3-6 | sed 's/ /-/g')
# 06-Nov-2024-02:08:50 # 06-Nov-2024-02:08:50
./check_downloader.py wechat $VERSION $X64_URL ./check_downloader.py wechat $VERSION $AMD64_URL amd64
# ARM64 # ARM64
ARM64_URL=$(echo $WEB_CONTENT | grep -o 'https:[0-9a-zA-Z/\._]*arm64\.deb') ARM64_URL=$(echo $WEB_CONTENT | grep -o 'https:[0-9a-zA-Z/\._]*arm64\.deb')

View File

@ -13,8 +13,8 @@ download_list_url="https://meeting.tencent.com/web-service/query-download-info?q
JSON=$(curl -s $download_list_url) JSON=$(curl -s $download_list_url)
VERSION=$(echo $JSON | jq -r '."info-list"[0].version') VERSION=$(echo $JSON | jq -r '."info-list"[0].version')
X64_URL=$(echo $JSON | jq -r '."info-list"[0].url') AMD64_URL=$(echo $JSON | jq -r '."info-list"[0].url')
./check_downloader.py wemeet $VERSION $X64_URL ./check_downloader.py wemeet $VERSION $AMD64_URL amd64
# ARM64 # ARM64
VERSION=$(echo $JSON | jq -r '."info-list"[1].version') VERSION=$(echo $JSON | jq -r '."info-list"[1].version')

31
get/wps-office.sh Normal file
View File

@ -0,0 +1,31 @@
# decrypt() {
# url=$1
# pathname="/$(echo $url | cut -d '/' -f 4-)"
# secrity_key="7f8faaaa468174dc1c9cd62e5f218a5b"
# timestamp10=$(date '+%s')
# md5hash=$(echo -n "${secrity_key}${pathname}${timestamp10}" | md5sum | cut -d " " -f 1 )
# url="$url?t=${timestamp10}&k=${md5hash}"
# echo $url
# }
# WPS 官网 JS 代码大致逻辑如下:
# function downLoad(url) {
# var urlObj=new URL(url);
# var uri=urlObj.pathname;
# var secrityKey="7f8faaaa468174dc1c9cd62e5f218a5b";
# var timestamp10=Math.floor(new Date().getTime() / 1000);
# var md5hash=CryptoJS.MD5(secrityKey + uri + timestamp10);
# url += '?t=' + timestamp10 + '&k=' + md5hash
# console.log(url);
# }
WEB_CONTENT=$(curl -fs https://linux.wps.cn/)
VERSION=$(echo $WEB_CONTENT | grep -o "<p class=\"banner_txt\">[0-9.]*</p>" | sed 's/<p class=\"banner_txt\">\(.*\)<\/p>/\1/')
AMD64_ORI_URL=$(echo $WEB_CONTENT | grep -o "https://[0-9a-zA-Z_\/\.\-]*amd64\.deb" | head -n 1)
# AMD64_URL=$(decrypt $AMD64_ORI_URL)
# 使用 CloudFlare Workers 动态生成重定向链接,其基本逻辑如上方 JS 代码所示。
# 这样 Packages 中固定链接也可重定向至官网,不给官方白嫖流量的机会。
AMD64_URL="https://wps302.wcbing.top/$AMD64_ORI_URL"
./check_downloader.py wps-office $VERSION $AMD64_URL amd64

View File

@ -1,27 +0,0 @@
decrypt() {
url=$1
pathname="/$(echo $url | cut -d '/' -f 4-)"
secrity_key="7f8faaaa468174dc1c9cd62e5f218a5b"
timestamp10=$(date '+%s')
md5hash=$(echo -n "${secrity_key}${pathname}${timestamp10}" | md5sum | cut -d " " -f 1 )
url="$url?t=${timestamp10}&k=${md5hash}"
echo $url
# # js
# function downLoad(url) {
# var urlObj=new URL(url);
# var uri=urlObj.pathname;
# var secrityKey="7f8faaaa468174dc1c9cd62e5f218a5b";
# var timestamp10=Math.floor(new Date().getTime() / 1000);
# var md5hash=CryptoJS.MD5(secrityKey + uri + timestamp10);
# url += '?t=' + timestamp10 + '&k=' + md5hash
# console.log(url);
# }
}
WEB_CONTENT=$(curl -fs https://linux.wps.cn/)
VERSION=$(echo $WEB_CONTENT | grep -o "<p class=\"banner_txt\">[0-9.]*</p>" | sed 's/<p class=\"banner_txt\">\(.*\)<\/p>/\1/')
X64_ORI_URL=$(echo $WEB_CONTENT | grep -o "https://[0-9a-zA-Z_\/\.\-]*amd64\.deb" | head -n 1)
X64_URL=$(decrypt $X64_ORI_URL)
./check_downloader.py wps-office $VERSION $X64_URL

View File

@ -1,6 +1,6 @@
X64_URL=$(curl -sI "https://xmind.cn/zen/download/linux_deb/" | grep location | cut -d ' ' -f 2 | tr -d '\r') AMD64_URL=$(curl -sI "https://xmind.cn/zen/download/linux_deb/" | grep location | cut -d ' ' -f 2 | tr -d '\r')
# https://dl3.xmind.cn/Xmind-for-Linux-amd64bit-24.04.10311-202405240010.deb # https://dl3.xmind.cn/Xmind-for-Linux-amd64bit-24.04.10311-202405240010.deb
VERSION=$(echo $X64_URL | cut -d '-' -f 5) VERSION=$(echo $AMD64_URL | cut -d '-' -f 5)
./check_downloader.py xmind-vana $VERSION $X64_URL ./check_downloader.py xmind-vana $VERSION $AMD64_URL amd64

View File

@ -12,25 +12,38 @@ import requests
import sys import sys
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
from threading import Lock from threading import Lock
import apt_pkg
from apt_pkg import version_compare
package_version = {arch: {} for arch in ["all", "amd64", "i386", "arm64"]} apt_pkg.init() # 初始化 apt_pkg
package_info = {arch: {} for arch in ["all", "amd64", "i386", "arm64"]}
lock = {arch: Lock() for arch in ["all", "amd64", "i386", "arm64"]}
USER_AGENT = "Debian APT-HTTP/1.3 (2.6.1)" # from Debian 12 USER_AGENT = "Debian APT-HTTP/1.3 (3.0.3)" # from Debian 13
arch_List = ["amd64", "arm64", "all", "i386"]
""" lock = {arch: Lock() for arch in arch_List}
repo info json format: packages = {arch: {} for arch in arch_List} # 存放用于生成 Packages 的内容
"repo_name": { """ packages format:
"repo": repo url, end with "/" {
"xxx_path": { "arch": {
"arch": repo Packages file path of "arch", start with no "/" "package1": {
"version": "1.0.0",
"url": "https://example.com/package1.deb",
"package": ""
}
} }
} }
""" """
def read_repo_list(repo_list_file: str) -> dict: def read_repo_list(repo_list_file: str) -> dict:
"""
repo info json format:
"repo_name": {
"repo": repo url, end with "/" is better
"path": {
"arch": repo Packages file path of "arch", don't start with "/"
}
}
"""
try: try:
with open(repo_list_file, "r") as f: with open(repo_list_file, "r") as f:
return json.load(f) return json.load(f)
@ -43,7 +56,7 @@ def get_remote_packages(repo_url: str, file_path: str) -> bytes:
""" """
get the packages file content from remote repo get the packages file content from remote repo
""" """
file_url = repo_url + file_path file_url = os.path.join(repo_url, file_path)
try: try:
response = requests.get( response = requests.get(
file_url, timeout=10, headers={"User-Agent": USER_AGENT} file_url, timeout=10, headers={"User-Agent": USER_AGENT}
@ -64,43 +77,46 @@ def get_remote_packages(repo_url: str, file_path: str) -> bytes:
else: # Packages else: # Packages
content = response.content content = response.content
# complete the two newlines if the ending is less than two newlines
# 结尾不足两个换行符的话,补全两个换行符
if not content.endswith(b"\n\n"):
content += b"\n"
return content.replace(b"Filename: ", f"Filename: {repo_url}".encode()) return content.replace(b"Filename: ", f"Filename: {repo_url}".encode())
except Exception as e: except Exception as e:
logging.error(f"Error fetching packages: {e}") logging.error(f"Error fetching packages: {e}")
return b"" return b""
def get_latest(deb_packages: bytes): def split_latest(packages_file_content: bytes):
""" """
split the information of each packet, deduplication and store the latest in infoList split the information of each packet, deduplication and store the latest in infoList
将每个包的信息分割开去重并将最新的存放到 infoList 将每个包的信息分割开去重并将最新的存放到 infoList
""" """
deb_packages = re.sub(rb"^Package: ", b"{{start}}Package: ", deb_packages, flags=re.MULTILINE) # Remove trailing empty lines first
info_list = deb_packages.split(b"{{start}}")[1:] packages_file_content = packages_file_content.rstrip(b"\n\r\t ")
find_name = re.compile(rb"Package: (.+)") # split on two or more consecutive blank lines
find_arch = re.compile(rb"Architecture: (.+)") package_list = [
find_version = re.compile(rb"Version: (.+)") part + b"\n\n"
for part in re.split(rb"(?:\r?\n){2,}", packages_file_content)
if part.strip()
]
for v in info_list: find_name = re.compile(rb"Package:[ ]*(.+)")
find_arch = re.compile(rb"Architecture:[ ]*(.+)")
find_url = re.compile(rb"Filename:[ ]*(.+)")
find_version = re.compile(rb"Version:[ ]*(.+)")
for package in package_list:
name = "unknown"
try: try:
name = find_name.search(v).group(1).decode() name = find_name.search(package).group(1).decode()
arch = find_arch.search(v).group(1).decode() arch = find_arch.search(package).group(1).decode()
tmp_version = find_version.search(v).group(1).decode() url = find_url.search(package).group(1).decode()
tmp_version = find_version.search(package).group(1).decode()
with lock[arch]: with lock[arch]:
# 使用 apt_pkg 进行版本比较
if ( if (
name not in package_version[arch] name not in packages[arch]
or os.system( or version_compare(tmp_version, packages[arch][name]["version"]) > 0
f"dpkg --compare-versions {tmp_version} gt {package_version[arch][name]}"
)
== 0
): ):
package_version[arch][name] = tmp_version packages[arch][name] = {"version": tmp_version, "url": url, "package": package}
package_info[arch][name] = v
except Exception as e: except Exception as e:
logging.error(f"Error processing package {name}: {e}") logging.error(f"Error processing package {name}: {e}")
return return
@ -111,10 +127,8 @@ def process_repo(r: dict):
获取仓库中不同架构子仓库的内容最后调用 get_latest 去重并保存 获取仓库中不同架构子仓库的内容最后调用 get_latest 去重并保存
""" """
try: try:
deb_packages = b"" for path in r["path"].values():
for arch, path in r["path"].items(): split_latest(get_remote_packages(r["repo"], path))
deb_packages += get_remote_packages(r["repo"], path)
get_latest(deb_packages)
except Exception as e: except Exception as e:
logging.error(f"Error processing repo {r.get('name', 'unknown')}: {e}") logging.error(f"Error processing repo {r.get('name', 'unknown')}: {e}")
@ -140,7 +154,7 @@ if __name__ == "__main__":
# 处理本地 repo # 处理本地 repo
if args.local: if args.local:
with open(args.local) as f: with open(args.local) as f:
get_latest(f.read().encode()) split_latest(f.read().encode())
# 读取 repo_list 配置 # 读取 repo_list 配置
repo_list = read_repo_list(args.repo) repo_list = read_repo_list(args.repo)
@ -152,17 +166,16 @@ if __name__ == "__main__":
executor.map(process_repo, repo_list.values()) executor.map(process_repo, repo_list.values())
# 分别输出到不同文件 # 分别输出到不同文件
os.makedirs("deb/amd64/", exist_ok=True) for arch in ["amd64", "arm64"]:
os.makedirs("deb/arm64/", exist_ok=True) os.makedirs(f"deb/dists/wcbing/main/binary-{arch}/", exist_ok=True)
with open(f"deb/dists/wcbing/main/binary-{arch}/Packages", "+wb") as f:
for i in packages[arch].values():
f.write(i["package"])
for i in packages["all"].values():
f.write(i["package"])
with open("deb/amd64/Packages", "+wb") as f: # 输出 packages.json用于展示仓库内容
for i in package_info["amd64"].values(): for arch in arch_List:
f.write(i) for i in packages[arch].values():
for i in package_info["all"].values(): i.pop("package")
f.write(i) json.dump(packages, open("deb/list/packages.json", "w"), indent=4)
with open("deb/arm64/Packages", "+wb") as f:
for i in package_info["arm64"].values():
f.write(i)
for i in package_info["all"].values():
f.write(i)

7
packages/README.md Normal file
View File

@ -0,0 +1,7 @@
# Packages
收集存档或疑似停止更新等长时间不更新但仍有下载地址的应用。
这里收集的应用不再检查更新,以减轻请求压力、加快仓库构建速度。
> 注:为保证包的信息可以被正确分割,每个文件末尾**请务必保留两个以上空行**。

View File

@ -0,0 +1,46 @@
Package: flameshot
Architecture: amd64
Version: 12.1.0-1
Priority: optional
Section: graphics
Maintainer: Boyuan Yang <byang@debian.org>
Installed-Size: 3239
Depends: hicolor-icon-theme, libqt5svg5 (>= 5.9.0~), libc6 (>= 2.14), libgcc-s1 (>= 3.0), libqt5core5a (>= 5.15.1), libqt5dbus5 (>= 5.14.1), libqt5gui5 (>= 5.14.1) | libqt5gui5-gles (>= 5.14.1), libqt5network5 (>= 5.9.0~), libqt5widgets5 (>= 5.15.1), libstdc++6 (>= 5.2)
Recommends: xdg-desktop-portal-gtk | xdg-desktop-portal-gnome | xdg-desktop-portal-kde | xdg-desktop-portal-wlr, grim
Suggests: ca-certificates, openssl
Filename: https://github.com/flameshot-org/flameshot/releases/download/v12.1.0/flameshot-12.1.0-1.debian-11.amd64.deb
Size: 651568
MD5sum: 42fe9a70ff05c36d27b5eae7f0c25dc6
SHA1: 595c8dae712f96680e23121433815899902da5ae
SHA256: 8fadc826b9fe3077fe55830cade2321438f4fc16ee03e65e0ad0b18eeb878def
SHA512: 160333faf8237fde25bf26deaa14616acaa128711454871117394fe37742ad933409d276ce1d8cf16270ef430a877650ec81a1b47996c0ecf77f4e10d9f73df6
Homepage: https://github.com/flameshot-org/flameshot
Description: Powerful yet simple-to-use screenshot software
Flameshot is a powerful yet simple-to-use screenshot software.
Notable features include customizable appearance, in-app screenshot editing,
D-Bus interface, experimental GNOME/KDE Wayland support, integration with
Imgur and support for both GUI and CLI interface.
Package: flameshot
Architecture: arm64
Version: 12.1.0-1
Priority: optional
Section: graphics
Maintainer: Boyuan Yang <byang@debian.org>
Installed-Size: 3223
Depends: hicolor-icon-theme, libqt5svg5 (>= 5.9.0~), libc6 (>= 2.17), libgcc-s1 (>= 3.0), libqt5core5a (>= 5.15.1), libqt5dbus5 (>= 5.14.1), libqt5gui5 (>= 5.14.1) | libqt5gui5-gles (>= 5.14.1), libqt5network5 (>= 5.9.0~), libqt5widgets5 (>= 5.15.1), libstdc++6 (>= 5.2)
Recommends: xdg-desktop-portal-gtk | xdg-desktop-portal-gnome | xdg-desktop-portal-kde | xdg-desktop-portal-wlr, grim
Suggests: ca-certificates, openssl
Filename: https://github.com/flameshot-org/flameshot/releases/download/v12.1.0/flameshot-12.1.0-1.debian-11.arm64.deb
Size: 604012
MD5sum: f12c6170b067d8137fcc6cb9dfa4de9d
SHA1: 2a8af2e95c048721e9211070d3e12999f27aa348
SHA256: 437c66abe0bdca413c97b6ad3bfd690b2a8ca3e20e60a9f99795d5f432aecef5
SHA512: 3fa0314558a56d5eebcbbd9bf0d803eab61dc499ef1fada34f327b243b70a7a878bdbcef07fd5e055f014fdfd6a2fe2c0d2f01796e7b429e3379c521e62b3003
Homepage: https://github.com/flameshot-org/flameshot
Description: Powerful yet simple-to-use screenshot software
Flameshot is a powerful yet simple-to-use screenshot software.
Notable features include customizable appearance, in-app screenshot editing,
D-Bus interface, experimental GNOME/KDE Wayland support, integration with
Imgur and support for both GUI and CLI interface.

View File

@ -0,0 +1,22 @@
Package: kali-undercover
Architecture: all
Version: 2025.2.0
Priority: optional
Section: misc
Maintainer: Kali Developers <devel@kali.org>
Installed-Size: 19510
Depends: python3:any, fonts-liberation, gir1.2-glib-2.0, libnotify-bin, mousepad, procps, psmisc, xdotool, xfce4, xfce4-datetime-plugin, xfce4-power-manager-plugins, xfce4-pulseaudio-plugin, xfce4-whiskermenu-plugin
Suggests: gtk2-engines-murrine
Filename: https://mirrors.cernet.edu.cn/kali/pool/main/k/kali-undercover/kali-undercover_2025.2.0_all.deb
Size: 7750640
MD5sum: 0e9d2d64929f8341ae1911478ce67b73
SHA1: 3ccc76ff06d60bbf40e627efa2733adad3ea8c64
SHA256: 24dc718af28210f6139a5f9238896c6e1d1bc40a951a9dfc742c51a773334ef6
SHA512: cb443141fee19af3e99257104ff359cf489929913ce9978a88ea46217e639bc4f582b3dc4ad33ab1b5d88a6fd0a4357757f5e5fecb8a369c7c611c8f78d52e9d
Description: Kali Undercover Mode
Run “kali-undercover” and you will instantly switch your Xfce desktop into
a Windows 10 desktop that will no longer draw attention to your activities.
.
Run it a second time to escape the cover mode and get back your original
desktop settings.

21
packages/marktext.package Normal file
View File

@ -0,0 +1,21 @@
Package: marktext
Architecture: amd64
Version: 0.17.1
Priority: optional
Section: default
Maintainer: MarkText Contributors
Installed-Size: 286529
Depends: libsecret-1-0, libx11-xcb1, libxkbfile1, libfontconfig1
Recommends: libappindicator3-1
Filename: https://github.com/marktext/marktext/releases/download/v0.17.1/marktext-amd64.deb
Size: 75198556
MD5sum: d5c4b6c6033a28d71d2da68e9d72cb90
SHA1: 06f1a3fe39e01704415294fc1d4c81465f0fa723
SHA256: 927fa87c11e6763171bd68dbf60f235bfea62989e799620dd392d19077574fd2
SHA512: fefc3ead08538ab8261295e94a91a3c5ae7a5041252d44e7ba0349c30424e0fa60db45d37e26b54a9b48491a3a3183baf08d19ee2362aec63b393ba6768df1f9
Homepage: https://marktext.app/
Description:
A simple and elegant open-source markdown editor that focused on speed and usability.
License: Expat
Vendor: MarkText Contributors

42
packages/motrix.package Normal file
View File

@ -0,0 +1,42 @@
Package: motrix
Architecture: amd64
Version: 1.8.19
Priority: optional
Section: default
Maintainer: Dr_rOot <agalwood.net@gmail.com>
Installed-Size: 245431
Depends: libgtk-3-0, libnotify4, libnss3, libxss1, libxtst6, xdg-utils, libatspi2.0-0, libuuid1, libsecret-1-0
Recommends: libappindicator3-1
Filename: https://github.com/agalwood/Motrix/releases/download/v1.8.19/Motrix_1.8.19_amd64.deb
Size: 71298984
MD5sum: 0b878031c5eeb536e09dbc17b5fc0b54
SHA1: 58394832c7c4d306e227c366d82fc822f6e1b9bb
SHA256: a21d1fcc0988325073b3778de875660c9d544834f3f92b2396a0a124a14fed11
SHA512: 8a3dab9c731268c2291f286d8efa7815046bbe00046deb938db061863d3ad3e14ddcb50ba4a7e44ada2c11d196d660bb6a762af4e6e589ddb38692266010e61a
Homepage: https://motrix.app
Description:
A full-featured download manager
License: MIT
Vendor: Dr_rOot <agalwood.net@gmail.com>
Package: motrix
Architecture: arm64
Version: 1.8.19
Priority: optional
Section: default
Maintainer: Dr_rOot <agalwood.net@gmail.com>
Installed-Size: 249147
Depends: libgtk-3-0, libnotify4, libnss3, libxss1, libxtst6, xdg-utils, libatspi2.0-0, libuuid1, libsecret-1-0
Recommends: libappindicator3-1
Filename: https://github.com/agalwood/Motrix/releases/download/v1.8.19/Motrix_1.8.19_arm64.deb
Size: 66839298
MD5sum: f55e76696960c4b0c56f39f85e81c72c
SHA1: e7953a8dd3f1758729d7699158b36f4c8437ecf7
SHA256: d191a0338bb4ae46e475f976bf926f3b61e8e5c96e9ac266242e883baaafd48a
SHA512: 3ea865afc8d3c214a87e381f44249789330064cd44e8313b377d188fe983a1fd8cb3ccab879d6b26f3fdbf00f5971054f5529aa1dcb05017a184b8c8ed0993c7
Homepage: https://motrix.app
Description:
A full-featured download manager
License: MIT
Vendor: Dr_rOot <agalwood.net@gmail.com>

18
packages/yolx.package Normal file
View File

@ -0,0 +1,18 @@
Package: yolx
Architecture: amd64
Version: 0.3.9+1
Priority: optional
Essential: no
Section: x11
Maintainer: Yoyo <admin@yzzi.icu>
Installed-Size: 6604
Depends: libappindicator3-1, libayatana-appindicator3-1
Filename: https://github.com/uiYzzi/Yolx/releases/download/0.3.9+1/yolx-linux-0.3.9+1.deb
Size: 11392180
MD5sum: 5b34c223e1b1e8eb0993d7d72c41d0cd
SHA1: 5cbcdb0cb88055e29f58a93b3a8f8199a5f2af96
SHA256: 52962ba986cea645b2b3817031899ba64fb32872160841f92a3fb9822b7e3561
SHA512: 563b28d6d7c3273e6d2f9ce5ebb60e261f4832efccc4d89dfa75007803e3fb639f7210bd52c80ab8dccb0748346a7e3dd5d82df0e6c9c9a5883dddf13c24f6f7
Description: An aria2 client
Uploaders: Yoyo <admin@yzzi.icu>

22
run.sh
View File

@ -1,25 +1,17 @@
#!/bin/sh #!/bin/sh
gen_release() {
apt-ftparchive release $1 >$1/Release
gpg --yes --detach-sign -a -o $1/Release.gpg $1/Release
gpg --yes --clearsign -o $1/InRelease $1/Release
}
# check for updates # check for updates
./get-github-releases.py ./get-github-releases.py
find get -type f -name "*.sh" -exec sh {} \; find get -type f -name "*.sh" -exec sh {} \;
cd deb ## merge the Packages file from local package
# generate the local Packages cat $(find packages -name "*.package") > deb/tmpPackages
apt-ftparchive packages . > tmpPackages
sed -i "s|\./\(https\?\):/|\1://|g" tmpPackages
cd .. ## merge the Packages files from third-party repositories
sed -i "s|\./|\.\./|g" deb/tmpPackages
# merge the Packages files from third-party repositories
./merge-apt-repo.py --local deb/tmpPackages ./merge-apt-repo.py --local deb/tmpPackages
# generate the Release file # generate the Release file
gen_release deb/amd64 cd deb/dists/wcbing && \
gen_release deb/arm64 apt-ftparchive release -c apt-ftparchive.conf . > Release && \
gpg --yes --detach-sign -a -o Release.gpg Release && \
gpg --yes --clearsign -o InRelease Release