233 lines
7.4 KiB
Python
233 lines
7.4 KiB
Python
from abc import ABC, abstractmethod
|
||
import random
|
||
|
||
from uwuipy import Uwuipy
|
||
|
||
|
||
class MutatorRegistry:
|
||
"""
|
||
Registry for tracking and retrieving mutators.
|
||
"""
|
||
|
||
def __init__(self):
|
||
self._registry = {}
|
||
|
||
def register(self, name: str, mutator_class):
|
||
self._registry[name] = mutator_class
|
||
|
||
def get_mutator(self, name: str, *args, **kwargs):
|
||
mutator_class = self._registry.get(name)
|
||
if mutator_class is None:
|
||
raise ValueError(f"Mutator '{name}' not found in registry.")
|
||
return mutator_class(*args, **kwargs)
|
||
|
||
|
||
class TextMutator(ABC):
|
||
"""
|
||
Mutates given text.
|
||
"""
|
||
|
||
@abstractmethod
|
||
def mutate(self, text: str) -> str:
|
||
pass
|
||
|
||
|
||
class Uwuify(TextMutator):
|
||
"""
|
||
Returns an 'uwuified' version of any given text.
|
||
"""
|
||
|
||
def mutate(self, text: str, nsfw=False) -> str:
|
||
uwu = Uwuipy(None, 0.1, 0.05, 0.075, 1, nsfw, 2)
|
||
return uwu.uwuify(text)
|
||
|
||
|
||
class UwuifyNSFW(TextMutator):
|
||
""""""
|
||
|
||
def mutate(self, text: str) -> str:
|
||
return Uwuify().mutate(text, nsfw=True)
|
||
|
||
|
||
class Gibberish(TextMutator):
|
||
def mutate(self, text: str) -> str:
|
||
return " ".join(["".join(random.sample(word, len(word))) for word in text.split()])
|
||
|
||
|
||
class LeetSpeak(TextMutator):
|
||
def mutate(self, text: str) -> str:
|
||
return "".join(self.leet_map.get(char.lower(), char) for char in text.upper())
|
||
|
||
|
||
class ReverseText(TextMutator):
|
||
def mutate(self, text: str) -> str:
|
||
return text[::-1]
|
||
|
||
|
||
class ShuffleWords(TextMutator):
|
||
def mutate(self, text: str) -> str:
|
||
words = text.split()
|
||
random.shuffle(words)
|
||
return " ".join(words)
|
||
|
||
|
||
class PigLatin(TextMutator):
|
||
def mutate(self, text: str) -> str:
|
||
return " ".join([self._pig_latin_word(word) for word in text.split()])
|
||
|
||
def _pig_latin_word(self, word: str) -> str:
|
||
for i, char in enumerate(word):
|
||
if char not in "aeiou":
|
||
continue
|
||
|
||
return word + "way" if i == 0 else word[i:] + word[:i] + "ay"
|
||
|
||
return word + "way"
|
||
|
||
|
||
class RandomiseCase(TextMutator):
|
||
def mutate(self, text: str) -> str:
|
||
return "".join(char.upper() if random.random() > .5 else char.lower() for char in text)
|
||
|
||
|
||
class UpsideDown(TextMutator):
|
||
_upside_down_dict = str.maketrans(
|
||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890,.!?\"'",
|
||
"ɐqɔpǝɟƃɥᴉɾʞlɯuodbɹsʇnʌʍxʎz∀BↃᗡƎℲ⅁HIſ⋊⅃WNOԀΌᴚS⊥∩ΛMX⅄Z⇂2Ɛᔭ59Ɫ860˙‘¡¿,'"
|
||
)
|
||
|
||
def mutate(self, text: str) -> str:
|
||
return text.translate(self._upside_down_dict)[::-1]
|
||
|
||
|
||
class GothicScript(TextMutator):
|
||
_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': 'ℨ'
|
||
}
|
||
|
||
def mutate(self, text: str) -> str:
|
||
return "".join(self._gothic_dict.get(char, char) for char in text)
|
||
|
||
|
||
class EmojiSubstitution(TextMutator):
|
||
_emoji_dict = {} # TODO:
|
||
|
||
def mutate(self, text: str) -> str:
|
||
return "".join(self._emoji_dict.get(char.lower(), char) for char in text)
|
||
|
||
|
||
class SmallCaps(TextMutator):
|
||
def mutate(self, text: str) -> str:
|
||
return "".join(self._small_cap(char) for char in text)
|
||
|
||
@staticmethod
|
||
def _small_cap(char: str) -> str:
|
||
if "a" <= char <= "z":
|
||
return chr(ord(char) + 0x1D00 - ord("a"))
|
||
elif "A" <= char <= "Z":
|
||
return chr(ord(char) + 0x1D00 - ord("A"))
|
||
else:
|
||
return char
|
||
|
||
|
||
class Zalgo(TextMutator):
|
||
_zalgo_chars = [chr(random.randint(768, 879)) for _ in range(3)]
|
||
|
||
def mutate(self, text: str) -> str:
|
||
return "".join(
|
||
char + "".join(random.choices(self._zalgo_chars, k=random.randint(1, 3))) for char in text
|
||
)
|
||
|
||
|
||
class MorseCode(TextMutator):
|
||
_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 mutate(self, text: str) -> str:
|
||
return " ".join(self._morse_code_dict.get(char.upper(), char) for char in text)
|
||
|
||
|
||
class ToBinary(TextMutator):
|
||
def mutate(self, text: str) -> str:
|
||
return " ".join(format(ord(c), '08b') for c in text)
|
||
|
||
|
||
class ToHexadecimal(TextMutator):
|
||
def mutate(self, text: str) -> str:
|
||
return " ".join(format(ord(c), '02x') for c in text)
|
||
|
||
|
||
class RemoveVowels(TextMutator):
|
||
def mutate(self, text: str) -> str:
|
||
return "".join(char for char in text if char.lower() not in "aeiou")
|
||
|
||
|
||
class DoubleCharacters(TextMutator):
|
||
def mutate(self, text: str) -> str:
|
||
return "".join(char*2 for char in text)
|
||
|
||
|
||
class BabyTalk(TextMutator):
|
||
def mutate(self, 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)
|
||
|
||
|
||
class BackwardsWords(TextMutator):
|
||
def mutate(self, text: str) -> str:
|
||
" ".join(word[::-1] for word in text.split())
|
||
|
||
|
||
class ShakeSpearean(TextMutator):
|
||
_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'
|
||
}
|
||
|
||
def mutate(self, text: str) -> str:
|
||
return " ".join(self._shakespearean_dict.get(word.lower(), word) for word in text.split())
|
||
|
||
|
||
registry = MutatorRegistry()
|
||
|
||
r = registry # shorthand, im not repeating this one hundred times
|
||
r.register("uwuify", Uwuify)
|
||
r.register("uwuify_nsfw", UwuifyNSFW)
|
||
r.register("gibberish", Gibberish)
|
||
r.register("leet_speak", LeetSpeak)
|
||
r.register("reverse_text", ReverseText)
|
||
r.register("shuffle_words", ShuffleWords)
|
||
r.register("pig_latin", PigLatin)
|
||
r.register("rnd_case", RandomiseCase)
|
||
r.register("flipped", UpsideDown)
|
||
r.register("gothic", GothicScript)
|
||
r.register("emj_substitute", EmojiSubstitution)
|
||
r.register("small_caps", SmallCaps)
|
||
r.register("zalgo", Zalgo)
|
||
r.register("morse_code", MorseCode)
|
||
r.register("to_bin", ToBinary)
|
||
r.register("to_hex", ToHexadecimal)
|
||
r.register("rm_vowels", RemoveVowels)
|
||
r.register("dbl_chars", DoubleCharacters)
|
||
r.register("backwards_words", BackwardsWords)
|
||
r.register("shakespear", ShakeSpearean)
|
||
# r.register("", )
|