Merge pull request #596 from lededev/m3newfeture

新功能:1.增量整理 2.保存运行及错误日志到目录
This commit is contained in:
Yoshiko2
2021-09-27 21:43:23 +08:00
committed by GitHub
6 changed files with 302 additions and 104 deletions

View File

@@ -1,7 +1,7 @@
from os import replace from os import replace
import requests import requests
import hashlib import hashlib
import pathlib from pathlib import Path
import random import random
import os.path import os.path
import uuid import uuid
@@ -467,6 +467,9 @@ def translate(
+ src + src
) )
result = get_html(url=url, return_type="object") result = get_html(url=url, return_type="object")
if not result.ok:
print('[-]Google-free translate web API calling failed.')
return ''
translate_list = [i["trans"] for i in result.json()["sentences"]] translate_list = [i["trans"] for i in result.json()["sentences"]]
trans_result = trans_result.join(translate_list) trans_result = trans_result.join(translate_list)
@@ -548,7 +551,7 @@ def load_cookies(filename):
# 文件修改时间距此时的天数 # 文件修改时间距此时的天数
def file_modification_days(filename) -> int: def file_modification_days(filename) -> int:
mfile = pathlib.Path(filename) mfile = Path(filename)
if not mfile.exists(): if not mfile.exists():
return 9999 return 9999
mtime = int(mfile.stat().st_mtime) mtime = int(mfile.stat().st_mtime)

View File

