simplified + added mutators

This commit is contained in:
Corban-Lee Jones 2024-06-19 00:37:58 +01:00
parent 745fda9bbe
commit bdc32ac5fa
2 changed files with 312 additions and 62 deletions

View File

@ -16,7 +16,7 @@ from sqlalchemy import select, insert, delete, and_
from sqlalchemy.exc import NoResultFound
from textwrap import shorten
import mutators
from mutators import mutator_map
from errors import IllegalFeed
from db import DatabaseManager, RssSourceModel, FeedChannelModel
from utils import get_rss_data, get_unparsed_feed
@ -69,55 +69,21 @@ class Article:
)
def mutate(self, mutator: dict):
"""
Apply a mutation to a certain text attribute of
this Article instance.
"""
log.debug("Applying mutator '%s'", mutator["name"])
match mutator["value"]:
mutator_value = mutator["value"]
case "UWU_TITLE":
self.title = mutators.uwu(self.title)
case "UWU_DESC":
self.description = mutators.uwu(self.description)
case "GIB_TITLE":
self.title = mutators.gibberish(self.title)
case "GIB_DESC":
self.description = mutators.gibberish(self.description)
case "L3_TITLE":
self.title = mutators.leet(self.title)
case "L3_DESC":
self.description = mutators.leet(self.description)
case "REV_TITLE":
self.title = mutators.reverse(self.title)
case "REV_DESC":
self.description = mutators.reverse(self.description)
case "RND_TITLE":
self.title = mutators.shuffle(self.title)
case "RND_DESC":
self.description = mutators.shuffle(self.description)
case "PGL_TITLE":
self.title = mutators.pig_latin(self.title)
case "PGL_DESC":
self.description = mutators.pig_latin(self.description)
case "RCS_TITLE":
self.title = mutators.random_case(self.title)
case "RCS_DESC":
self.description = mutators.random_case(self.description)
case _:
log.warn("Unknown mutator value '%s', skipping", mutator["value"])
if mutator_value in mutator_map:
attr, func = mutator_map[mutator_value]
setattr(self, attr, func(getattr(self, attr)))
log.debug("mutated %s, to: %s", attr, getattr(self, attr))
else:
log.warn("Unknown mutator value '%s', skipping", mutator["value"])
async def get_thumbnail_url(self, session: aiohttp.ClientSession) -> str | None:
"""Returns the thumbnail URL for an article.

View File

@ -2,50 +2,334 @@ import random
import uwuify
# For l33t sp34k translation
leet_map = {'a': '4', 'e': '3', 'i': '1', 'o': '0', 's': '5', 't': '7'}
# For upside-down translation
upside_down_dict = str.maketrans(
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890,.!?\"'",
"ɐqɔpǝɟƃɥᴉɾʞlɯuodbɹsʇnʌʍxʎz∀BↃᗡƎℲ⅁HIſ⋊⅃WNOԀΌᴚS⊥∩ΛMX⅄Z⇂2Ɛᔭ59Ɫ860˙¡¿,'"
)
# For gothic script
gothic_dict = {
'a': '𝔞', 'b': '𝔟', 'c': '𝔠', 'd': '𝔡', 'e': '𝔢', 'f': '𝔣', 'g': '𝔤', 'h': '𝔥', 'i': '𝔦', 'j': '𝔧',
'k': '𝔨', 'l': '𝔩', 'm': '𝔪', 'n': '𝔫', 'o': '𝔬', 'p': '𝔭', 'q': '𝔮', 'r': '𝔯', 's': '𝔰', 't': '𝔱',
'u': '𝔲', 'v': '𝔳', 'w': '𝔴', 'x': '𝔵', 'y': '𝔶', 'z': '𝔷', 'A': '𝔄', 'B': '𝔅', 'C': '', 'D': '𝔇',
'E': '𝔈', 'F': '𝔉', 'G': '𝔊', 'H': '', 'I': '', 'J': '𝔍', 'K': '𝔎', 'L': '𝔏', 'M': '𝔐', 'N': '𝔑',
'O': '𝔒', 'P': '𝔓', 'Q': '𝔔', 'R': '', 'S': '𝔖', 'T': '𝔗', 'U': '𝔘', 'V': '𝔙', 'W': '𝔚', 'X': '𝔛',
'Y': '𝔜', 'Z': ''
}
# For emoji substitution
emoji_dict = {
'a': '🅰️', 'b': '🅱️', 'c': '🌜', 'd': '🌛', 'e': '📧', 'f': '🎏', 'g': '🌀', 'h': '', 'i': '',
'j': '🎷', 'k': '🎋', 'l': '👢', 'm': 'Ⓜ️', 'n': '', 'o': '', 'p': '🅿️', 'q': '🍳', 'r': '🌱',
's': '💲', 't': '🌴', 'u': '', 'v': '', 'w': '🔱', 'x': '', 'y': '🍸', 'z': ''
}
# For Zalgo translation
zalgo_chars = [chr(random.randint(768, 879)) for _ in range(3)]
# For morse code translation
morse_code_dict = {
'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', 'F': '..-.', 'G': '--.', 'H': '....',
'I': '..', 'J': '.---', 'K': '-.-', 'L': '.-..', 'M': '--', 'N': '-.', 'O': '---', 'P': '.--.',
'Q': '--.-', 'R': '.-.', 'S': '...', 'T': '-', 'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-',
'Y': '-.--', 'Z': '--..', '1': '.----', '2': '..---', '3': '...--', '4': '....-', '5': '.....',
'6': '-....', '7': '--...', '8': '---..', '9': '----.', '0': '-----', ',': '--..--', '.': '.-.-.-',
'?': '..--..', '/': '-..-.', '-': '-....-', '(': '-.--.', ')': '-.--.-', ' ': '/'
}
def uwu(text: str) -> str:
"""
Returns an 'uwuified' version of the given string.
"""
return uwuify.uwu(text)
def gibberish(text: str) -> str:
"""
Returns a given string, but each character is randomy re-ordered.
"""
return " ".join(["".join(
random.sample(word, len(word)))
for word in text.split()
])
def leet(text: str) -> str:
"""
Translates a given string into 'l33t sp34k' and returns it.
"""
return "".join([
leet_map.get(char.lower(), char)
for char in text
for char in text.upper()
])
def reverse(text: str) -> str:
"""
Returns the passed string in reverse.
"""
return text[::-1]
def shuffle(text: str) -> str:
"""
Returns a given string, where each word is randomly shuffled.
"""
words = text.split()
random.shuffle(words)
return " ".join(words)
def _pig_latin_word(word: str) -> str:
first_vowel = 0
for char in word:
if char in "aeiou":
break
first_vowel += 1
if first_vowel == 0:
return word + "way"
else:
return word[first_vowel:] + word[:first_vowel] + "ay"
def pig_latin(text: str) -> str:
"""
Takes a given string, translates it to 'pig latin' and returns it.
"""
def _pig_latin_word(word: str) -> str:
first_vowel = 0
for char in word:
if char in "aeiou":
break
first_vowel += 1
if first_vowel == 0:
return word + "way"
else:
return word[first_vowel:] + word[:first_vowel] + "ay"
return " ".join([_pig_latin_word(word) for word in text.split()])
def random_case(text: str) -> str:
"""
Randomly converts each character of a given string to upper
or lower case, and returns the result.
"""
return "".join([
char.upper() if random.random() > 0.5 else char.lower()
for char in text
])
])
def upside_down_text(text: str) -> str:
"""
Returns an upside-down translation of the given string.
"""
return text.translate(upside_down_dict)[::-1]
def gothic_script(text: str) -> str:
"""
Returns a 'gothic script' version of the given string.
"""
return ''.join(gothic_dict.get(c, c) for c in text)
def emoji_substitution(text: str) -> str:
"""
Uses an emoji substitution sipher on the given string,
and returns the result.
"""
return ''.join(emoji_dict.get(c.lower(), c) for c in text)
def small_caps(text: str) -> str:
"""
Translates a given string to it's small caps ascii counterpart,
and returns the result.
"""
def _to_small_caps(c: str) -> str:
if "a" <= c <= "z":
return chr(ord(c) + 0x1D00 - ord("a"))
elif "A" <= c <= "Z":
return chr(ord(c) + 0x1D00 - ord("A"))
else:
return c
return ''.join(_to_small_caps(c) for c in text)
def zalgo(text: str) -> str:
return "".join(
c + "".join(random.choices(
zalgo_chars, k=random.randint(1, 3)
)) for c in text
)
def morse_code(text: str) -> str:
return " ".join(morse_code_dict.get(c.upper(), c) for c in text)
def to_binary(text: str) -> str:
return ' '.join(format(ord(c), '08b') for c in text)
def to_hexadecimal(text: str) -> str:
return ' '.join(format(ord(c), '02x') for c in text)
def remove_vowels(text: str) -> str:
return ''.join(c for c in text if c.lower() not in 'aeiou')
def double_characters(text: str) -> str:
return ''.join(c*2 for c in text)
def randomly_inserted_emoji(text: str) -> str:
emojis = ['😀', '😂', '😍', '😎', '😊', '😜']
return ' '.join(word + random.choice(emojis) for word in text.split())
def baby_talk(text: str) -> str:
replacements = {'r': 'w', 'l': 'w', 'th': 'd', 'u': 'oo'}
baby_text = []
for word in text.split():
for k, v in replacements.items():
word = word.replace(k, v)
baby_text.append(word)
return " ".join(baby_text)
def pirate_speak(text: str) -> str:
replacements = {'hello': 'ahoy', 'my': 'me', 'friend': 'matey', 'is': 'be', 'am': 'be', 'are': 'be'}
pirate_text = [
replacements.get(word.lower(), word)
for word in text.split()
]
return " ".join(pirate_text) + ", arrr!"
def valley_girl(text: str) -> str:
valley_text = []
for word in text.split():
valley_text.append(word)
if random.random() < 0.3:
valley_text.append("like")
return ' '.join(valley_text) + ", you know?"
def degeneracy(text: str) -> str:
cute_phrases = ['kawaii', 'nya~', 'uwu', '^_^', 'rawr']
cute_text = []
for word in text.split():
cute_text.append(word)
if random.random() < 0.3:
cute_text.append(random.choice(cute_phrases))
return " ".join(cute_text)
def cat_speak(text: str) -> str:
cat_text = []
for word in text.split():
cat_text.append(word)
if random.random() < 0.3:
cat_text.append('meow')
return " ".join(cat_text)
def nerdify(text: str) -> str:
nerdy_phrases = ['quark', 'photon', 'nanobot', 'AI', 'quantum', 'algorithm']
words = text.split()
return ' '.join(word + random.choice(nerdy_phrases) if random.random() < 0.3 else word for word in words)
def backward_words(text: str) -> str:
return ' '.join(word[::-1] for word in text.split())
def random_gibberish(text: str) -> str:
gibberish_words = ['blorpy', 'snorf', 'flibber', 'zoodle', 'womp', 'glarb']
words = text.split()
return ' '.join(random.choice(gibberish_words) if random.random() < 0.3 else word for word in words)
def insert_random_animal_sounds(text: str) -> str:
animal_sounds = ['moo', 'oink', 'meow', 'woof', 'quack', 'neigh']
result = []
for word in text.split():
result.append(word)
if random.random() < 0.3:
result.append(random.choice(animal_sounds))
return ' '.join(result)
def shakespearean_speak(text: str) -> str:
shakespearean_dict = {
'you': 'thou', 'your': 'thy', 'you\'re': 'thou art', 'are': 'art', 'am': 'am', 'is': 'is', 'have': 'hast',
'will': 'wilt', 'today': 'this day', 'hello': 'hail', 'goodbye': 'farewell'
}
words = text.split()
return ' '.join(shakespearean_dict.get(word.lower(), word) for word in words)
def robot_speak(text: str) -> str:
robot_noises = ['beep', 'boop', 'whirr', 'click', 'buzz']
words = text.split()
return ' '.join(random.choice(robot_noises) if word.isalpha() and random.random() < 0.2 else word for word in words)
def emojify(text: str) -> str:
emoji_dict = {
'happy': '😄', 'sad': '😢', 'angry': '😡', 'love': '❤️', 'laugh': '😂', 'cry': '😭', 'sleepy': '😴',
'surprise': '😮', 'cool': '😎', 'fire': '🔥', 'party': '🎉', 'star': ''
}
words = text.split()
return ' '.join(emoji_dict.get(word.lower(), word) for word in words)
# Maps instructions for an Article item to mutate attributes.
mutator_map = {
"UWU_TITLE": ("title", uwu),
"UWU_DESC": ("description", uwu),
"GIB_TITLE": ("title", gibberish),
"GIB_DESC": ("description", gibberish),
"L3_TITLE": ("title", leet),
"L3_DESC": ("description", leet),
"REV_TITLE": ("title", reverse),
"REV_DESC": ("description", reverse),
"RND_TITLE": ("title", shuffle),
"RND_DESC": ("description", shuffle),
"PGL_TITLE": ("title", pig_latin),
"PGL_DESC": ("description", pig_latin),
"RNC_TITLE": ("title", random_case),
"RNC_DESC": ("description", random_case),
"UDT_TITLE": ("title", upside_down_text),
"UDT_DESC": ("description", upside_down_text),
"GS_TITLE": ("title", gothic_script),
"GS_DESC": ("description", gothic_script),
"EMJ_TITLE": ("title", emoji_substitution),
"EMJ_DESC": ("description", emoji_substitution),
"SML_TITLE": ("title", small_caps),
"SML_DESC": ("description", small_caps),
"ZGO_TITLE": ("title", zalgo),
"ZGO_DESC": ("description", zalgo),
"MC_TITLE": ("title", morse_code),
"MC_DESC": ("description", morse_code),
"BIN_TITLE": ("title", to_binary),
"BIN_DESC": ("description", to_binary),
"HEX_TITLE": ("title", to_hexadecimal),
"HEX_DESC": ("description", to_hexadecimal),
"RMV_TITLE": ("title", remove_vowels),
"RMV_DESC": ("description", remove_vowels),
"DBL_TITLE": ("title", double_characters),
"DBL_DESC": ("description", double_characters),
"RNE_TITLE": ("title", randomly_inserted_emoji),
"RNE_DESC": ("description", randomly_inserted_emoji),
"PIR_TITLE": ("title", pirate_speak),
"PIR_DESC": ("description", pirate_speak),
"VAL_TITLE": ("title", valley_girl),
"VAL_DESC": ("description", valley_girl),
"DEG_TITLE": ("title", degeneracy),
"DEG_DESC": ("description", degeneracy),
"CAT_TITLE": ("title", cat_speak),
"CAT_DESC": ("description", cat_speak),
"NRD_TITLE": (),
"NRD_DESC": (),
"BKW_TITLE": (),
"BKW_DESC": (),
"RNG_TITLE": (),
"RNG_DESC": (),
"RAS_TITLE": (),
"RAS_DESC": (),
"SHK_TITLE": (),
"SHK_DESC": (),
"RBT_TITLE": (),
"RBT_DESC": (),
"EMI_TITLE": (),
"EMI_DESC": (),
}