From 37869f58e7f96feb43bbbe271d68afd689973f7c Mon Sep 17 00:00:00 2001 From: lededev Date: Sat, 25 Sep 2021 18:56:18 +0800 Subject: [PATCH 01/22] =?UTF-8?q?=E6=96=B0=E5=8A=9F=E8=83=BD:1.=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F3=E5=A2=9E=E9=87=8F=E6=95=B4=E7=90=86=202.=E4=BF=9D?= =?UTF-8?q?=E5=AD=98=E8=BF=90=E8=A1=8C=E5=8F=8A=E9=94=99=E8=AF=AF=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E5=88=B0=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AV_Data_Capture.py | 109 ++++++++++++++++++++++++++++++++++++++++++--- config.ini | 9 ++++ config.py | 17 +++++++ 3 files changed, 129 insertions(+), 6 deletions(-) diff --git a/AV_Data_Capture.py b/AV_Data_Capture.py index 6a70072..d56f946 100755 --- a/AV_Data_Capture.py +++ b/AV_Data_Capture.py @@ -8,8 +8,10 @@ import typing import urllib3 import config +import datetime 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 core import core_main @@ -37,13 +39,87 @@ def argparse_function(ver: str) -> typing.Tuple[str, str, bool]: 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("-c", "--config", default='config.ini', nargs='?', help="The config file Path.") + parser.add_argument("-o","--log-dir",dest='logdir',default='',nargs='?', + help="Duplicate from stdout and stderr to logfiles in log directory.") parser.add_argument("-n", "--number", default='', nargs='?', help="Custom file number") parser.add_argument("-a", "--auto-exit", dest='autoexit', action="store_true", help="Auto exit after program complete") parser.add_argument("-v", "--version", action="version", version=ver) args = parser.parse_args() - return args.file, args.path, args.number, args.autoexit + return args.file, args.path, args.number, args.autoexit, args.logdir + + +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 + + +class ErrLogger(OutLogger): + 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.mkdir(logdir) + if not os.path.isdir(logdir): + return + + log_tmstr = datetime.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 + G_trailerRE = re.compile(r'-trailer\.', re.IGNORECASE) @@ -60,6 +136,10 @@ def movie_lists(root, escape_folder): total += movie_lists(f, escape_folder) elif os.path.splitext(f)[1].upper() in file_type: absf = os.path.abspath(f) + if conf.main_mode() == 3 and conf.mode3_nfo_skip_days() > 0: + nfo = Path(absf).with_suffix('.nfo') + if file_modification_days(nfo) <= conf.mode3_nfo_skip_days(): + continue if (conf.main_mode() == 3 or not is_link(absf)) and not G_trailerRE.search(f): total.append(absf) return total @@ -97,7 +177,7 @@ def create_data_and_move(file_path: str, c: config.Config, debug): file_path = os.path.abspath(file_path) 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: core_main(file_path, n_number, c) else: @@ -105,14 +185,14 @@ def create_data_and_move(file_path: str, c: config.Config, debug): print("[*]======================================================") else: 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: core_main(file_path, n_number, c) else: raise ValueError("number empty") print("[*]======================================================") except Exception as err: - print("[-] [{}] ERROR:".format(file_path)) + print(f"[-] [{file_path}] ERROR:") print('[-]', err) # 3.7.2 New: Move or not move to failed folder. @@ -157,7 +237,9 @@ if __name__ == '__main__': version = '4.7.2' urllib3.disable_warnings() #Ignore http proxy warning # 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 = argparse_function(version) + + dupe_stdout_to_logfile(logdir) print('[*]================== AV Data Capture ===================') print('[*]' + version.center(54)) @@ -194,12 +276,24 @@ if __name__ == '__main__': count = 0 count_all = str(len(movie_list)) print('[+]Find', count_all, 'movies') + main_mode = conf.main_mode() + stop_count = conf.mode3_stop_counter() + if stop_count<1: + stop_count = 999999 + elif main_mode == 3: + count_all = str(min(len(movie_list), stop_count)) + print( +f'[!]运行模式:**维护模式**,本程序将在处理{count_all}个视频文件后停止,如需后台执行自动退出请结合 -a 参数。' + ) for movie_path in movie_list: # 遍历电影列表 交给core处理 count = count + 1 percentage = str(count / int(count_all) * 100)[:4] + '%' print('[!] - ' + percentage + ' [' + str(count) + '/' + count_all + '] -') create_data_and_move(movie_path, conf, conf.debug()) + if main_mode == 3 and count >= stop_count: + print("[!]Mode 3 stop counter triggered!") + break if conf.del_empty_folder(): rm_empty_folder(conf.success_folder()) @@ -214,4 +308,7 @@ if __name__ == '__main__': print("[+]All finished!!!") if not (conf.auto_exit() or auto_exit): input("Press enter key exit, you can check the error message before you exit...") + + close_logfile(logdir) + sys.exit(0) diff --git a/config.ini b/config.ini index 410f9dc..d384bc4 100755 --- a/config.ini +++ b/config.ini @@ -74,3 +74,12 @@ water=2 [extrafanart] switch=0 extrafanart_folder=extrafanart + +; 整理模式 ([common] main_mode=3) +[main_mode_3] +; 整理时跳过最近(默认:30)天新修改过的.NFO,可避免反复整理靠前的文件,0为总是整理全部文件 +nfo_skip_days=30 +; 整理文件时达到指定个数即停止,配合google free翻译使用时,避免触发翻译次数上限导致的翻译失败,0为不限制 +mode3_stop_counter=0 +; 以上两个参数配合使用,可以用于定时执行的计划任务,例如将数千个视频文件的元数据在几周内分批更新 +; 程序启动参数'-o 日志目录'则可生成日志,检查几周内日志可找出失败文件手工处理 diff --git a/config.py b/config.py index 13ba670..76ffcbd 100644 --- a/config.py +++ b/config.py @@ -149,6 +149,18 @@ class Config: def debug(self) -> bool: return self.conf.getboolean("debug_mode", "switch") + def mode3_nfo_skip_days(self) -> int: + try: + return self.conf.getint("main_mode_3", "nfo_skip_days") + except: + return 30 + + def mode3_stop_counter(self) -> int: + try: + return self.conf.getint("main_mode_3", "mode3_stop_counter") + except: + return 0 + @staticmethod def _exit(sec: str) -> None: print("[-] Read config error! Please check the {} section in config.ini", sec) @@ -236,6 +248,11 @@ class Config: conf.set(sec13, "switch", 1) conf.set(sec13, "extrafanart_folder", "extrafanart") + sec14 = "main_mode_3" + conf.add_section(sec14) + conf.set(sec14, "nfo_skip_days", 30) + conf.set(sec14, "mode3_stop_counter", 0) + return conf From 0ca57fa8c19e862a02caeade00d9ec1bec728b0b Mon Sep 17 00:00:00 2001 From: lededev Date: Sat, 25 Sep 2021 19:31:53 +0800 Subject: [PATCH 02/22] add Google-free translate failed warnning --- ADC_function.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ADC_function.py b/ADC_function.py index 199a26e..b39bf48 100755 --- a/ADC_function.py +++ b/ADC_function.py @@ -467,6 +467,9 @@ def translate( + src ) 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"]] trans_result = trans_result.join(translate_list) From bdbd97149f9c46e3ddad8d35278e73e0ae7e22eb Mon Sep 17 00:00:00 2001 From: lededev Date: Sat, 25 Sep 2021 22:26:21 +0800 Subject: [PATCH 03/22] turn on log by default, to turn off by '--log-dir=' --- AV_Data_Capture.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AV_Data_Capture.py b/AV_Data_Capture.py index d56f946..de80596 100755 --- a/AV_Data_Capture.py +++ b/AV_Data_Capture.py @@ -39,7 +39,7 @@ def argparse_function(ver: str) -> typing.Tuple[str, str, bool]: 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("-c", "--config", default='config.ini', nargs='?', help="The config file Path.") - parser.add_argument("-o","--log-dir",dest='logdir',default='',nargs='?', + parser.add_argument("-o","--log-dir",dest='logdir',default=os.path.join(Path.home(),'.avlogs'),nargs='?', help="Duplicate from stdout and stderr to logfiles in log directory.") parser.add_argument("-n", "--number", default='', nargs='?', help="Custom file number") parser.add_argument("-a", "--auto-exit", dest='autoexit', action="store_true", From 4fbb6454c02560e40d38a8ba4214d09974b82fca Mon Sep 17 00:00:00 2001 From: lededev Date: Sat, 25 Sep 2021 22:41:12 +0800 Subject: [PATCH 04/22] show default --log-dir for current user in --help --- AV_Data_Capture.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/AV_Data_Capture.py b/AV_Data_Capture.py index de80596..e4aa564 100755 --- a/AV_Data_Capture.py +++ b/AV_Data_Capture.py @@ -39,8 +39,10 @@ def argparse_function(ver: str) -> typing.Tuple[str, str, bool]: 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("-c", "--config", default='config.ini', nargs='?', help="The config file Path.") - parser.add_argument("-o","--log-dir",dest='logdir',default=os.path.join(Path.home(),'.avlogs'),nargs='?', - help="Duplicate from stdout and stderr to logfiles in log directory.") + parser.add_argument("-o","--log-dir",dest='logdir', + default=os.path.join(Path.home(),'.avlogs'),nargs='?', + help=f"Duplicate from stdout and stderr to logfiles in log directory. " + + "Default for current user is: " + os.path.join(Path.home(),'.avlogs')) parser.add_argument("-n", "--number", default='', nargs='?', help="Custom file number") parser.add_argument("-a", "--auto-exit", dest='autoexit', action="store_true", help="Auto exit after program complete") From 184230f9341b0900ba1b035f257158cf1a86d51b Mon Sep 17 00:00:00 2001 From: lededev Date: Sat, 25 Sep 2021 22:57:48 +0800 Subject: [PATCH 05/22] supplementary explanation in --help --- AV_Data_Capture.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/AV_Data_Capture.py b/AV_Data_Capture.py index e4aa564..2bf96b9 100755 --- a/AV_Data_Capture.py +++ b/AV_Data_Capture.py @@ -35,14 +35,15 @@ def check_update(local_version): def argparse_function(ver: str) -> typing.Tuple[str, str, bool]: - parser = argparse.ArgumentParser() + default_logdir = os.path.join(Path.home(),'.avlogs') + parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter) 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("-c", "--config", default='config.ini', nargs='?', help="The config file Path.") - parser.add_argument("-o","--log-dir",dest='logdir', - default=os.path.join(Path.home(),'.avlogs'),nargs='?', - help=f"Duplicate from stdout and stderr to logfiles in log directory. " + - "Default for current user is: " + os.path.join(Path.home(),'.avlogs')) + parser.add_argument("-o","--log-dir",dest='logdir',default=default_logdir,nargs='?', + help=f"""Duplicate from stdout and stderr to logfiles in log directory. +Current user's default log folder is: {default_logdir} +Use --log-dir= to turn off log feature.""") parser.add_argument("-n", "--number", default='', nargs='?', help="Custom file number") parser.add_argument("-a", "--auto-exit", dest='autoexit', action="store_true", help="Auto exit after program complete") From 6834b7d2154f796e42eecf95e424dda3046f3148 Mon Sep 17 00:00:00 2001 From: lededev Date: Sat, 25 Sep 2021 23:14:57 +0800 Subject: [PATCH 06/22] help output format --- AV_Data_Capture.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/AV_Data_Capture.py b/AV_Data_Capture.py index 2bf96b9..06f3f6b 100755 --- a/AV_Data_Capture.py +++ b/AV_Data_Capture.py @@ -35,15 +35,16 @@ def check_update(local_version): def argparse_function(ver: str) -> typing.Tuple[str, str, bool]: - default_logdir = os.path.join(Path.home(),'.avlogs') parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter) 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("-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 from stdout and stderr to logfiles in log directory. -Current user's default log folder is: {default_logdir} -Use --log-dir= to turn off log feature.""") + 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("-a", "--auto-exit", dest='autoexit', action="store_true", help="Auto exit after program complete") From aae5b0a8d3ad035f97348c778991677b0993d5c2 Mon Sep 17 00:00:00 2001 From: lededev Date: Sat, 25 Sep 2021 23:45:55 +0800 Subject: [PATCH 07/22] using makedirs() --- AV_Data_Capture.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AV_Data_Capture.py b/AV_Data_Capture.py index 06f3f6b..7ce0bb1 100755 --- a/AV_Data_Capture.py +++ b/AV_Data_Capture.py @@ -97,7 +97,7 @@ def dupe_stdout_to_logfile(logdir: str): if not isinstance(logdir, str) or len(logdir) == 0: return if not os.path.isdir(logdir): - os.mkdir(logdir) + os.makedirs(logdir) if not os.path.isdir(logdir): return From 16078b95b1cc5a7869025e70123b34b63c9dc9c1 Mon Sep 17 00:00:00 2001 From: lededev Date: Sun, 26 Sep 2021 00:35:00 +0800 Subject: [PATCH 08/22] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E8=A7=86=E9=A2=91=E6=96=87=E4=BB=B6=E5=90=8D=E4=B8=8D=E5=B8=A6?= =?UTF-8?q?,=E8=80=8C.nfo=E6=96=87=E4=BB=B6=E5=90=8D=E5=B8=A6'-=E6=B5=81?= =?UTF-8?q?=E5=87=BA'=E7=9A=84=E6=AD=BB=E5=BE=AA=E7=8E=AFbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ADC_function.py | 4 ++-- core.py | 19 ++++++++++++------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/ADC_function.py b/ADC_function.py index b39bf48..dfd01f1 100755 --- a/ADC_function.py +++ b/ADC_function.py @@ -1,7 +1,7 @@ from os import replace import requests import hashlib -import pathlib +from pathlib import Path import random import os.path import uuid @@ -551,7 +551,7 @@ def load_cookies(filename): # 文件修改时间距此时的天数 def file_modification_days(filename) -> int: - mfile = pathlib.Path(filename) + mfile = Path(filename) if not mfile.exists(): return 9999 mtime = int(mfile.stat().st_mtime) diff --git a/core.py b/core.py index 7c131bf..e1291f4 100755 --- a/core.py +++ b/core.py @@ -9,6 +9,7 @@ import sys from PIL import Image from io import BytesIO +from pathlib import Path from ADC_function import * from WebCrawler import get_data_from_json @@ -201,13 +202,17 @@ def image_download(cover, number, leak_word, c_word, path, conf: config.Config, shutil.copyfile(path + '/' + number + leak_word + c_word + '-fanart.jpg',path + '/' + 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) - + 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: if not os.path.exists(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('', file=code) print("", file=code) print(" " + naming_rule + "", file=code) @@ -262,7 +267,7 @@ def print_files(path, leak_word, c_word, naming_rule, part, cn_sub, json_data, f print(" " + trailer + "", file=code) print(" " + website + "", file=code) print("", file=code) - print("[+]Wrote! " + path + "/" + number + part + leak_word + c_word + ".nfo") + print("[+]Wrote! " + nfo_path) except IOError as e: print("[-]Write Failed!") print(e) @@ -562,7 +567,7 @@ def core_main(file_path, number_th, conf: config.Config): 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) @@ -608,8 +613,8 @@ def core_main(file_path, number_th, conf: config.Config): 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) 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") From 911f43cd5c75d01f66fd4c7f900c03323d70706a Mon Sep 17 00:00:00 2001 From: lededev Date: Sun, 26 Sep 2021 01:23:44 +0800 Subject: [PATCH 09/22] =?UTF-8?q?=E8=B7=AF=E5=BE=84=E5=88=86=E9=9A=94?= =?UTF-8?q?=E7=AC=A6=E6=96=B9=E5=90=91=E4=BF=9D=E6=8C=81=E4=B8=80=E8=87=B4?= =?UTF-8?q?=E8=BE=93=E5=87=BA=E4=BC=9A=E6=9B=B4=E7=BE=8E=E8=A7=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core.py | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/core.py b/core.py index e1291f4..fc9725d 100755 --- a/core.py +++ b/core.py @@ -55,8 +55,9 @@ def get_info(json_data): # 返回json里的数据 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) - print('[+]Image Downloaded! ' + path + '/' + number + leak_word + c_word + '-poster.jpg') + filename = f"{number}{leak_word}{c_word}-poster.jpg" + download_file_with_filename(cover_small, filename, path, conf, filepath) + print('[+]Image Downloaded! ' + os.path.join(str(path), filename)) def create_folder(json_data, conf: config.Config): # 创建文件夹 @@ -162,44 +163,48 @@ def trailer_download(trailer, leak_word, c_word, number, path, filepath, conf: c # 剧照下载成功,否则移动到failed def extrafanart_download(data, path, conf: config.Config, filepath): j = 1 - path = path + '/' + conf.get_extrafanart() + path = os.path.join(str(path), conf.get_extrafanart()) for url in data: - if download_file_with_filename(url, 'extrafanart-' + str(j)+'.jpg', path, conf, filepath) == 'failed': + jpg_filename = f'extrafanart-{j}.jpg' + jpg_fullpath = os.path.join(str(path), jpg_filename) + if download_file_with_filename(url, jpg_filename, path, conf, filepath) == 'failed': moveFailedFolder(filepath) return configProxy = conf.proxy() 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) - download_file_with_filename(url, 'extrafanart-' + str(j)+'.jpg', path, conf, filepath) + download_file_with_filename(url, jpg_filename, path, conf, filepath) continue else: break - if os.path.getsize(path + '/extrafanart-' + str(j) + '.jpg') == 0: + if os.path.getsize(jpg_fullpath) == 0: return - print('[+]Image Downloaded!', path + '/extrafanart-' + str(j) + '.jpg') + print('[+]Image Downloaded!', jpg_fullpath) j += 1 # 封面是否下载成功,否则移动到failed 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" + full_filepath = os.path.join(str(path), filename) + if download_file_with_filename(cover, filename, path, conf, filepath) == 'failed': moveFailedFolder(filepath) return configProxy = conf.proxy() 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) - 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 else: break - if os.path.getsize(path + '/' + number + leak_word + c_word + '-fanart.jpg') == 0: + if os.path.getsize(full_filepath) == 0: return - print('[+]Image Downloaded!', path + '/' + number + leak_word + c_word + '-fanart.jpg') - shutil.copyfile(path + '/' + number + leak_word + c_word + '-fanart.jpg',path + '/' + number + leak_word + c_word + '-thumb.jpg') + print('[+]Image Downloaded!', full_filepath) + shutil.copyfile(full_filepath, os.path.join(str(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, tag, actor_list, liuchu, uncensored, conf): @@ -281,21 +286,21 @@ def print_files(path, leak_word, c_word, naming_rule, part, cn_sub, json_data, f def cutImage(imagecut, path, number, leak_word, c_word): + fullpath_noext = os.path.join(path, f"{number}{leak_word}{c_word}") if imagecut == 1: # 剪裁大封面 try: - img = Image.open(path + '/' + number + leak_word + c_word + '-fanart.jpg') + img = Image.open(fullpath_noext + '-fanart.jpg') imgSize = img.size w = img.width h = img.height img2 = img.crop((w / 1.9, 0, w, h)) - img2.save(path + '/' + number + leak_word + c_word + '-poster.jpg') - print('[+]Image Cutted! ' + path + '/' + number + leak_word + c_word + '-poster.jpg') + img2.save(fullpath_noext + '-poster.jpg') + print('[+]Image Cutted! ' + fullpath_noext + '-poster.jpg') except: print('[-]Cover cut failed!') elif imagecut == 0: # 复制封面 - shutil.copyfile(path + '/' + number + leak_word + c_word + '-fanart.jpg', - path + '/' + number + leak_word + c_word + '-poster.jpg') - print('[+]Image Copyed! ' + path + '/' + number + leak_word + c_word + '-poster.jpg') + shutil.copyfile(fullpath_noext + '-fanart.jpg', fullpath_noext + '-poster.jpg') + print('[+]Image Copyed! ' + fullpath_noext + '-poster.jpg') # 此函数从gui版copy过来用用 # 参数说明 From e87f5b7a1f9abdcedd4b24dc931a7188d35a1fdb Mon Sep 17 00:00:00 2001 From: lededev Date: Sun, 26 Sep 2021 02:07:33 +0800 Subject: [PATCH 10/22] Path().parent is a better way in here --- core.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/core.py b/core.py index fc9725d..f549f35 100755 --- a/core.py +++ b/core.py @@ -57,7 +57,7 @@ def get_info(json_data): # 返回json里的数据 def small_cover_check(path, number, cover_small, leak_word, c_word, conf: config.Config, filepath): filename = f"{number}{leak_word}{c_word}-poster.jpg" download_file_with_filename(cover_small, filename, path, conf, filepath) - print('[+]Image Downloaded! ' + os.path.join(str(path), filename)) + print('[+]Image Downloaded! ' + os.path.join(path, filename)) def create_folder(json_data, conf: config.Config): # 创建文件夹 @@ -114,7 +114,7 @@ def download_file_with_filename(url, filename, path, conf: config.Config, filepa if r == '': print('[-]Movie Data not found!') 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) return else: @@ -126,7 +126,7 @@ def download_file_with_filename(url, filename, path, conf: config.Config, filepa if r == '': print('[-]Movie Data not found!') 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) return except requests.exceptions.RequestException: @@ -163,10 +163,10 @@ def trailer_download(trailer, leak_word, c_word, number, path, filepath, conf: c # 剧照下载成功,否则移动到failed def extrafanart_download(data, path, conf: config.Config, filepath): j = 1 - path = os.path.join(str(path), conf.get_extrafanart()) + path = os.path.join(path, conf.get_extrafanart()) for url in data: jpg_filename = f'extrafanart-{j}.jpg' - jpg_fullpath = os.path.join(str(path), jpg_filename) + jpg_fullpath = os.path.join(path, jpg_filename) if download_file_with_filename(url, jpg_filename, path, conf, filepath) == 'failed': moveFailedFolder(filepath) return @@ -188,7 +188,7 @@ def extrafanart_download(data, path, conf: config.Config, filepath): # 封面是否下载成功,否则移动到failed def image_download(cover, number, leak_word, c_word, path, conf: config.Config, filepath): filename = f"{number}{leak_word}{c_word}-fanart.jpg" - full_filepath = os.path.join(str(path), filename) + full_filepath = os.path.join(path, filename) if download_file_with_filename(cover, filename, path, conf, filepath) == 'failed': moveFailedFolder(filepath) return @@ -204,7 +204,7 @@ def image_download(cover, number, leak_word, c_word, path, conf: config.Config, if os.path.getsize(full_filepath) == 0: return print('[+]Image Downloaded!', full_filepath) - shutil.copyfile(full_filepath, os.path.join(str(path), f"{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, tag, actor_list, liuchu, uncensored, conf): @@ -593,8 +593,7 @@ def core_main(file_path, number_th, conf: config.Config): add_mark(poster_path, thumb_path, cn_sub, leak, uncensored, conf) elif conf.main_mode() == 3: - path = file_path.rsplit('/', 1)[0] - path = path.rsplit('\\', 1)[0] + path = str(Path(file_path).parent) if multi_part == 1: number += part # 这时number会被附加上CD1后缀 From c6efec91dd6dea924b88392431ff1eed70bff39d Mon Sep 17 00:00:00 2001 From: lededev Date: Sun, 26 Sep 2021 04:25:25 +0800 Subject: [PATCH 11/22] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=88=97=E8=A1=A8=E4=BB=A5=E9=81=BF=E5=85=8D?= =?UTF-8?q?=E9=87=8D=E5=A4=8D=E5=88=AE=E5=89=8A=EF=BC=8C=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?3=E4=B8=8E=E8=BD=AF=E8=BF=9E=E6=8E=A5=E9=80=82=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AV_Data_Capture.py | 50 +++++++++++++++++++++++++++--------------- WebCrawler/__init__.py | 8 +++---- core.py | 46 +++++++++++++++++++------------------- 3 files changed, 60 insertions(+), 44 deletions(-) diff --git a/AV_Data_Capture.py b/AV_Data_Capture.py index 7ce0bb1..4fbf25e 100755 --- a/AV_Data_Capture.py +++ b/AV_Data_Capture.py @@ -126,26 +126,40 @@ def close_logfile(logdir: str): -G_trailerRE = re.compile(r'-trailer\.', re.IGNORECASE) - -def movie_lists(root, escape_folder): - if os.path.basename(root) in escape_folder: - return [] +# 重写视频文件扫描,消除递归,取消全局变量,新增失败文件列表跳过处理 +def movie_lists(root, conf): + escape_folder = re.split("[,,]", conf.escape_folder()) + failed_folder = conf.failed_folder() + main_mode = conf.main_mode() total = [] file_type = conf.media_type().upper().split(",") - dirs = os.listdir(root) - for entry in dirs: - f = os.path.join(root, entry) - if os.path.isdir(f): - total += movie_lists(f, escape_folder) - elif os.path.splitext(f)[1].upper() in file_type: - absf = os.path.abspath(f) - if conf.main_mode() == 3 and conf.mode3_nfo_skip_days() > 0: - nfo = Path(absf).with_suffix('.nfo') - if file_modification_days(nfo) <= conf.mode3_nfo_skip_days(): + trailerRE = re.compile(r'-trailer\.', re.IGNORECASE) + try: + failed_list = open(os.path.join(failed_folder, 'failed_list.txt'), 'r', encoding='utf-8').read().splitlines() + except: + failed_list = [] + pass + for current_dir, subdirs, files in os.walk(root, topdown=False): + try: + 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 - if (conf.main_mode() == 3 or not is_link(absf)) and not G_trailerRE.search(f): - total.append(absf) + absf = os.path.abspath(full_name) + if absf in failed_list: + if conf.debug(): + print('[!]Skip failed file:', absf) + continue + if main_mode == 3 and conf.mode3_nfo_skip_days() > 0: + nfo = Path(absf).with_suffix('.nfo') + if file_modification_days(nfo) <= conf.mode3_nfo_skip_days(): + continue + if (main_mode == 3 or not is_link(absf)) and not trailerRE.search(f): + total.append(absf) + except: + pass return total @@ -275,7 +289,7 @@ if __name__ == '__main__': if folder_path == '': folder_path = os.path.abspath(".") - movie_list = movie_lists(folder_path, re.split("[,,]", conf.escape_folder())) + movie_list = movie_lists(folder_path, conf) count = 0 count_all = str(len(movie_list)) diff --git a/WebCrawler/__init__.py b/WebCrawler/__init__.py index 364f7c3..cadc5d6 100644 --- a/WebCrawler/__init__.py +++ b/WebCrawler/__init__.py @@ -126,8 +126,8 @@ def get_data_from_json(file_number, conf: config.Config): # 从JSON返回元数 # Return if data not found in all sources if not json_data: - print('[-]Movie Data not found!') - return + print('[-]Movie Number not found!') + return None # ================================================网站规则添加结束================================================ @@ -165,8 +165,8 @@ def get_data_from_json(file_number, conf: config.Config): # 从JSON返回元数 actor = str(actor_list).strip("[ ]").replace("'", '').replace(" ", '') if title == '' or number == '': - print('[-]Movie Data not found!') - return + print('[-]Movie Number or Title not found!') + return None # if imagecut == '3': # DownloadFileWithFilename() diff --git a/core.py b/core.py index f549f35..ea92cb5 100755 --- a/core.py +++ b/core.py @@ -22,18 +22,20 @@ def escape_path(path, escape_literals: str): # Remove escape literals return path -def moveFailedFolder(filepath): - conf = config.Config() - if conf.failed_move(): - failed_folder = conf.failed_folder() +def moveFailedFolder(filepath, conf): + failed_folder = conf.failed_folder() + soft_link = conf.soft_link() + # 模式3或软连接,改为维护一个失败列表,启动扫描时加载用于排除该路径,以免反复处理 + # 原先的创建软连接到失败目录,并不直观,不方便找到失败文件位置,不如直接记录该文件路径 + if conf.main_mode() == 3 or soft_link: + with open(os.path.join(failed_folder, 'failed_list.txt'), 'a', encoding='utf-8') as m3f: + m3f.write(f'{filepath}\n') + m3f.close() + print('[-]Add to failed list file') + elif conf.failed_move() and not soft_link: file_name = os.path.basename(filepath) - if conf.soft_link(): - print('[-]Create symlink to Failed output folder') - os.symlink(filepath, os.path.join(failed_folder, file_name)) - else: - print('[-]Move to Failed output folder') - shutil.move(filepath, os.path.join(failed_folder, file_name)) - return + print('[-]Move to Failed output folder') + shutil.move(filepath, os.path.join(failed_folder, file_name)) def get_info(json_data): # 返回json里的数据 @@ -112,7 +114,7 @@ def download_file_with_filename(url, filename, path, conf: config.Config, filepa 'User-Agent': G_USER_AGENT} r = requests.get(url, headers=headers, timeout=configProxy.timeout, proxies=proxies) if r == '': - print('[-]Movie Data not found!') + print('[-]Movie Download Data not found!') return with open(os.path.join(path, filename), "wb") as code: code.write(r.content) @@ -124,7 +126,7 @@ def download_file_with_filename(url, filename, path, conf: config.Config, filepa 'User-Agent': G_USER_AGENT} r = requests.get(url, timeout=configProxy.timeout, headers=headers) if r == '': - print('[-]Movie Data not found!') + print('[-]Movie Download Data not found!') return with open(os.path.join(path, filename), "wb") as code: code.write(r.content) @@ -142,7 +144,7 @@ def download_file_with_filename(url, filename, path, conf: config.Config, filepa i += 1 print('[-]Image Download : Connect retry ' + str(i) + '/' + str(configProxy.retry)) print('[-]Connect Failed! Please check your Proxy or Network!') - moveFailedFolder(filepath) + moveFailedFolder(filepath, conf) return def trailer_download(trailer, leak_word, c_word, number, path, filepath, conf: config.Config): @@ -168,7 +170,7 @@ def extrafanart_download(data, path, conf: config.Config, filepath): jpg_filename = f'extrafanart-{j}.jpg' jpg_fullpath = os.path.join(path, jpg_filename) if download_file_with_filename(url, jpg_filename, path, conf, filepath) == 'failed': - moveFailedFolder(filepath) + moveFailedFolder(filepath, conf) return configProxy = conf.proxy() for i in range(configProxy.retry): @@ -190,7 +192,7 @@ def image_download(cover, number, leak_word, c_word, path, conf: config.Config, filename = f"{number}{leak_word}{c_word}-fanart.jpg" full_filepath = os.path.join(path, filename) if download_file_with_filename(cover, filename, path, conf, filepath) == 'failed': - moveFailedFolder(filepath) + moveFailedFolder(filepath, conf) return configProxy = conf.proxy() @@ -276,12 +278,12 @@ def print_files(path, leak_word, c_word, naming_rule, part, cn_sub, json_data, f except IOError as e: print("[-]Write Failed!") print(e) - moveFailedFolder(filepath) + moveFailedFolder(filepath, conf) return except Exception as e1: print(e1) print("[-]Write Failed!") - moveFailedFolder(filepath) + moveFailedFolder(filepath, conf) return @@ -450,7 +452,7 @@ def paste_file_to_folder_mode2(filepath, path, multi_part, number, part, leak_wo print('[-]OS Error errno ' + oserr.errno) return -def get_part(filepath): +def get_part(filepath, conf): try: if re.search('-CD\d+', filepath): return re.findall('-CD\d+', filepath)[0] @@ -458,7 +460,7 @@ def get_part(filepath): return re.findall('-cd\d+', filepath)[0] except: print("[-]failed!Please rename the filename again!") - moveFailedFolder(filepath) + moveFailedFolder(filepath, conf) return @@ -496,7 +498,7 @@ def core_main(file_path, number_th, conf: config.Config): # Return if blank dict returned (data not found) if not json_data: - moveFailedFolder(filepath) + moveFailedFolder(filepath, conf) return if json_data["number"] != number: @@ -511,7 +513,7 @@ def core_main(file_path, number_th, conf: config.Config): # =======================================================================判断-C,-CD后缀 if '-CD' in filepath or '-cd' in filepath: 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: cn_sub = '1' c_word = '-C' # 中文字幕影片后缀 From bf5bd5d4440bf3be61a9aedba36b9ac35f344351 Mon Sep 17 00:00:00 2001 From: lededev Date: Sun, 26 Sep 2021 06:35:35 +0800 Subject: [PATCH 12/22] =?UTF-8?q?=E5=A2=9E=E9=87=8F=E6=95=B4=E7=90=86?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=BA=E9=80=82=E7=94=A8=E4=BA=8E=E6=89=80?= =?UTF-8?q?=E6=9C=89=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AV_Data_Capture.py | 40 ++++++++++++++++++++++++++++++---------- config.ini | 14 ++++++-------- config.py | 31 ++++++++++++------------------- core.py | 5 ++--- 4 files changed, 50 insertions(+), 40 deletions(-) diff --git a/AV_Data_Capture.py b/AV_Data_Capture.py index 4fbf25e..715ddf2 100755 --- a/AV_Data_Capture.py +++ b/AV_Data_Capture.py @@ -131,6 +131,8 @@ def movie_lists(root, conf): escape_folder = re.split("[,,]", conf.escape_folder()) failed_folder = conf.failed_folder() main_mode = conf.main_mode() + debug = conf.debug() + nfo_skip_days = conf.nfo_skip_days() total = [] file_type = conf.media_type().upper().split(",") trailerRE = re.compile(r'-trailer\.', re.IGNORECASE) @@ -149,17 +151,36 @@ def movie_lists(root, conf): continue absf = os.path.abspath(full_name) if absf in failed_list: - if conf.debug(): + if debug: print('[!]Skip failed file:', absf) continue - if main_mode == 3 and conf.mode3_nfo_skip_days() > 0: + if main_mode == 3 and nfo_skip_days > 0: nfo = Path(absf).with_suffix('.nfo') - if file_modification_days(nfo) <= conf.mode3_nfo_skip_days(): + 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) except: pass + if nfo_skip_days <= 0 or not conf.soft_link(): + 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 os.path.splitext(f)[1].upper() in file_type: + nfo_file = os.path.join(current_dir, str(Path(f).with_suffix('.nfo'))) + if file_modification_days(nfo_file) <= nfo_skip_days: + file_name = os.path.basename(f) + number = get_number(False, file_name) + if number: + skip_numbers.add(number.upper()) + for f in total: + file_name = os.path.basename(f) + n_number = get_number(False, file_name) + if n_number and n_number.upper() in skip_numbers: + total.pop(total.index(f)) return total @@ -295,22 +316,21 @@ if __name__ == '__main__': count_all = str(len(movie_list)) print('[+]Find', count_all, 'movies') main_mode = conf.main_mode() - stop_count = conf.mode3_stop_counter() + stop_count = conf.stop_counter() if stop_count<1: stop_count = 999999 - elif main_mode == 3: + else: count_all = str(min(len(movie_list), stop_count)) + if main_mode == 3: print( -f'[!]运行模式:**维护模式**,本程序将在处理{count_all}个视频文件后停止,如需后台执行自动退出请结合 -a 参数。' - ) - +f'[!]运行模式:**维护模式**,本程序将在处理{count_all}个视频文件后停止,如需后台执行自动退出请结合 -a 参数。') for movie_path in movie_list: # 遍历电影列表 交给core处理 count = count + 1 percentage = str(count / int(count_all) * 100)[:4] + '%' print('[!] - ' + percentage + ' [' + str(count) + '/' + count_all + '] -') create_data_and_move(movie_path, conf, conf.debug()) - if main_mode == 3 and count >= stop_count: - print("[!]Mode 3 stop counter triggered!") + if count >= stop_count: + print("[!]Stop counter triggered!") break if conf.del_empty_folder(): diff --git a/config.ini b/config.ini index d384bc4..2d655d5 100755 --- a/config.ini +++ b/config.ini @@ -10,6 +10,12 @@ multi_threading=1 ;actor_gender value: female(♀) or male(♂) or both(♀ ♂) or all(♂ ♀ ⚧) actor_gender=female del_empty_folder=1 +; 跳过最近(默认:30)天新修改过的.NFO,可避免整理模式(main_mode=3)和软连接(soft_link=0)时 +; 反复刮削靠前的视频文件,0为处理所有视频文件 +nfo_skip_days=30 +; 处理完多少个视频文件后停止,0为处理所有视频文件 +stop_counter=0 +; 以上两个参数配合使用可以以多次少量的方式刮削或整理数千个文件而不触发翻译或元数据站封禁 [proxy] ;proxytype: http or socks5 or socks5h switch: 0 1 @@ -75,11 +81,3 @@ water=2 switch=0 extrafanart_folder=extrafanart -; 整理模式 ([common] main_mode=3) -[main_mode_3] -; 整理时跳过最近(默认:30)天新修改过的.NFO,可避免反复整理靠前的文件,0为总是整理全部文件 -nfo_skip_days=30 -; 整理文件时达到指定个数即停止,配合google free翻译使用时,避免触发翻译次数上限导致的翻译失败,0为不限制 -mode3_stop_counter=0 -; 以上两个参数配合使用,可以用于定时执行的计划任务,例如将数千个视频文件的元数据在几周内分批更新 -; 程序启动参数'-o 日志目录'则可生成日志,检查几周内日志可找出失败文件手工处理 diff --git a/config.py b/config.py index 76ffcbd..274b90c 100644 --- a/config.py +++ b/config.py @@ -54,6 +54,16 @@ class Config: return self.conf.getboolean("common", "multi_threading") def del_empty_folder(self) -> bool: 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: return self.conf.getboolean("transalte", "switch") def is_trailer(self) -> bool: @@ -149,18 +159,6 @@ class Config: def debug(self) -> bool: return self.conf.getboolean("debug_mode", "switch") - def mode3_nfo_skip_days(self) -> int: - try: - return self.conf.getint("main_mode_3", "nfo_skip_days") - except: - return 30 - - def mode3_stop_counter(self) -> int: - try: - return self.conf.getint("main_mode_3", "mode3_stop_counter") - except: - return 0 - @staticmethod def _exit(sec: str) -> None: print("[-] Read config error! Please check the {} section in config.ini", sec) @@ -183,6 +181,8 @@ class Config: # actor_gender value: female or male or both or all(含人妖) conf.set(sec1, "actor_gender", "female") conf.set(sec1, "del_empty_folder", "1") + conf.set(sec1, "nfo_skip_days", 30) + conf.set(sec1, "stop_counter", 0) sec2 = "proxy" conf.add_section(sec2) @@ -248,16 +248,9 @@ class Config: conf.set(sec13, "switch", 1) conf.set(sec13, "extrafanart_folder", "extrafanart") - sec14 = "main_mode_3" - conf.add_section(sec14) - conf.set(sec14, "nfo_skip_days", 30) - conf.set(sec14, "mode3_stop_counter", 0) - return conf - - class IniProxy(): """ Proxy Config from .ini """ diff --git a/core.py b/core.py index ea92cb5..4951fab 100755 --- a/core.py +++ b/core.py @@ -28,9 +28,8 @@ def moveFailedFolder(filepath, conf): # 模式3或软连接,改为维护一个失败列表,启动扫描时加载用于排除该路径,以免反复处理 # 原先的创建软连接到失败目录,并不直观,不方便找到失败文件位置,不如直接记录该文件路径 if conf.main_mode() == 3 or soft_link: - with open(os.path.join(failed_folder, 'failed_list.txt'), 'a', encoding='utf-8') as m3f: - m3f.write(f'{filepath}\n') - m3f.close() + open(os.path.join(failed_folder, 'failed_list.txt'), 'a', encoding='utf-8' + ).write(f'{filepath}\n').close() print('[-]Add to failed list file') elif conf.failed_move() and not soft_link: file_name = os.path.basename(filepath) From ecd5c7de1c0e8ef26ba1e1118dd312abda75a9a0 Mon Sep 17 00:00:00 2001 From: lededev Date: Sun, 26 Sep 2021 07:43:57 +0800 Subject: [PATCH 13/22] =?UTF-8?q?=E5=B0=8F=E6=B8=85=E7=90=86=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81=E6=8E=92=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AV_Data_Capture.py | 57 ++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/AV_Data_Capture.py b/AV_Data_Capture.py index 715ddf2..1523bfe 100755 --- a/AV_Data_Capture.py +++ b/AV_Data_Capture.py @@ -129,7 +129,6 @@ def close_logfile(logdir: str): # 重写视频文件扫描,消除递归,取消全局变量,新增失败文件列表跳过处理 def movie_lists(root, conf): escape_folder = re.split("[,,]", conf.escape_folder()) - failed_folder = conf.failed_folder() main_mode = conf.main_mode() debug = conf.debug() nfo_skip_days = conf.nfo_skip_days() @@ -137,48 +136,46 @@ def movie_lists(root, conf): file_type = conf.media_type().upper().split(",") trailerRE = re.compile(r'-trailer\.', re.IGNORECASE) try: - failed_list = open(os.path.join(failed_folder, 'failed_list.txt'), 'r', encoding='utf-8').read().splitlines() + failed_list = open(os.path.join(conf.failed_folder(), 'failed_list.txt'), + 'r', encoding='utf-8').read().splitlines() except: failed_list = [] pass for current_dir, subdirs, files in os.walk(root, topdown=False): - try: - if current_dir in escape_folder: + 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 - for f in files: - full_name = os.path.join(current_dir, f) - if not os.path.splitext(full_name)[1].upper() in file_type: + absf = os.path.abspath(full_name) + if absf in failed_list: + if debug: + print('[!]Skip failed file:', 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 - absf = os.path.abspath(full_name) - if absf in failed_list: - if debug: - print('[!]Skip failed file:', 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) - except: - pass - if nfo_skip_days <= 0 or not conf.soft_link(): + if (main_mode == 3 or not is_link(absf)) and not trailerRE.search(f): + total.append(absf) + if nfo_skip_days <= 0 or not conf.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 os.path.splitext(f)[1].upper() in file_type: - nfo_file = os.path.join(current_dir, str(Path(f).with_suffix('.nfo'))) - if file_modification_days(nfo_file) <= nfo_skip_days: - file_name = os.path.basename(f) - number = get_number(False, file_name) - if number: - skip_numbers.add(number.upper()) + 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: - file_name = os.path.basename(f) - n_number = get_number(False, file_name) + 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 From 6a4739c0352171abee0df62162ae874e5581b548 Mon Sep 17 00:00:00 2001 From: lededev Date: Sun, 26 Sep 2021 09:07:19 +0800 Subject: [PATCH 14/22] fix file close, add moving list --- AV_Data_Capture.py | 16 +++++++++------- core.py | 21 +++++++++++++-------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/AV_Data_Capture.py b/AV_Data_Capture.py index 1523bfe..fc081d1 100755 --- a/AV_Data_Capture.py +++ b/AV_Data_Capture.py @@ -132,15 +132,17 @@ def movie_lists(root, conf): main_mode = conf.main_mode() debug = conf.debug() nfo_skip_days = conf.nfo_skip_days() + soft_link = conf.soft_link() total = [] file_type = conf.media_type().upper().split(",") trailerRE = re.compile(r'-trailer\.', re.IGNORECASE) - try: - failed_list = open(os.path.join(conf.failed_folder(), 'failed_list.txt'), - 'r', encoding='utf-8').read().splitlines() - except: - failed_list = [] - pass + failed_list = [] + if main_mode == 3 or soft_link: + try: + failed_list = open(os.path.join(conf.failed_folder(), 'failed_list.txt'), + 'r', encoding='utf-8').read().splitlines() + except: + pass for current_dir, subdirs, files in os.walk(root, topdown=False): if current_dir in escape_folder: continue @@ -159,7 +161,7 @@ def movie_lists(root, conf): continue if (main_mode == 3 or not is_link(absf)) and not trailerRE.search(f): total.append(absf) - if nfo_skip_days <= 0 or not conf.soft_link() or main_mode == 3: + if nfo_skip_days <= 0 or not soft_link or main_mode == 3: return total # 软连接方式,已经成功削刮的也需要从成功目录中检查.nfo更新天数,跳过N天内更新过的 skip_numbers = set() diff --git a/core.py b/core.py index 4951fab..fb6fccd 100755 --- a/core.py +++ b/core.py @@ -28,13 +28,18 @@ def moveFailedFolder(filepath, conf): # 模式3或软连接,改为维护一个失败列表,启动扫描时加载用于排除该路径,以免反复处理 # 原先的创建软连接到失败目录,并不直观,不方便找到失败文件位置,不如直接记录该文件路径 if conf.main_mode() == 3 or soft_link: - open(os.path.join(failed_folder, 'failed_list.txt'), 'a', encoding='utf-8' - ).write(f'{filepath}\n').close() - print('[-]Add to failed list file') + with open(os.path.join(failed_folder, 'failed_list.txt'), 'a', encoding='utf-8') as flt: + flt.write(f'{filepath}\n') + flt.close() + print('[-]Add to failed list file, see failed_list.txt') elif conf.failed_move() and not soft_link: - file_name = os.path.basename(filepath) - print('[-]Move to Failed output folder') - shutil.move(filepath, os.path.join(failed_folder, file_name)) + failed_name = os.path.join(failed_folder, os.path.basename(filepath)) + print('[-]Move to Failed output folder, see where_was_i_before_being_moved.txt') + with open(os.path.join(failed_folder, 'where_was_i_before_being_moved.txt'), 'a', + encoding='utf-8') as wwibbmt: + wwibbmt.write(f'FROM[{filepath}]TO[{failed_name}]\n') + wwibbmt.close() + shutil.move(filepath, failed_name) def get_info(json_data): # 返回json里的数据 @@ -418,7 +423,7 @@ def paste_file_to_folder(filepath, path, number, leak_word, c_word, conf: config print('[-]Error! Please run as administrator!') return except OSError as oserr: - print('[-]OS Error errno ' + oserr.errno) + print(f'[-]OS Error errno {oserr.errno}') return @@ -448,7 +453,7 @@ def paste_file_to_folder_mode2(filepath, path, multi_part, number, part, leak_wo print('[-]Error! Please run as administrator!') return except OSError as oserr: - print('[-]OS Error errno ' + oserr.errno) + print(f'[-]OS Error errno {oserr.errno}') return def get_part(filepath, conf): From 948a3d20b018f1a931d5cae90867c36a0189eeda Mon Sep 17 00:00:00 2001 From: lededev Date: Sun, 26 Sep 2021 09:49:28 +0800 Subject: [PATCH 15/22] =?UTF-8?q?=E8=BE=93=E5=87=BA=E5=86=85=E5=AE=B9?= =?UTF-8?q?=E6=9B=B4=E8=AF=A6=E7=BB=86=E4=B8=80=E4=BA=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AV_Data_Capture.py | 4 ++-- core.py | 15 +++++++++------ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/AV_Data_Capture.py b/AV_Data_Capture.py index fc081d1..30cd2e8 100755 --- a/AV_Data_Capture.py +++ b/AV_Data_Capture.py @@ -8,7 +8,7 @@ import typing import urllib3 import config -import datetime +from datetime import datetime import time from pathlib import Path from ADC_function import file_modification_days, get_html, is_link @@ -101,7 +101,7 @@ def dupe_stdout_to_logfile(logdir: str): if not os.path.isdir(logdir): return - log_tmstr = datetime.datetime.now().strftime("%Y%m%dT%H%M%S") + 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') diff --git a/core.py b/core.py index fb6fccd..06ff053 100755 --- a/core.py +++ b/core.py @@ -10,6 +10,7 @@ import sys from PIL import Image from io import BytesIO from pathlib import Path +from datetime import datetime from ADC_function import * from WebCrawler import get_data_from_json @@ -28,16 +29,18 @@ def moveFailedFolder(filepath, conf): # 模式3或软连接,改为维护一个失败列表,启动扫描时加载用于排除该路径,以免反复处理 # 原先的创建软连接到失败目录,并不直观,不方便找到失败文件位置,不如直接记录该文件路径 if conf.main_mode() == 3 or soft_link: - with open(os.path.join(failed_folder, 'failed_list.txt'), 'a', encoding='utf-8') as flt: + ftxt = os.path.join(failed_folder, 'failed_list.txt') + print("[-]Add to Failed List file, see '%s'" % ftxt) + with open(ftxt, 'a', encoding='utf-8') as flt: flt.write(f'{filepath}\n') flt.close() - print('[-]Add to failed list file, see failed_list.txt') elif conf.failed_move() and not soft_link: failed_name = os.path.join(failed_folder, os.path.basename(filepath)) - print('[-]Move to Failed output folder, see where_was_i_before_being_moved.txt') - with open(os.path.join(failed_folder, 'where_was_i_before_being_moved.txt'), 'a', - encoding='utf-8') as wwibbmt: - wwibbmt.write(f'FROM[{filepath}]TO[{failed_name}]\n') + 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) From 620affc9871a9aac47d9af91faa0ac0fbeef3f59 Mon Sep 17 00:00:00 2001 From: lededev Date: Sun, 26 Sep 2021 19:20:20 +0800 Subject: [PATCH 16/22] add param -q regex query filepath --- AV_Data_Capture.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/AV_Data_Capture.py b/AV_Data_Capture.py index 30cd2e8..be9053d 100755 --- a/AV_Data_Capture.py +++ b/AV_Data_Capture.py @@ -48,10 +48,11 @@ Use --log-dir= to turn off logging feature.""") parser.add_argument("-n", "--number", default='', nargs='?', help="Custom file number") parser.add_argument("-a", "--auto-exit", dest='autoexit', action="store_true", 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) args = parser.parse_args() - return args.file, args.path, args.number, args.autoexit, args.logdir + return args.file, args.path, args.number, args.autoexit, args.logdir, args.regexstr class OutLogger(object): @@ -127,7 +128,7 @@ def close_logfile(logdir: str): # 重写视频文件扫描,消除递归,取消全局变量,新增失败文件列表跳过处理 -def movie_lists(root, conf): +def movie_lists(root, conf, regexstr): escape_folder = re.split("[,,]", conf.escape_folder()) main_mode = conf.main_mode() debug = conf.debug() @@ -136,6 +137,12 @@ def movie_lists(root, conf): total = [] file_type = conf.media_type().upper().split(",") trailerRE = re.compile(r'-trailer\.', re.IGNORECASE) + cliRE = None + if len(regexstr): + try: + cliRE = re.compile(regexstr, re.IGNORECASE) + except: + pass failed_list = [] if main_mode == 3 or soft_link: try: @@ -155,6 +162,8 @@ def movie_lists(root, conf): 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: @@ -275,7 +284,7 @@ if __name__ == '__main__': version = '4.7.2' urllib3.disable_warnings() #Ignore http proxy warning # Parse command line args - single_file_path, folder_path, custom_number, auto_exit, logdir = argparse_function(version) + single_file_path, folder_path, custom_number, auto_exit, logdir, regexstr = argparse_function(version) dupe_stdout_to_logfile(logdir) @@ -309,7 +318,7 @@ if __name__ == '__main__': if folder_path == '': folder_path = os.path.abspath(".") - movie_list = movie_lists(folder_path, conf) + movie_list = movie_lists(folder_path, conf, regexstr) count = 0 count_all = str(len(movie_list)) From d7197d8b8c717878c059d84bb00384377fa124d8 Mon Sep 17 00:00:00 2001 From: lededev Date: Sun, 26 Sep 2021 19:49:24 +0800 Subject: [PATCH 17/22] =?UTF-8?q?=E6=97=A5=E5=BF=97=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E5=8C=85=E5=90=AB=E5=91=BD=E4=BB=A4=E8=A1=8C=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AV_Data_Capture.py | 1 + 1 file changed, 1 insertion(+) diff --git a/AV_Data_Capture.py b/AV_Data_Capture.py index be9053d..ffe8bd6 100755 --- a/AV_Data_Capture.py +++ b/AV_Data_Capture.py @@ -304,6 +304,7 @@ if __name__ == '__main__': print('[+]Enable debug') if conf.soft_link(): print('[!]Enable soft link') + print('[!]CmdLine:'," ".join(sys.argv[1:])) create_failed_folder(conf.failed_folder()) start_time = time.time() From cc36562c1757d059184cc627fe357076ea7b8fb7 Mon Sep 17 00:00:00 2001 From: lededev Date: Mon, 27 Sep 2021 01:05:24 +0800 Subject: [PATCH 18/22] add config path search order --- config.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/config.py b/config.py index 274b90c..33550fd 100644 --- a/config.py +++ b/config.py @@ -2,15 +2,29 @@ import os import sys import configparser import codecs +from pathlib import Path class Config: 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() try: - self.conf.read(path, encoding="utf-8-sig") + self.conf.read(ini_path, encoding="utf-8-sig") except: - self.conf.read(path, encoding="utf-8") + self.conf.read(ini_path, encoding="utf-8") else: print("[-]Config file not found!") sys.exit(2) From 3ef0db1890664d97308b8d446d98c924a0a60022 Mon Sep 17 00:00:00 2001 From: lededev Date: Mon, 27 Sep 2021 03:23:33 +0800 Subject: [PATCH 19/22] =?UTF-8?q?=E6=AF=8F=E5=AE=8C=E6=88=90=E4=B8=80?= =?UTF-8?q?=E9=83=A8=E5=BD=B1=E7=89=87=E5=88=B7=E6=96=B0=E4=B8=80=E4=B8=8B?= =?UTF-8?q?=E8=BE=93=E5=87=BA=EF=BC=8C=E4=BB=A5=E5=85=8D=E7=AD=89=E5=88=B0?= =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E7=BB=93=E6=9D=9F=E6=89=8D=E7=9C=8B=E5=88=B0?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AV_Data_Capture.py | 1 + 1 file changed, 1 insertion(+) diff --git a/AV_Data_Capture.py b/AV_Data_Capture.py index ffe8bd6..c19cab1 100755 --- a/AV_Data_Capture.py +++ b/AV_Data_Capture.py @@ -338,6 +338,7 @@ f'[!]运行模式:**维护模式**,本程序将在处理{count_all}个视频 percentage = str(count / int(count_all) * 100)[:4] + '%' print('[!] - ' + percentage + ' [' + str(count) + '/' + count_all + '] -') create_data_and_move(movie_path, conf, conf.debug()) + sys.stdout.flush() if count >= stop_count: print("[!]Stop counter triggered!") break From 9304aab940c1324b3376f3c70a5f24163dde0155 Mon Sep 17 00:00:00 2001 From: lededev Date: Mon, 27 Sep 2021 03:56:59 +0800 Subject: [PATCH 20/22] =?UTF-8?q?=E5=A4=96=E5=B1=82=E4=B9=9F=E8=B0=83?= =?UTF-8?q?=E7=94=A8moveFailedFolder()=E5=87=BD=E6=95=B0=E6=9D=A5=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AV_Data_Capture.py | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/AV_Data_Capture.py b/AV_Data_Capture.py index c19cab1..64420b3 100755 --- a/AV_Data_Capture.py +++ b/AV_Data_Capture.py @@ -13,7 +13,7 @@ import time from pathlib import Path from ADC_function import file_modification_days, get_html, is_link from number_parser import get_number -from core import core_main +from core import core_main, moveFailedFolder def check_update(local_version): @@ -242,21 +242,10 @@ def create_data_and_move(file_path: str, c: config.Config, debug): print(f"[-] [{file_path}] ERROR:") print('[-]', err) - # 3.7.2 New: Move or not move to failed folder. - if c.failed_move() == False: - if c.soft_link(): - print("[-]Link {} to failed folder".format(file_path)) - 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) + try: + moveFailedFolder(file_path, conf) + except Exception as err: + print('[!]', err) def create_data_and_move_with_custom_number(file_path: str, c: config.Config, custom_number): From d7aea9a09d320d6df4c0f82509354423feed34fc Mon Sep 17 00:00:00 2001 From: lededev Date: Mon, 27 Sep 2021 04:34:41 +0800 Subject: [PATCH 21/22] =?UTF-8?q?=E5=8F=8C=E9=87=8D=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E6=9C=89=E6=97=B6=E4=BC=9A=E7=94=9F=E6=88=90=E4=B8=A4=E6=9D=A1?= =?UTF-8?q?=E7=9B=B8=E5=90=8C=E8=AE=B0=E5=BD=95=EF=BC=8C=E7=94=A8=E9=9B=86?= =?UTF-8?q?=E5=90=88=E5=8E=BB=E9=87=8D=E5=86=99=E5=9B=9E=EF=BC=8C=E5=B9=B6?= =?UTF-8?q?=E5=88=A9=E7=94=A8=E9=9B=86=E5=90=88=E6=8F=90=E5=8D=87=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E9=80=9F=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AV_Data_Capture.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/AV_Data_Capture.py b/AV_Data_Capture.py index 64420b3..bd79252 100755 --- a/AV_Data_Capture.py +++ b/AV_Data_Capture.py @@ -143,11 +143,17 @@ def movie_lists(root, conf, regexstr): cliRE = re.compile(regexstr, re.IGNORECASE) except: pass - failed_list = [] + failed_set = set() if main_mode == 3 or soft_link: try: - failed_list = open(os.path.join(conf.failed_folder(), 'failed_list.txt'), - 'r', encoding='utf-8').read().splitlines() + 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): @@ -158,7 +164,7 @@ def movie_lists(root, conf, regexstr): if not os.path.splitext(full_name)[1].upper() in file_type: continue absf = os.path.abspath(full_name) - if absf in failed_list: + if absf in failed_set: if debug: print('[!]Skip failed file:', absf) continue From afc011883030c947e41c285d9a00a783805a0005 Mon Sep 17 00:00:00 2001 From: lededev Date: Mon, 27 Sep 2021 06:39:47 +0800 Subject: [PATCH 22/22] =?UTF-8?q?=E7=94=B1=E8=B0=83=E7=94=A8flush()?= =?UTF-8?q?=E6=94=B9=E4=B8=BAhook=20print()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AV_Data_Capture.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/AV_Data_Capture.py b/AV_Data_Capture.py index bd79252..edd1ecd 100755 --- a/AV_Data_Capture.py +++ b/AV_Data_Capture.py @@ -126,6 +126,13 @@ def close_logfile(logdir: str): 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): @@ -333,7 +340,6 @@ f'[!]运行模式:**维护模式**,本程序将在处理{count_all}个视频 percentage = str(count / int(count_all) * 100)[:4] + '%' print('[!] - ' + percentage + ' [' + str(count) + '/' + count_all + '] -') create_data_and_move(movie_path, conf, conf.debug()) - sys.stdout.flush() if count >= stop_count: print("[!]Stop counter triggered!") break