@@ -8,10 +8,12 @@ import typing
import urllib3 import urllib3
import config import config
from datetime import datetime
import time import time
from ADC_function import get_html, is_link from pathlib import Path
from ADC_function import file_modification_days, get_html, is_link
from number_parser import get_number from number_parser import get_number
from core import core_main from core import core_main, moveFailedFolder
def check_update(local_version): def check_update(local_version):
@@ -33,35 +35,173 @@ def check_update(local_version):
def argparse_function(ver: str) -> typing.Tuple[str, str, bool]: def argparse_function(ver: str) -> typing.Tuple[str, str, bool]:
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument("file", default='', nargs='?', help="Single Movie file path.") parser.add_argument("file", default='', nargs='?', help="Single Movie file path.")
parser.add_argument("-p","--path",default='',nargs='?',help="Analysis folder path.") parser.add_argument("-p","--path",default='',nargs='?',help="Analysis folder path.")
# parser.add_argument("-c", "--config", default='config.ini', nargs='?', help="The config file Path.") # parser.add_argument("-c", "--config", default='config.ini', nargs='?', help="The config file Path.")
default_logdir = os.path.join(Path.home(),'.avlogs')
parser.add_argument("-o","--log-dir",dest='logdir',default=default_logdir,nargs='?',
help=f"""Duplicate stdout and stderr to logfiles
in logging folder, default on.
default for current user: {default_logdir}
Use --log-dir= to turn off logging feature.""")
parser.add_argument("-n", "--number", default='', nargs='?', help="Custom file number") parser.add_argument("-n", "--number", default='', nargs='?', help="Custom file number")
parser.add_argument("-a", "--auto-exit", dest='autoexit', action="store_true", parser.add_argument("-a", "--auto-exit", dest='autoexit', action="store_true",
help="Auto exit after program complete") help="Auto exit after program complete")
parser.add_argument("-q","--regex-query",dest='regexstr',default='',nargs='?',help="python re module regex filepath filtering.")
parser.add_argument("-v", "--version", action="version", version=ver) parser.add_argument("-v", "--version", action="version", version=ver)
args = parser.parse_args() args = parser.parse_args()
return args.file, args.path, args.number, args.autoexit return args.file, args.path, args.number, args.autoexit, args.logdir, args.regexstr
G_trailerRE = re.compile(r'-trailer\.', re.IGNORECASE) class OutLogger(object):
def __init__(self, logfile) -> None:
self.term = sys.stdout
self.log = open(logfile,"w",encoding='utf-8')
def __del__(self):
self.close()
def __enter__(self):
pass
def __exit__(self, *args):
self.close()
def write(self,msg):
self.term.write(msg)
self.log.write(msg)
def flush(self):
self.term.flush()
self.log.flush()
os.fsync(self.log.fileno())
def close(self):
if self.term != None:
sys.stdout = self.term
self.term = None
if self.log != None:
self.log.close()
self.log = None
def movie_lists(root, escape_folder):
if os.path.basename(root) in escape_folder: class ErrLogger(OutLogger):
return [] def __init__(self, logfile) -> None:
self.term = sys.stderr
self.log = open(logfile,"w",encoding='utf-8')
def close(self):
if self.term != None:
sys.stderr = self.term
self.term = None
if self.log != None:
self.log.close()
self.log = None
def dupe_stdout_to_logfile(logdir: str):
if not isinstance(logdir, str) or len(logdir) == 0:
return
if not os.path.isdir(logdir):
os.makedirs(logdir)
if not os.path.isdir(logdir):
return
log_tmstr = datetime.now().strftime("%Y%m%dT%H%M%S")
logfile = os.path.join(logdir, f'avdc_{log_tmstr}.txt')
errlog = os.path.join(logdir, f'avdc_{log_tmstr}_err.txt')
sys.stdout = OutLogger(logfile)
sys.stderr = ErrLogger(errlog)
def close_logfile(logdir: str):
if not isinstance(logdir, str) or len(logdir) == 0 or not os.path.isdir(logdir):
return
sys.stdout.close()
sys.stderr.close()
# 清理空文件
for current_dir, subdirs, files in os.walk(logdir, topdown=False):
try:
for f in files:
full_name = os.path.join(current_dir, f)
if os.path.getsize(full_name) == 0:
os.remove(full_name)
except:
pass
_print = print # Hook print
_stdout = sys.stdout
def print(*args, **kw):
_print(*args, **kw)
if _stdout != sys.stdout:
sys.stdout.flush()
# 重写视频文件扫描,消除递归,取消全局变量,新增失败文件列表跳过处理
def movie_lists(root, conf, regexstr):
escape_folder = re.split("[,]", conf.escape_folder())
main_mode = conf.main_mode()
debug = conf.debug()
nfo_skip_days = conf.nfo_skip_days()
soft_link = conf.soft_link()
total = [] total = []
file_type = conf.media_type().upper().split(",") file_type = conf.media_type().upper().split(",")
dirs = os.listdir(root) trailerRE = re.compile(r'-trailer\.', re.IGNORECASE)
for entry in dirs: cliRE = None
f = os.path.join(root, entry) if len(regexstr):
if os.path.isdir(f): try:
total += movie_lists(f, escape_folder) cliRE = re.compile(regexstr, re.IGNORECASE)
elif os.path.splitext(f)[1].upper() in file_type: except:
absf = os.path.abspath(f) pass
if (conf.main_mode() == 3 or not is_link(absf)) and not G_trailerRE.search(f): failed_set = set()
if main_mode == 3 or soft_link:
try:
with open(os.path.join(conf.failed_folder(), 'failed_list.txt'), 'r', encoding='utf-8') as flt:
flist = flt.read().splitlines()
failed_set = set(flist)
flt.close()
if len(flist) != len(failed_set):
with open(os.path.join(conf.failed_folder(), 'failed_list.txt'), 'w', encoding='utf-8') as flt:
flt.writelines([line + '\n' for line in failed_set])
flt.close()
except:
pass
for current_dir, subdirs, files in os.walk(root, topdown=False):
if current_dir in escape_folder:
continue
for f in files:
full_name = os.path.join(current_dir, f)
if not os.path.splitext(full_name)[1].upper() in file_type:
continue
absf = os.path.abspath(full_name)
if absf in failed_set:
if debug:
print('[!]Skip failed file:', absf)
continue
if cliRE and not cliRE.search(absf):
continue
if main_mode == 3 and nfo_skip_days > 0:
nfo = Path(absf).with_suffix('.nfo')
if file_modification_days(nfo) <= nfo_skip_days:
continue
if (main_mode == 3 or not is_link(absf)) and not trailerRE.search(f):
total.append(absf) total.append(absf)
if nfo_skip_days <= 0 or not soft_link or main_mode == 3:
return total
# 软连接方式,已经成功削刮的也需要从成功目录中检查.nfo更新天数跳过N天内更新过的
skip_numbers = set()
success_folder = conf.success_folder()
for current_dir, subdirs, files in os.walk(success_folder, topdown=False):
for f in files:
if not os.path.splitext(f)[1].upper() in file_type:
continue
nfo_file = os.path.join(current_dir, str(Path(f).with_suffix('.nfo')))
if file_modification_days(nfo_file) > nfo_skip_days:
continue
number = get_number(False, os.path.basename(f))
if number:
skip_numbers.add(number.upper())
for f in total:
n_number = get_number(False, os.path.basename(f))
if n_number and n_number.upper() in skip_numbers:
total.pop(total.index(f))
return total return total
@@ -97,7 +237,7 @@ def create_data_and_move(file_path: str, c: config.Config, debug):
file_path = os.path.abspath(file_path) file_path = os.path.abspath(file_path)
if debug == True: if debug == True:
print("[!]Making Data for [{}], the number is [{}]".format(file_path, n_number)) print(f"[!]Making Data for [{file_path}], the number is [{n_number}]")
if n_number: if n_number:
core_main(file_path, n_number, c) core_main(file_path, n_number, c)
else: else:
@@ -105,31 +245,20 @@ def create_data_and_move(file_path: str, c: config.Config, debug):
print("[*]======================================================") print("[*]======================================================")
else: else:
try: try:
print("[!]Making Data for [{}], the number is [{}]".format(file_path, n_number)) print(f"[!]Making Data for [{file_path}], the number is [{n_number}]")
if n_number: if n_number:
core_main(file_path, n_number, c) core_main(file_path, n_number, c)
else: else:
raise ValueError("number empty") raise ValueError("number empty")
print("[*]======================================================") print("[*]======================================================")
except Exception as err: except Exception as err:
print("[-] [{}] ERROR:".format(file_path)) print(f"[-] [{file_path}] ERROR:")
print('[-]', err) print('[-]', err)
# 3.7.2 New: Move or not move to failed folder. try:
if c.failed_move() == False: moveFailedFolder(file_path, conf)
if c.soft_link(): except Exception as err:
print("[-]Link {} to failed folder".format(file_path)) print('[!]', err)
os.symlink(file_path, os.path.join(conf.failed_folder(), file_name))
elif c.failed_move() == True:
if c.soft_link():
print("[-]Link {} to failed folder".format(file_path))
os.symlink(file_path, os.path.join(conf.failed_folder(), file_name))
else:
try:
print("[-]Move [{}] to failed folder".format(file_path))
shutil.move(file_path, os.path.join(conf.failed_folder(), file_name))
except Exception as err:
print('[!]', err)
def create_data_and_move_with_custom_number(file_path: str, c: config.Config, custom_number): def create_data_and_move_with_custom_number(file_path: str, c: config.Config, custom_number):
@@ -157,7 +286,9 @@ if __name__ == '__main__':
version = '4.7.2' version = '4.7.2'
urllib3.disable_warnings() #Ignore http proxy warning urllib3.disable_warnings() #Ignore http proxy warning
# Parse command line args # Parse command line args
single_file_path, folder_path, custom_number, auto_exit = argparse_function(version) single_file_path, folder_path, custom_number, auto_exit, logdir, regexstr = argparse_function(version)
dupe_stdout_to_logfile(logdir)
print('[*]================== AV Data Capture ===================') print('[*]================== AV Data Capture ===================')
print('[*]' + version.center(54)) print('[*]' + version.center(54))
@@ -175,6 +306,7 @@ if __name__ == '__main__':
print('[+]Enable debug') print('[+]Enable debug')
if conf.soft_link(): if conf.soft_link():
print('[!]Enable soft link') print('[!]Enable soft link')
print('[!]CmdLine:'," ".join(sys.argv[1:]))
create_failed_folder(conf.failed_folder()) create_failed_folder(conf.failed_folder())
start_time = time.time() start_time = time.time()
@@ -189,17 +321,28 @@ if __name__ == '__main__':
if folder_path == '': if folder_path == '':
folder_path = os.path.abspath(".") folder_path = os.path.abspath(".")
movie_list = movie_lists(folder_path, re.split("[,]", conf.escape_folder())) movie_list = movie_lists(folder_path, conf, regexstr)
count = 0 count = 0
count_all = str(len(movie_list)) count_all = str(len(movie_list))
print('[+]Find', count_all, 'movies') print('[+]Find', count_all, 'movies')
main_mode = conf.main_mode()
stop_count = conf.stop_counter()
if stop_count<1:
stop_count = 999999
else:
count_all = str(min(len(movie_list), stop_count))
if main_mode == 3:
print(
f'[!]运行模式:**维护模式**,本程序将在处理{count_all}个视频文件后停止,如需后台执行自动退出请结合 -a 参数。')
for movie_path in movie_list: # 遍历电影列表 交给core处理 for movie_path in movie_list: # 遍历电影列表 交给core处理
count = count + 1 count = count + 1
percentage = str(count / int(count_all) * 100)[:4] + '%' percentage = str(count / int(count_all) * 100)[:4] + '%'
print('[!] - ' + percentage + ' [' + str(count) + '/' + count_all + '] -') print('[!] - ' + percentage + ' [' + str(count) + '/' + count_all + '] -')
create_data_and_move(movie_path, conf, conf.debug()) create_data_and_move(movie_path, conf, conf.debug())
if count >= stop_count:
print("[!]Stop counter triggered!")
break
if conf.del_empty_folder(): if conf.del_empty_folder():
rm_empty_folder(conf.success_folder()) rm_empty_folder(conf.success_folder())
@@ -214,4 +357,7 @@ if __name__ == '__main__':
print("[+]All finished!!!") print("[+]All finished!!!")
if not (conf.auto_exit() or auto_exit): if not (conf.auto_exit() or auto_exit):
input("Press enter key exit, you can check the error message before you exit...") input("Press enter key exit, you can check the error message before you exit...")
close_logfile(logdir)
sys.exit(0) sys.exit(0)

