Hyphonical/MCP-Utilities
4
1from itertools import permutations2from pymongo import MongoClient3from collections import Counter4from dotenv import load_dotenv5from Purify import PurifyHtml6from typing import Literal7from bson import ObjectId8from io import StringIO9import statistics10import datetime11import requests12import hashlib13import random14import base6415import gradio16import string17import json18import sys19import os20 21load_dotenv()22MemoryPassword = os.getenv('MEMORY_PASSWORD')23MongoURI = os.getenv('MONGO_URI')24DatabaseName = 'MCP-Utilities'25CollectionName = 'Memories'26Headers = {27 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'28}29 30Categories = {31 'Any Category': 'any',32 'General Knowledge': '9',33 'Entertainment: Books': '10',34 'Entertainment: Film': '11',35 'Entertainment: Music': '12',36 'Entertainment: Musicals & Theatres': '13',37 'Entertainment: Television': '14',38 'Entertainment: Video Games': '15',39 'Entertainment: Board Games': '16',40 'Science & Nature': '17',41 'Science: Computers': '18',42 'Science: Mathematics': '19',43 'Mythology': '20',44 'Sports': '21',45 'Geography': '22',46 'History': '23',47 'Politics': '24',48 'Art': '25',49 'Celebrities': '26',50 'Animals': '27',51 'Vehicles': '28',52 'Entertainment: Comics': '29',53 'Science: Gadgets': '30',54 'Entertainment: Japanese Anime & Manga': '31',55 'Entertainment: Cartoon & Animations': '32'56}57 58Difficulties = {59 'Any Difficulty': 'any',60 'Easy': 'easy',61 'Medium': 'medium',62 'Hard': 'hard'63}64 65EightBallResponses = {66 'Affirmative': [67 'It is certain.',68 'It is decidedly so.',69 'Without a doubt.',70 'Yes - definitely.',71 'You may rely on it.',72 'As I see it, yes.',73 'Most likely.',74 'Outlook good.',75 'Yes.',76 'Signs point to yes.'77 ],78 'Non-committal': [79 'Reply hazy, try again.',80 'Ask again later.',81 'Better not tell you now.',82 'Cannot predict now.',83 'Concentrate and ask again.'84 ],85 'Negative': [86 'Don\'t count on it.',87 'My sources say no.',88 'Very doubtful.',89 'Outlook not so good.',90 'My reply is no.'91 ]92}93 94try:95 Client = MongoClient(MongoURI)96 Database = Client[DatabaseName]97 Collection = Database[CollectionName]98 Client.server_info()99 print('Connected to MongoDB successfully.')100except Exception as e:101 print(f'Error connecting to MongoDB: {str(e)}')102 Collection = None103 104Theme = gradio.themes.Citrus( # type: ignore105 primary_hue='blue',106 secondary_hue='blue',107 radius_size=gradio.themes.sizes.radius_xxl, # type: ignore108 font=[gradio.themes.GoogleFont('Nunito'), 'Arial', 'sans-serif'] # type: ignore109).set(110 link_text_color='blue'111)112 113# ╭─────────────────────╮114# │ General Tools │115# ╰─────────────────────╯116 117def Weather(Location: str) -> str:118 '''119 Get the current weather for a specified location.120 Args:121 Location (str): The location for which to get the weather. E.g., "London", "France", "50.85045,4.34878" "~NASA"122 Returns:123 str: The current weather.".124 '''125 return requests.get(f'https://wttr.in/{Location}?A&format=4', headers=Headers).text126 127def Date() -> str:128 '''Get the current date and time.129 Returns:130 str: The current date and time in the format "YYYY-MM-DD HH:MM:SS".131 '''132 return datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')133 134def Dice(Sides: int = 6) -> int:135 '''Roll a dice with a specified number of sides.136 Args:137 Sides (int): The number of sides on the dice. Default is 6.138 Returns:139 int: The result of the dice roll.140 '''141 return random.randint(1, Sides)142 143def CoinFlip() -> str:144 '''Flip a coin and return the result.145 Returns:146 str: "Heads" or "Tails".147 '''148 return random.choice(['Heads', 'Tails'])149 150def Math(Num1: float, Num2: float, Operation: Literal['add', 'subtract', 'multiply', 'divide', 'modulus', 'exponent']) -> float | str:151 '''Perform a mathematical operation on two numbers.152 Args:153 Num1 (float): The first number.154 Num2 (float): The second number.155 Operation (Literal['add', 'subtract', 'multiply', 'divide', 'modulus', 'exponent']): The operation to perform.156 Returns:157 float | str: The result of the operation or an error message.158 '''159 Operations = {160 'add': lambda x, y: x + y,161 'subtract': lambda x, y: x - y,162 'multiply': lambda x, y: x * y,163 'divide': lambda x, y: x / y if y != 0 else 'Error: Division by zero',164 'modulus': lambda x, y: x % y if y != 0 else 'Error: Division by zero',165 'exponent': lambda x, y: x ** y,166 }167 168 if Operation in Operations:169 return Operations[Operation](Num1, Num2)170 else:171 return 'Error: Invalid operation'172 173def TempConversion(Value: float, FromUnit: Literal['Celsius', 'Fahrenheit', 'Kelvin'], ToUnit: Literal['Celsius', 'Fahrenheit', 'Kelvin']) -> float | str:174 '''Convert temperature between Celsius, Fahrenheit, and Kelvin.175 Args:176 Value (float): The temperature value to convert.177 FromUnit (Literal['Celsius', 'Fahrenheit', 'Kelvin']): The unit to convert from.178 ToUnit (Literal['Celsius', 'Fahrenheit', 'Kelvin']): The unit to convert to.179 Returns:180 float | str: The converted temperature value or an error message.181 '''182 if FromUnit == ToUnit:183 return Value184 185 if FromUnit == 'Celsius':186 if ToUnit == 'Fahrenheit':187 return Value * 9/5 + 32188 elif ToUnit == 'Kelvin':189 return Value + 273.15190 elif FromUnit == 'Fahrenheit':191 if ToUnit == 'Celsius':192 return (Value - 32) * 5/9193 elif ToUnit == 'Kelvin':194 return (Value - 32) * 5/9 + 273.15195 elif FromUnit == 'Kelvin':196 if ToUnit == 'Celsius':197 return Value - 273.15198 elif ToUnit == 'Fahrenheit':199 return (Value - 273.15) * 9/5 + 32200 201 return 'Error: Invalid temperature conversion'202 203def CurrencyConversion(Value: float, FromCurrency: str, ToCurrency: str) -> float | str:204 '''Convert currency from one type to another using an online API.205 Args:206 Value (float): The amount of money to convert.207 FromCurrency (str): The currency to convert from (e.g., "USD", "EUR").208 ToCurrency (str): The currency to convert to (e.g., "USD", "EUR").209 Returns:210 float | str: The converted amount or an error message.211 '''212 Raw = requests.get(f'https://api.frankfurter.dev/v1/latest?base={FromCurrency}&symbols={ToCurrency}')213 if Raw.status_code == 200:214 Data = Raw.json()215 return Data['rates'][ToCurrency] * Value216 else:217 return 'Error: Currency conversion failed'218 219def ExecuteCode(Code: str) -> str:220 '''221 Execute Python code and return the output or error message.222 Args:223 Code (str): The Python code to execute.224 Returns:225 str: The output of the executed code or the error message if an exception occurs.226 '''227 OldStdout = sys.stdout228 RedirectedOutput = StringIO()229 sys.stdout = RedirectedOutput230 try:231 Namespace = {}232 exec(Code, Namespace, Namespace)233 Result = RedirectedOutput.getvalue()234 return Result if Result.strip() else 'Code executed successfully (no output).'235 except Exception as e:236 return f'Error: {str(e)}'237 finally:238 sys.stdout = OldStdout239 240def PasswordGenerator(Length: int = 12, IncludeSpecialChars: bool = True, UseDiceware: bool = False) -> str:241 '''Generate a random password.242 Args:243 Length (int): The length of the password to generate. Default is 12.244 IncludeSpecialChars (bool): Whether to include special characters in the password. Default is True.245 UseDiceware (bool): Whether to use Diceware words for the password. Default is False.246 Returns:247 str: The generated password.248 '''249 if UseDiceware:250 with open(r'Data/Diceware.txt', 'r', encoding='utf-8') as DicewareFile:251 Words = DicewareFile.read().splitlines()252 return ' '.join(random.choice(Words) for _ in range(Length))253 254 Characters = string.ascii_letters + string.digits255 if IncludeSpecialChars:256 Characters += string.punctuation257 return ''.join(random.choice(Characters) for _ in range(Length))258 259def Anagram(Text: str) -> str:260 '''Generate an anagram of the input text that is a valid dictionary word.261 Args:262 Text (str): The input text to generate an anagram from.263 Returns:264 str: A generated anagram of the input text.265 '''266 with open(r'Data/Dictionary.txt', 'r', encoding='utf-8') as Database:267 Dictionary = set(word.strip().lower() for word in Database if word.strip())268 269 Letters = [Char.lower() for Char in Text if Char.isalpha()]270 Anagrams = set(''.join(P) for P in permutations(Letters, len(Letters)))271 ValidAnagrams = sorted(word for word in Anagrams if word in Dictionary)272 273 if ValidAnagrams:274 return '\n'.join(ValidAnagrams)275 else:276 return 'No valid anagrams found.'277 278def Ping(Host: str, Count: int = 8) -> str:279 '''Ping a host to check its availability.280 Args:281 Host (str): The host to ping (e.g., "google.com", "192.168.1.1").282 Count (int): The number of ping requests to send. Default is 8.283 Returns:284 str: The result of the ping command.285 '''286 if not Host:287 return 'Error: Host cannot be empty'288 Durations = []289 for _ in range(Count):290 try:291 Start = datetime.datetime.now()292 Response = requests.get(f'http://{Host}', timeout=2, headers=Headers)293 if Response.status_code != 200:294 continue295 End = datetime.datetime.now()296 Durations.append((End - Start).total_seconds() * 1000)297 except requests.RequestException:298 Durations.append(None)299 300 if Durations:301 Durations = [d for d in Durations if d is not None]302 Mean = statistics.mean(Durations)303 Median = statistics.median(Durations)304 return f'Ping to {Host} successful: {Mean} ms (avg), {Median} ms (median)'305 else:306 return f'Ping to {Host} failed: No successful responses'307 308def Purify(Url: str) -> str:309 '''Purify HTML content from a URL.310 Args:311 Url (str): The URL to fetch and purify HTML content from.312 Returns:313 str: The purified HTML content or an error message.314 '''315 316 return PurifyHtml(Url)317 318# ╭───────────────────────────────────╮319# │ Fun and Entertainment Tools │320# ╰───────────────────────────────────╯321 322def Joke(Type: Literal['Any', 'Programming', 'Misc', 'Dark', 'Pun', 'Spooky', 'Christmas']) -> str:323 '''Get a random joke.324 Args:325 Type (Literal['Any', 'Programming', 'Misc', 'Dark', 'Pun', 'Spooky', 'Christmas']): The type of joke to fetch.326 Returns:327 str: A random joke.328 '''329 return requests.get(f'https://v2.jokeapi.dev/joke/{Type}?format=txt', headers=Headers).text330 331def Fact() -> str:332 '''Get a random fact.333 Returns:334 str: A random fact.335 '''336 return requests.get('https://uselessfacts.jsph.pl/random.json?language=en', headers=Headers).json()['text']337 338def Plot(GiveExamplePrompt: bool = True) -> list[str]:339 '''Generate a random plot for a movie or story.340 Args:341 GiveExamplePrompt (bool): If True, returns a random plot prompt from a predefined dataset.342 Returns:343 str: A random plot description.344 '''345 with open(r'Data/human-writing-dpo.json', 'r', encoding='utf-8') as PlotFile:346 Data = json.load(PlotFile)347 Plot = random.choice(Data)348 Prompt = Plot['prompt']349 Chosen = Plot['chosen']350 if GiveExamplePrompt:351 return [Prompt, Chosen]352 else:353 return [Prompt, '']354 355def Trivia(Category: str, Difficulty: str) -> str:356 CategoryParam = f'&category={Categories[Category]}' if Category != 'Any Category' else ''357 DifficultyParam = f'&difficulty={Difficulties[Difficulty]}' if Difficulty != 'Any Difficulty' else ''358 Raw = requests.get(f'https://opentdb.com/api.php?amount=1{CategoryParam}{DifficultyParam}&encode=base64', headers=Headers)359 if Raw.status_code == 200:360 RawBase64 = Raw.json()361 Question = RawBase64['results'][0]['question']362 Question = base64.b64decode(Question).decode('utf-8')363 CorrectAnswer = base64.b64decode(RawBase64['results'][0]['correct_answer']).decode('utf-8')364 IncorrectAnswers = [base64.b64decode(ans).decode('utf-8') for ans in RawBase64['results'][0]['incorrect_answers']]365 Options = [CorrectAnswer] + IncorrectAnswers366 random.shuffle(Options)367 OptionsText = '\n'.join(f'- {Opt}' for Opt in Options)368 return f'Trivia Question: {Question}\n\nOptions:\n{OptionsText}\n\nCorrect Answer: {CorrectAnswer}'369 else:370 return 'Error: Unable to fetch trivia question. Please try again later.'371 372def Casino(Game: Literal['Roulette', 'Slots'], Input: None | Literal['Red', 'Black', 'Green'], Bet: float) -> str:373 '''Generate a random casino game result.374 Args:375 Game (Literal['Roulette', 'Slots']): The casino game to simulate.376 Input (None | Literal['Red', 'Black', 'Green']): The input color for Roulette.377 Bet (float): The amount of money to bet.378 Returns:379 str: A random casino game result.380 '''381 match Game:382 case 'Roulette':383 if Input is None:384 return 'Place your bet on a color (Red, Black, Green) for Roulette.'385 else:386 Payout = {387 'red': 2,388 'black': 2,389 'green': 18390 }391 Wheel = ['green'] + ['red'] * 18 + ['black'] * 18392 Result = random.choice(Wheel)393 if Result == Input.lower():394 return f'You played Roulette and won! 🎉 You bet €{Bet} on {Input} and the result was {Result.capitalize()}.\nYou\'ve won €{Bet * Payout[Result]}'395 else:396 return f'You played Roulette and lost! 😢 You bet €{Bet} on {Input} and the result was {Result.capitalize()}.'397 398 case 'Slots':399 Reels = ['🍒', '🍋', '🍊', '🍉', '🍇', '🔔', '⭐']400 SpinResult = random.choices(Reels, k=3)401 Counts = Counter(SpinResult)402 MostCommon = Counts.most_common(1)[0]403 Symbol, Count = MostCommon404 405 if Count == 3:406 if Symbol == '⭐':407 return f'You played Slots and hit the jackpot! 🎰 You spun [{" | ".join(SpinResult)}] and won €{Bet * 50}!'408 elif Symbol == '🔔':409 return f'You played Slots and won! 🎉 You spun [{" | ".join(SpinResult)}] and won €{Bet * 25}!'410 elif Symbol == '🍒':411 return f'You played Slots and won! 🎉 You spun [{" | ".join(SpinResult)}] and won €{Bet * 10}!'412 else:413 return f'You played Slots and won! 🎉 You spun [{" | ".join(SpinResult)}] and won €{Bet * 5}!'414 elif Count == 2:415 return f'You played Slots and got a pair! 🎰 You spun [{" | ".join(SpinResult)}] and won €{Bet * 1.5}!'416 else:417 return f'You played Slots and lost! 😢 You spun [{" | ".join(SpinResult)}] and won nothing.'418 419def EightBall(Question: str) -> str:420 '''Ask the Magic 8-Ball a question and get a response.421 Args:422 Question (str): The question to ask the Magic 8-Ball.423 Returns:424 str: The response from the Magic 8-Ball.425 '''426 427 # Get a random response from the appropriate category428 ResponseCategory = random.choices(list(EightBallResponses.keys()), weights=[0.4, 0.2, 0.4])[0]429 Response = random.choice(EightBallResponses[ResponseCategory])430 return Response431 432def PigLatin(Text: str) -> str:433 '''Convert the input text to Pig Latin.434 Args:435 Text (str): The text to convert.436 Returns:437 str: The converted text in Pig Latin.438 '''439 Words = Text.split()440 PigLatinWords = []441 442 for Word in Words:443 if Word:444 FirstLetter = Word[0].lower()445 if FirstLetter in 'aeiou':446 PigLatinWord = Word + 'way'447 else:448 PigLatinWord = Word[1:] + FirstLetter + 'ay'449 PigLatinWords.append(PigLatinWord)450 451 return ' '.join(PigLatinWords)452 453# ╭─────────────────────────────╮454# │ Text Processing Tools │455# ╰─────────────────────────────╯456 457def Reverse(Text: str) -> str:458 '''Reverse the input text.459 Args:460 Text (str): The text to reverse.461 Returns:462 str: The reversed text.463 '''464 return Text[::-1]465 466def WordCount(Text: str, Choice: Literal['words', 'characters']) -> int:467 '''Count the number of words or characters in the input text.468 Args:469 Text (str): The text to count words in.470 Choice (Literal['words', 'characters']): The type of count to perform.471 Returns:472 int: The number of words in the text.473 '''474 if Choice == 'words':475 return len(Text.split())476 elif Choice == 'characters':477 return len(Text)478 else:479 return 0480 481def Base64(Text: str, Choice: Literal['encode', 'decode']) -> str:482 '''Encode or decode text using Base64.483 Args:484 Text (str): The text to encode or decode.485 Choice (Literal['encode', 'decode']): The operation to perform.486 - 'encode': Encode the text to Base64.487 - 'decode': Decode the Base64 text back to original text.488 Returns:489 str: The encoded or decoded text.490 '''491 if Choice == 'encode':492 return base64.b64encode(Text.encode()).decode()493 elif Choice == 'decode':494 return base64.b64decode(Text.encode()).decode()495 else:496 return 'Error: Invalid choice.'497 498def Hash(Text: str, Algorithm: Literal['md5', 'sha1', 'sha256', 'sha512']) -> str:499 '''Hash the input text using the specified algorithm.500 Args:501 Text (str): The text to hash.502 Algorithm (Literal['md5', 'sha1', 'sha256', 'sha512']): The hashing algorithm to use.503 Returns:504 str: The resulting hash.505 '''506 Hashes = {507 'md5': hashlib.md5,508 'sha1': hashlib.sha1,509 'sha256': hashlib.sha256,510 'sha512': hashlib.sha512511 }512 513 if Algorithm in Hashes:514 return Hashes[Algorithm](Text.encode()).hexdigest()515 else:516 return 'Error: Invalid algorithm.'517 518# ╭────────────────────╮519# │ Memory Tools │520# ╰────────────────────╯521 522def SaveMemory(Text: str, Password: str) -> str:523 '''524 Save a memory with the given text to MongoDB.525 '''526 try:527 if Collection is None:528 return 'Error: MongoDB connection not available'529 530 if Password != MemoryPassword:531 return 'Error: Invalid password'532 533 MemoryEntry = {534 'text': Text,535 'timestamp': datetime.datetime.now()536 }537 538 Collection.insert_one(MemoryEntry)539 return 'Memory saved successfully'540 except Exception as e:541 return f'Error: {str(e)}'542 543def ListMemories(Password: str) -> str:544 '''545 List all saved memories from MongoDB.546 '''547 try:548 if Collection is None:549 return 'Error: MongoDB connection not available'550 551 if Password != MemoryPassword:552 return 'Error: Invalid password'553 554 Memories = list(Collection.find().sort('timestamp', -1).limit(50))555 556 if not Memories:557 return 'No memories found'558 559 FormattedMemories = []560 for Memory in Memories:561 Timestamp = Memory['timestamp'].strftime('%Y-%m-%d %H:%M:%S')562 MemoryId = str(Memory['_id'])563 FormattedMemories.append(f'{MemoryId} [{Timestamp}]: {Memory["text"]}')564 565 return '\n'.join(FormattedMemories)566 except Exception as e:567 return f'Error: {str(e)}'568 569def DeleteMemory(MemoryID: str, Password: str) -> str:570 '''571 Delete a memory by its MongoDB ObjectId.572 '''573 try:574 if Collection is None:575 return 'Error: MongoDB connection not available'576 577 if Password != MemoryPassword:578 return 'Error: Invalid password'579 580 if not ObjectId.is_valid(MemoryID):581 return 'Error: Invalid memory ID format'582 583 Result = Collection.delete_one({'_id': ObjectId(MemoryID)})584 585 if Result.deleted_count > 0:586 return 'Memory deleted successfully'587 else:588 return 'Memory not found'589 except Exception as e:590 return f'Error: {str(e)}'591 592def SearchMemories(Query: str, Password: str) -> str:593 '''594 Search memories by text content.595 '''596 try:597 if Collection is None:598 return 'Error: MongoDB connection not available'599 600 if Password != MemoryPassword:601 return 'Error: Invalid password'602 603 try:604 Collection.create_index([('text', 'text')])605 except Exception:606 pass607 608 Memories = list(Collection.find(609 {'$text': {'$search': Query}}610 ).sort('timestamp', -1).limit(20))611 612 if not Memories:613 return f'No memories found matching "{Query}"'614 615 FormattedMemories = []616 for Memory in Memories:617 Timestamp = Memory['timestamp'].strftime('%Y-%m-%d %H:%M:%S')618 MemoryId = str(Memory['_id'])619 FormattedMemories.append(f'{MemoryId} [{Timestamp}]: {Memory["text"]}')620 621 return '\n'.join(FormattedMemories)622 except Exception as e:623 return f'Error: {str(e)}'624 625# ╭──────────────────────────────╮626# │ Gradio Interface Setup │627# ╰──────────────────────────────╯628 629with gradio.Blocks(630 title='MCP Utilities 🛠️',631 theme=Theme632) as App:633 gradio.Markdown('''634# MCP Utilities 🛠️635 636A collection of useful tools and utilities for various tasks.637This app provides functionalities like weather information, date and time retrieval, code execution, dice rolling, coin flipping, mathematical operations, pinging hosts, web scraping, jokes, facts, plots, trivia quizzes, casino games and memory management.638''')639 with gradio.TabItem('General Tools 🛠️'):640 with gradio.TabItem('Weather 🌤️'):641 with gradio.Group():642 LocationInput = gradio.Textbox(label='Location 🌍', placeholder='Enter a location for weather', lines=1, max_lines=1)643 WeatherOutput = gradio.Text(label='Weather ☁️', interactive=False)644 WeatherBtn = gradio.Button('Get Weather 🔎', variant='primary')645 WeatherBtn.click(Weather, inputs=LocationInput, outputs=WeatherOutput)646 647 with gradio.TabItem('Date & Time 📅'):648 with gradio.Group():649 DateOutput = gradio.Text(label='Date 📅', interactive=False)650 DateBtn = gradio.Button('Get Date 📅', variant='primary')651 DateBtn.click(Date, outputs=DateOutput)652 653 with gradio.TabItem('Code Execution 🐍'):654 with gradio.Group():655 CodeInput = gradio.Textbox(label='Python Code 🐍', placeholder='Enter Python code to execute', lines=5)656 CodeOutput = gradio.Text(label='Execution Output 📜', interactive=False)657 CodeBtn = gradio.Button('Execute Code ▶️', variant='primary')658 CodeBtn.click(ExecuteCode, inputs=CodeInput, outputs=CodeOutput)659 660 with gradio.TabItem('Password Generator 🔐'):661 with gradio.Group():662 PasswordLength = gradio.Slider(label='Password Length 🔢', minimum=8, maximum=64, step=1, value=12)663 IncludeSpecialChars = gradio.Checkbox(label='Include Special Characters 🔒', value=True)664 UseDiceware = gradio.Checkbox(label='Generate Diceware Password', value=False, interactive=True)665 PasswordOutput = gradio.Text(label='Generated Password 🔑', interactive=False)666 PasswordBtn = gradio.Button('Generate Password 🔐', variant='primary')667 PasswordBtn.click(PasswordGenerator, inputs=[PasswordLength, IncludeSpecialChars, UseDiceware], outputs=PasswordOutput)668 669 with gradio.TabItem('Anagram Generator 🔤'):670 with gradio.Group():671 AnagramInput = gradio.Textbox(label='Text for Anagram 🔤', placeholder='Enter text to generate anagram', lines=1, max_lines=1)672 AnagramOutput = gradio.Text(label='Generated Anagram 🔤', interactive=False, max_lines=20)673 AnagramBtn = gradio.Button('Generate Anagram 🔤', variant='primary')674 AnagramBtn.click(Anagram, inputs=AnagramInput, outputs=AnagramOutput)675 676 with gradio.TabItem('Dice Roller 🎲'):677 with gradio.Group():678 DiceSides = gradio.Number(label='Sides of Dice 🔢', value=6, minimum=1, maximum=100)679 DiceOutput = gradio.Text(label='Dice Roll Result 🎲', interactive=False)680 DiceBtn = gradio.Button('Roll Dice ♻️', variant='primary')681 DiceBtn.click(Dice, inputs=DiceSides, outputs=DiceOutput)682 683 with gradio.TabItem('Coin Flip 🪙'):684 with gradio.Group():685 CoinOutput = gradio.Text(label='Coin Flip Result 🪙', interactive=False)686 CoinBtn = gradio.Button('Flip Coin 🪙', variant='primary')687 CoinBtn.click(CoinFlip, outputs=CoinOutput)688 689 with gradio.TabItem('Math Operations ➕➖✖️➗'):690 with gradio.Group():691 Num1Input = gradio.Number(label='Number 1 1️⃣', value=0)692 Num2Input = gradio.Number(label='Number 2 2️⃣', value=0)693 OperationInput = gradio.Radio(label='Operation 🔣', choices=['add', 'subtract', 'multiply', 'divide', 'modulus', 'exponent'], value='add', interactive=True)694 MathOutput = gradio.Text(label='Math Result 🟰', interactive=False)695 MathBtn = gradio.Button('Calculate 🧮', variant='primary')696 MathBtn.click(Math, inputs=[Num1Input, Num2Input, OperationInput], outputs=MathOutput)697 698 with gradio.TabItem('Temperature Conversion 🌡️'):699 with gradio.Group():700 TempValue = gradio.Number(label='Temperature Value 🌡️', value=0)701 TempFromUnit = gradio.Radio(label='From Unit 🔄', choices=['Celsius', 'Fahrenheit', 'Kelvin'], value='Celsius', interactive=True)702 TempToUnit = gradio.Radio(label='To Unit 🔄', choices=['Celsius', 'Fahrenheit', 'Kelvin'], value='Celsius', interactive=True)703 TempOutput = gradio.Text(label='Converted Temperature 🌡️', interactive=False)704 TempBtn = gradio.Button('Convert Temperature 🔄', variant='primary')705 TempBtn.click(TempConversion, inputs=[TempValue, TempFromUnit, TempToUnit], outputs=TempOutput)706 707 with gradio.TabItem('Currency Conversion 💱'):708 with gradio.Group():709 CurrencyValue = gradio.Number(label='Amount 💰', value=1, minimum=0.01, step=0.01)710 CurrencyFrom = gradio.Textbox(label='From Currency (e.g., USD) 💵', placeholder='Enter currency code', lines=1, max_lines=1)711 CurrencyTo = gradio.Textbox(label='To Currency (e.g., EUR) 💶', placeholder='Enter currency code', lines=1, max_lines=1)712 CurrencyOutput = gradio.Text(label='Converted Amount 💱', interactive=False)713 CurrencyBtn = gradio.Button('Convert Currency 💱', variant='primary')714 CurrencyBtn.click(CurrencyConversion, inputs=[CurrencyValue, CurrencyFrom, CurrencyTo], outputs=CurrencyOutput)715 716 with gradio.TabItem('Ping Host 📡'):717 with gradio.Group():718 PingInput = gradio.Textbox(label='Host to Ping 🌐', placeholder='Enter host (e.g., google.com)', lines=1, max_lines=1)719 PingCount = gradio.Number(label='Ping Count 🔢', value=8, minimum=1, maximum=100)720 PingOutput = gradio.Text(label='Ping Result 📡', interactive=False)721 PingBtn = gradio.Button('Ping Host 📡', variant='primary')722 PingBtn.click(Ping, inputs=[PingInput, PingCount], outputs=PingOutput)723 724 with gradio.TabItem('Web Scraping 🌐'):725 with gradio.Group():726 PurifyInput = gradio.Textbox(label='URL to Scrape 🌐', placeholder='Enter URL to fetch and purify HTML (e.g., https://huggingface.co)', lines=1, max_lines=1)727 PurifyOutput = gradio.Text(label='Scraped HTML Content 📝', interactive=False)728 PurifyBtn = gradio.Button('Scrape HTML 🧹 (🚧 WIP 🚧)', variant='primary', interactive=False)729 PurifyBtn.click(Purify, inputs=PurifyInput, outputs=PurifyOutput)730 731 with gradio.TabItem('Fun & Entertainment 🎭'):732 with gradio.TabItem('Random Joke 😂'):733 with gradio.Group():734 JokeOutput = gradio.Text(label='Random Joke 😂', interactive=False)735 JokeType = gradio.Radio(label='Joke Type 🤡', choices=['Any', 'Programming', 'Misc', 'Dark', 'Pun', 'Spooky', 'Christmas'], value='Any', interactive=True)736 JokeBtn = gradio.Button('Get Joke 🎪', variant='primary')737 JokeBtn.click(Joke, inputs=[JokeType], outputs=JokeOutput)738 739 with gradio.TabItem('Random Fact 🧠'):740 with gradio.Group():741 FactOutput = gradio.Text(label='Random Fact 🧠', interactive=False)742 FactBtn = gradio.Button('Get Fact 📚', variant='primary')743 FactBtn.click(Fact, outputs=FactOutput)744 745 with gradio.TabItem('Random Plot 🎬'):746 with gradio.Group():747 PlotOutput = gradio.Text(label='Random Plot 🎬', interactive=False)748 PlotExample = gradio.Checkbox(label='Give Example Plot Prompt 📜', value=True, interactive=True)749 PlotExampleOutput = gradio.Text(label='Example Plot Prompt 📜', interactive=False)750 PlotBtn = gradio.Button('Get Plot 🎥', variant='primary')751 PlotBtn.click(Plot, inputs=[PlotExample], outputs=[PlotOutput, PlotExampleOutput])752 753 with gradio.TabItem('Trivia Quiz ❓'):754 with gradio.Group():755 TriviaCategory = gradio.Radio(label='Category 🎭', choices=list(Categories.keys()), value='Any Category', interactive=True)756 TriviaDifficulty = gradio.Radio(label='Difficulty 🎮', choices=list(Difficulties.keys()), value='Any Difficulty', interactive=True)757 TriviaOutput = gradio.Text(label='Trivia Question ❓', interactive=False, max_lines=5)758 TriviaBtn = gradio.Button('Get Trivia Question 🎉', variant='primary')759 TriviaBtn.click(Trivia, inputs=[TriviaCategory, TriviaDifficulty], outputs=TriviaOutput)760 761 with gradio.TabItem('Casino Games 🎰'):762 with gradio.Group():763 CasinoGame = gradio.Radio(label='Casino Game 🎲', choices=['Roulette', 'Slots'], value='Roulette', interactive=True)764 CasinoBet = gradio.Slider(label='Bet Amount 💰', minimum=1, maximum=1000, step=0.5, value=10, interactive=True)765 CasinoWheel = gradio.Radio(label='Roulette Color 🎡', choices=['Red', 'Black', 'Green'], value=None, interactive=True)766 CasinoOutput = gradio.Text(label='Casino Result 🎰', interactive=False)767 CasinoBtn = gradio.Button('Play Casino 🎲', variant='primary')768 CasinoBtn.click(Casino, inputs=[CasinoGame, CasinoWheel, CasinoBet], outputs=CasinoOutput)769 770 with gradio.TabItem('Magic 8-Ball 🔮'):771 with gradio.Group():772 EightBallInput = gradio.Textbox(label='Ask a Question ❓', placeholder='Enter your question for the Magic 8-Ball', lines=1, max_lines=1)773 EightBallOutput = gradio.Text(label='Magic 8-Ball Response 🔮', interactive=False)774 EightBallBtn = gradio.Button('Ask Magic 8-Ball 🔮', variant='primary')775 EightBallBtn.click(EightBall, inputs=EightBallInput, outputs=EightBallOutput)776 777 with gradio.TabItem('Pig Latin Translator 🐷'):778 with gradio.Group():779 PigLatinInput = gradio.Textbox(label='Text to Convert to Pig Latin 🐷', placeholder='Enter text to convert', lines=3)780 PigLatinOutput = gradio.Text(label='Pig Latin Translation 🐷', interactive=False)781 PigLatinBtn = gradio.Button('Convert to Pig Latin 🐷', variant='primary')782 PigLatinBtn.click(PigLatin, inputs=PigLatinInput, outputs=PigLatinOutput)783 784 with gradio.TabItem('Text Processing 📝'):785 with gradio.TabItem('Text Reversal 🔄'):786 with gradio.Group():787 ReverseInput = gradio.Textbox(label='Text to Reverse 🔄', placeholder='Enter text to reverse', lines=3)788 ReverseOutput = gradio.Text(label='Reversed Text ↩️', interactive=False)789 ReverseBtn = gradio.Button('Reverse Text 🔄', variant='primary')790 ReverseBtn.click(Reverse, inputs=ReverseInput, outputs=ReverseOutput)791 792 with gradio.TabItem('Word Count 📏'):793 with gradio.Group():794 WordCountInput = gradio.Textbox(label='Text for Word Count 📏', placeholder='Enter text to count words', lines=3)795 WordCountChoice = gradio.Radio(label='Count Type 🔢', choices=['words', 'characters'], value='words', interactive=True)796 WordCountOutput = gradio.Text(label='Word Count Result 📊', interactive=False)797 WordCountBtn = gradio.Button('Count Words 📈', variant='primary')798 WordCountBtn.click(WordCount, inputs=[WordCountInput, WordCountChoice], outputs=WordCountOutput)799 800 with gradio.TabItem('Base64 Encoding/Decoding 📦'):801 with gradio.Group():802 Base64Input = gradio.Textbox(label='Text for Base64 📦', placeholder='Enter text to encode/decode', lines=3)803 Base64Choice = gradio.Radio(label='Operation 🔄', choices=['encode', 'decode'], value='encode', interactive=True)804 Base64Output = gradio.Text(label='Base64 Result 📦', interactive=False)805 Base64Btn = gradio.Button('Process Base64 📦', variant='primary')806 Base64Btn.click(Base64, inputs=[Base64Input, Base64Choice], outputs=Base64Output)807 808 with gradio.TabItem('Hashing 🔐'):809 with gradio.Group():810 HashInput = gradio.Textbox(label='Text to Hash 🔐', placeholder='Enter text to hash', lines=3)811 HashChoice = gradio.Radio(label='Hashing Algorithm 🔄', choices=['md5', 'sha1', 'sha256', 'sha512'], value='md5', interactive=True)812 HashOutput = gradio.Text(label='Hash Result 🔐', interactive=False)813 HashBtn = gradio.Button('Generate Hash 🔐', variant='primary')814 HashBtn.click(Hash, inputs=[HashInput, HashChoice], outputs=HashOutput)815 816 with gradio.TabItem('Memory Tools 💾'):817 MemoryPasswordInput = gradio.Textbox(label='Password 🔐', placeholder='Enter memory password', type='password', lines=1)818 with gradio.TabItem('Save Memory 💾'):819 with gradio.Group():820 SaveInput = gradio.Textbox(label='Memory Text 💭', placeholder='Enter text to save', lines=3)821 SaveBtn = gradio.Button('Save Memory 💾', variant='primary')822 SaveBtn.click(SaveMemory, inputs=[SaveInput, MemoryPasswordInput], outputs=gradio.Text(label='Result'))823 824 with gradio.TabItem('Delete Memory 🗑️'):825 with gradio.Group():826 DeleteInput = gradio.Textbox(label='Memory ID 🗑️', placeholder='Enter ObjectId to delete', lines=1)827 DeleteBtn = gradio.Button('Delete Memory 🗑️', variant='secondary')828 DeleteBtn.click(DeleteMemory, inputs=[DeleteInput, MemoryPasswordInput], outputs=gradio.Text(label='Result'))829 830 with gradio.TabItem('List Memories 📄'):831 with gradio.Group():832 ListBtn = gradio.Button('List All Memories 📄', variant='primary')833 ListBtn.click(ListMemories, inputs=MemoryPasswordInput, outputs=gradio.Text(label='Memories'))834 835 with gradio.TabItem('Search Memories 🔍'):836 with gradio.Group():837 SearchInput = gradio.Textbox(label='Search Query 🔍', placeholder='Enter search text', lines=1)838 SearchBtn = gradio.Button('Search Memories 🔎', variant='primary')839 SearchBtn.click(SearchMemories, inputs=[SearchInput, MemoryPasswordInput], outputs=gradio.Text(label='Results'))840 841 App.launch(842 mcp_server=True843 )