코드 리뷰, 수정

파일 이름을 파싱해서 각 항목에 삽입하는 설명 추가
This commit is contained in:
2026-08-28 16:52:21 +09:00
parent a4e0ae0b08
commit ced90ed2ca
3 changed files with 38 additions and 35 deletions
+10 -26
View File
@@ -7,6 +7,7 @@ import shutil
import difflib import difflib
import subprocess import subprocess
import hashlib import hashlib
import glob
try: try:
import rarfile import rarfile
@@ -244,36 +245,19 @@ def CreateZIP(output_zip: str, files: list[str]) -> bool:
# 파일 리스트에 들어있는 파일만 골라서 압축을 합니다. 상대경로를 제거하는게 기본값. # 파일 리스트에 들어있는 파일만 골라서 압축을 합니다. 상대경로를 제거하는게 기본값.
def CreateZIPShell(zipName: str, files: list[str], bRmvRPath: bool = True) -> bool: def CreateZIPShell(zipName: str, files: list[str], bRmvRPath: bool = True) -> bool:
command = "zip " command = ["zip"]
if True == bRmvRPath: if True == bRmvRPath:
command += "-j " command.append("-j")
command.extend([zipName, *files])
command += f"\"{zipName}\" " result = subprocess.run(command, capture_output=True, text=True)
return result.returncode == 0
# 이중 리스트인 이유를 모르겠다.
for file in files:
command += f"\"{file}\" "
result = subprocess.run(command, shell=True, capture_output=True, text=True)
bRet = False
if 0 == result.returncode:
bRet = True
return bRet
# 특정 확장자만 쉘을 이용해서 압축한다 # 특정 확장자만 쉘을 이용해서 압축한다
def CreateZIPShExt(zipName: str, TrgExt: str)-> bool: def CreateZIPShExt(zipName: str, TrgExt: str)-> bool:
command = f"zip -j {zipName} *.{TrgExt}" matching_files = glob.glob(f"*.{TrgExt}")
command = ["zip", "-j", zipName, *matching_files]
result = subprocess.run(command, shell=True, capture_output=True, text=True) result = subprocess.run(command, capture_output=True, text=True)
return result.returncode == 0
bRet = False
if 0 == result.returncode:
bRet = True
return bRet
# 압축 파일 내의 모든 파일 및 디렉토리 목록 가져오기 # 압축 파일 내의 모든 파일 및 디렉토리 목록 가져오기
def GetZipContentList(path: str) -> list[str]: def GetZipContentList(path: str) -> list[str]:
+27 -9
View File
@@ -26,7 +26,17 @@ DEFAULT_VALUES = {
# #
def main(argc, argv): def main(argc, argv):
parser = argparse.ArgumentParser(description="ComicInfo.XML 생성기") parser = argparse.ArgumentParser(
description="ComicInfo.XML 생성기",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=(
"사용 예시:\n"
" 폴더명이 '[작가] 제목'인 경우:\n"
" python3 main.py --in \"/path/[작가] 제목/book.cbz\" "
"--title '<currentfolder>:s/^\\[([^\\]]+)\\]\\s*(.+)$/$2/' "
"--author '<currentfolder>:s/^\\[([^\\]]+)\\]\\s*(.+)$/$1/'"
),
)
parser.add_argument('--root', dest='root_dir', required=False, help='입력 폴더 지정') parser.add_argument('--root', dest='root_dir', required=False, help='입력 폴더 지정')
parser.add_argument('--in', dest='arc_file', required=False, help='대상 파일 지정') parser.add_argument('--in', dest='arc_file', required=False, help='대상 파일 지정')
parser.add_argument('--title', dest='info_title', required=False, help='제목') parser.add_argument('--title', dest='info_title', required=False, help='제목')
@@ -198,15 +208,21 @@ def ExpandPathVars(text: str | None, filepath: str) -> str | None:
for key, value in var_map.items(): for key, value in var_map.items():
result = result.replace(f"<{key}>", value) result = result.replace(f"<{key}>", value)
# After variable expansion, check for :s/pattern/replacement/ or s/pattern/replacement/ suffix # After variable expansion, check for :s/pattern/replacement/ suffix.
m = re.match(r'^(.*):?s(.)(.+?)\2(.*?)(?:\2([ig]*))?$', result, re.DOTALL) transform_pos = result.find(':s')
if transform_pos >= 0:
source = result[:transform_pos]
transform = result[transform_pos + 1:]
m = re.match(r'^s(?P<delim>.)(?P<pattern>.*?)(?P=delim)(?P<replacement>.*?)(?P=delim)(?P<flags>[ig]*)$', transform, re.DOTALL)
else:
source = ''
m = None
if m: if m:
source = m.group(1) pattern = m.group('pattern')
delim = m.group(2) replacement = m.group('replacement')
pattern = m.group(3) flags_str = m.group('flags')
replacement = m.group(4) replacement_safe = re.sub(r'\$(\d+)', lambda match: '\\' + match.group(1), replacement)
flags_str = m.group(5) or ''
replacement_safe = re.sub(r'\$(\d+)', r'\\\1', replacement)
flags = 0 flags = 0
if 'i' in flags_str: if 'i' in flags_str:
flags |= re.IGNORECASE flags |= re.IGNORECASE
@@ -311,6 +327,7 @@ def ValidateAndFixComicInfoXML(xml_bytes: bytes) -> tuple[bytes | None, list[str
msgs.append("XML is now well-formed.") msgs.append("XML is now well-formed.")
except ET.ParseError as e2: except ET.ParseError as e2:
msgs.append(f"Remaining issues after fix: {e2}") msgs.append(f"Remaining issues after fix: {e2}")
return (None, msgs)
return (fixed_bytes, msgs) return (fixed_bytes, msgs)
msgs.append("No fixable issues found.") msgs.append("No fixable issues found.")
@@ -604,6 +621,7 @@ def ProcessMetadataToCBZ(strArcPath: str, bPrint: bool = False,
xml_content = output.getvalue().decode('utf-8') xml_content = output.getvalue().decode('utf-8')
except Exception as e: except Exception as e:
util.DbgOut(f"XML 수정 중 오류: {e}", True) util.DbgOut(f"XML 수정 중 오류: {e}", True)
return False
# 출력 옵션이 켜져 있으면 내용 출력 # 출력 옵션이 켜져 있으면 내용 출력
if True == bPrint: if True == bPrint:
+1
View File
@@ -1 +1,2 @@
rarfile>=4.0 rarfile>=4.0
comicapi