View File

@@ -126,8 +126,8 @@ def get_data_from_json(file_number, conf: config.Config): # 从JSON返回元数
# Return if data not found in all sources # Return if data not found in all sources
if not json_data: if not json_data:
print('[-]Movie Data not found!') print('[-]Movie Number not found!')
return return None
# ================================================网站规则添加结束================================================ # ================================================网站规则添加结束================================================
@@ -165,8 +165,8 @@ def get_data_from_json(file_number, conf: config.Config): # 从JSON返回元数
actor = str(actor_list).strip("[ ]").replace("'", '').replace(" ", '') actor = str(actor_list).strip("[ ]").replace("'", '').replace(" ", '')
if title == '' or number == '': if title == '' or number == '':
print('[-]Movie Data not found!') print('[-]Movie Number or Title not found!')
return return None
# if imagecut == '3': # if imagecut == '3':
# DownloadFileWithFilename() # DownloadFileWithFilename()

View File

@@ -10,6 +10,12 @@ multi_threading=1
;actor_gender value: female(♀) or male(♂) or both(♀ ♂) or all(♂ ♀ ⚧) ;actor_gender value: female(♀) or male(♂) or both(♀ ♂) or all(♂ ♀ ⚧)
actor_gender=female actor_gender=female
del_empty_folder=1 del_empty_folder=1
; 跳过最近(默认:30)天新修改过的.NFO可避免整理模式(main_mode=3)和软连接(soft_link=0)时
; 反复刮削靠前的视频文件0为处理所有视频文件
nfo_skip_days=30
; 处理完多少个视频文件后停止0为处理所有视频文件
stop_counter=0
; 以上两个参数配合使用可以以多次少量的方式刮削或整理数千个文件而不触发翻译或元数据站封禁
[proxy] [proxy]
;proxytype: http or socks5 or socks5h switch: 0 1 ;proxytype: http or socks5 or socks5h switch: 0 1
@@ -74,3 +80,4 @@ water=2
[extrafanart] [extrafanart]
switch=0 switch=0
extrafanart_folder=extrafanart extrafanart_folder=extrafanart

View File

@@ -2,15 +2,29 @@ import os
import sys import sys
import configparser import configparser
import codecs import codecs
from pathlib import Path
class Config: class Config:
def __init__(self, path: str = "config.ini"): def __init__(self, path: str = "config.ini"):
if os.path.exists(path): path_search_order = [
path,
"./config.ini",
os.path.join(Path.home(), "avdc.ini"),
os.path.join(Path.home(), ".avdc.ini"),
os.path.join(Path.home(), ".avdc/config.ini"),
os.path.join(Path.home(), ".config/avdc/config.ini")
]
ini_path = None
for p in path_search_order:
if os.path.exists(p):
ini_path = p
break
if ini_path:
self.conf = configparser.ConfigParser() self.conf = configparser.ConfigParser()
try: try:
self.conf.read(path, encoding="utf-8-sig") self.conf.read(ini_path, encoding="utf-8-sig")
except: except:
self.conf.read(path, encoding="utf-8") self.conf.read(ini_path, encoding="utf-8")
else: else:
print("[-]Config file not found!") print("[-]Config file not found!")
sys.exit(2) sys.exit(2)
@@ -54,6 +68,16 @@ class Config:
return self.conf.getboolean("common", "multi_threading") return self.conf.getboolean("common", "multi_threading")
def del_empty_folder(self) -> bool: def del_empty_folder(self) -> bool:
return self.conf.getboolean("common", "del_empty_folder") return self.conf.getboolean("common", "del_empty_folder")
def nfo_skip_days(self) -> int:
try:
return self.conf.getint("common", "nfo_skip_days")
except:
return 30
def stop_counter(self) -> int:
try:
return self.conf.getint("common", "stop_counter")
except:
return 0
def is_transalte(self) -> bool: def is_transalte(self) -> bool:
return self.conf.getboolean("transalte", "switch") return self.conf.getboolean("transalte", "switch")
def is_trailer(self) -> bool: def is_trailer(self) -> bool:
@@ -171,6 +195,8 @@ class Config:
# actor_gender value: female or male or both or all(含人妖) # actor_gender value: female or male or both or all(含人妖)
conf.set(sec1, "actor_gender", "female") conf.set(sec1, "actor_gender", "female")
conf.set(sec1, "del_empty_folder", "1") conf.set(sec1, "del_empty_folder", "1")
conf.set(sec1, "nfo_skip_days", 30)
conf.set(sec1, "stop_counter", 0)
sec2 = "proxy" sec2 = "proxy"
conf.add_section(sec2) conf.add_section(sec2)
@@ -239,8 +265,6 @@ class Config:
return conf return conf
class IniProxy(): class IniProxy():
""" Proxy Config from .ini """ Proxy Config from .ini
""" """

