diff --git a/AutoBangumi2.0/Dockerfile b/AutoBangumi2.0/Dockerfile
new file mode 100644
index 00000000..100900e6
--- /dev/null
+++ b/AutoBangumi2.0/Dockerfile
@@ -0,0 +1,11 @@
+# syntax=docker/dockerfile:1
+FROM python:3.10-slim-buster
+WORKDIR /auto-bangumi
+COPY requirements.txt .
+RUN pip3 install -r requirements.txt
+
+COPY ./app /app
+COPY ./config /config
+
+
+CMD [ "python3", "/app/docker_main.py"]
\ No newline at end of file
diff --git a/Docker/auto_set_rule.py b/AutoBangumi2.0/app/auto_set_rule.py
similarity index 53%
rename from Docker/auto_set_rule.py
rename to AutoBangumi2.0/app/auto_set_rule.py
index 78be1eb0..8cba2e00 100644
--- a/Docker/auto_set_rule.py
+++ b/AutoBangumi2.0/app/auto_set_rule.py
@@ -4,23 +4,19 @@ import os
class SetRule:
- def __init__(self):
- with open("config.json") as f:
- info = json.load(f)
-
- with open("bangumi.json") as f:
- self.bangumi_info = json.load(f)
- self.rss_link = info["rss_link"]
- self.host_ip = "192.168.31.10:8181"
- self.user_name = "admin"
- self.password = "adminadmin"
-
- def set_rule(self, bangumi_name, season):
- qb = qbittorrentapi.Client(host=self.host_ip, username=self.user_name, password=self.password)
+ def __init__(self, config, info):
+ self.bangumi_info = info
+ self.rss_link = config["rss_link"]
+ self.host_ip = config["host_ip"]
+ self.user_name = config["user_name"]
+ self.password = config["password"]
+ self.qb = qbittorrentapi.Client(host=self.host_ip, username=self.user_name, password=self.password)
try:
- qb.auth_log_in()
+ self.qb.auth_log_in()
except qbittorrentapi.LoginFailed as e:
print(e)
+
+ def set_rule(self, bangumi_name, season):
rule = {
'enable': False,
'mustContain': bangumi_name,
@@ -29,20 +25,16 @@ class SetRule:
'episodeFilter': '',
'smartFilter': False,
'previouslyMatchedEpisodes': [],
- 'affectedFeeds': [rss_link],
+ 'affectedFeeds': [self.rss_link],
'ignoreDays': 0,
'lastMatch': '',
'addPaused': False,
'assignedCategory': 'Bangumi',
'savePath': os.path.join('/downloads', bangumi_name, season)
}
- qb.rss_set_rule(rule_name=bangumi_name, rule_def=rule)
+ self.qb.rss_set_rule(rule_name=bangumi_name, rule_def=rule)
- def set_rule_main(self):
+ def run(self):
for info in self.bangumi_info:
self.set_rule(info["title"], info["season"])
-
-if __name__ == "__main__":
- rule = SetRule()
- rule.set_rule_main()
\ No newline at end of file
diff --git a/AutoBangumi2.0/app/collect_bangumi_info.py b/AutoBangumi2.0/app/collect_bangumi_info.py
new file mode 100644
index 00000000..f9c8fb52
--- /dev/null
+++ b/AutoBangumi2.0/app/collect_bangumi_info.py
@@ -0,0 +1,66 @@
+# -*- coding: UTF-8 -*-
+import requests
+from bs4 import BeautifulSoup
+import json
+import re
+
+
+class CollectRSS:
+ def __init__(self, config, info):
+ self.info = info
+ self.config = config
+ self.bangumi_title = []
+
+ def collect_info(self):
+ episode_rules = [r'(.*)\[(\d{1,3}|\d{1,3}\.\d{1,2})(?:v\d{1,2})?(?:END)?\](.*)',
+ r'(.*)\[E(\d{1,3}|\d{1,3}\.\d{1,2})(?:v\d{1,2})?(?:END)?\](.*)',
+ r'(.*)\[第(\d*\.*\d*)话(?:END)?\](.*)',
+ r'(.*)\[第(\d*\.*\d*)話(?:END)?\](.*)',
+ r'(.*)第(\d*\.*\d*)话(?:END)?(.*)',
+ r'(.*)第(\d*\.*\d*)話(?:END)?(.*)',
+ r'(.*)- (\d{1,3}|\d{1,3}\.\d{1,2})(?:v\d{1,2})?(?:END)? (.*)']
+ url = self.config["rss_link"]
+ rss = requests.get(url, 'utf-8')
+ soup = BeautifulSoup(rss.text, 'xml')
+ item = soup.find_all('item')
+ bangumi_title = []
+ for a in item:
+ name = str(a.find('title'))
+ name = re.sub('
|', '', name)
+ parrten = r'\[|\]|\u3010|\u3011|\★|\*'
+ for i in range(2):
+ n = re.split(parrten, name)
+ name = re.sub(f'\[{n[1]}\]|【{n[1]}】|★{n[1]}★', '', name)
+ for rule in episode_rules:
+ matchObj = re.match(rule, name, re.I)
+ if matchObj is not None:
+ new_name = re.sub(r'\[|\]', '', f'{matchObj.group(1)}')
+ new_name = re.split(r'/', new_name)[-1].strip()
+ if new_name not in self.bangumi_title:
+ self.bangumi_title.append(new_name)
+
+ def write_info(self):
+ bangumi_info = self.info
+ had_data = []
+ for data in bangumi_info:
+ had_data.append(data["title"])
+ for title in self.bangumi_title:
+ a = re.match(r'(.*)(S.\d)', title, re.I)
+ if a is not None:
+ title = a.group(1).strip()
+ season = a.group(2).strip()
+ else:
+ season = ''
+ if title not in had_data:
+ bangumi_info.append({
+ "title": title,
+ "season": season
+ })
+ print(f"add {title} {season}")
+ # 写入数据
+ with open("../config/bangumi.json", 'w', encoding='utf8') as f:
+ json.dump(bangumi_info, f, indent=4, separators=(',', ': '), ensure_ascii=False)
+
+ def run(self):
+ self.collect_info()
+ self.write_info()
\ No newline at end of file
diff --git a/AutoBangumi2.0/app/docker_main.py b/AutoBangumi2.0/app/docker_main.py
new file mode 100644
index 00000000..d5480e4c
--- /dev/null
+++ b/AutoBangumi2.0/app/docker_main.py
@@ -0,0 +1,19 @@
+import os
+import time
+from collect_bangumi_info import CollectRSS
+from auto_set_rule import SetRule
+from rename_qb import QbittorrentRename
+import json
+
+#sleep_time = os.environ["TIME"]
+
+if __name__ == "__main__":
+ while True:
+ with open("../config/config.json") as f:
+ config = json.load(f)
+ with open("../config/bangumi.json") as f:
+ info = json.load(f)
+ CollectRSS(config, info).run()
+ SetRule(config, info).run()
+ QbittorrentRename(config).run()
+ time.sleep(1800)
diff --git a/AutoBangumi2.0/app/rename_qb.py b/AutoBangumi2.0/app/rename_qb.py
new file mode 100644
index 00000000..41ab7439
--- /dev/null
+++ b/AutoBangumi2.0/app/rename_qb.py
@@ -0,0 +1,94 @@
+import re
+import io
+import sys
+import qbittorrentapi
+from os import environ
+import time
+
+
+class QbittorrentRename:
+ def __init__(self, config):
+ self.qbt_client = qbittorrentapi.Client(host=config['host_ip'], username=config['user_name'], password=config['password'])
+ try:
+ self.qbt_client.auth_log_in()
+ except qbittorrentapi.LoginFailed as e:
+ print(e)
+ self.recent_info = self.qbt_client.torrents_info(status_filter='completed')
+ self.hash = None
+ self.name = None
+ self.new_name = None
+ self.path_name = None
+ self.count = 0
+ self.rename_count = 0
+ self.torrent_count = len(self.recent_info)
+ self.method = config['method']
+ self.rules = [r'(.*)\[(\d{1,3}|\d{1,3}\.\d{1,2})(?:v\d{1,2})?(?:END)?\](.*)',
+ r'(.*)\[E(\d{1,3}|\d{1,3}\.\d{1,2})(?:v\d{1,2})?(?:END)?\](.*)',
+ r'(.*)\[第(\d*\.*\d*)话(?:END)?\](.*)',
+ r'(.*)\[第(\d*\.*\d*)話(?:END)?\](.*)',
+ r'(.*)第(\d*\.*\d*)话(?:END)?(.*)',
+ r'(.*)第(\d*\.*\d*)話(?:END)?(.*)',
+ r'(.*)- (\d{1,3}|\d{1,3}\.\d{1,2})(?:v\d{1,2})?(?:END)? (.*)']
+
+ def rename_normal(self, idx):
+ self.name = self.recent_info[idx].name
+ self.hash = self.recent_info[idx].hash
+ self.path_name = self.recent_info[idx].content_path.split("/")[-1]
+ file_name = self.name
+ for rule in self.rules:
+ matchObj = re.match(rule, file_name, re.I)
+ if matchObj is not None:
+ self.new_name = f'{matchObj.group(1).strip()} E{matchObj.group(2)}{matchObj.group(3)}'
+
+ def rename_pn(self, idx):
+ self.name = self.recent_info[idx].name
+ self.hash = self.recent_info[idx].hash
+ self.path_name = self.recent_info[idx].content_path.split("/")[-1]
+ n = re.split(r'\[|\]', self.name)
+ file_name = self.name.replace(f'[{n[1]}]', '')
+ for rule in self.rules:
+ matchObj = re.match(rule, file_name, re.I)
+ if matchObj is not None:
+ self.new_name = re.sub(r'\[|\]', '', f'{matchObj.group(1).strip()} E{matchObj.group(2)}{n[-1]}')
+
+ def rename(self):
+ if self.path_name != self.new_name:
+ self.qbt_client.torrents_rename_file(torrent_hash=self.hash, old_path=self.name, new_path=self.new_name)
+ print(f'{self.name} >> {self.new_name}')
+ self.count += 1
+ else:
+ return
+
+ def clear_info(self):
+ self.name = None
+ self.hash = None
+ self.new_name = None
+
+ def print_result(self):
+ sys.stdout.write(f"[{time.strftime('%X')}] 已完成对{self.torrent_count}个文件的检查" + '\n')
+ sys.stdout.write(f"[{time.strftime('%X')}] 已对其中{self.count}个文件进行重命名" + '\n')
+ sys.stdout.write(f"[{time.strftime('%X')}] 完成" + '\n')
+ sys.stdout.flush()
+
+ def run(self):
+ if self.method not in ['pn', 'normal']:
+ print('error method')
+ elif self.method == 'normal':
+ for i in range(0, self.torrent_count + 1):
+ try:
+ self.rename_normal(i)
+ self.rename()
+ self.clear_info()
+ except:
+ self.print_result()
+ elif self.method == 'pn':
+ for i in range(0, self.torrent_count + 1):
+ try:
+ self.rename_pn(i)
+ self.rename()
+ self.clear_info()
+ except:
+ self.print_result()
+
+
+
diff --git a/Docker/data/bangumi.json b/AutoBangumi2.0/config/bangumi.json
similarity index 100%
rename from Docker/data/bangumi.json
rename to AutoBangumi2.0/config/bangumi.json
diff --git a/Docker/config/config.json b/AutoBangumi2.0/config/config.json
similarity index 92%
rename from Docker/config/config.json
rename to AutoBangumi2.0/config/config.json
index c75b5345..31c36bf7 100644
--- a/Docker/config/config.json
+++ b/AutoBangumi2.0/config/config.json
@@ -2,6 +2,7 @@
"host_ip": "192.168.31.10:8181",
"user_name": "admin",
"password": "adminadmin",
+ "method": "pn",
"rss_link": "https://mikanani.me/RSS/MyBangumi?token=Td8ceWZZv3s2OZm5ji9RoMer8vk5VS3xzC1Hmg8A26E%3d",
"download_path": "/downloads/Bangumi"
}
\ No newline at end of file
diff --git a/AutoBangumi2.0/config/rename_rule.txt b/AutoBangumi2.0/config/rename_rule.txt
new file mode 100644
index 00000000..e69de29b
diff --git a/AutoBangumi2.0/requirements.txt b/AutoBangumi2.0/requirements.txt
new file mode 100644
index 00000000..dd08288c
--- /dev/null
+++ b/AutoBangumi2.0/requirements.txt
@@ -0,0 +1,5 @@
+qbittorrent-api==2022.4.30
+requests-html==0.10.0
+requests-oauthlib==1.3.1
+requests==2.27.1
+
diff --git a/Docker/collect_bangumi_info.py b/Docker/collect_bangumi_info.py
deleted file mode 100644
index e79fa8c0..00000000
--- a/Docker/collect_bangumi_info.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# -*- coding: UTF-8 -*-
-import requests
-from bs4 import BeautifulSoup
-import json
-import re
-
-
-def collect_info():
- episode_rules = [r'(.*)\[(\d{1,3}|\d{1,3}\.\d{1,2})(?:v\d{1,2})?(?:END)?\](.*)',
- r'(.*)\[E(\d{1,3}|\d{1,3}\.\d{1,2})(?:v\d{1,2})?(?:END)?\](.*)',
- r'(.*)\[第(\d*\.*\d*)话(?:END)?\](.*)',
- r'(.*)\[第(\d*\.*\d*)話(?:END)?\](.*)',
- r'(.*)第(\d*\.*\d*)话(?:END)?(.*)',
- r'(.*)第(\d*\.*\d*)話(?:END)?(.*)',
- r'(.*)- (\d{1,3}|\d{1,3}\.\d{1,2})(?:v\d{1,2})?(?:END)? (.*)']
- with open('./config/config.json') as f:
- config = json.load(f)
- url = config["rss_link"]
- rss = requests.get(url, 'utf-8')
- soup = BeautifulSoup(rss.text, 'xml')
- item = soup.find_all('item')
- bangumi_title = []
- for a in item:
- name = str(a.find('title'))
- name = re.sub('|', '', name)
- parrten = r'\[|\]|\u3010|\u3011|\★|\*'
- symbol = [['[', ']'], ['【', '】'], ['★', '★']]
- for i in range(2):
- n = re.split(parrten, name)
- name = re.sub(f'\[{n[1]}\]|【{n[1]}】|★{n[1]}★', '', name)
- for rule in episode_rules:
- matchObj = re.match(rule, name, re.I)
- if matchObj is not None:
- new_name = re.sub(r'\[|\]', '', f'{matchObj.group(1)}')
- new_name = re.split(r'/', new_name)[-1].strip()
- if new_name not in bangumi_title:
- bangumi_title.append(new_name)
-
- with open("./data/bangumi.json", encoding='utf-8') as f:
- bangumi_info = json.load(f)
- had_data = []
- for data in bangumi_info:
- had_data.append(data["title"])
-
- season_rules = r'(.*)(S.\d)'
- for title in bangumi_title:
- a = re.match(season_rules, title, re.I)
- if a is not None:
- title = a.group(1).strip()
- season = a.group(2).strip()
- else:
- season = ''
- if title not in had_data:
- bangumi_info.append({
- "title": title,
- "season": season
- })
- print(f"add {title} {season}")
- # 写入数据
- with open("./data/bangumi.json", 'w', encoding='utf8') as f:
- json.dump(bangumi_info, f, indent=4, separators=(',', ': '), ensure_ascii=False)
\ No newline at end of file
diff --git a/Docker/docker_main.py b/Docker/docker_main.py
deleted file mode 100644
index b6d85859..00000000
--- a/Docker/docker_main.py
+++ /dev/null
@@ -1,15 +0,0 @@
-import os
-import time
-from collect_bangumi_info import collect_info
-from rename_qb import rename_main
-from auto_set_rule import SetRule
-
-sleep_time = os.environ["TIME"]
-
-if __name__ == "__main__":
- while True:
- collect_info()
- rename_main()
- rule = SetRule()
- rule.set_rule_main()
- time.sleep(float(sleep_time))