























前段时间写 Misc 页面 的时候就在考虑书影音记录的数据源问题,最后得出结论还得有一份自己本地的备份才好。Excel 固然可以满足,但不够优雅,搜索 media tracker 也能找到不少已经比较完善的项目,但我只想要一个小而美。于是决定着手开发一个自己的书影音记录管理工具。
一开始准备用 Python 或者 PHP 写,不过既然主要目的是备份,运行环境要求自然越低越好,最好只需要一个可执行文件和 SQLite 数据库。目光最终转向了 Rust 和 Go 语言。
上一次接触 Go 还是多年前的 Hello World,所以这个项目也是抱着学习的态度,想到哪写到哪,写到哪查到哪。奋发图强了半个多月,基本功能也比较完善了,如有需要欢迎使用体验。
Github 项目地址:https://github.com/scenery/mediax
mediaX 是一款使用 Go 语言开发的个人阅读/观影/看剧/追番/游戏记录 Web 管理工具。
特点:
预览:
Update: 2025-05-03
最近一周花时间更新了下 mediaX,v0.6.0 版本对样式和功能进行了较大幅度的改动,主要包括:
条目的信息字段没有设计太多,只记录一些关键数据。网页样式上延续了本站的风格没有风格,同样没有使用任何 JavaScript 代码和 Cookie(v0.6.0 版本为了排序功能,加了一行仅有的内联 JS this.form.submit();为了用户功能也被迫使用了 Cookie),因此部分功能实现上比较受限。总之 mediaX 预期是一个运行在树莓派、NAS 等设备上的局域网应用,并无过多的安全设计,如需放到公网使用请使用 HTTPS 或加密 Tunnel 连接,同时也请在 Web Server 上做好鉴权和 IP 限制。
* 该项目主要是为了满足个人学习和使用需要,暂不接受新功能建议,如果有额外功能需求欢迎 fork 修改(MIT 协议)。
mediaX 从 v0.6.0 版本开始通过配置文件启动,默认加载程序目录下的 config.json 文件,也可通过 --config 参数指定。配置文件格式如下:
{
"server": {
"address": "0.0.0.0",
"port": 8080,
"use_https": false
},
"user": {
"username": "username",
"password": "{bcrypt}$2a$password"
},
"session_timeout": "168h",
"categories": ["book", "movie", "tv", "anime", "game"],
"pagination": {
"page_size": 10
},
"api_key": ""
}
其中:
配置文件中用户名和密码不能为空,且密码使用 BCrypt 加密,可使用 --bcrypt 参数加密,例如:
# 设置密码: hubcap-oxidation-album-glitzy-tying
# Linux / macOS
./mediax --bcrypt "hubcap-oxidation-album-glitzy-tying"
# Windows
mediax.exe --bcrypt "hubcap-oxidation-album-glitzy-tying"
# 输出:
{bcrypt}$2a$10$kR.uXEAfE.ADUoGd5SaXqu75HjGwzSdmi2rbFHX/OT8DrkoltS7a6
将输出的值填入配置文件 password 字段中即可。
mediaX 支持导入豆瓣(图书/电影/剧集)或 Bangumi 番组计划(图书/电影/剧集/番剧/游戏)数据来源的个人历史记录,其中 Bangumi 的电影和剧集记录因 API 返回内容限制未做详细区分,简单的判断如果只有一集归类为电影,大于一集则归类为剧集。
新建任务,选择备份的项目中只勾选第一个 影/音/书/游/剧,等待任务完成后,点击右上方 浏览备份 - 备份数据库,解压下载的文件,其中的 tofu[xxxxxx].json 为需要的文件。将 JSON 文件放到 mediaX 程序相同目录下,执行命令:
# Linux / macOS
./mediax --import <douban|bangumi> --file <file.json> [--download-image]
# Windows
mediax.exe --import <douban|bangumi> --file <file.json> [--download-image]
# e.g. 导入豆瓣数据
# ./mediax --import douban --file tofu[xxxxxx].json --download-image
最后的 --download-image 为可选参数,如果加上则导入的时候会尝试下载封面图片,如果数据量大的话会比较耗时(为了避免 IP 被 ban 下载间隔为 1s),请耐心等待。
不推荐重复导入一个文件,如果重复导入文件,目前只是简单的比对已导入的记录(原链接)和已下载的图片文件是否已经存在,如果存在则跳过导入。
mediaX 支持导出内部数据为 JSON 文件:
{
"subjects": [
{
"uuid": string,
"subject_type": string,
"title": string,
"alt_title": string,
"pub_date": string,
"creator": string,
"press": string,
"status": int,
"rating": int,
"summary": string,
"comment": string,
"external_url": string,
"mark_date": string,
"created_at": string
}
],
"export_time": string,
"total_count": int
}
导出命令:
# Linux / macOS
./mediax --export <all|anime|movie|book|tv|game> [--limit <number>]
# Windows
mediax.exe --export <all|anime|movie|book|tv|game> [--limit <number>]
# e.g. 导出最近 5 条图书数据,如果不加 --limit 参数则导出该类型全部记录
# ./mediax --export book --limit 5
导出的文件将自动保存在程序目录下。
目前 mediaX 支持通过 API 获取基本的个人收藏条目数据,请求接口如下:
/api/v0/collection
返回格式:
{
"subjects": [
{
"uuid": string,
"subject_type": string,
"title": string,
"alt_title": string,
"pub_date": string,
"creator": string,
"press": string,
"status": int,
"rating": int,
"summary": string,
"comment": string,
"external_url": string,
"mark_date": string,
"created_at": string
}
],
"response_tim": string,
"total_count": int,
"limit": int,
"offset": int
}
你可以使用 --api-key 参数生成一个 API Key:
# Linux / macOS
./mediax --api-key
# Windows
mediax.ext --api-key
# 输出:
------- Generated API Key -------
API Key: 6ElNVkplRJgasQKfRyFNRDvxl0iV1kebIJpVl9Dt_Eg=
Hashed API Key: QEr6mA6HkILFwBYckw4Ek+9v41ooV64VGebOSDwqiKM=
---------------------------------
其中 Hashed API Key 需要复制到配置文件 config.json 的 api_key 字段中。请保管好 API Key,不要在非加密的公网中使用。如需重置,重新生成并替换即可。
可选参数:
例如,使用 curl 命令获取数据:
# 获取最近 5 条图书数据
curl "http://localhost:8080/api/v0/collection?type=book&limit=5" \
-H "Authorization: Bearer 6ElNVkplRJgasQKfRyFNRDvxl0iV1kebIJpVl9Dt_Eg="
# 获取第 6 至 10 条图书数据
curl "http://localhost:8080/api/v0/collection?type=book&limit=5&offset=5" \
-H "Authorization: Bearer 6ElNVkplRJgasQKfRyFNRDvxl0iV1kebIJpVl9Dt_Eg="
一个简单的持久化运行配置示例,新建 systemd 服务:
vim /etc/systemd/system/mediax.service
添加下面内容,其中 User 为运行服务的用户,需要有 mediaX 工作目录的读写权限, --port 8080 可以修改为你需要的运行端口。
[Unit]
Description=mediaX - https://github.com/scenery/mediax
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/path/to/mediax
ExecStart=/path/to/mediax/mediax --config /path/to/config.json
Restart=on-failure
RestartSec=10s
[Install]
WantedBy=multi-user.target
运行管理:
# 重新加载 systemd 配置:
sudo systemctl daemon-reload
# 设置开机自启:
sudo systemctl enable mediax
# 启动服务:
sudo systemctl start mediax
# 停止服务:
sudo systemctl stop mediax
# 服务状态:
sudo systemctl status mediax
因为 Go 语言入门比较友好,整个项目也比较简单,开发过程中除了写缓存功能时大脑多次宕机外,其他都还算比较顺利。不过是个体力活,赞美 if err != nil。
数据库最初设计时按类别建了多张表,差不多写完的时候突然觉得数据量又不大,一个正常地球人一生也读不了看不了多少,多表徒增复杂度,最后又把数据库重新设计合并为一张表。如果你是三体人可能会遇到数据库性能瓶颈。
导入记录功能需要用户提前准备数据,虽然可以写进程序里但没必要。新增条目时自动获取数据依赖 API,如果未来获取豆瓣数据失效,会考虑改为从 The Movie Database (TMDB) 上获取数据。顺便提一下导入豆瓣数据后搜索“未知”,可能会发现一些被豆瓣下架的条目,比如「V 字仇杀队」等,到 Wayback Machine 上搜一下相应链接说不定能在远古记录中找回来。
最后,这应该不是一个长期维护项目,稳定之后可能不怎么更新。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。