新增不联网批量封面剪裁(人脸识别)和打水印
This commit is contained in:
@@ -18,7 +18,7 @@ from opencc import OpenCC
|
|||||||
import config
|
import config
|
||||||
from ADC_function import file_modification_days, get_html, parallel_download_files
|
from ADC_function import file_modification_days, get_html, parallel_download_files
|
||||||
from number_parser import get_number
|
from number_parser import get_number
|
||||||
from core import core_main, moveFailedFolder
|
from core import core_main, core_main_no_net_op, moveFailedFolder
|
||||||
|
|
||||||
|
|
||||||
def check_update(local_version):
|
def check_update(local_version):
|
||||||
@@ -40,7 +40,7 @@ def check_update(local_version):
|
|||||||
print("[*]======================================================")
|
print("[*]======================================================")
|
||||||
|
|
||||||
|
|
||||||
def argparse_function(ver: str) -> typing.Tuple[str, str, str, str, bool]:
|
def argparse_function(ver: str) -> typing.Tuple[str, str, str, str, bool, bool]:
|
||||||
conf = config.getInstance()
|
conf = config.getInstance()
|
||||||
parser = argparse.ArgumentParser(epilog=f"Load Config file '{conf.ini_path}'.")
|
parser = argparse.ArgumentParser(epilog=f"Load Config file '{conf.ini_path}'.")
|
||||||
parser.add_argument("file", default='', nargs='?', help="Single Movie file path.")
|
parser.add_argument("file", default='', nargs='?', help="Single Movie file path.")
|
||||||
@@ -70,6 +70,8 @@ def argparse_function(ver: str) -> typing.Tuple[str, str, str, str, bool]:
|
|||||||
help="Auto exit after program complete")
|
help="Auto exit after program complete")
|
||||||
parser.add_argument("-g", "--debug", action="store_true",
|
parser.add_argument("-g", "--debug", action="store_true",
|
||||||
help="Turn on debug mode to generate diagnostic log for issue report.")
|
help="Turn on debug mode to generate diagnostic log for issue report.")
|
||||||
|
parser.add_argument("-N", "--no-network-operation", action="store_true",
|
||||||
|
help="No network query, do not get metadata, for cover cropping purposes, only takes effect when main mode is 3.")
|
||||||
parser.add_argument("-z", "--zero-operation", dest='zero_op', action="store_true",
|
parser.add_argument("-z", "--zero-operation", dest='zero_op', action="store_true",
|
||||||
help="""Only show job list of files and numbers, and **NO** actual operation
|
help="""Only show job list of files and numbers, and **NO** actual operation
|
||||||
is performed. It may help you correct wrong numbers before real job.""")
|
is performed. It may help you correct wrong numbers before real job.""")
|
||||||
@@ -96,7 +98,14 @@ is performed. It may help you correct wrong numbers before real job.""")
|
|||||||
config.G_conf_override["debug_mode:switch"] = get_bool_or_none(args.debug)
|
config.G_conf_override["debug_mode:switch"] = get_bool_or_none(args.debug)
|
||||||
config.G_conf_override["common:rerun_delay"] = get_str_or_none(args.delaytm)
|
config.G_conf_override["common:rerun_delay"] = get_str_or_none(args.delaytm)
|
||||||
|
|
||||||
return args.file, args.number, args.logdir, args.regexstr, args.zero_op
|
no_net_op = False
|
||||||
|
if conf.main_mode() == 3:
|
||||||
|
no_net_op = args.no_network_operation
|
||||||
|
config.G_conf_override["common:stop_counter"] = 0
|
||||||
|
config.G_conf_override["common:rerun_delay"] = '0s'
|
||||||
|
config.G_conf_override["face:aways_imagecut"] = True
|
||||||
|
|
||||||
|
return args.file, args.number, args.logdir, args.regexstr, args.zero_op, no_net_op
|
||||||
|
|
||||||
|
|
||||||
class OutLogger(object):
|
class OutLogger(object):
|
||||||
@@ -416,38 +425,44 @@ def rm_empty_folder(path):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def create_data_and_move(file_path: str, zero_op, oCC):
|
def create_data_and_move(movie_path: str, zero_op: bool, no_net_op: bool, oCC):
|
||||||
# Normalized number, eg: 111xxx-222.mp4 -> xxx-222.mp4
|
# Normalized number, eg: 111xxx-222.mp4 -> xxx-222.mp4
|
||||||
debug = config.getInstance().debug()
|
debug = config.getInstance().debug()
|
||||||
n_number = get_number(debug, os.path.basename(file_path))
|
n_number = get_number(debug, os.path.basename(movie_path))
|
||||||
file_path = os.path.abspath(file_path)
|
movie_path = os.path.abspath(movie_path)
|
||||||
|
|
||||||
if debug is True:
|
if debug is True:
|
||||||
print(f"[!] [{n_number}] As Number making data for '{file_path}'")
|
print(f"[!] [{n_number}] As Number making data for '{movie_path}'")
|
||||||
if zero_op:
|
if zero_op:
|
||||||
return
|
return
|
||||||
if n_number:
|
if n_number:
|
||||||
core_main(file_path, n_number, oCC)
|
if no_net_op:
|
||||||
|
core_main_no_net_op(movie_path, n_number)
|
||||||
|
else:
|
||||||
|
core_main(movie_path, n_number, oCC)
|
||||||
else:
|
else:
|
||||||
print("[-] number empty ERROR")
|
print("[-] number empty ERROR")
|
||||||
moveFailedFolder(file_path)
|
moveFailedFolder(movie_path)
|
||||||
print("[*]======================================================")
|
print("[*]======================================================")
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
print(f"[!] [{n_number}] As Number making data for '{file_path}'")
|
print(f"[!] [{n_number}] As Number making data for '{movie_path}'")
|
||||||
if zero_op:
|
if zero_op:
|
||||||
return
|
return
|
||||||
if n_number:
|
if n_number:
|
||||||
core_main(file_path, n_number, oCC)
|
if no_net_op:
|
||||||
|
core_main_no_net_op(movie_path, n_number)
|
||||||
|
else:
|
||||||
|
core_main(movie_path, n_number, oCC)
|
||||||
else:
|
else:
|
||||||
raise ValueError("number empty")
|
raise ValueError("number empty")
|
||||||
print("[*]======================================================")
|
print("[*]======================================================")
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
print(f"[-] [{file_path}] ERROR:")
|
print(f"[-] [{movie_path}] ERROR:")
|
||||||
print('[-]', err)
|
print('[-]', err)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
moveFailedFolder(file_path)
|
moveFailedFolder(movie_path)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
print('[!]', err)
|
print('[!]', err)
|
||||||
|
|
||||||
@@ -478,7 +493,7 @@ def create_data_and_move_with_custom_number(file_path: str, custom_number, oCC):
|
|||||||
|
|
||||||
|
|
||||||
def main(args: tuple) -> Path:
|
def main(args: tuple) -> Path:
|
||||||
(single_file_path, custom_number, logdir, regexstr, zero_op) = args
|
(single_file_path, custom_number, logdir, regexstr, zero_op, no_net_op) = args
|
||||||
conf = config.getInstance()
|
conf = config.getInstance()
|
||||||
main_mode = conf.main_mode()
|
main_mode = conf.main_mode()
|
||||||
folder_path = ""
|
folder_path = ""
|
||||||
@@ -592,7 +607,7 @@ def main(args: tuple) -> Path:
|
|||||||
percentage = str(count / int(count_all) * 100)[:4] + '%'
|
percentage = str(count / int(count_all) * 100)[:4] + '%'
|
||||||
print('[!] {:>30}{:>21}'.format('- ' + percentage + ' [' + str(count) + '/' + count_all + '] -',
|
print('[!] {:>30}{:>21}'.format('- ' + percentage + ' [' + str(count) + '/' + count_all + '] -',
|
||||||
time.strftime("%H:%M:%S")))
|
time.strftime("%H:%M:%S")))
|
||||||
create_data_and_move(movie_path, zero_op, oCC)
|
create_data_and_move(movie_path, zero_op, no_net_op, oCC)
|
||||||
if count >= stop_count:
|
if count >= stop_count:
|
||||||
print("[!]Stop counter triggered!")
|
print("[!]Stop counter triggered!")
|
||||||
break
|
break
|
||||||
|
|||||||
14
config.py
14
config.py
@@ -18,7 +18,8 @@ G_conf_override = {
|
|||||||
"common:stop_counter": None,
|
"common:stop_counter": None,
|
||||||
"common:ignore_failed_list": None,
|
"common:ignore_failed_list": None,
|
||||||
"common:rerun_delay": None,
|
"common:rerun_delay": None,
|
||||||
"debug_mode:switch": None
|
"debug_mode:switch": None,
|
||||||
|
"face:aways_imagecut": None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -101,9 +102,12 @@ class Config:
|
|||||||
# sys.exit(3)
|
# sys.exit(3)
|
||||||
# #self.conf = self._default_config()
|
# #self.conf = self._default_config()
|
||||||
|
|
||||||
def getboolean_override(self, section, item) -> bool:
|
def getboolean_override(self, section, item, fallback=None) -> bool:
|
||||||
return self.conf.getboolean(section, item) if G_conf_override[f"{section}:{item}"] is None else bool(
|
if G_conf_override[f"{section}:{item}"] is not None:
|
||||||
G_conf_override[f"{section}:{item}"])
|
return bool(G_conf_override[f"{section}:{item}"])
|
||||||
|
if fallback is not None:
|
||||||
|
return self.conf.getboolean(section, item, fallback=fallback)
|
||||||
|
return self.conf.getboolean(section, item)
|
||||||
|
|
||||||
def getint_override(self, section, item, fallback=None) -> int:
|
def getint_override(self, section, item, fallback=None) -> int:
|
||||||
if G_conf_override[f"{section}:{item}"] is not None:
|
if G_conf_override[f"{section}:{item}"] is not None:
|
||||||
@@ -359,7 +363,7 @@ class Config:
|
|||||||
return self.conf.getboolean("face", "uncensored_only", fallback=True)
|
return self.conf.getboolean("face", "uncensored_only", fallback=True)
|
||||||
|
|
||||||
def face_aways_imagecut(self) -> bool:
|
def face_aways_imagecut(self) -> bool:
|
||||||
return self.conf.getboolean("face", "aways_imagecut", fallback=False)
|
return self.getboolean_override("face", "aways_imagecut", fallback=False)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _exit(sec: str) -> None:
|
def _exit(sec: str) -> None:
|
||||||
|
|||||||
81
core.py
81
core.py
@@ -615,7 +615,46 @@ def debug_print(data: json):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def core_main(file_path, number_th, oCC):
|
def core_main_no_net_op(movie_path, number):
|
||||||
|
conf = config.getInstance()
|
||||||
|
leak_word = ''
|
||||||
|
leak = 0
|
||||||
|
c_word = ''
|
||||||
|
cn_sub = ''
|
||||||
|
hack = ''
|
||||||
|
hack_word = ''
|
||||||
|
ext = '.jpg'
|
||||||
|
imagecut = 1
|
||||||
|
path = str(Path(movie_path).parent)
|
||||||
|
|
||||||
|
if '-c.' in movie_path or '-C.' in movie_path or '中文' in movie_path or '字幕' in movie_path:
|
||||||
|
cn_sub = '1'
|
||||||
|
c_word = '-C' # 中文字幕影片后缀
|
||||||
|
uncensored = 1 if is_uncensored(number) else 0
|
||||||
|
if '流出' in movie_path or 'uncensored' in movie_path:
|
||||||
|
leak_word = '-流出' # 流出影片后缀
|
||||||
|
leak = 1
|
||||||
|
|
||||||
|
if 'hack'.upper() in str(movie_path).upper() or '破解' in movie_path:
|
||||||
|
hack = 1
|
||||||
|
hack_word = "-hack"
|
||||||
|
|
||||||
|
fanart_path = f"{number}{leak_word}{c_word}{hack_word}-fanart{ext}"
|
||||||
|
poster_path = f"{number}{leak_word}{c_word}{hack_word}-poster{ext}"
|
||||||
|
thumb_path = f"{number}{leak_word}{c_word}{hack_word}-thumb{ext}"
|
||||||
|
full_fanart_path = os.path.join(path, fanart_path)
|
||||||
|
full_poster_path = os.path.join(path, poster_path)
|
||||||
|
full_thumb_path = os.path.join(path, thumb_path)
|
||||||
|
|
||||||
|
if not all(os.path.isfile(f) for f in (full_fanart_path, full_thumb_path)):
|
||||||
|
return
|
||||||
|
|
||||||
|
cutImage(imagecut, path, fanart_path, poster_path, bool(conf.face_uncensored_only() and not uncensored))
|
||||||
|
if conf.is_watermark():
|
||||||
|
add_mark(full_poster_path, full_thumb_path, cn_sub, leak, uncensored, hack)
|
||||||
|
|
||||||
|
|
||||||
|
def core_main(movie_path, number_th, oCC):
|
||||||
conf = config.getInstance()
|
conf = config.getInstance()
|
||||||
# =======================================================================初始化所需变量
|
# =======================================================================初始化所需变量
|
||||||
multi_part = 0
|
multi_part = 0
|
||||||
@@ -627,8 +666,6 @@ def core_main(file_path, number_th, oCC):
|
|||||||
hack = ''
|
hack = ''
|
||||||
hack_word = ''
|
hack_word = ''
|
||||||
|
|
||||||
|
|
||||||
filepath = file_path # 影片的路径 绝对路径
|
|
||||||
# 下面被注释的变量不需要
|
# 下面被注释的变量不需要
|
||||||
#rootpath= os.getcwd
|
#rootpath= os.getcwd
|
||||||
number = number_th
|
number = number_th
|
||||||
@@ -636,7 +673,7 @@ def core_main(file_path, number_th, oCC):
|
|||||||
|
|
||||||
# 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(movie_path)
|
||||||
return
|
return
|
||||||
|
|
||||||
if json_data["number"] != number:
|
if json_data["number"] != number:
|
||||||
@@ -649,10 +686,10 @@ def core_main(file_path, number_th, oCC):
|
|||||||
imagecut = json_data.get('imagecut')
|
imagecut = json_data.get('imagecut')
|
||||||
tag = json_data.get('tag')
|
tag = json_data.get('tag')
|
||||||
# =======================================================================判断-C,-CD后缀
|
# =======================================================================判断-C,-CD后缀
|
||||||
if re.search('-CD\d+', filepath, re.IGNORECASE):
|
if re.search('-CD\d+', movie_path, re.IGNORECASE):
|
||||||
multi_part = 1
|
multi_part = 1
|
||||||
part = re.findall('-CD\d+', filepath, re.IGNORECASE)[0]
|
part = re.findall('-CD\d+', movie_path, re.IGNORECASE)[0]
|
||||||
if '-c.' in filepath or '-C.' in filepath or '中文' in filepath or '字幕' in filepath:
|
if '-c.' in movie_path or '-C.' in movie_path or '中文' in movie_path or '字幕' in movie_path:
|
||||||
cn_sub = '1'
|
cn_sub = '1'
|
||||||
c_word = '-C' # 中文字幕影片后缀
|
c_word = '-C' # 中文字幕影片后缀
|
||||||
|
|
||||||
@@ -660,14 +697,14 @@ def core_main(file_path, number_th, oCC):
|
|||||||
uncensored = 1 if is_uncensored(number) else 0
|
uncensored = 1 if is_uncensored(number) else 0
|
||||||
|
|
||||||
|
|
||||||
if '流出' in filepath or 'uncensored' in filepath:
|
if '流出' in movie_path or 'uncensored' in movie_path:
|
||||||
liuchu = '流出'
|
liuchu = '流出'
|
||||||
leak = 1
|
leak = 1
|
||||||
leak_word = '-流出' # 流出影片后缀
|
leak_word = '-流出' # 流出影片后缀
|
||||||
else:
|
else:
|
||||||
leak = 0
|
leak = 0
|
||||||
|
|
||||||
if 'hack'.upper() in str(filepath).upper() or '破解' in filepath:
|
if 'hack'.upper() in str(movie_path).upper() or '破解' in movie_path:
|
||||||
hack = 1
|
hack = 1
|
||||||
hack_word = "-hack"
|
hack_word = "-hack"
|
||||||
|
|
||||||
@@ -696,22 +733,22 @@ def core_main(file_path, number_th, oCC):
|
|||||||
|
|
||||||
# 检查小封面, 如果image cut为3,则下载小封面
|
# 检查小封面, 如果image cut为3,则下载小封面
|
||||||
if imagecut == 3:
|
if imagecut == 3:
|
||||||
small_cover_check(path, poster_path, json_data.get('cover_small'), filepath)
|
small_cover_check(path, poster_path, json_data.get('cover_small'), movie_path)
|
||||||
|
|
||||||
# creatFolder会返回番号路径
|
# creatFolder会返回番号路径
|
||||||
image_download( cover, fanart_path,thumb_path, path, filepath)
|
image_download( cover, fanart_path,thumb_path, path, movie_path)
|
||||||
|
|
||||||
if not multi_part or part.lower() == '-cd1':
|
if not multi_part or part.lower() == '-cd1':
|
||||||
try:
|
try:
|
||||||
# 下载预告片
|
# 下载预告片
|
||||||
if conf.is_trailer() and json_data.get('trailer'):
|
if conf.is_trailer() and json_data.get('trailer'):
|
||||||
trailer_download(json_data.get('trailer'), leak_word, c_word, hack_word, number, path, filepath)
|
trailer_download(json_data.get('trailer'), leak_word, c_word, hack_word, number, path, movie_path)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
# 下载剧照 data, path, filepath
|
# 下载剧照 data, path, filepath
|
||||||
if conf.is_extrafanart() and json_data.get('extrafanart'):
|
if conf.is_extrafanart() and json_data.get('extrafanart'):
|
||||||
extrafanart_download(json_data.get('extrafanart'), path, number, filepath)
|
extrafanart_download(json_data.get('extrafanart'), path, number, movie_path)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -724,40 +761,40 @@ def core_main(file_path, number_th, oCC):
|
|||||||
add_mark(os.path.join(path,poster_path), os.path.join(path,thumb_path), cn_sub, leak, uncensored, hack)
|
add_mark(os.path.join(path,poster_path), os.path.join(path,thumb_path), cn_sub, leak, uncensored, hack)
|
||||||
|
|
||||||
# 移动电影
|
# 移动电影
|
||||||
paste_file_to_folder(filepath, path, multi_part, number, part, leak_word, c_word, hack_word)
|
paste_file_to_folder(movie_path, path, multi_part, number, part, leak_word, c_word, hack_word)
|
||||||
|
|
||||||
# 最后输出.nfo元数据文件,以完成.nfo文件创建作为任务成功标志
|
# 最后输出.nfo元数据文件,以完成.nfo文件创建作为任务成功标志
|
||||||
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, hack_word
|
print_files(path, leak_word, c_word, json_data.get('naming_rule'), part, cn_sub, json_data, movie_path, tag, json_data.get('actor_list'), liuchu, uncensored, hack_word
|
||||||
,fanart_path,poster_path,thumb_path)
|
,fanart_path,poster_path,thumb_path)
|
||||||
|
|
||||||
elif conf.main_mode() == 2:
|
elif conf.main_mode() == 2:
|
||||||
# 创建文件夹
|
# 创建文件夹
|
||||||
path = create_folder(json_data)
|
path = create_folder(json_data)
|
||||||
# 移动文件
|
# 移动文件
|
||||||
paste_file_to_folder_mode2(filepath, path, multi_part, number, part, leak_word, c_word, hack_word)
|
paste_file_to_folder_mode2(movie_path, path, multi_part, number, part, leak_word, c_word, hack_word)
|
||||||
if conf.is_watermark():
|
if conf.is_watermark():
|
||||||
add_mark(os.path.join(path,poster_path), os.path.join(path,thumb_path), cn_sub, leak, uncensored, hack)
|
add_mark(os.path.join(path,poster_path), os.path.join(path,thumb_path), cn_sub, leak, uncensored, hack)
|
||||||
|
|
||||||
elif conf.main_mode() == 3:
|
elif conf.main_mode() == 3:
|
||||||
path = str(Path(file_path).parent)
|
path = str(Path(movie_path).parent)
|
||||||
if multi_part == 1:
|
if multi_part == 1:
|
||||||
number += part # 这时number会被附加上CD1后缀
|
number += part # 这时number会被附加上CD1后缀
|
||||||
|
|
||||||
# 检查小封面, 如果image cut为3,则下载小封面
|
# 检查小封面, 如果image cut为3,则下载小封面
|
||||||
if imagecut == 3:
|
if imagecut == 3:
|
||||||
small_cover_check(path, poster_path, json_data.get('cover_small'), filepath)
|
small_cover_check(path, poster_path, json_data.get('cover_small'), movie_path)
|
||||||
|
|
||||||
# creatFolder会返回番号路径
|
# creatFolder会返回番号路径
|
||||||
image_download( cover, fanart_path,thumb_path, path, filepath)
|
image_download( cover, fanart_path, thumb_path, path, movie_path)
|
||||||
|
|
||||||
if not multi_part or part.lower() == '-cd1':
|
if not multi_part or part.lower() == '-cd1':
|
||||||
# 下载预告片
|
# 下载预告片
|
||||||
if conf.is_trailer() and json_data.get('trailer'):
|
if conf.is_trailer() and json_data.get('trailer'):
|
||||||
trailer_download(json_data.get('trailer'), leak_word, c_word, hack_word, number, path, filepath)
|
trailer_download(json_data.get('trailer'), leak_word, c_word, hack_word, number, path, movie_path)
|
||||||
|
|
||||||
# 下载剧照 data, path, filepath
|
# 下载剧照 data, path, filepath
|
||||||
if conf.is_extrafanart() and json_data.get('extrafanart'):
|
if conf.is_extrafanart() and json_data.get('extrafanart'):
|
||||||
extrafanart_download(json_data.get('extrafanart'), path, number, filepath)
|
extrafanart_download(json_data.get('extrafanart'), path, number, movie_path)
|
||||||
|
|
||||||
# 裁剪图
|
# 裁剪图
|
||||||
cutImage(imagecut, path, fanart_path, poster_path, bool(conf.face_uncensored_only() and not uncensored))
|
cutImage(imagecut, path, fanart_path, poster_path, bool(conf.face_uncensored_only() and not uncensored))
|
||||||
@@ -767,5 +804,5 @@ def core_main(file_path, number_th, oCC):
|
|||||||
add_mark(os.path.join(path,poster_path), os.path.join(path,thumb_path), cn_sub, leak, uncensored, hack)
|
add_mark(os.path.join(path,poster_path), os.path.join(path,thumb_path), cn_sub, leak, uncensored, hack)
|
||||||
|
|
||||||
# 最后输出.nfo元数据文件,以完成.nfo文件创建作为任务成功标志
|
# 最后输出.nfo元数据文件,以完成.nfo文件创建作为任务成功标志
|
||||||
print_files(path, leak_word, c_word, json_data.get('naming_rule'), part, cn_sub, json_data, filepath,
|
print_files(path, leak_word, c_word, json_data.get('naming_rule'), part, cn_sub, json_data, movie_path,
|
||||||
tag, json_data.get('actor_list'), liuchu, uncensored, hack_word,fanart_path,poster_path,thumb_path)
|
tag, json_data.get('actor_list'), liuchu, uncensored, hack_word,fanart_path,poster_path,thumb_path)
|
||||||
|
|||||||
Reference in New Issue
Block a user