mirror of
https://github.com/Cp0204/quark-auto-save.git
synced 2026-01-12 23:30:44 +08:00
Compare commits
9 Commits
cdbd2882f3
...
fe4643ff7c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe4643ff7c | ||
|
|
588a957768 | ||
|
|
8c0be4cf4d | ||
|
|
6c8416d7d6 | ||
|
|
bdc9068f3d | ||
|
|
0faf3ec569 | ||
|
|
10a8ce01ba | ||
|
|
dfc33a19c5 | ||
|
|
ae64cb3dfb |
@ -11,10 +11,10 @@
|
||||
定期执行本脚本自动转存、文件名整理,配合 Alist, rclone, Emby 可达到自动追更的效果。🥳
|
||||
|
||||
|
||||
[![wiki][wiki-image]][wiki-url] [![github tag][gitHub-tag-image]][github-url] [![docker pulls][docker-pulls-image]][docker-url] [![docker image size][docker-image-size-image]][docker-url]
|
||||
[![wiki][wiki-image]][wiki-url] [![github releases][gitHub-releases-image]][github-url] [![docker pulls][docker-pulls-image]][docker-url] [![docker image size][docker-image-size-image]][docker-url]
|
||||
|
||||
[wiki-image]: https://img.shields.io/badge/wiki-Documents-green?logo=github
|
||||
[gitHub-tag-image]: https://img.shields.io/github/v/tag/Cp0204/quark-auto-save?logo=github
|
||||
[gitHub-releases-image]: https://img.shields.io/github/v/release/Cp0204/quark-auto-save?logo=github
|
||||
[docker-pulls-image]: https://img.shields.io/docker/pulls/cp0204/quark-auto-save?logo=docker&&logoColor=white
|
||||
[docker-image-size-image]: https://img.shields.io/docker/image-size/cp0204/quark-auto-save?logo=docker&&logoColor=white
|
||||
[github-url]: https://github.com/Cp0204/quark-auto-save
|
||||
@ -57,6 +57,7 @@
|
||||
- 媒体库整合
|
||||
- [x] 根据任务名搜索 Emby 媒体库
|
||||
- [x] 追更或整理后自动刷新 Emby 媒体库
|
||||
- [x] **媒体库模块化,用户可很方便地[开发自己的媒体库hook模块](./media_servers)**
|
||||
|
||||
- 其它
|
||||
- [x] 每日签到领空间 <sup>[?](https://github.com/Cp0204/quark-auto-save/wiki/%E4%BD%BF%E7%94%A8%E6%8A%80%E5%B7%A7%E9%9B%86%E9%94%A6#%E6%AF%8F%E6%97%A5%E7%AD%BE%E5%88%B0%E9%A2%86%E7%A9%BA%E9%97%B4)</sup>
|
||||
|
||||
@ -60,7 +60,7 @@
|
||||
<div class="col">
|
||||
<h2 style="display: inline-block;">通知</h2>
|
||||
<span class="badge badge-pill badge-light">
|
||||
<a href="https://github.com/Cp0204/quark-auto-save/wiki/%E9%80%9A%E7%9F%A5%E6%8E%A8%E9%80%81%E6%9C%8D%E5%8A%A1%E9%85%8D%E7%BD%AE" target="_blank">?</a>
|
||||
<a href="https://github.com/Cp0204/quark-auto-save/wiki/%E9%80%9A%E7%9F%A5%E6%8E%A8%E9%80%81%E6%9C%8D%E5%8A%A1%E9%85%8D%E7%BD%AE" target="_blank" title="通知配置说明">?</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="col text-right">
|
||||
@ -82,7 +82,10 @@
|
||||
|
||||
<div class="row title">
|
||||
<div class="col">
|
||||
<h2>媒体库</h2>
|
||||
<h2 style="display: inline-block;">媒体库</h2>
|
||||
<span class="badge badge-pill badge-light">
|
||||
<a href="https://github.com/Cp0204/quark-auto-save/tree/main/media_servers" target="_blank" title="媒体库模块开发指南">?</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-for="(server, serverName) in formData.media_servers" :key="serverName" class="task mb-3">
|
||||
@ -97,7 +100,7 @@
|
||||
<div v-for="(value, key) in server" :key="key" class="form-group row">
|
||||
<label class="col-sm-2 col-form-label">{{ key }}</label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" v-model="formData.media_servers[serverName][key]" class="form-control" :placeholder="key === 'url' ? 'URL' : 'API Key/Token'">
|
||||
<input type="text" v-model="formData.media_servers[serverName][key]" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -109,7 +112,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-2 col-form-label">Crontab <span class="badge badge-pill badge-light"><a target="_blank" href="https://tool.lu/crontab/">?</a></span></label>
|
||||
<label class="col-sm-2 col-form-label">Crontab <span class="badge badge-pill badge-light"><a target="_blank" href="https://tool.lu/crontab/" title="CRON时间计算器">?</a></span></label>
|
||||
<div class="col-sm-10">
|
||||
<input type="text" v-model="formData.crontab" class="form-control" placeholder="必填">
|
||||
</div>
|
||||
|
||||
87
media_servers/README.md
Normal file
87
media_servers/README.md
Normal file
@ -0,0 +1,87 @@
|
||||
# 媒体库模块开发指南
|
||||
|
||||
本指南介绍如何开发自定义媒体库模块,你可以通过添加新的媒体库模块来扩展项目功能。
|
||||
|
||||
## 基本结构
|
||||
|
||||
* 模块位于 `media_servers` 目录下.
|
||||
* 每个模块是一个 `.py` 文件 (例如 `emby.py`, `plex.py`),文件名小写。
|
||||
* 每个模块文件包含一个与文件名对应的大驼峰命名法类(例如 `emby.py` 中的 `Emby` 类)。
|
||||
|
||||
## 模块要求
|
||||
|
||||
每个模块类必须包含以下内容:
|
||||
|
||||
* **`default_config`**:字典,包含模块所需参数及其默认值。例如:
|
||||
|
||||
```python
|
||||
# 该模块必须配置的键,值可留空
|
||||
default_config = {"url": "", "token": ""}
|
||||
```
|
||||
|
||||
* **`is_active`**:布尔值,默认为 `False`.
|
||||
|
||||
* **`__init__(self, **kwargs)`**:构造函数,接收配置参数 `kwargs`。它应该:
|
||||
1. 检查 `kwargs` 是否包含所有 `default_config` 中的参数,缺少参数则打印警告。
|
||||
2. 若参数完整,尝试连接服务器并验证配置,成功则设置 `self.is_active = True`。
|
||||
|
||||
* **`run(self, task)`**:整个模块入口函数,处理模块逻辑。
|
||||
* `task` 是一个字典,包含任务信息。如果需要修改任务参数,返回修改后的 `task` 字典;
|
||||
* 无修改则不返回或返回 `False`。
|
||||
|
||||
## 模块示例
|
||||
|
||||
参考 [emby.py](emby.py)
|
||||
|
||||
参考函数:
|
||||
|
||||
* **`get_info(self)`**:获取服务器信息(例如名称、版本),成功返回 `True`,失败返回 `False` 。用于验证赋值 `self.is_active` 。
|
||||
|
||||
* **`refresh(self, media_id)`**:刷新指定媒体信息,成功返回服务器响应数据(通常是字典),失败返回 `None` 。
|
||||
|
||||
* **`search(self, media_name)`**:搜索媒体. 成功返回服务器响应数据(通常包含媒体ID的字典), 失败返回 `None` 。
|
||||
|
||||
### 最佳实践
|
||||
|
||||
requests 部分使用 try-except 块,以防模块请求出错中断整个转存任务。
|
||||
|
||||
```python
|
||||
try:
|
||||
response = requests.request("GET", url, headers=headers, params=querystring)
|
||||
# 处理响应数据
|
||||
# ......
|
||||
# 返回
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"Error: {e}")
|
||||
return False
|
||||
```
|
||||
|
||||
## 使用自定义模块
|
||||
|
||||
放到 `/media_servers` 目录即可识别,如果你使用 docker 运行:
|
||||
|
||||
```shell
|
||||
docker run -d \
|
||||
# ... 例如添加这行挂载,其它一致
|
||||
-v ./quark-auto-save/media_servers/plex.py:/app/media_servers/plex.py \
|
||||
# ...
|
||||
```
|
||||
|
||||
如果你有写自定义模块的能力,相信你也知道如何挂载自定义模块,算我啰嗦。🙃
|
||||
|
||||
## 配置文件
|
||||
|
||||
在 `quark_config.json` 的 `media_servers` 中配置模块参数:
|
||||
|
||||
```json
|
||||
{
|
||||
"media_servers": {
|
||||
"emby": {
|
||||
"url": "http://your-emby-server:8096",
|
||||
"token": "YOUR_EMBY_TOKEN"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
当模块代码正确赋值 `default_config` 时,首次运行会自动补充缺失的键。
|
||||
84
media_servers/alist.py
Normal file
84
media_servers/alist.py
Normal file
@ -0,0 +1,84 @@
|
||||
import os
|
||||
import re
|
||||
import requests
|
||||
|
||||
|
||||
class Alist:
|
||||
|
||||
default_config = {"url": "", "token": "", "path_prefix": "/quark"}
|
||||
is_active = False
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
if kwargs:
|
||||
for key, value in self.default_config.items():
|
||||
if key in kwargs:
|
||||
setattr(self, key, kwargs[key])
|
||||
else:
|
||||
print(f"{self.__class__.__name__} 模块缺少必要参数: {key}")
|
||||
if self.url and self.token:
|
||||
if self.get_info():
|
||||
self.is_active = True
|
||||
|
||||
def run(self, task):
|
||||
if task.get("savepath"):
|
||||
path = self._normalize_path(task["savepath"])
|
||||
self.refresh(path)
|
||||
|
||||
def get_info(self):
|
||||
url = f"{self.url}/api/admin/setting/list"
|
||||
headers = {"Authorization": self.token}
|
||||
querystring = {"group": "1"}
|
||||
try:
|
||||
response = requests.request("GET", url, headers=headers, params=querystring)
|
||||
response.raise_for_status()
|
||||
response = response.json()
|
||||
if response.get("code") == 200:
|
||||
print(
|
||||
f"Alist: {response.get('data',[])[1].get('value','')} {response.get('data',[])[0].get('value','')}"
|
||||
)
|
||||
return True
|
||||
else:
|
||||
print(f"Alist: 连接失败❌ {response.get('message')}")
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"获取Alist信息出错: {e}")
|
||||
return False
|
||||
|
||||
def refresh(self, path, force_refresh=True):
|
||||
url = f"{self.url}/api/fs/list"
|
||||
headers = {"Authorization": self.token}
|
||||
querystring = {
|
||||
"path": path,
|
||||
"refresh": force_refresh,
|
||||
"page": 1,
|
||||
"per_page": 0,
|
||||
}
|
||||
try:
|
||||
response = requests.request(
|
||||
"POST", url, headers=headers, params=querystring
|
||||
)
|
||||
response.raise_for_status()
|
||||
response = response.json()
|
||||
if response.get("code") == 200:
|
||||
print(f"📁 刷新Alist目录:{path} 成功✅")
|
||||
return response.get("data")
|
||||
elif "object not found" in response.get("message", ""):
|
||||
# 如果是根目录就不再往上查找
|
||||
if path == "/" or path == self.path_prefix:
|
||||
print(f"📁 刷新Alist目录:根目录不存在,请检查 Alist 配置")
|
||||
return False
|
||||
# 获取父目录
|
||||
parent_path = os.path.dirname(path)
|
||||
print(f"📁 刷新Alist目录:{path} 不存在,转父目录 {parent_path}")
|
||||
# 递归刷新父目录
|
||||
return self.refresh(parent_path)
|
||||
else:
|
||||
print(f"📁 刷新Alist目录:失败❌ {response.get('message')}")
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"刷新Alist目录出错: {e}")
|
||||
return False
|
||||
|
||||
def _normalize_path(self, path):
|
||||
"""标准化路径格式"""
|
||||
if not path.startswith(self.path_prefix):
|
||||
path = f"/{self.path_prefix}/{path}"
|
||||
return re.sub(r"/{2,}", "/", path)
|
||||
69
media_servers/alist_strm.py
Normal file
69
media_servers/alist_strm.py
Normal file
@ -0,0 +1,69 @@
|
||||
import re
|
||||
import requests
|
||||
"""
|
||||
配合 alist-strm 项目,触发特定配置运行
|
||||
https://github.com/tefuirZ/alist-strm
|
||||
"""
|
||||
class Alist_strm:
|
||||
|
||||
default_config = {"url": "", "cookie": "", "config_id": ""}
|
||||
is_active = False
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
if kwargs:
|
||||
for key, value in self.default_config.items():
|
||||
if key in kwargs:
|
||||
setattr(self, key, kwargs[key])
|
||||
else:
|
||||
print(f"{self.__class__.__name__} 模块缺少必要参数: {key}")
|
||||
if self.url and self.cookie and self.config_id:
|
||||
if self.get_info(self.config_id):
|
||||
self.is_active = True
|
||||
|
||||
def run(self, task):
|
||||
self.run_selected_configs(self.config_id)
|
||||
|
||||
def get_info(self, config_id):
|
||||
url = f"{self.url}/edit/{config_id}"
|
||||
headers = {"Cookie": self.cookie}
|
||||
try:
|
||||
response = requests.request("GET", url, headers=headers)
|
||||
response.raise_for_status()
|
||||
html_content = response.text
|
||||
# 用正则提取 config_name 的值
|
||||
match = re.search(r'name="config_name" value="([^"]+)"', html_content)
|
||||
if match:
|
||||
config_name = match.group(1)
|
||||
print(f"alist-strm配置: {config_name}")
|
||||
return True
|
||||
else:
|
||||
print(f"alist-strm配置: 匹配失败❌")
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"获取alist-strm配置信息出错: {e}")
|
||||
return False
|
||||
|
||||
def run_selected_configs(self, selected_configs_str):
|
||||
url = f"{self.url}/run_selected_configs"
|
||||
headers = {"Cookie": self.cookie}
|
||||
try:
|
||||
selected_configs = [int(x.strip()) for x in selected_configs_str.split(",")]
|
||||
except ValueError:
|
||||
print("Error: 运行alist-strm配置错误,id应以,分割")
|
||||
return None
|
||||
data = [("selected_configs", config_id) for config_id in selected_configs]
|
||||
data.append(("action", "run_selected"))
|
||||
try:
|
||||
response = requests.post(url, headers=headers, data=data)
|
||||
response.raise_for_status()
|
||||
html_content = response.text
|
||||
# 用正则提取 config_name 的值
|
||||
match = re.search(r'role="alert">\s*([^<]+)\s*<button', html_content)
|
||||
if match:
|
||||
alert = match.group(1).strip()
|
||||
print(f"🔗 alist-strm配置运行: {alert}✅")
|
||||
return True
|
||||
else:
|
||||
print(f"🔗 alist-strm配置运行: 失败❌")
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"Error: {e}")
|
||||
return False
|
||||
@ -3,71 +3,91 @@ import requests
|
||||
|
||||
class Emby:
|
||||
|
||||
default_config = {"url": "", "apikey": ""}
|
||||
default_config = {"url": "", "token": ""}
|
||||
is_active = False
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.is_active = False
|
||||
if kwargs:
|
||||
for key, value in self.default_config.items():
|
||||
if key in kwargs:
|
||||
setattr(self, key, kwargs[key])
|
||||
else:
|
||||
print(f"{self.__class__.__name__} 模块缺少必要参数: {key}")
|
||||
if self.url and self.apikey:
|
||||
if self.url and self.token:
|
||||
if self.get_info():
|
||||
self.is_active = True
|
||||
|
||||
def run(self, task):
|
||||
if task.get("media_id"):
|
||||
if task["media_id"] != "0":
|
||||
self.refresh(task["media_id"])
|
||||
else:
|
||||
match_media_id = self.search(task["taskname"])
|
||||
if match_media_id:
|
||||
task["media_id"] = match_media_id
|
||||
self.refresh(match_media_id)
|
||||
return task
|
||||
|
||||
def get_info(self):
|
||||
url = f"{self.url}/emby/System/Info"
|
||||
headers = {"X-Emby-Token": self.apikey}
|
||||
headers = {"X-Emby-Token": self.token}
|
||||
querystring = {}
|
||||
response = requests.request("GET", url, headers=headers, params=querystring)
|
||||
if "application/json" in response.headers["Content-Type"]:
|
||||
response = response.json()
|
||||
print(
|
||||
f"Emby媒体库: {response.get('ServerName','')} v{response.get('Version','')}"
|
||||
)
|
||||
return True
|
||||
else:
|
||||
print(f"Emby媒体库: 连接失败❌ {response.text}")
|
||||
return False
|
||||
try:
|
||||
response = requests.request("GET", url, headers=headers, params=querystring)
|
||||
if "application/json" in response.headers["Content-Type"]:
|
||||
response = response.json()
|
||||
print(
|
||||
f"Emby媒体库: {response.get('ServerName','')} v{response.get('Version','')}"
|
||||
)
|
||||
return True
|
||||
else:
|
||||
print(f"Emby媒体库: 连接失败❌ {response.text}")
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"获取Emby媒体库信息出错: {e}")
|
||||
return False
|
||||
|
||||
def refresh(self, emby_id):
|
||||
if emby_id:
|
||||
url = f"{self.url}/emby/Items/{emby_id}/Refresh"
|
||||
headers = {"X-Emby-Token": self.apikey}
|
||||
querystring = {
|
||||
"Recursive": "true",
|
||||
"MetadataRefreshMode": "FullRefresh",
|
||||
"ImageRefreshMode": "FullRefresh",
|
||||
"ReplaceAllMetadata": "false",
|
||||
"ReplaceAllImages": "false",
|
||||
}
|
||||
if not emby_id:
|
||||
return False
|
||||
url = f"{self.url}/emby/Items/{emby_id}/Refresh"
|
||||
headers = {"X-Emby-Token": self.token}
|
||||
querystring = {
|
||||
"Recursive": "true",
|
||||
"MetadataRefreshMode": "FullRefresh",
|
||||
"ImageRefreshMode": "FullRefresh",
|
||||
"ReplaceAllMetadata": "false",
|
||||
"ReplaceAllImages": "false",
|
||||
}
|
||||
try:
|
||||
response = requests.request(
|
||||
"POST", url, headers=headers, params=querystring
|
||||
)
|
||||
if response.text == "":
|
||||
print(f"🎞 刷新Emby媒体库:成功✅")
|
||||
print(f"🎞️ 刷新Emby媒体库:成功✅")
|
||||
return True
|
||||
else:
|
||||
print(f"🎞 刷新Emby媒体库:{response.text}❌")
|
||||
return False
|
||||
print(f"🎞️ 刷新Emby媒体库:{response.text}❌")
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"刷新Emby媒体库出错: {e}")
|
||||
return False
|
||||
|
||||
def search(self, media_name):
|
||||
if media_name:
|
||||
url = f"{self.url}/emby/Items"
|
||||
headers = {"X-Emby-Token": self.apikey}
|
||||
querystring = {
|
||||
"IncludeItemTypes": "Series",
|
||||
"StartIndex": 0,
|
||||
"SortBy": "SortName",
|
||||
"SortOrder": "Ascending",
|
||||
"ImageTypeLimit": 0,
|
||||
"Recursive": "true",
|
||||
"SearchTerm": media_name,
|
||||
"Limit": 10,
|
||||
"IncludeSearchTypes": "false",
|
||||
}
|
||||
if not media_name:
|
||||
return False
|
||||
url = f"{self.url}/emby/Items"
|
||||
headers = {"X-Emby-Token": self.token}
|
||||
querystring = {
|
||||
"IncludeItemTypes": "Series",
|
||||
"StartIndex": 0,
|
||||
"SortBy": "SortName",
|
||||
"SortOrder": "Ascending",
|
||||
"ImageTypeLimit": 0,
|
||||
"Recursive": "true",
|
||||
"SearchTerm": media_name,
|
||||
"Limit": 10,
|
||||
"IncludeSearchTypes": "false",
|
||||
}
|
||||
try:
|
||||
response = requests.request("GET", url, headers=headers, params=querystring)
|
||||
if "application/json" in response.headers["Content-Type"]:
|
||||
response = response.json()
|
||||
@ -75,9 +95,11 @@ class Emby:
|
||||
for item in response["Items"]:
|
||||
if item["IsFolder"]:
|
||||
print(
|
||||
f"🎞 《{item['Name']}》匹配到Emby媒体库ID:{item['Id']}"
|
||||
f"🎞️ 《{item['Name']}》匹配到Emby媒体库ID:{item['Id']}"
|
||||
)
|
||||
return item["Id"]
|
||||
else:
|
||||
print(f"🎞 搜索Emby媒体库:{response.text}❌")
|
||||
print(f"🎞️ 搜索Emby媒体库:{response.text}❌")
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"搜索Emby媒体库出错: {e}")
|
||||
return False
|
||||
|
||||
@ -692,6 +692,7 @@ def load_media_servers(media_servers_config, media_servers_dir="media_servers"):
|
||||
available_modules = [
|
||||
f.replace(".py", "") for f in os.listdir(media_servers_dir) if f.endswith(".py")
|
||||
]
|
||||
print(f"🧩 载入媒体库模块")
|
||||
for module_name in available_modules:
|
||||
try:
|
||||
module = importlib.import_module(f"{media_servers_dir}.{module_name}")
|
||||
@ -703,7 +704,8 @@ def load_media_servers(media_servers_config, media_servers_dir="media_servers"):
|
||||
else:
|
||||
media_servers_config[module_name] = ServerClass().default_config
|
||||
except (ImportError, AttributeError):
|
||||
print(f"加载模块 {module_name} 失败")
|
||||
print(f"载入模块 {module_name} 失败")
|
||||
print()
|
||||
return media_servers
|
||||
|
||||
|
||||
@ -795,8 +797,8 @@ def do_save(account, tasklist=[]):
|
||||
print(f"正则替换: {task['replace']}")
|
||||
if task.get("enddate"):
|
||||
print(f"任务截止: {task['enddate']}")
|
||||
if task.get("emby_id"):
|
||||
print(f"刷媒体库: {task['emby_id']}")
|
||||
if task.get("media_id"):
|
||||
print(f"刷媒体库: {task['media_id']}")
|
||||
if task.get("ignore_extension"):
|
||||
print(f"忽略后缀: {task['ignore_extension']}")
|
||||
if task.get("update_subdir"):
|
||||
@ -804,20 +806,12 @@ def do_save(account, tasklist=[]):
|
||||
print()
|
||||
is_new = account.do_save_task(task)
|
||||
is_rename = account.do_rename_task(task)
|
||||
# 刷新媒体库
|
||||
for server_name, media_server in media_servers.items():
|
||||
if (
|
||||
media_server.is_active
|
||||
and (is_new or is_rename)
|
||||
and task.get("media_id") != "0"
|
||||
):
|
||||
if task.get("media_id"):
|
||||
media_server.refresh(task["media_id"])
|
||||
else:
|
||||
match_media_id = media_server.search(task["taskname"])
|
||||
if match_media_id:
|
||||
task["media_id"] = match_media_id
|
||||
media_server.refresh(match_media_id)
|
||||
# 调用媒体库模块
|
||||
if is_new or is_rename:
|
||||
print(f"🧩 调用媒体库模块")
|
||||
for server_name, media_server in media_servers.items():
|
||||
if media_server.is_active:
|
||||
task = media_server.run(task) or task
|
||||
print()
|
||||
|
||||
|
||||
@ -825,11 +819,15 @@ def reaking_change_update():
|
||||
global CONFIG_DATA
|
||||
# print("Update config v0.3.6.1 to 0.3.7")
|
||||
if CONFIG_DATA.get("emby"):
|
||||
CONFIG_DATA.setdefault("media_servers", {})["emby"] = CONFIG_DATA["emby"]
|
||||
CONFIG_DATA.setdefault("media_servers", {})["emby"] = {
|
||||
"url": CONFIG_DATA["emby"]["url"],
|
||||
"token": CONFIG_DATA["emby"]["apikey"],
|
||||
}
|
||||
del CONFIG_DATA["emby"]
|
||||
for task in CONFIG_DATA.get("tasklist", {}):
|
||||
task["media_id"] = task.get("emby_id", "")
|
||||
del task["emby_id"]
|
||||
if task.get("emby_id"):
|
||||
del task["emby_id"]
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
@ -6,9 +6,11 @@
|
||||
"QUARK_SIGN_NOTIFY": true,
|
||||
"其他推送渠道//此项可删": "配置方法同青龙"
|
||||
},
|
||||
"emby": {
|
||||
"url": "",
|
||||
"apikey": ""
|
||||
"media_servers": {
|
||||
"emby": {
|
||||
"url": "",
|
||||
"token": ""
|
||||
}
|
||||
},
|
||||
"tasklist": [
|
||||
{
|
||||
@ -18,7 +20,7 @@
|
||||
"pattern": "$TV",
|
||||
"replace": "",
|
||||
"enddate": "2099-01-30",
|
||||
"emby_id": "",
|
||||
"media_id": "",
|
||||
"update_subdir": "4k|1080p"
|
||||
},
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user