Spaces:
Running
Running

โจ Update PurifyHtml function: change model loading to use 'jinaai/ReaderLM-v2' for improved performance.
3fa127c
from pymongo import MongoClient | |
from dotenv import load_dotenv | |
from Purify import PurifyHtml | |
from typing import Literal | |
from bson import ObjectId | |
from io import StringIO | |
import statistics | |
import datetime | |
import requests | |
import hashlib | |
import random | |
import base64 | |
import gradio | |
import json | |
import sys | |
import os | |
load_dotenv() | |
MemoryPassword = os.getenv('MEMORY_PASSWORD') | |
MongoURI = os.getenv('MONGO_URI') | |
DatabaseName = 'MCP-Utilities' | |
CollectionName = 'Memories' | |
try: | |
Client = MongoClient(MongoURI) | |
Database = Client[DatabaseName] | |
Collection = Database[CollectionName] | |
Client.server_info() | |
print('Connected to MongoDB successfully.') | |
except Exception as e: | |
print(f'Error connecting to MongoDB: {str(e)}') | |
Collection = None | |
Theme = gradio.themes.Citrus( # type: ignore | |
primary_hue='blue', | |
secondary_hue='blue', | |
radius_size=gradio.themes.sizes.radius_xxl, # type: ignore | |
font=[gradio.themes.GoogleFont('Nunito'), 'Arial', 'sans-serif'] # type: ignore | |
).set( | |
link_text_color='blue' | |
) | |
# โญโโโโโโโโโโโโโโโโโโโโโโฎ | |
# โ General Tools โ | |
# โฐโโโโโโโโโโโโโโโโโโโโโโฏ | |
def Weather(Location: str) -> str: | |
''' | |
Get the current weather for a specified location. | |
Args: | |
Location (str): The location for which to get the weather. E.g., "London", "France", "50.85045,4.34878" "~NASA" | |
Returns: | |
str: The current weather.". | |
''' | |
return requests.get(f'https://wttr.in/{Location}?A&format=4').text | |
def Date() -> str: | |
'''Get the current date and time. | |
Returns: | |
str: The current date and time in the format "YYYY-MM-DD HH:MM:SS". | |
''' | |
return datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') | |
def Dice(Sides: int = 6) -> int: | |
'''Roll a dice with a specified number of sides. | |
Args: | |
Sides (int): The number of sides on the dice. Default is 6. | |
Returns: | |
int: The result of the dice roll. | |
''' | |
return random.randint(1, Sides) | |
def Math(Num1: float, Num2: float, Operation: Literal['add', 'subtract', 'multiply', 'divide', 'modulus', 'exponent']) -> float | str: | |
'''Perform a mathematical operation on two numbers. | |
Args: | |
Num1 (float): The first number. | |
Num2 (float): The second number. | |
Operation (Literal['add', 'subtract', 'multiply', 'divide', 'modulus', 'exponent']): The operation to perform. | |
Returns: | |
float | str: The result of the operation or an error message. | |
''' | |
Operations = { | |
'add': lambda x, y: x + y, | |
'subtract': lambda x, y: x - y, | |
'multiply': lambda x, y: x * y, | |
'divide': lambda x, y: x / y if y != 0 else 'Error: Division by zero', | |
'modulus': lambda x, y: x % y if y != 0 else 'Error: Division by zero', | |
'exponent': lambda x, y: x ** y, | |
} | |
if Operation in Operations: | |
return Operations[Operation](Num1, Num2) | |
else: | |
return 'Error: Invalid operation' | |
def ExecuteCode(Code: str) -> str: | |
''' | |
Execute Python code and return the output or error message. | |
Args: | |
Code (str): The Python code to execute. | |
Returns: | |
str: The output of the executed code or the error message if an exception occurs. | |
''' | |
OldStdout = sys.stdout | |
RedirectedOutput = StringIO() | |
sys.stdout = RedirectedOutput | |
try: | |
Namespace = {} | |
exec(Code, Namespace, Namespace) | |
Result = RedirectedOutput.getvalue() | |
return Result if Result.strip() else 'Code executed successfully (no output).' | |
except Exception as e: | |
return f'Error: {str(e)}' | |
finally: | |
sys.stdout = OldStdout | |
def Ping(Host: str, Count: int = 8) -> str: | |
'''Ping a host to check its availability. | |
Args: | |
Host (str): The host to ping (e.g., "google.com", "192.168.1.1"). | |
Count (int): The number of ping requests to send. Default is 8. | |
Returns: | |
str: The result of the ping command. | |
''' | |
if not Host: | |
return 'Error: Host cannot be empty' | |
Durations = [] | |
for _ in range(Count): | |
try: | |
Start = datetime.datetime.now() | |
Response = requests.get(f'http://{Host}', timeout=2) | |
if Response.status_code != 200: | |
continue | |
End = datetime.datetime.now() | |
Durations.append((End - Start).total_seconds() * 1000) | |
except requests.RequestException: | |
Durations.append(None) | |
if Durations: | |
Durations = [d for d in Durations if d is not None] | |
Mean = statistics.mean(Durations) | |
Median = statistics.median(Durations) | |
return f'Ping to {Host} successful: {Mean} ms (avg), {Median} ms (median)' | |
else: | |
return f'Ping to {Host} failed: No successful responses' | |
def Purify(Url: str) -> str: | |
'''Purify HTML content from a URL. | |
Args: | |
Url (str): The URL to fetch and purify HTML content from. | |
Returns: | |
str: The purified HTML content or an error message. | |
''' | |
return PurifyHtml(Url) | |
# โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ | |
# โ Fun and Entertainment Tools โ | |
# โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ | |
def Joke(Type: Literal['Any', 'Programming', 'Misc', 'Dark', 'Pun', 'Spooky', 'Christmas']) -> str: | |
'''Get a random joke. | |
Args: | |
Type (Literal['Any', 'Programming', 'Misc', 'Dark', 'Pun', 'Spooky', 'Christmas']): The type of joke to fetch. | |
Returns: | |
str: A random joke. | |
''' | |
return requests.get(f'https://v2.jokeapi.dev/joke/{Type}?format=txt').text | |
def Fact() -> str: | |
'''Get a random fact. | |
Returns: | |
str: A random fact. | |
''' | |
return requests.get('https://uselessfacts.jsph.pl/random.json?language=en').json()['text'] | |
def Plot(GiveExamplePrompt: bool = True) -> list[str]: | |
'''Generate a random plot for a movie or story. | |
Args: | |
GiveExamplePrompt (bool): If True, returns a random plot prompt from a predefined dataset. | |
Returns: | |
str: A random plot description. | |
''' | |
with open(r'Data/human-writing-dpo.json', 'r', encoding='utf-8') as PlotFile: | |
Data = json.load(PlotFile) | |
Plot = random.choice(Data) | |
Prompt = Plot['prompt'] | |
Chosen = Plot['chosen'] | |
if GiveExamplePrompt: | |
return [Prompt, Chosen] | |
else: | |
return [Prompt, ''] | |
# โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ | |
# โ Text Processing Tools โ | |
# โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ | |
def Reverse(Text: str) -> str: | |
'''Reverse the input text. | |
Args: | |
Text (str): The text to reverse. | |
Returns: | |
str: The reversed text. | |
''' | |
return Text[::-1] | |
def WordCount(Text: str, Choice: Literal['words', 'characters']) -> int: | |
'''Count the number of words or characters in the input text. | |
Args: | |
Text (str): The text to count words in. | |
Choice (Literal['words', 'characters']): The type of count to perform. | |
Returns: | |
int: The number of words in the text. | |
''' | |
if Choice == 'words': | |
return len(Text.split()) | |
elif Choice == 'characters': | |
return len(Text) | |
else: | |
return 0 | |
def Base64(Text: str, Choice: Literal['encode', 'decode']) -> str: | |
'''Encode or decode text using Base64. | |
Args: | |
Text (str): The text to encode or decode. | |
Choice (Literal['encode', 'decode']): The operation to perform. | |
- 'encode': Encode the text to Base64. | |
- 'decode': Decode the Base64 text back to original text. | |
Returns: | |
str: The encoded or decoded text. | |
''' | |
if Choice == 'encode': | |
return base64.b64encode(Text.encode()).decode() | |
elif Choice == 'decode': | |
return base64.b64decode(Text.encode()).decode() | |
else: | |
return 'Error: Invalid choice.' | |
def Hash(Text: str, Algorithm: Literal['md5', 'sha1', 'sha256', 'sha512']) -> str: | |
'''Hash the input text using the specified algorithm. | |
Args: | |
Text (str): The text to hash. | |
Algorithm (Literal['md5', 'sha1', 'sha256', 'sha512']): The hashing algorithm to use. | |
Returns: | |
str: The resulting hash. | |
''' | |
Hashes = { | |
'md5': hashlib.md5, | |
'sha1': hashlib.sha1, | |
'sha256': hashlib.sha256, | |
'sha512': hashlib.sha512 | |
} | |
if Algorithm in Hashes: | |
return Hashes[Algorithm](Text.encode()).hexdigest() | |
else: | |
return 'Error: Invalid algorithm.' | |
# โญโโโโโโโโโโโโโโโโโโโโโฎ | |
# โ Memory Tools โ | |
# โฐโโโโโโโโโโโโโโโโโโโโโฏ | |
def SaveMemory(Text: str, Password: str) -> str: | |
''' | |
Save a memory with the given text to MongoDB. | |
''' | |
try: | |
if Collection is None: | |
return 'Error: MongoDB connection not available' | |
if Password != MemoryPassword: | |
return 'Error: Invalid password' | |
MemoryEntry = { | |
'text': Text, | |
'timestamp': datetime.datetime.now() | |
} | |
Collection.insert_one(MemoryEntry) | |
return 'Memory saved successfully' | |
except Exception as e: | |
return f'Error: {str(e)}' | |
def ListMemories(Password: str) -> str: | |
''' | |
List all saved memories from MongoDB. | |
''' | |
try: | |
if Collection is None: | |
return 'Error: MongoDB connection not available' | |
if Password != MemoryPassword: | |
return 'Error: Invalid password' | |
Memories = list(Collection.find().sort('timestamp', -1).limit(50)) | |
if not Memories: | |
return 'No memories found' | |
FormattedMemories = [] | |
for Memory in Memories: | |
Timestamp = Memory['timestamp'].strftime('%Y-%m-%d %H:%M:%S') | |
MemoryId = str(Memory['_id']) | |
FormattedMemories.append(f'{MemoryId} [{Timestamp}]: {Memory["text"]}') | |
return '\n'.join(FormattedMemories) | |
except Exception as e: | |
return f'Error: {str(e)}' | |
def DeleteMemory(MemoryID: str, Password: str) -> str: | |
''' | |
Delete a memory by its MongoDB ObjectId. | |
''' | |
try: | |
if Collection is None: | |
return 'Error: MongoDB connection not available' | |
if Password != MemoryPassword: | |
return 'Error: Invalid password' | |
if not ObjectId.is_valid(MemoryID): | |
return 'Error: Invalid memory ID format' | |
Result = Collection.delete_one({'_id': ObjectId(MemoryID)}) | |
if Result.deleted_count > 0: | |
return 'Memory deleted successfully' | |
else: | |
return 'Memory not found' | |
except Exception as e: | |
return f'Error: {str(e)}' | |
def SearchMemories(Query: str, Password: str) -> str: | |
''' | |
Search memories by text content. | |
''' | |
try: | |
if Collection is None: | |
return 'Error: MongoDB connection not available' | |
if Password != MemoryPassword: | |
return 'Error: Invalid password' | |
try: | |
Collection.create_index([('text', 'text')]) | |
except Exception: | |
pass | |
Memories = list(Collection.find( | |
{'$text': {'$search': Query}} | |
).sort('timestamp', -1).limit(20)) | |
if not Memories: | |
return f'No memories found matching "{Query}"' | |
FormattedMemories = [] | |
for Memory in Memories: | |
Timestamp = Memory['timestamp'].strftime('%Y-%m-%d %H:%M:%S') | |
MemoryId = str(Memory['_id']) | |
FormattedMemories.append(f'{MemoryId} [{Timestamp}]: {Memory["text"]}') | |
return '\n'.join(FormattedMemories) | |
except Exception as e: | |
return f'Error: {str(e)}' | |
# โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฎ | |
# โ Gradio Interface Setup โ | |
# โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ | |
with gradio.Blocks( | |
title='MCP Utilities ๐ ๏ธ', | |
theme=Theme | |
) as App: | |
gradio.Markdown('# MCP Utilities ๐ ๏ธ') | |
with gradio.TabItem('General Tools ๐ ๏ธ'): | |
with gradio.TabItem('Weather ๐ค๏ธ'): | |
with gradio.Group(): | |
LocationInput = gradio.Textbox(label='Location ๐', placeholder='Enter a location for weather', lines=1, max_lines=1) | |
WeatherOutput = gradio.Text(label='Weather โ๏ธ', interactive=False) | |
WeatherBtn = gradio.Button('Get Weather ๐', variant='primary') | |
WeatherBtn.click(Weather, inputs=LocationInput, outputs=WeatherOutput) | |
with gradio.TabItem('Date & Time ๐ '): | |
with gradio.Group(): | |
DateOutput = gradio.Text(label='Date ๐ ', interactive=False) | |
DateBtn = gradio.Button('Get Date ๐ ', variant='primary') | |
DateBtn.click(Date, outputs=DateOutput) | |
with gradio.TabItem('Code Execution ๐'): | |
with gradio.Group(): | |
CodeInput = gradio.Textbox(label='Python Code ๐', placeholder='Enter Python code to execute', lines=5) | |
CodeOutput = gradio.Text(label='Execution Output ๐', interactive=False) | |
CodeBtn = gradio.Button('Execute Code โถ๏ธ', variant='primary') | |
CodeBtn.click(ExecuteCode, inputs=CodeInput, outputs=CodeOutput) | |
with gradio.TabItem('Dice Roller ๐ฒ'): | |
with gradio.Group(): | |
DiceSides = gradio.Number(label='Sides of Dice ๐ข', value=6, minimum=1, maximum=100) | |
DiceOutput = gradio.Text(label='Dice Roll Result ๐ฒ', interactive=False) | |
DiceBtn = gradio.Button('Roll Dice โป๏ธ', variant='primary') | |
DiceBtn.click(Dice, inputs=DiceSides, outputs=DiceOutput) | |
with gradio.TabItem('Math Operations โโโ๏ธโ'): | |
with gradio.Group(): | |
Num1Input = gradio.Number(label='Number 1 1๏ธโฃ', value=0) | |
Num2Input = gradio.Number(label='Number 2 2๏ธโฃ', value=0) | |
OperationInput = gradio.Radio(label='Operation ๐ฃ', choices=['add', 'subtract', 'multiply', 'divide', 'modulus', 'exponent'], value='add', interactive=True) | |
MathOutput = gradio.Text(label='Math Result ๐ฐ', interactive=False) | |
MathBtn = gradio.Button('Calculate ๐งฎ', variant='primary') | |
MathBtn.click(Math, inputs=[Num1Input, Num2Input, OperationInput], outputs=MathOutput) | |
with gradio.TabItem('Ping Host ๐ก'): | |
with gradio.Group(): | |
PingInput = gradio.Textbox(label='Host to Ping ๐', placeholder='Enter host (e.g., google.com)', lines=1, max_lines=1) | |
PingCount = gradio.Number(label='Ping Count ๐ข', value=8, minimum=1, maximum=100) | |
PingOutput = gradio.Text(label='Ping Result ๐ก', interactive=False) | |
PingBtn = gradio.Button('Ping Host ๐ก', variant='primary') | |
PingBtn.click(Ping, inputs=[PingInput, PingCount], outputs=PingOutput) | |
with gradio.TabItem('Web Scraping & Purification ๐'): | |
with gradio.Group(): | |
PurifyInput = gradio.Textbox(label='URL to Purify ๐', placeholder='Enter URL to fetch and purify HTML (e.g., https://huggingface.co)', lines=1, max_lines=1) | |
PurifyOutput = gradio.Text(label='Purified HTML Content ๐', interactive=False) | |
PurifyBtn = gradio.Button('Purify HTML ๐งน', variant='primary') | |
PurifyBtn.click(Purify, inputs=PurifyInput, outputs=PurifyOutput) | |
with gradio.TabItem('Fun & Entertainment ๐ญ'): | |
with gradio.TabItem('Random Joke ๐'): | |
with gradio.Group(): | |
JokeOutput = gradio.Text(label='Random Joke ๐', interactive=False) | |
JokeType = gradio.Radio(label='Joke Type ๐คก', choices=['Any', 'Programming', 'Misc', 'Dark', 'Pun', 'Spooky', 'Christmas'], value='Any', interactive=True) | |
JokeBtn = gradio.Button('Get Joke ๐ช', variant='primary') | |
JokeBtn.click(Joke, inputs=[JokeType], outputs=JokeOutput) | |
with gradio.TabItem('Random Fact ๐ง '): | |
with gradio.Group(): | |
FactOutput = gradio.Text(label='Random Fact ๐ง ', interactive=False) | |
FactBtn = gradio.Button('Get Fact ๐', variant='primary') | |
FactBtn.click(Fact, outputs=FactOutput) | |
with gradio.TabItem('Random Plot ๐ฌ'): | |
with gradio.Group(): | |
PlotOutput = gradio.Text(label='Random Plot ๐ฌ', interactive=False) | |
PlotExample = gradio.Checkbox(label='Give Example Plot Prompt ๐', value=True, interactive=True) | |
PlotExampleOutput = gradio.Text(label='Example Plot Prompt ๐', interactive=False) | |
PlotBtn = gradio.Button('Get Plot ๐ฅ', variant='primary') | |
PlotBtn.click(Plot, inputs=[PlotExample], outputs=[PlotOutput, PlotExampleOutput]) | |
with gradio.TabItem('Text Processing ๐'): | |
with gradio.TabItem('Text Reversal ๐'): | |
with gradio.Group(): | |
ReverseInput = gradio.Textbox(label='Text to Reverse ๐', placeholder='Enter text to reverse', lines=3) | |
ReverseOutput = gradio.Text(label='Reversed Text โฉ๏ธ', interactive=False) | |
ReverseBtn = gradio.Button('Reverse Text ๐', variant='primary') | |
ReverseBtn.click(Reverse, inputs=ReverseInput, outputs=ReverseOutput) | |
with gradio.TabItem('Word Count ๐'): | |
with gradio.Group(): | |
WordCountInput = gradio.Textbox(label='Text for Word Count ๐', placeholder='Enter text to count words', lines=3) | |
WordCountChoice = gradio.Radio(label='Count Type ๐ข', choices=['words', 'characters'], value='words', interactive=True) | |
WordCountOutput = gradio.Text(label='Word Count Result ๐', interactive=False) | |
WordCountBtn = gradio.Button('Count Words ๐', variant='primary') | |
WordCountBtn.click(WordCount, inputs=[WordCountInput, WordCountChoice], outputs=WordCountOutput) | |
with gradio.TabItem('Base64 Encoding/Decoding ๐ฆ'): | |
with gradio.Group(): | |
Base64Input = gradio.Textbox(label='Text for Base64 ๐ฆ', placeholder='Enter text to encode/decode', lines=3) | |
Base64Choice = gradio.Radio(label='Operation ๐', choices=['encode', 'decode'], value='encode', interactive=True) | |
Base64Output = gradio.Text(label='Base64 Result ๐ฆ', interactive=False) | |
Base64Btn = gradio.Button('Process Base64 ๐ฆ', variant='primary') | |
Base64Btn.click(Base64, inputs=[Base64Input, Base64Choice], outputs=Base64Output) | |
with gradio.TabItem('Hashing ๐'): | |
with gradio.Group(): | |
HashInput = gradio.Textbox(label='Text to Hash ๐', placeholder='Enter text to hash', lines=3) | |
HashChoice = gradio.Radio(label='Hashing Algorithm ๐', choices=['md5', 'sha1', 'sha256', 'sha512'], value='md5', interactive=True) | |
HashOutput = gradio.Text(label='Hash Result ๐', interactive=False) | |
HashBtn = gradio.Button('Generate Hash ๐', variant='primary') | |
HashBtn.click(Hash, inputs=[HashInput, HashChoice], outputs=HashOutput) | |
with gradio.TabItem('Memory Tools ๐พ'): | |
MemoryPasswordInput = gradio.Textbox(label='Password ๐', placeholder='Enter memory password', type='password', lines=1) | |
with gradio.TabItem('Save Memory ๐พ'): | |
with gradio.Group(): | |
SaveInput = gradio.Textbox(label='Memory Text ๐ญ', placeholder='Enter text to save', lines=3) | |
SaveBtn = gradio.Button('Save Memory ๐พ', variant='primary') | |
SaveBtn.click(SaveMemory, inputs=[SaveInput, MemoryPasswordInput], outputs=gradio.Text(label='Result')) | |
with gradio.TabItem('Delete Memory ๐๏ธ'): | |
with gradio.Group(): | |
DeleteInput = gradio.Textbox(label='Memory ID ๐๏ธ', placeholder='Enter ObjectId to delete', lines=1) | |
DeleteBtn = gradio.Button('Delete Memory ๐๏ธ', variant='secondary') | |
DeleteBtn.click(DeleteMemory, inputs=[DeleteInput, MemoryPasswordInput], outputs=gradio.Text(label='Result')) | |
with gradio.TabItem('List Memories ๐'): | |
with gradio.Group(): | |
ListBtn = gradio.Button('List All Memories ๐', variant='primary') | |
ListBtn.click(ListMemories, inputs=MemoryPasswordInput, outputs=gradio.Text(label='Memories')) | |
with gradio.TabItem('Search Memories ๐'): | |
with gradio.Group(): | |
SearchInput = gradio.Textbox(label='Search Query ๐', placeholder='Enter search text', lines=1) | |
SearchBtn = gradio.Button('Search Memories ๐', variant='primary') | |
SearchBtn.click(SearchMemories, inputs=[SearchInput, MemoryPasswordInput], outputs=gradio.Text(label='Results')) | |
App.launch( | |
mcp_server=True | |
) |