Compare commits

..

No commits in common. "aff54b38ed5814b7e57cc31a1b354a4e44746164" and "66db5acc76904b92761fdbe0b4faf741022ab724" have entirely different histories.

6 changed files with 111 additions and 222 deletions

View File

@ -9,7 +9,8 @@ THIS IS A PORT OF [Gankra/cargo-mommy](https://github.com/Gankra/cargo-mommy)
# TODO # TODO
- make compatibility with https://github.com/Gankra/cargo-mommy/blob/main/responses.json - edit executable in .venv/pyenv.cfg
- link it to a mommy wrapper
# Installation # Installation

View File

@ -15,7 +15,6 @@ license-files = ["LICENSE"]
[project.scripts] [project.scripts]
python-mommy-dev = "python_mommy_venv.__main__:development" python-mommy-dev = "python_mommy_venv.__main__:development"
python-mommy-generate-config = "python_mommy_venv.__main__:write_current_config"
mommify-venv = "python_mommy_venv.__main__:mommify_venv" mommify-venv = "python_mommy_venv.__main__:mommify_venv"
[build-system] [build-system]

View File

@ -6,18 +6,22 @@ import os
import re import re
import signal import signal
from .config import get_mood, get_template_values from .config import CONFIG
from .static import RESPONSES, Situation, colors from .static import RESPONSES, Situation, colors
def _expand_template(template: str) -> str:
for key, value in CONFIG.items():
template = template.replace(key, random.choice(value))
return template + " " + random.choice(CONFIG["MOMMYS_EMOTES"])
def get_response(situation: Situation, colorize: Optional[bool] = None): def get_response(situation: Situation, colorize: Optional[bool] = None):
if colorize is None: if colorize is None:
colorize = sys.stdout.isatty() colorize = sys.stdout.isatty()
# get message # get message
mood = get_mood() possible_templates = RESPONSES[random.choice(CONFIG["MOMMYS_MOODS"])][situation]
template = random.choice(RESPONSES[mood][situation]) message = _expand_template(random.choice(possible_templates))
message = template.format(**get_template_values(mood))
# return message # return message
if not colorize: if not colorize:

View File

@ -2,11 +2,8 @@ import sys
from pathlib import Path from pathlib import Path
import stat import stat
import toml
from . import get_response from . import get_response
from .static import Situation from .static import Situation
from .config import CONFIG_FILES, CONFIG_DIRECTORY, generate_current_configuration
def development(): def development():
@ -14,21 +11,9 @@ def development():
if len(sys.argv) > 1: if len(sys.argv) > 1:
s = sys.argv[1] s = sys.argv[1]
print(get_response(Situation(s))) print(get_response(Situation(s)))
def write_current_config():
f = "python-mommy.toml"
if len(sys.argv) > 1:
f = sys.argv[1]
config_file = CONFIG_DIRECTORY / f
print(f"writing to: {config_file}")
data = toml.dumps(generate_current_configuration())
print(data)
with config_file.open("w") as f:
f.write(data)
TEMPLATE = """#!{inner_bin} TEMPLATE = """#!{inner_bin}
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-

View File

@ -1,11 +1,11 @@
from typing import Optional, List, Dict, Union from typing import Optional, List
import os import os
from os.path import expandvars from os.path import expandvars
from sys import platform from sys import platform
import logging import logging
from pathlib import Path from pathlib import Path
import configparser
import toml import toml
import random
from .static import RESPONSES from .static import RESPONSES
@ -16,60 +16,64 @@ PREFIXES = [
"CARGO", "CARGO",
] ]
def _get_var(key: str, fallback: str) -> List[str]:
value = os.environ.get(
PREFIXES[0] + "_" + key,
os.environ.get(
key,
None
)
)
# env key is just a backup key for compatibility with cargo mommy if value is None:
CONFIG = { for prefix in PREFIXES[1:]:
"mood": { value = os.environ.get(prefix + "_" + key, None)
"defaults": ["chill"] if value != None:
}, break
"emote": {
"defaults": ["❤️", "💖", "💗", "💓", "💞"] return (value or fallback).split("/")
},
"pronoun": {
"defaults": ["her"] _DEFAULT_CONFIG = {key: _get_var(key, value) for key, value in {
}, "MOMMYS_ROLE": "mommy",
"role": { "MOMMYS_PRONOUNS": "her",
"defaults": ["mommy"] "MOMMYS_LITTLE": "girl",
}, "MOMMYS_EMOTES": "❤️/💖/💗/💓/💞",
"affectionate_term": { "MOMMYS_PARTS": "milk",
"defaults": ["girl"], "MOMMYS_FUCKING": "slut/toy/pet/pervert/whore",
"env_key": "LITTLE" # needs validation
}, "MOMMYS_MOODS": "chill",
"denigrating_term": { }.items()}
"spiciness": "yikes",
"defaults": ["slut", "toy", "pet", "pervert", "whore"], CONFIG = {}
"env_key": "FUCKING"
}, def load_config(data: Optional[dict] = None):
"part": { global CONFIG
"spiciness": "yikes", data = data if data is not None else {}
"defaults": ["milk"]
} data = {
**_DEFAULT_CONFIG,
**data,
} }
MOOD_PRIORITIES: Dict[str, int] = {} # convert toml keys from snake_case to UPPER_CASE
for i, mood in enumerate(RESPONSES): data = {
MOOD_PRIORITIES[mood] = i key.upper(): value
for key, value in data.items()
}
PREFIXES = [ # validate needed values
"PYTHON", # first one is always the prefix of the current program unfiltered_moods = data["MOMMYS_MOODS"]
"CARGO", data["MOMMYS_MOODS"] = filtered_moods = []
] for mood in unfiltered_moods:
if mood in RESPONSES:
filtered_moods.append(mood)
else:
logger.warning("mood %s isn't supported", mood)
for key, value in CONFIG.items(): CONFIG = data
env_keys = [
PREFIXES[0] + "_MOMMY_" + key.upper(),
"MOMMY_" + key.upper(),
*(p + "_MOMMY_" + key.upper() for p in PREFIXES)
]
if value.get("env_key") is not None:
env_keys.append(value.get("env_key"))
for env_key in env_keys:
res = os.environ.get(env_key)
if res is not None:
value["default"] = res.split("/")
load_config()
def _get_xdg_config_dir() -> Path: def _get_xdg_config_dir() -> Path:
res = os.environ.get("XDG_CONFIG_HOME") res = os.environ.get("XDG_CONFIG_HOME")
@ -119,25 +123,19 @@ def _get_xdg_config_dir() -> Path:
return default return default
CONFIG_DIRECTORY = _get_xdg_config_dir() / "mommy" _CONFIG_DIRECTORY = _get_xdg_config_dir() / "mommy"
CONFIG_FILES = [ CONFIG_FILES = [
CONFIG_DIRECTORY / "python-mommy.toml", _CONFIG_DIRECTORY / "python-mommy.toml",
CONFIG_DIRECTORY / "mommy.toml", _CONFIG_DIRECTORY / "mommy.toml",
] ]
def load_config_file(config_file: Path) -> bool: def load_config_file(config_file: Path) -> bool:
global CONFIG
if not config_file.exists(): if not config_file.exists():
return False return False
with config_file.open("r") as f: with config_file.open("r") as f:
data = toml.load(f) data = toml.load(f)
load_config(data=data)
for key, value in data.items():
if isinstance(value, str):
CONFIG[key]["defaults"] = [value]
else:
CONFIG[key]["defaults"] = value
return True return True
@ -145,49 +143,3 @@ def load_config_file(config_file: Path) -> bool:
for c in CONFIG_FILES: for c in CONFIG_FILES:
if load_config_file(c): if load_config_file(c):
break break
# validate config file
if True:
unfiltered_moods = CONFIG["mood"]["defaults"]
CONFIG["mood"]["defaults"] = filtered_moods = []
for mood in unfiltered_moods:
if mood in RESPONSES:
filtered_moods.append(mood)
else:
logger.warning("mood %s isn't supported", mood)
def get_mood() -> str:
return random.choice(CONFIG["mood"]["defaults"])
def get_template_values(mood: str) -> Dict[str, str]:
mood_spice_level = MOOD_PRIORITIES[mood]
result = {}
for key, value in CONFIG.items():
spice = value.get("spiciness")
allow_key = spice is None
if not allow_key:
key_spice_level = MOOD_PRIORITIES[spice]
allow_key = mood_spice_level >= key_spice_level
if not allow_key:
continue
result[key] = random.choice(value["defaults"])
return result
def generate_current_configuration() -> Dict[str, Union[str, List[str]]]:
global CONFIG
generated = {}
for key, definition in CONFIG.items():
value = definition["defaults"]
if len(value) == 1:
value = value[0]
generated[key] = value
return generated

