feat(file_renamer): Support more formats

This commit is contained in:
2026-07-24 15:56:38 +02:00
parent d0c1f1ab8a
commit b0088aeeef
3 changed files with 1182 additions and 91 deletions
+29 -29
View File
@@ -62,7 +62,9 @@ def parse_date(filename: str) -> ParsedDate | None:
def from_us_format():
match = re_date_us.search(filename)
m, d, y = map(int, match.groups())
return ParsedDate(datetime.date(y + 2000, m, d), start=match.start(), end=match.end())
return ParsedDate(
datetime.date(y + 2000, m, d), start=match.start(), end=match.end()
)
def from_iso():
match = re_date_iso.search(filename)
@@ -72,7 +74,9 @@ def parse_date(filename: str) -> ParsedDate | None:
def from_iso_short():
match = re_date_iso_short.search(filename)
y, m, d = map(int, match.groups())
return ParsedDate(datetime.date(y + 2000, m, d), start=match.start(), end=match.end())
return ParsedDate(
datetime.date(y + 2000, m, d), start=match.start(), end=match.end()
)
def from_iso_reversed():
match = re_date_iso_rev.search(filename)
@@ -82,7 +86,9 @@ def parse_date(filename: str) -> ParsedDate | None:
def from_iso_reversed_short():
match = re_date_iso_rev_short.search(filename)
d, m, y = map(int, match.groups())
return ParsedDate(datetime.date(y + 2000, m, d), start=match.start(), end=match.end())
return ParsedDate(
datetime.date(y + 2000, m, d), start=match.start(), end=match.end()
)
candidates = []
for fn in [
@@ -101,7 +107,9 @@ def parse_date(filename: str) -> ParsedDate | None:
today = datetime.date.today()
future_threshold = today + datetime.timedelta(days=60)
past_threshold = datetime.date(2010, 1, 1)
candidates = [it for it in candidates if past_threshold < it.date < future_threshold]
candidates = [
it for it in candidates if past_threshold < it.date < future_threshold
]
if not candidates:
return
@@ -139,23 +147,9 @@ def trash(path: Path):
subprocess.run(cmd).check_returncode()
def filenames_to_actors():
sources = [
Path(r"/Users/abdus/Downloads/temp/"),
Path(r"/Volumes/BANDAID/_temp/__reenc/"),
Path(r"/Volumes/BANDAID/_temp/"),
]
actors = set()
for it in sources:
for f in it.glob("*.mp4"):
if not f.is_file():
continue
if r := parse_release(f.name):
actors.update(r.actors)
return actors
def parse_release(filename: str, known_actors: set[str] | None = None) -> Release | None:
def parse_release(
filename: str, known_actors: set[str] | None = None
) -> Release | None:
if not known_actors:
known_actors = set()
if any(filename.lower().endswith(ext) for ext in [".mp4", ".mkv"]):
@@ -174,7 +168,9 @@ def parse_release(filename: str, known_actors: set[str] | None = None) -> Releas
title=title,
released_at=datetime.date.fromisoformat(date),
)
case [actors, studio, date] if studio.startswith("@") and (parsed := parse_date(date)):
case [actors, studio, date] if studio.startswith("@") and (
parsed := parse_date(date)
):
return Release(
actors=sorted(actors.split(", ")),
studio=studio.removeprefix("@"),
@@ -210,14 +206,20 @@ def parse_release(filename: str, known_actors: set[str] | None = None) -> Releas
# assert '.PRT' in filename
remaining = re.sub(r"\.(720p|1080p|HEVC|x265|PRT|XXX)", " ", filename)
studio = remaining[: remaining.index(".")]
remaining = remaining[len(studio) :]
parsed_date = parse_date(remaining)
remaining = remaining[parsed_date.end :]
if parsed_date:
remaining = remaining[parsed_date.end :]
remaining = re.sub(r"[. ]+", " ", remaining).strip()
actors = []
title = None
# PornFidelity.E1109.Uma.Jolie
match remaining.split(" "):
case [episode, *names] if episode.startswith("E") and episode[1:].isdigit():
title = episode
actors = [" ".join(names)]
case [a_first, a_last, "And", b_first, b_last]:
actors = [f"{a_first} {a_last}", f"{b_first} {b_last}"]
case [a_first, a_last, "And", b_first, b_last, *rest]:
@@ -235,16 +237,12 @@ def parse_release(filename: str, known_actors: set[str] | None = None) -> Releas
studio=studio,
actors=sorted(actors),
title=title,
released_at=parsed_date.date,
released_at=parsed_date.date if parsed_date else None,
)
def from_galaxxxy():
pass
for fn in [
from_own,
from_prt,
from_galaxxxy,
]:
try:
if res := fn():
@@ -255,7 +253,9 @@ def parse_release(filename: str, known_actors: set[str] | None = None) -> Releas
def parse_args():
arger = argparse.ArgumentParser()
arger.add_argument("filenames", nargs="+", type=lambda v: Path(v).resolve(), help="Filenames")
arger.add_argument(
"filenames", nargs="+", type=lambda v: Path(v).resolve(), help="Filenames"
)
return arger.parse_args()