CoolFace
Apppublic

Hyphonical/MCP-Utilities

sourceHugging Facemitupdated 1y agoView on Hugging Face
4likes
app.py843 linesDownload Raw Back to root
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	)