130
core.py
View File

@@ -9,6 +9,8 @@ import sys
from PIL import Image from PIL import Image
from io import BytesIO from io import BytesIO
from pathlib import Path
from datetime import datetime
from ADC_function import * from ADC_function import *
from WebCrawler import get_data_from_json from WebCrawler import get_data_from_json
@@ -21,18 +23,26 @@ def escape_path(path, escape_literals: str): # Remove escape literals
return path return path
def moveFailedFolder(filepath): def moveFailedFolder(filepath, conf):
conf = config.Config() failed_folder = conf.failed_folder()
if conf.failed_move(): soft_link = conf.soft_link()
failed_folder = conf.failed_folder() # 模式3或软连接改为维护一个失败列表启动扫描时加载用于排除该路径以免反复处理
file_name = os.path.basename(filepath) # 原先的创建软连接到失败目录,并不直观,不方便找到失败文件位置,不如直接记录该文件路径
if conf.soft_link(): if conf.main_mode() == 3 or soft_link:
print('[-]Create symlink to Failed output folder') ftxt = os.path.join(failed_folder, 'failed_list.txt')
os.symlink(filepath, os.path.join(failed_folder, file_name)) print("[-]Add to Failed List file, see '%s'" % ftxt)
else: with open(ftxt, 'a', encoding='utf-8') as flt:
print('[-]Move to Failed output folder') flt.write(f'{filepath}\n')
shutil.move(filepath, os.path.join(failed_folder, file_name)) flt.close()
return elif conf.failed_move() and not soft_link:
failed_name = os.path.join(failed_folder, os.path.basename(filepath))
mtxt = os.path.join(failed_folder, 'where_was_i_before_being_moved.txt')
print("'[-]Move to Failed output folder, see '%s'" % mtxt)
with open(mtxt, 'a', encoding='utf-8') as wwibbmt:
tmstr = datetime.now().strftime("%Y-%m-%d %H:%M")
wwibbmt.write(f'{tmstr} FROM[{filepath}]TO[{failed_name}]\n')
wwibbmt.close()
shutil.move(filepath, failed_name)
def get_info(json_data): # 返回json里的数据 def get_info(json_data): # 返回json里的数据
@@ -54,8 +64,9 @@ def get_info(json_data): # 返回json里的数据
def small_cover_check(path, number, cover_small, leak_word, c_word, conf: config.Config, filepath): def small_cover_check(path, number, cover_small, leak_word, c_word, conf: config.Config, filepath):
download_file_with_filename(cover_small, number + leak_word+ c_word + '-poster.jpg', path, conf, filepath) filename = f"{number}{leak_word}{c_word}-poster.jpg"
print('[+]Image Downloaded! ' + path + '/' + number + leak_word + c_word + '-poster.jpg') download_file_with_filename(cover_small, filename, path, conf, filepath)
print('[+]Image Downloaded! ' + os.path.join(path, filename))
def create_folder(json_data, conf: config.Config): # 创建文件夹 def create_folder(json_data, conf: config.Config): # 创建文件夹
@@ -110,9 +121,9 @@ def download_file_with_filename(url, filename, path, conf: config.Config, filepa
'User-Agent': G_USER_AGENT} 'User-Agent': G_USER_AGENT}
r = requests.get(url, headers=headers, timeout=configProxy.timeout, proxies=proxies) r = requests.get(url, headers=headers, timeout=configProxy.timeout, proxies=proxies)
if r == '': if r == '':
print('[-]Movie Data not found!') print('[-]Movie Download Data not found!')
return return
with open(os.path.join(str(path), filename), "wb") as code: with open(os.path.join(path, filename), "wb") as code:
code.write(r.content) code.write(r.content)
return return
else: else:
@@ -122,9 +133,9 @@ def download_file_with_filename(url, filename, path, conf: config.Config, filepa
'User-Agent': G_USER_AGENT} 'User-Agent': G_USER_AGENT}
r = requests.get(url, timeout=configProxy.timeout, headers=headers) r = requests.get(url, timeout=configProxy.timeout, headers=headers)
if r == '': if r == '':
print('[-]Movie Data not found!') print('[-]Movie Download Data not found!')
return return
with open(os.path.join(str(path), filename), "wb") as code: with open(os.path.join(path, filename), "wb") as code:
code.write(r.content) code.write(r.content)
return return
except requests.exceptions.RequestException: except requests.exceptions.RequestException:
@@ -140,7 +151,7 @@ def download_file_with_filename(url, filename, path, conf: config.Config, filepa
i += 1 i += 1
print('[-]Image Download : Connect retry ' + str(i) + '/' + str(configProxy.retry)) print('[-]Image Download : Connect retry ' + str(i) + '/' + str(configProxy.retry))
print('[-]Connect Failed! Please check your Proxy or Network!') print('[-]Connect Failed! Please check your Proxy or Network!')
moveFailedFolder(filepath) moveFailedFolder(filepath, conf)
return return
def trailer_download(trailer, leak_word, c_word, number, path, filepath, conf: config.Config): def trailer_download(trailer, leak_word, c_word, number, path, filepath, conf: config.Config):
@@ -161,53 +172,61 @@ def trailer_download(trailer, leak_word, c_word, number, path, filepath, conf: c
# 剧照下载成功否则移动到failed # 剧照下载成功否则移动到failed
def extrafanart_download(data, path, conf: config.Config, filepath): def extrafanart_download(data, path, conf: config.Config, filepath):
j = 1 j = 1
path = path + '/' + conf.get_extrafanart() path = os.path.join(path, conf.get_extrafanart())
for url in data: for url in data:
if download_file_with_filename(url, 'extrafanart-' + str(j)+'.jpg', path, conf, filepath) == 'failed': jpg_filename = f'extrafanart-{j}.jpg'
moveFailedFolder(filepath) jpg_fullpath = os.path.join(path, jpg_filename)
if download_file_with_filename(url, jpg_filename, path, conf, filepath) == 'failed':
moveFailedFolder(filepath, conf)
return return
configProxy = conf.proxy() configProxy = conf.proxy()
for i in range(configProxy.retry): for i in range(configProxy.retry):
if os.path.getsize(path + '/extrafanart-' + str(j) + '.jpg') == 0: if os.path.getsize(jpg_fullpath) == 0:
print('[!]Image Download Failed! Trying again. [{}/3]', i + 1) print('[!]Image Download Failed! Trying again. [{}/3]', i + 1)
download_file_with_filename(url, 'extrafanart-' + str(j)+'.jpg', path, conf, filepath) download_file_with_filename(url, jpg_filename, path, conf, filepath)
continue continue
else: else:
break break
if os.path.getsize(path + '/extrafanart-' + str(j) + '.jpg') == 0: if os.path.getsize(jpg_fullpath) == 0:
return return
print('[+]Image Downloaded!', path + '/extrafanart-' + str(j) + '.jpg') print('[+]Image Downloaded!', jpg_fullpath)
j += 1 j += 1
# 封面是否下载成功否则移动到failed # 封面是否下载成功否则移动到failed
def image_download(cover, number, leak_word, c_word, path, conf: config.Config, filepath): def image_download(cover, number, leak_word, c_word, path, conf: config.Config, filepath):
if download_file_with_filename(cover, number + leak_word + c_word + '-fanart.jpg', path, conf, filepath) == 'failed': filename = f"{number}{leak_word}{c_word}-fanart.jpg"
moveFailedFolder(filepath) full_filepath = os.path.join(path, filename)
if download_file_with_filename(cover, filename, path, conf, filepath) == 'failed':
moveFailedFolder(filepath, conf)
return return
configProxy = conf.proxy() configProxy = conf.proxy()
for i in range(configProxy.retry): for i in range(configProxy.retry):
if os.path.getsize(path + '/' + number + leak_word + c_word + '-fanart.jpg') == 0: if os.path.getsize(full_filepath) == 0:
print('[!]Image Download Failed! Trying again. [{}/3]', i + 1) print('[!]Image Download Failed! Trying again. [{}/3]', i + 1)
download_file_with_filename(cover, number + leak_word + c_word + '-fanart.jpg', path, conf, filepath) download_file_with_filename(cover, filename, path, conf, filepath)
continue continue
else: else:
break break
if os.path.getsize(path + '/' + number + leak_word + c_word + '-fanart.jpg') == 0: if os.path.getsize(full_filepath) == 0:
return return
print('[+]Image Downloaded!', path + '/' + number + leak_word + c_word + '-fanart.jpg') print('[+]Image Downloaded!', full_filepath)
shutil.copyfile(path + '/' + number + leak_word + c_word + '-fanart.jpg',path + '/' + number + leak_word + c_word + '-thumb.jpg') shutil.copyfile(full_filepath, os.path.join(path, f"{number}{leak_word}{c_word}-thumb.jpg"))
def print_files(path, leak_word, c_word, naming_rule, part, cn_sub, json_data, filepath, failed_folder, tag, actor_list, liuchu, uncensored): def print_files(path, leak_word, c_word, naming_rule, part, cn_sub, json_data, filepath, tag, actor_list, liuchu, uncensored, conf):
title, studio, year, outline, runtime, director, actor_photo, release, number, cover, trailer, website, series, label = get_info(json_data) title, studio, year, outline, runtime, director, actor_photo, release, number, cover, trailer, website, series, label = get_info(json_data)
failed_folder = conf.failed_folder()
if conf.main_mode() == 3: # 模式3下由于视频文件不做任何改变.nfo文件必须和视频文件名称除后缀外完全一致KODI等软件方可支持
nfo_path = str(Path(filepath).with_suffix('.nfo'))
else:
nfo_path = os.path.join(path,f"{number}{part}{leak_word}{c_word}.nfo")
try: try:
if not os.path.exists(path): if not os.path.exists(path):
os.makedirs(path) os.makedirs(path)
with open(path + "/" + number + part + leak_word + c_word + ".nfo", "wt", encoding='UTF-8') as code: with open(nfo_path, "wt", encoding='UTF-8') as code:
print('<?xml version="1.0" encoding="UTF-8" ?>', file=code) print('<?xml version="1.0" encoding="UTF-8" ?>', file=code)
print("<movie>", file=code) print("<movie>", file=code)
print(" <title>" + naming_rule + "</title>", file=code) print(" <title>" + naming_rule + "</title>", file=code)
@@ -262,35 +281,35 @@ def print_files(path, leak_word, c_word, naming_rule, part, cn_sub, json_data, f
print(" <trailer>" + trailer + "</trailer>", file=code) print(" <trailer>" + trailer + "</trailer>", file=code)
print(" <website>" + website + "</website>", file=code) print(" <website>" + website + "</website>", file=code)
print("</movie>", file=code) print("</movie>", file=code)
print("[+]Wrote! " + path + "/" + number + part + leak_word + c_word + ".nfo") print("[+]Wrote! " + nfo_path)
except IOError as e: except IOError as e:
print("[-]Write Failed!") print("[-]Write Failed!")
print(e) print(e)
moveFailedFolder(filepath) moveFailedFolder(filepath, conf)
return return
except Exception as e1: except Exception as e1:
print(e1) print(e1)
print("[-]Write Failed!") print("[-]Write Failed!")
moveFailedFolder(filepath) moveFailedFolder(filepath, conf)
return return
def cutImage(imagecut, path, number, leak_word, c_word): def cutImage(imagecut, path, number, leak_word, c_word):
fullpath_noext = os.path.join(path, f"{number}{leak_word}{c_word}")
if imagecut == 1: # 剪裁大封面 if imagecut == 1: # 剪裁大封面
try: try:
img = Image.open(path + '/' + number + leak_word + c_word + '-fanart.jpg') img = Image.open(fullpath_noext + '-fanart.jpg')
imgSize = img.size imgSize = img.size
w = img.width w = img.width
h = img.height h = img.height
img2 = img.crop((w / 1.9, 0, w, h)) img2 = img.crop((w / 1.9, 0, w, h))
img2.save(path + '/' + number + leak_word + c_word + '-poster.jpg') img2.save(fullpath_noext + '-poster.jpg')
print('[+]Image Cutted! ' + path + '/' + number + leak_word + c_word + '-poster.jpg') print('[+]Image Cutted! ' + fullpath_noext + '-poster.jpg')
except: except:
print('[-]Cover cut failed!') print('[-]Cover cut failed!')
elif imagecut == 0: # 复制封面 elif imagecut == 0: # 复制封面
shutil.copyfile(path + '/' + number + leak_word + c_word + '-fanart.jpg', shutil.copyfile(fullpath_noext + '-fanart.jpg', fullpath_noext + '-poster.jpg')
path + '/' + number + leak_word + c_word + '-poster.jpg') print('[+]Image Copyed! ' + fullpath_noext + '-poster.jpg')
print('[+]Image Copyed! ' + path + '/' + number + leak_word + c_word + '-poster.jpg')
# 此函数从gui版copy过来用用 # 此函数从gui版copy过来用用
# 参数说明 # 参数说明
@@ -407,7 +426,7 @@ def paste_file_to_folder(filepath, path, number, leak_word, c_word, conf: config
print('[-]Error! Please run as administrator!') print('[-]Error! Please run as administrator!')
return return
except OSError as oserr: except OSError as oserr:
print('[-]OS Error errno ' + oserr.errno) print(f'[-]OS Error errno {oserr.errno}')
return return
@@ -437,10 +456,10 @@ def paste_file_to_folder_mode2(filepath, path, multi_part, number, part, leak_wo
print('[-]Error! Please run as administrator!') print('[-]Error! Please run as administrator!')
return return
except OSError as oserr: except OSError as oserr:
print('[-]OS Error errno ' + oserr.errno) print(f'[-]OS Error errno {oserr.errno}')
return return
def get_part(filepath): def get_part(filepath, conf):
try: try:
if re.search('-CD\d+', filepath): if re.search('-CD\d+', filepath):
return re.findall('-CD\d+', filepath)[0] return re.findall('-CD\d+', filepath)[0]
@@ -448,7 +467,7 @@ def get_part(filepath):
return re.findall('-cd\d+', filepath)[0] return re.findall('-cd\d+', filepath)[0]
except: except:
print("[-]failed!Please rename the filename again!") print("[-]failed!Please rename the filename again!")
moveFailedFolder(filepath) moveFailedFolder(filepath, conf)
return return
@@ -486,7 +505,7 @@ def core_main(file_path, number_th, conf: config.Config):
# Return if blank dict returned (data not found) # Return if blank dict returned (data not found)
if not json_data: if not json_data:
moveFailedFolder(filepath) moveFailedFolder(filepath, conf)
return return
if json_data["number"] != number: if json_data["number"] != number:
@@ -501,7 +520,7 @@ def core_main(file_path, number_th, conf: config.Config):
# =======================================================================判断-C,-CD后缀 # =======================================================================判断-C,-CD后缀
if '-CD' in filepath or '-cd' in filepath: if '-CD' in filepath or '-cd' in filepath:
multi_part = 1 multi_part = 1
part = get_part(filepath) part = get_part(filepath, conf)
if '-c.' in filepath or '-C.' in filepath or '中文' in filepath or '字幕' in filepath: if '-c.' in filepath or '-C.' in filepath or '中文' in filepath or '字幕' in filepath:
cn_sub = '1' cn_sub = '1'
c_word = '-C' # 中文字幕影片后缀 c_word = '-C' # 中文字幕影片后缀
@@ -562,7 +581,7 @@ def core_main(file_path, number_th, conf: config.Config):
cutImage(imagecut, path, number, leak_word, c_word) cutImage(imagecut, path, number, leak_word, c_word)
# 打印文件 # 打印文件
print_files(path, leak_word, c_word, json_data.get('naming_rule'), part, cn_sub, json_data, filepath, conf.failed_folder(), tag, json_data.get('actor_list'), liuchu, uncensored) print_files(path, leak_word, c_word, json_data.get('naming_rule'), part, cn_sub, json_data, filepath, tag, json_data.get('actor_list'), liuchu, uncensored, conf)
# 移动文件 # 移动文件
paste_file_to_folder(filepath, path, number, leak_word, c_word, conf) paste_file_to_folder(filepath, path, number, leak_word, c_word, conf)
@@ -583,8 +602,7 @@ def core_main(file_path, number_th, conf: config.Config):
add_mark(poster_path, thumb_path, cn_sub, leak, uncensored, conf) add_mark(poster_path, thumb_path, cn_sub, leak, uncensored, conf)
elif conf.main_mode() == 3: elif conf.main_mode() == 3:
path = file_path.rsplit('/', 1)[0] path = str(Path(file_path).parent)
path = path.rsplit('\\', 1)[0]
if multi_part == 1: if multi_part == 1:
number += part # 这时number会被附加上CD1后缀 number += part # 这时number会被附加上CD1后缀
@@ -608,8 +626,8 @@ def core_main(file_path, number_th, conf: config.Config):
cutImage(imagecut, path, number, leak_word, c_word) cutImage(imagecut, path, number, leak_word, c_word)
# 打印文件 # 打印文件
print_files(path, leak_word, c_word, json_data.get('naming_rule'), part, cn_sub, json_data, filepath, conf.failed_folder(), print_files(path, leak_word, c_word, json_data.get('naming_rule'), part, cn_sub, json_data, filepath,
tag, json_data.get('actor_list'), liuchu, uncensored) tag, json_data.get('actor_list'), liuchu, uncensored, conf)
poster_path = os.path.join(path, f"{number}{leak_word}{c_word}-poster.jpg") poster_path = os.path.join(path, f"{number}{leak_word}{c_word}-poster.jpg")
thumb_path = os.path.join(path, f"{number}{leak_word}{c_word}-thumb.jpg") thumb_path = os.path.join(path, f"{number}{leak_word}{c_word}-thumb.jpg")