View File

@ -1,11 +1,8 @@
from __future__ import annotations
from enum import Enum from enum import Enum
class Situation(Enum): class Situation(Enum):
POSITIVE = "positive" POSITIVE = "positive"
NEGATIVE = "negative" NEGATIVE = "negative"
OVERFLOW = "overflow "
RESPONSES = { RESPONSES = {
"chill": { "chill": {
@ -13,121 +10,72 @@ RESPONSES = {
"*pets your head*", "*pets your head*",
"*gives you scritches*", "*gives you scritches*",
"you're such a smart cookie~", "you're such a smart cookie~",
"that's a good {affectionate_term}~", "that's a good MOMMYS_LITTLE~",
"{role} thinks {pronoun} little {affectionate_term} earned a big hug~", "MOMMYS_ROLE thinks MOMMYS_PRONOUNS little MOMMYS_LITTLE earned a big hug~",
"good {affectionate_term}~\n{role}'s so proud of you~", "good MOMMYS_LITTLE~\nMOMMYS_ROLE's so proud of you~",
"aww, what a good {affectionate_term}~\n{role} knew you could do it~", "aww, what a good MOMMYS_LITTLE~\nMOMMYS_ROLE knew you could do it~",
"you did it~!", "you did it~!",
"{role} loves you~", "MOMMYS_ROLE loves you~",
"*gives you a sticker*", "*gives you a sticker*"
"*boops your nose*",
"*wraps you in a big hug*",
"well done~!\n{role} is so happy for you~",
"what a good {affectionate_term} you are~",
"that's {role}'s clever little {affectionate_term}~",
"you're doing so well~!",
"you're making {role} so happy~",
"{role} loves {pronoun} cute little {affectionate_term}~"
], ],
Situation.NEGATIVE: [ Situation.NEGATIVE: [
"{role} believes in you~", "MOMMYS_ROLE believes in you~",
"don't forget to hydrate~", "don't forget to hydrate~",
"aww, you'll get it next time~", "aww, you'll get it next time~",
"do you need {role}'s help~?", "do you need MOMMYS_ROLE's help~?",
"everything's gonna be ok~", "MOMMYS_ROLE still loves you no matter what~",
"{role} still loves you no matter what~", "oh no did MOMMYS_ROLE's little MOMMYS_LITTLE make a big mess~?",
"oh no did {role}'s little {affectionate_term} make a big mess~?", "MOMMYS_ROLE knows MOMMYS_PRONOUNS little MOMMYS_LITTLE can do better~",
"{role} knows {pronoun} little {affectionate_term} can do better~", "MOMMYS_ROLE still loves you~",
"{role} still loves you~", "just a little further, sweetie~"
"{role} thinks {pronoun} little {affectionate_term} is getting close~",
"it's ok, {role}'s here for you~",
"oh, darling, you're almost there~",
"does {role}'s little {affectionate_term} need a bit of a break~?",
"oops~! {role} loves you anyways~",
"try again for {role}, {affectionate_term}~",
"don't worry, {role} knows you can do it~"
],
Situation.OVERFLOW: [
"{role} has executed too many times and needs to take a nap~"
]
},
"ominous": {
Situation.POSITIVE: [
"What you have set in motion today will be remembered for aeons to come!",
"{role} will see to it that {pronoun} little {affectionate_term}'s name is feared~",
"{role} is proud of the evil seed {pronoun} {affectionate_term} has planted into this accursed world"
],
Situation.NEGATIVE: [
"Ah, failure? {role} will make sure the stars are right next time",
"Does {role}'s little {affectionate_term} need more time for worship~?",
"May the mark of the beast stain your flesh forever, {role} will haunt your soul forevermore"
],
Situation.OVERFLOW: [
"THOU HAST DRUNK TOO DEEPLY OF THE FONT"
] ]
}, },
"thirsty": { "thirsty": {
"spiciness": "thirsty",
Situation.POSITIVE: [ Situation.POSITIVE: [
"*tugs your leash*\nthat's a VERY good {affectionate_term}~", "*tugs your leash*\nthat's a VERY good MOMMYS_LITTLE~",
"*runs {pronoun} fingers through your hair* good {affectionate_term}~ keep going~", "*runs MOMMYS_PRONOUNS fingers through your hair* good MOMMYS_LITTLE~ keep going~",
"*smooches your forehead*\ngood job~", "*smooches your forehead*\ngood job~",
"*nibbles on your ear*\nthat's right~\nkeep going~", "*nibbles on your ear*\nthat's right~\nkeep going~",
"*pats your butt*\nthat's a good {affectionate_term}~", "*pats your butt*\nthat's a good MOMMYS_LITTLE~",
"*drags {pronoun} nail along your cheek*\nsuch a good {affectionate_term}~", "*drags MOMMYS_PRONOUNS nail along your cheek*\nsuch a good MOMMYS_LITTLE~",
"*bites {pronoun} lip*\nmhmm~", "*bites MOMMYS_PRONOUNS lip*\nmhmm~",
"give {role} a kiss~", "give MOMMYS_PRONOUNS a kiss~",
"*heavy breathing against your neck*" "*heavy breathing against your neck*"
], ],
Situation.NEGATIVE: [ Situation.NEGATIVE: [
"you're so cute when you're flustered~", "do you think you're going to get a reward from MOMMYS_ROLE like that~?",
"do you think you're going to get a reward from {role} like that~?", "*grabs your hair and pulls your head back*\nyou can do better than that for MOMMYS_ROLE can't you~?",
"*grabs your hair and pulls your head back*\nyou can do better than that for {role} can't you~?", "if you don't learn how to code better, MOMMYS_ROLE is going to put you in time-out~",
"if you don't learn how to code better, {role} is going to put you in time-out~", "does MOMMYS_ROLE need to give MOMMYS_PRONOUNS little MOMMYS_LITTLE some special lessons~?",
"does {role} need to give {pronoun} little {affectionate_term} some special lessons~?", "you need to work harder to please MOMMYS_ROLE~",
"you need to work harder to please {role}~",
"gosh you must be flustered~", "gosh you must be flustered~",
"are you just keysmashing now~?\ncute~", "are you just keysmashing now~?\ncute~",
"is {role}'s little {affectionate_term} having trouble reaching the keyboard~?" "is MOMMYS_ROLE's little MOMMYS_LITTLE having trouble reaching the keyboard~?"
],
Situation.OVERFLOW: [
"you've been a bad little {affectionate_term} and worn out {role}~"
] ]
}, },
"yikes": { "yikes": {
"spiciness": "yikes",
Situation.POSITIVE: [ Situation.POSITIVE: [
"keep it up and {role} might let you cum you little {denigrating_term}~", "keep it up and MOMMYS_ROLE might let you cum you little MOMMYS_FUCKING~",
"good {denigrating_term}~\nyou've earned five minutes with the buzzy wand~", "good MOMMYS_FUCKING~\nyou've earned five minutes with the buzzy wand~",
"mmm~ come taste {role}'s {part}~", "mmm~ come taste MOMMYS_ROLE's MOMMYS_PARTS~",
"*slides {pronoun} finger in your mouth*\nthat's a good little {denigrating_term}~", "*slides MOMMYS_PRONOUNS finger in your mouth*\nthat's a good little MOMMYS_FUCKING~",
"you're so good with your fingers~\n{role} knows where {pronoun} {denigrating_term} should put them next~", "you're so good with your fingers~\nMOMMYS_ROLE knows where MOMMYS_PRONOUNS MOMMYS_FUCKING should put them next~",
"{role} is getting hot~", "MOMMYS_ROLE is getting hot~",
"that's a good {denigrating_term}~", "that's a good MOMMYS_FUCKING~",
"yes~\nyes~~\nyes~~~", "yes~\nyes~~\nyes~~~",
"{role}'s going to keep {pronoun} good little {denigrating_term}~", "MOMMYS_ROLE's going to keep MOMMYS_PRONOUNS good little MOMMYS_FUCKING~"
"open wide {denigrating_term}.\nyou've earned {role}'s {part}~",
"do you want {role}'s {part}?\nkeep this up and you'll earn it~",
"oooh~ what a good {denigrating_term} you are~"
], ],
Situation.NEGATIVE: [ Situation.NEGATIVE: [
"you filthy {denigrating_term}~\nyou made a mess, now clean it up~\nwith your tongue~", "you filthy MOMMYS_FUCKING~\nyou made a mess, now clean it up~\nwith your tongue~",
"*picks you up by the throat*\npathetic~", "*picks you up by the throat*\npathetic~",
"*drags {pronoun} claws down your back*\ndo it again~", "*drags MOMMYS_PRONOUNS claws down your back*\ndo it again~",
"*brandishes {pronoun} paddle*\ndon't make me use this~", "*brandishes MOMMYS_PRONOUNS paddle*\ndon't make me use this~",
"{denigrating_term}.\n{denigrating_term}~\n{denigrating_term}~~", "MOMMYS_FUCKING.\nMOMMYS_FUCKING~\nMOMMYS_FUCKING~~",
"get on your knees and beg {role} for forgiveness you {denigrating_term}~", "get on your knees and beg MOMMYS_ROLE for forgiveness you MOMMYS_FUCKING~",
"{role} doesn't think {pronoun} little {denigrating_term} should have permission to wear clothes anymore~", "MOMMYS_ROLE doesn't think MOMMYS_PRONOUNS little MOMMYS_FUCKING should have permission to wear clothes anymore~",
"never forget you belong to {role}~", "never forget you belong to MOMMYS_ROLE~",
"does {role} need to put you in the {denigrating_term} wiggler~?", "does MOMMYS_ROLE need to put you in the MOMMYS_FUCKING wiggler~?",
"{role} is starting to wonder if you should just give up and become {pronoun} breeding stock~", "MOMMYS_ROLE is starting to wonder if you should just give up and become MOMMYS_PRONOUNS breeding stock~"
"on your knees {denigrating_term}~",
"oh dear. {role} is not pleased",
"one spank per error sounds appropriate, don't you think {denigrating_term}?",
"no more {part} for you {denigrating_term}"
],
Situation.OVERFLOW: [
"brats like you don't get to talk to {role}"
] ]
} }
} }