Extract oral role graph wording

This commit is contained in:
2026-06-26 17:14:12 +02:00
parent 4646f97ee7
commit 86a8f6167a
5 changed files with 247 additions and 96 deletions
+3 -96
View File
@@ -5,8 +5,10 @@ import re
from typing import Any
try:
from .hardcore_role_oral import build_oral_role_graph
from .hardcore_role_outercourse import build_outercourse_role_graph
except ImportError: # Allows local smoke tests with `python -c`.
from hardcore_role_oral import build_oral_role_graph
from hardcore_role_outercourse import build_outercourse_role_graph
@@ -53,7 +55,6 @@ def build_hardcore_role_graph(
people = participants["people"]
slug = str(subcategory.get("slug") or subcategory.get("name") or "").lower()
item_text = " ".join((item_axis_values or {}).values()).lower()
pov_set = set(pov_labels or [])
def any_person(exclude: set[str] | None = None) -> str:
exclude = exclude or set()
@@ -298,100 +299,6 @@ def build_hardcore_role_graph(
return f"{woman} kneels forward with hips raised while {man} kneels behind her and thrusts his penis into her ass."
return f"{woman} is on all fours with hips raised while {man} is positioned behind her and thrusts his penis into her ass."
def oral_position_graph(woman: str, man: str) -> str:
position_text = str((item_axis_values or {}).get("position") or "").lower()
text = " ".join(
str(part or "").lower()
for part in (
item_text,
*((item_axis_values or {}).values()),
)
)
man_is_pov = man in pov_set
woman_gives = any(
term in text
for term in (
"fellatio",
"blowjob",
"deepthroat",
"penis sucking",
"penis in mouth",
"penis in her mouth",
"mouth stretched around a penis",
"lips wrapped",
)
)
man_gives = any(
term in text
for term in (
"cunnilingus",
"pussy licking",
"tongue on pussy",
"mouth on pussy",
"pussy and tongue",
"face-sitting",
"tongue contact clearly visible",
)
)
if "mouth on genitals" in text and not woman_gives and not man_gives:
if any(term in text for term in ("face-sitting", "reclining", "straddled", "spread-leg", "open thighs")):
man_gives = True
else:
woman_gives = True
if "sixty-nine" in position_text or ("sixty-nine" in text and not position_text):
return f"{woman} and {man} lie head-to-hips in a sixty-nine position, with {woman}'s mouth on {man}'s penis and {man}'s mouth on {woman}'s pussy."
if "face-sitting" in position_text or ("face-sitting" in text and not position_text):
if man_is_pov:
return (
f"{woman} is above the POV camera, straddling the POV viewer's face with thighs on both sides of his head, "
"pussy directly over the POV viewer's mouth for close first-person underview tongue contact."
)
return f"{man} lies on his back while {woman} straddles his face with her thighs around his head and {man}'s mouth pressed to her pussy."
if "straddled oral" in position_text or ("straddled oral" in text and not position_text):
if woman_gives and not man_gives:
return f"{man} straddles forward near {woman}'s face while {woman} kneels below him with her mouth on his penis."
return f"{woman} straddles above {man}'s face with her thighs framing his head while {man}'s mouth stays pressed to her pussy."
if "side-lying oral" in position_text or ("side-lying oral" in text and not position_text):
if woman_gives and not man_gives:
return f"{man} lies on his side with hips angled toward {woman} while {woman} lies beside his thighs and takes his penis in her mouth."
return f"{woman} lies on her side with her top thigh lifted while {man} lies beside her hips with his mouth pressed to her pussy."
if (
"edge-of-bed oral" in position_text
or "edge of bed oral" in position_text
or "edge-supported oral" in position_text
or (("edge-of-bed oral" in text or "edge of bed oral" in text or "edge-supported oral" in text) and not position_text)
):
if woman_gives and not man_gives:
return f"{man} sits at a raised edge with legs apart while {woman} kneels between his thighs and takes his penis in her mouth."
return f"{woman} lies at a raised edge with thighs open while {man} kneels between her legs with his mouth on her pussy."
if "standing oral" in position_text or ("standing oral" in text and not position_text):
if man_gives and not woman_gives:
return f"{woman} stands braced with one thigh lifted while {man} kneels between her legs with his mouth on her pussy."
return f"{man} stands with hips forward while {woman} kneels in front of him at hip height and takes his penis in her mouth."
if "chair oral" in position_text or ("chair oral" in text and not position_text):
if man_gives and not woman_gives:
return f"{woman} sits in a chair with thighs open while {man} kneels between her legs with his mouth pressed to her pussy."
return f"{man} sits in a chair with legs apart while {woman} kneels between his thighs and takes his penis in her mouth."
if (
"reclining cunnilingus" in position_text
or "spread-leg oral" in position_text
or (("reclining cunnilingus" in text or "spread-leg oral" in text) and not position_text)
):
if woman_gives and not man_gives:
return f"{man} reclines with legs apart while {woman} kneels between his thighs and takes his penis in her mouth."
return f"{woman} reclines on her back with thighs spread while {man} kneels between her legs with his mouth on her pussy."
if "kneeling oral" in position_text or ("kneeling oral" in text and not position_text):
if man_gives and not woman_gives:
return f"{woman} kneels with thighs parted and hips angled forward while {man} kneels in front of her with his mouth on her pussy."
return (
f"{woman} kneels in front of {man}'s penis while {man} stands over her; "
f"{woman} takes {man}'s penis in her mouth with saliva dripping on the penis as {man} looks down toward her."
)
if man_gives and not woman_gives:
return f"{woman} lies on her back with thighs open while {man} kneels between her legs with his mouth pressed to her pussy."
return f"{woman} kneels in front of {man}'s hips and takes his penis in her mouth while {man} keeps his hips aligned with her face."
if people_count == 1:
solo = people[0]
if women_count == 1:
@@ -480,7 +387,7 @@ def build_hardcore_role_graph(
elif "outercourse" in slug:
graph = build_outercourse_role_graph(woman, man, item_text, item_axis_values, pov_labels)
elif "oral" in slug:
graph = oral_position_graph(woman, man)
graph = build_oral_role_graph(woman, man, item_text, item_axis_values, pov_labels)
elif "anal" in slug or "double" in slug:
if "double" in item_text or "toy" in item_text:
if people_count >= 3: