Files
playground/clean_vids.py
T

786 lines
26 KiB
Python
Executable File

#!/usr/bin/env -S uv run
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "paramiko",
# "psycopg",
# ]
# ///
import contextlib
import hashlib
import json
import logging
import re
import sqlite3
import subprocess
import typing
from collections import Counter, defaultdict
from pathlib import Path
import paramiko
import psycopg
import psycopg.rows
import ffmpeg
VIDS_DIR = Path(r"/Volumes/FIVER/_ingress/")
schema = """
create table if not exists videos(
file_path text not null primary key,
size_bytes int not null,
hash_partial text not null,
ffprobe json not null
);
create table if not exists scan_state(
file_path text not null primary key,
stderr text
);
"""
def find_vids(root: Path):
extensions = [".mkv", ".mp4"]
for ext in extensions:
for f in root.rglob(f"*{ext}"):
yield f
def hash_partial(f: Path) -> str:
sha1 = hashlib.sha1()
chunk_size = 1024 * 1024 * 10 # 10MB chunk size
total_read = 0
with f.open("rb") as file:
while chunk := file.read(chunk_size):
total_read += len(chunk)
sha1.update(chunk)
break # Only reads the first 10MB
return f"sha1:{total_read}:{sha1.hexdigest()}"
@contextlib.contextmanager
def connect_db_sqlite() -> typing.Generator[psycopg.Connection, typing.Any, typing.Any]:
with sqlite3.connect("vids.sqlite3") as conn:
conn.row_factory = sqlite3.Row
conn.execute("PRAGMA foreign_keys = 1")
yield conn
@contextlib.contextmanager
def connect_db() -> typing.Generator[psycopg.Connection, typing.Any, typing.Any]:
with psycopg.connect("postgres://abdus:abdus@db.abdus.dev:5444/smut?sslmode=disable") as conn:
conn.row_factory = psycopg.rows.dict_row
yield conn
def video_exists(con: psycopg.Connection, file_path: str) -> bool:
stmt = con.execute(
"select exists(select 1 from videos where file_path = %s) as exists",
[file_path],
)
row = stmt.fetchone()
return row["exists"]
def delete_video(con: psycopg.Connection, file_path: str) -> bool:
con.execute("delete from videos where file_path = %s", [file_path])
def save_video(
con: psycopg.Connection,
category: str,
file_path: str,
ffprobe: dict,
hash_partial: str,
):
sql = """insert into videos(category, file_path, ffprobe, hash_partial) values (%s, %s, %s, %s);"""
con.execute(
sql,
[
category,
file_path,
json.dumps(ffprobe),
hash_partial,
],
)
def save_error(con: psycopg.Connection, file_path: str, stderr: str):
sql = """insert into scan_state(file_path, stderr) values (%s, %s) on conflict do nothing"""
con.execute(
sql,
[
file_path,
stderr,
],
)
def scan_videos():
logging.basicConfig(format=logging.BASIC_FORMAT, level=logging.DEBUG)
with connect_db() as con:
# with con:
# con.executescript(schema)
all_vids = list(find_vids(VIDS_DIR))
for i, f in enumerate(all_vids):
if "/_picks/" in str(f):
continue
progress = f"[{i + 1}/{len(all_vids)}]"
if f.is_dir():
continue
file_path = str(f.absolute())
if video_exists(con, file_path=file_path):
logging.debug(f"{progress} video already exists {f=}")
continue
logging.debug(f"probing {f=}")
try:
probed = ffmpeg.ffprobe(f)
except subprocess.CalledProcessError as e:
save_error(con, file_path=file_path, stderr=e.stderr)
continue
file_hash = hash_partial(f)
save_video(
category="downloaded.fiver",
con=con,
file_path=file_path,
ffprobe=probed.__dict__,
hash_partial=file_hash,
)
logging.info(f"{progress} saved {f=}")
con.commit()
def clean_records():
all_vids = set(map(str, find_vids(VIDS_DIR)))
with connect_db() as con:
for row in con.execute("select file_path from videos"):
file_path = row["file_path"]
if file_path not in all_vids:
delete_video(con, file_path=row["file_path"])
def unwanted(dry_run: bool):
take = set(
r"""
aidra fox
rachel starr
abella danger
sata jones
octavia red
paige owens
lily lou
cj miles
arabelle raphael
chloe amour
erin everheart
kenzie reeves
alex grey
alicia trece
angel youngs
angela white
april olsen
blake blossom
brandy renee
chantal
demi sutra
eden ivy
ema karter
emma hix
gianna dior
hazel moore
jazmin luv
jessy jey
josephine jackson
katsaros
kira noir
kitana lure
kitana montana
kristy black
leal
lia lin
lily labeau
liya silver
maddy may
nata ocean
rebel rhyder
rein
savannah bond
scarlett alexis
scarlit scandal
shalina
simon kitty
slimthick vic
stratton
tatum
tommy king
vanna bardot
vic marie
violet starr
vittoria
emily willis
THUNDERCOCK
lucky bee
charlotte sins
mandy muse
skye blue
alexis tae
willow
TRUEANAL
ALLANAL
avery cristy
ANALONLY
SWALLOWED
kelly collins
nicole black
xxlayna marie
katrina colt
allie addison
DIRTYAUDITIONS
scarlet chase
#sloppiest kiss
liz ocean
medusa
nicole aria
stacy bloom
lara frost
jamie jett
brooklyn gray
kimmy granger
kelsey kane
kay lovely
ivy wolfe
stefany kyler
leo ahsoka
lydia black
renee rose
emily jade
anya olsen
alexis crystal
sybil
megan rain
charlotte sartre
madison ivy
maddy black
gina valentina
lacey jayne
hailey rose
graycee baybee
katie kush
lilu moon
juis wild
kylie rocket
dolly dyson
nichole saphir
Octokuro
reislin
isabella de laa
qween goddess
INTHECRACK
athenea rose
daniela garcia
kama oxi
mina
baby nicols
jade amor
daniela ortiz
NYMPHO
""".strip().splitlines(keepends=False)
)
drop = set(
r"""
ADDICTED2GIRLS
ASIANSEEPLOITED
BANANAFEVER
BBCPOVD
BFFS
# BRAZZERSEXXTRA
BRIDE4K
CHLOELAMOUR
DRKINLA
ETERNALDESIRE
EVERYTHINGBUTT
FAKEHOSTEL
FAKEHUBORIGINALS
FAKETAXI
FAMILYSINNERS
FEETISHPOV
GIRLGIRLXXX
GOTFILLED
HOOKUPHOTSHOT
HOWWOMENORGASM
IMMORALLIVE
IWANTCLIPS
JACQUIEETMICHELTV
JERKAOKE
NICONICE
NURUMASSAGE
OHMYHOLES
OYELOCA
PASCALSSUBSLUTS
SCHOOLOFCOCK
SHOTHERFIRST
SLIPPERYMASSAGE
TABOOHEAT
TEAMSKEETX
WAXXXED
WOODMANCASTINGX
PISSVIDS
LEGALPORNO
ANALVIDS
PORNBOX
\btap\b
alice xo
alicia williams
mona azar
anna de ville
baby kxtten
bella rolland
betzz
charlie forde
charlie red
cheyla collins
claudia garcia
cory chase
dani blue
dellai
eimy zoren
emily pink
gia dibella
greta foss
danielle renae
harley king
ivy maddox
sasha rose
olive glass
katherin moore
kristina grace
kylie page
larissa leite
lily starfire
lina arian
luna legend
luna rishi
luna wolfs
lya cutie
margan lee
marie berger
marilyn johnson
mia cheers
monika fox
moona snake
nichole saphir
nicole murkovski
olivia sparkle
polly petrova
pornworld
publicagent
publicbang
stacy cruz
sussy sweet
triple anal
vanessa vega
venera maxima
victoria nyx
whitney wright
zirael rem
""".lower()
.strip()
.splitlines(keepends=False)
)
take_patterns = [re.compile(p.strip().replace(" ", "."), flags=re.I) for p in take if not p.strip().startswith("#")]
drop_patterns = [re.compile(p.strip().replace(" ", "."), flags=re.I) for p in drop if not p.strip().startswith("#")]
to_delete = set()
with connect_db() as con:
for row in con.execute("select file_path from videos where category = 'box'"):
file_path = Path(row["file_path"])
text = re.sub(r"[.]+", " ", file_path.stem.lower())
if any(p.search(text) for p in drop_patterns):
to_delete.add(file_path)
if any(p.search(text) for p in take_patterns):
to_delete.discard(file_path)
for it in sorted(to_delete):
print(it)
return
with connect_db() as con:
for path in sorted(to_delete, key=str):
try:
print(path.stem)
con.execute(
"update videos set marked_for_deletion_at = now() where file_path = %s",
[str(path)],
)
if not dry_run:
path.unlink()
delete_video(con, file_path=str(path))
con.commit()
except:
pass
print(len(to_delete))
def large_unwanted():
with connect_db() as con:
for row in con.execute("select file_path from videos order by size_bytes desc limit 500"):
file_path = Path(row["file_path"])
print(file_path)
def list_studios():
re_studio = re.compile(r"^(.+?)\.\d+", flags=re.IGNORECASE)
seen = defaultdict(int)
with connect_db() as con:
for row in con.execute("select file_path from videos"):
file_path = Path(row["file_path"])
m = re_studio.search(file_path.stem.lower())
if m:
seen[m.group(1)] += 1
for it, n in Counter(seen).most_common(20):
print(it, n)
def lower_resolutions(dry_run: bool):
with connect_db() as con:
for row in con.execute("""select file_path from videos where file_path like '%720p%';"""):
file_path = Path(row["file_path"])
video_1080p_path = file_path.with_stem(file_path.stem.replace("720p", "1080p"))
if video_exists(con, file_path=str(video_1080p_path)) and video_1080p_path.is_file():
print(file_path)
if not dry_run:
file_path.unlink()
def dupes():
sql = """
with durationed as (
select v.*, json_extract(v.ffprobe, '$.duration_sec') as duration_sec from videos v
)
select v.file_path, dupe.file_path from durationed v
join durationed dupe on v.file_path != dupe.file_path and abs(dupe.duration_sec - v.duration_sec) < 3
where abs(dupe.size_bytes - v.size_bytes) < 3000000
"""
with connect_db() as con:
for row in con.execute(sql):
print(row[0], row[1])
print()
def different_format(dry_run: bool):
sql = """
select file_path from videos where file_path like '%.mkv'
"""
with connect_db() as con:
for row in con.execute(sql):
mkv_path = Path(row["file_path"])
mp4_path = mkv_path.with_suffix(".mp4")
if mkv_path.is_file() and mp4_path.is_file():
if abs(mp4_path.stat().st_size - mkv_path.stat().st_size) < 5_000_000:
print(mkv_path)
if not dry_run:
mkv_path.unlink()
def count_shared_words(a: str, b: str) -> int:
a_words = set(re.split(r"[\s\-.]+", a.lower()))
b_words = set(re.split(r"[\s\-.]+", b.lower()))
return len(a_words.intersection(b_words))
def reencoded_self(dry_run: bool):
sql = """
with
durationed_v as (
select v.*, json_extract(v.ffprobe, '$.duration_sec') as duration_sec from videos v
),
durationed_dl as (
select v.*, json_extract(v.ffprobe, '$.duration_sec') as duration_sec from downloaded_videos v
)
select v.file_path, dlv.file_path from durationed_v v
join durationed_dl dlv on abs(v.duration_sec - dlv.duration_sec) < 0.1
where dlv.file_path like '%/_reenc/%'
"""
with connect_db() as con:
for row in con.execute(sql):
v_path = Path(row[0])
dlv_path = Path(row[1])
if count_shared_words(v_path.stem, dlv_path.stem) < 2:
continue
print(v_path.name, dlv_path.name, sep="\n")
if not dry_run:
try:
v_path.unlink()
except:
pass
def local_duped(dry_run: bool):
sql = """
with durationed_dl as (
select v.*, json_extract(v.ffprobe, '$.duration_sec') as duration_sec from downloaded_videos v
)
select v.file_path, dupe.file_path
from durationed_dl v
join durationed_dl dupe on
v.id != dupe.id
and v.id > dupe.id
and abs(dupe.duration_sec - v.duration_sec) < 0.1
and abs(dupe.size_bytes - v.size_bytes) < 3000000
"""
root = Path(r"/Volumes/FIVER/_ingress/")
with connect_db() as con:
for row in con.execute(sql):
a_path = Path(row[0])
b_path = Path(row[1])
if count_shared_words(a_path.stem, b_path.stem) < 6:
continue
# print(a_path.name, b_path.name, sep='\n')
keep, remove = a_path, b_path
if len(b_path.stem) > len(a_path.stem):
keep, remove = b_path, a_path
print(" # ", "matching", keep.name)
print(" rm", f'"{remove}"')
print()
def delete_dupes():
rows = []
with connect_db() as con:
for row in rows:
file_path = Path(row["file_path"])
try:
file_path.unlink()
delete_video(con, file_path=row["file_path"])
con.commit()
except:
pass
def save_suggested_names():
rows = []
with connect_db() as con:
for row in rows:
bandaid_path = Path(row["file_path"])
fiver_path = Path(row["fiver_path"])
if bandaid_path.stem == fiver_path.stem:
continue
if count_shared_words(bandaid_path.stem, fiver_path.stem) < 3:
print("unsimilar", row)
continue
if bandaid_path.stem.count("--") == 3:
better_stem = bandaid_path.stem
else:
better_stem = fiver_path.stem
better_stem = re.sub(r"(\d{4})(\d{2})(\d{2})", r"\1-\2-\3", better_stem)
if better_stem == fiver_path.stem:
continue
print(fiver_path.name, better_stem, sep="\n")
con.execute(
"update videos set suggested_filename = %s where file_path = %s",
[better_stem, fiver_path.name],
)
con.commit()
def delete_remote_files():
rows = [
{"file_path": "/mnt/box/files/_raw/prt/LegalPorno.2024.AngeloGodshakOriginal.Eden.Ivy.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/LegalPorno.24.07.13.Daniela.Garcia.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/Bang.Rammed.24.10.03.Dan.Dangler.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/LegalPorno.2024.AngeloGodshackOriginal.Claudia.Macc.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/EvilAngel.22.05.29.Kitana.Montana.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/MySistersHotFriend.24.11.29.Anya.Olsen.XXX.720p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/CheatingSis.25.01.23.Kylie.Rocket.Property.Of.Stepbro.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/NFBusty.23.12.12.Hailey.Rose.And.Octavia.Red.Christmas.Party.Passion.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/SexArt.25.02.05.Leya.Desantis.Perfect.Man.XXX.720p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/TrueAnal.24.06.19.Katrina.Colt.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/AmericanDaydreams.23.07.03.Graycee.Baybee.XXX.1080p.HEVC.x265.PRT.mkv"},
{"file_path": "/mnt/box/files/_raw/prt/Slayed.25.03.04.Sonya.Blaze.And.Ellie.Luna.Tiny.Cutie.Is.Obsessed.With.Eating.Her.Hot.BFFs.Pussy.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/MYLFSeeker.25.02.08.Kelly.Caprice.Since.You.Became.My.Stepmom.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/JulesJordan.25.02.26.Emma.Hix.Sinful.Kitty.Gapes.After.A.Hard.Anal.Pounding.XXX.720p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/SexArt.23.08.04.Kelly.Collins.And.Milena.Ray.Rising.Passion.XXX.1080p.HEVC.x265.PRT.mkv"},
{"file_path": "/mnt/box/files/_raw/prt/JulesJordan.25.03.02.Melissa.Stratton.Craves.Every.Inch.Of.Manuel.Ferraras.Fat.Cock.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/Tushy.24.12.15.Agatha.Vega.And.Eve.Sweet.Long.Con.Part.3.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/DirtyAuditions.24.11.01.Alexa.Chains.XXX.720p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/Deeper.24.09.12.Amber.Moore.Cucked.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/Hegre.25.01.14.Anna.L.Gynecology.Photography.XXX.720p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/Bang.Rammed.24.12.26.Brenna.Mckenna.And.Chanel.Camryn.XXX.720p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/BlackedRaw.24.08.19.Cherry.Candle.Fiery.Red-head.Cherry.Drops.BF.For.His.Thick.BBC.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/AmericanDaydreams.23.09.09.Chloe.Amour.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/BrattySis.24.08.23.Chloe.Temple.Stop.Staring.At.It.And.Fuck.It.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/Luxure.23.03.10.Clara.Mia.And.Mary.Popiense.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/BrazzersExxtra.23.10.19.Elisa.Calvi.Big.Milky.Breakfast.Tits.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/RoccoSiffredi.24.01.11.Elisa.Calvi.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/SheLovesBlack.22.10.27.Elisa.Calvi.Cougar.Hospitality.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/MyGirlfriendsBustyFriend.24.07.09.Ellie.Nova.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/SpankMonster.24.02.14.Ellie.Nova.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/Private.25.01.23.Eva.Generosi.Cum.In.My.Ass.XXX.720p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/BlackedRaw.22.12.20.Gianna.Dior.And.Kylie.Rocket.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/BlackedRaw.22.12.20.Gianna.Dior.And.Kylie.Rocket.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/BangBrosClips.22.09.13.Graycee.Baybee.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/TushyRaw.24.12.31.Graycee.Baybee.Anal.Crazy.Blonde.Gapes.Wide.Open.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/MySistersHotFriend.24.12.02.Hailey.Rose.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/AnalOnly.24.12.12.Isabel.Love.XXX.720p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/EvilAngel.23.09.22.Jena.Larose.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/EvilAngel.24.05.27.Katie.Kush.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/DirtyAuditions.23.12.25.Katrina.Colt.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/JulesJordan.22.12.18.Katrina.Colt.Is.A.Big.Black.Cock.Slut.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/Swallowed.24.12.16.Ashley.Alexander.And.Katrina.Colt.XXX.720p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/BlackedRaw.25.02.15.Kelly.Collins.And.Zazie.Skymm.Kelly.And.Blonde.BFF.Prowl.For.BBC.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/Blacked.22.07.09.Kylie.Rocket.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/TrueAnal.24.11.27.Lilith.Grace.XXX.720p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/Joymii.23.02.15.Mary.Popiense.Surprise.Visit.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/TeenFidelity.E475.Mary.Popiense.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/NubileFilms.23.02.05.Molly.Little.A.Touch.Down.Here.Wins.The.Game.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/LittleCaprice-Dreams.23.11.17.Nata.Ocean.Nasstyx.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/ClubSweethearts.24.02.09.Princess.Alice.Hardcore.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/AnalOnly.24.12.04.Raven.Lane.And.Cassidy.Luxe.XXX.720p.HEVC.x265.PRT.mp4"},
{
"file_path": "/mnt/box/files/_raw/prt/LegalPorno.23.11.15.Rebel.Rhyder.Interracial.Fisting.Gangbang.Wet.4on1.BBC.DAP.Gapes.ButtRose.Pee.Drink.Shower.Squirt.Creampie.Swallow.GIO2595.XXX.1080p.HEVC.x265.PRT.mp4"
},
{
"file_path": "/mnt/box/files/_raw/prt/PissVids.23.07.21.Rebel.Rhyder.Blackended.Wet.DAP.Rough.Sex.Big.Gapes.Pee.Cocktail.Pee.Drink.Pee.Shower.Creampie.Cum.In.Mouth.GIO2512.XXX.1080p.HEVC.x265.PRT.mp4"
},
{
"file_path": "/mnt/box/files/_raw/prt/PissVids.23.02.08.Masked.Vs.Rebel.Rhyder.Wet.4on1.BBC.ATM.DAP.No.Pussy.Gapes.ButtRose.Pee.Drink.Squirt.Cum.In.Mouth.Swallow.GIO2330.XXX.1080p.HEVC.x265.PRT.mp4"
},
{
"file_path": "/mnt/box/files/_raw/prt/PissVids.23.06.18.Rebel.Rhyder.The.Loan.Re-Payment.Wet.5on1.Rough.Sex.ATM.DAP.Gapes.Pee.Drink.Pee.Shower.Cum.In.Mouth.Swallow.GIO2514.XXX.1080p.HEVC.x265.PRT.mp4"
},
{"file_path": "/mnt/box/files/_raw/prt/BrazzersExxtra.24.10.10.Ryan.Reid.Face.Fucking.The.Slutty.Sitter.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/BrazzersExxtra.25.01.27.Ryan.Reid.Horny.House.Sitter.Hits.The.Jackpot.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/Private.22.06.14.Sata.Jones.Anal.Debut.XXX.1080p.HEVC.x265.PRT.mkv"},
{"file_path": "/mnt/box/files/_raw/prt/EvilAngel.24.11.05.Scarlet.Chase.Latex.Gloves.Fist.And.Jerk.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/BangBrosClips.24.12.03.Shalina.Devine.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/AllAnal.24.12.07.Selena.Love.And.Stella.Luxx.XXX.720p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/TrueAnal.24.08.24.Tessa.Thomas.XXX.720p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/EvilAngel.25.02.10.Willow.Ryder.XXX.720p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/ThePOVGod.24.12.13.Willow.Ryder.Fuckin.With.The.Best.XXX.720p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/FamilyXXX.24.01.05.Ellie.Nova.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/JaxSlayher.24.01.11.Ellie.Nova.XXX.1080p.HEVC.x265.PRT.mp4"},
{"file_path": "/mnt/box/files/_raw/prt/POVMasters.24.09.23.Lina.Love.XXX.720p.HEVC.x265.PRT.mp4"},
]
with connect_server("klein") as ssh, connect_db() as con:
for row in rows:
file_path = row["file_path"]
try:
print("deleting", file_path)
ssh.exec_command(f'rm -rf "{file_path}"')
delete_video(con, file_path=file_path)
con.commit()
except:
pass
@contextlib.contextmanager
def connect_server(host: str) -> typing.Generator[paramiko.SSHClient, typing.Any, None]:
config = paramiko.SSHConfig.from_path(str(Path(r"~/.ssh/config").expanduser()))
key = paramiko.RSAKey.from_private_key_file(filename=str(Path(r"~/.ssh/id_rsa").expanduser()))
target = config.lookup(host)
ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_client.connect(
hostname=target["hostname"],
port=target.as_int("port"),
username=target["user"],
pkey=key,
)
yield ssh_client
ssh_client.close()
def collect_all():
root = Path("/Volumes/FATBLUE/_backup/_vidz/_all")
video_files = find_vids(root)
# re_good = re.compile(r"(?P<people>.+) - (?P<title>.+) --? (?P<studio>\S+) (?P<date_year>\d{4})(?P<date_month>\d{2})(?P<date_day>\d{2})")
# re_good = re.compile(r"(?P<people>.+) - (?P<title>.+) --? (?P<studio>\S+)")
# re_good = re.compile(r"(?P<people>.+) - (?P<title>.+) --? (?P<date_year>\d{4})(?P<date_month>\d{2})(?P<date_day>\d{2})")
re_good = re.compile(r"(?P<people>.+) - (?P<title>[^-]+) (?P<date_year>\d{4})(?P<date_month>\d{2})(?P<date_day>\d{2})")
for f in sorted(video_files):
m = re_good.search(f.stem)
if not m:
continue
params = m.groupdict()
title = params["title"]
if " " not in title:
print(f.stem, title, sep="\t\t")
continue
# better_name = f"{m['people']} -- @{m['studio']} -- {m['title']} -- {m['date_year']}-{m['date_month']}-{m['date_day']}"
better_name = f"{m['people']} -- {m['title']} -- {m['date_year']}-{m['date_month']}-{m['date_day']}"
# better_name = f"{m['people']} -- @{m['studio']} -- {m['title']}"
print(f.stem, better_name, sep="\n")
better_path = f.with_stem(better_name)
f.rename(better_path)
def clean_images():
from PIL import Image
for img in Path(r"/Users/abdus/Downloads/temp/Ploy Tigerstam -- OnlyFans Leak").glob("*.jpg"):
image = Image.open(img)
width, height = image.size
if width < 2000 or height < 2000:
img.unlink()
def main():
dry = True
try:
# clean_images()
# collect_all()
# save_suggested_names()
delete_remote_files()
# transfer()
# different_format(dry_run=dry)
# local_duped(dry_run=dry)
# reencoded_self(dry_run=dry)
# dupes()
# scan_videos()
# list_studios()
# lower_resolutions(dry_run=dry)
# large_unwanted()
# unwanted(dry_run=dry)
finally:
pass
# clean_records()
if __name__ == "__main__":
main()