Spaces:
Runtime error
Runtime error
File size: 7,532 Bytes
10aaa36 6e6128e 09095fe f22964e 2a8d7ab 6e6128e 09095fe ac588ec 6e6128e 09095fe 6e6128e 09095fe fe81e0b 09095fe 6e6128e 09095fe 18a8600 6e6128e 09095fe 6e6128e 09095fe ac588ec 6e6128e 09095fe 6e6128e 09095fe 6e6128e 09095fe 6e6128e 09095fe 2a8d7ab 09095fe 55f620f 09095fe 6e6128e 09095fe |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
import asyncio
import gradio as gr
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.future import select # Correct async query API
from sqlalchemy.orm import sessionmaker
from models import Article # Assuming the Article model is defined in models.py
import logging
logger = logging.getLogger(__name__)
# This will constantly check the database status and update the textbox
async def update_db_status(db_status_textbox):
while True:
try:
await db_session.execute("SELECT 1") # Simple query to check connection
db_status_textbox.update("Connected")
except SQLAlchemyError:
db_status_textbox.update("Disconnected")
await asyncio.sleep(60) # Wait for 60 seconds before checking again
# Fetch the latest 20 articles and return them in a feed format
async def update_feed_content():
try:
result = await db_session.execute(
select(Article).order_by(Article.timestamp.desc()).limit(20)
)
articles = result.scalars().all() # Fetch latest articles
feed = {
'title': 'Website Changes Feed',
'link': 'http://yourwebsite.com/feed',
'description': 'Feed of changes detected on monitored websites.',
'items': [{
'title': article.title,
'link': article.url,
'description': article.content,
'pubDate': str(article.timestamp)
} for article in articles]
}
return feed
except SQLAlchemyError as e:
logger.error(f"Database error: {e}")
return None
# Periodic feed updater with error handling
async def periodic_update_with_error_handling():
while True:
try:
await asyncio.sleep(300) # Wait for 5 minutes
await update_feed_content() # Update the feed content
except Exception as e:
logger.error(f"Error in periodic update: {e}")
# Function for dynamically setting the database connection
async def set_db_connection(host, port, user, password, db_name):
global db_session, engine
try:
engine = create_async_engine(
f"mysql+aiomysql://{user}:{password}@{host}:{port}/{db_name}",
echo=False
)
Session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
db_session = Session()
return "Database connection established."
except Exception as e:
logger.error(f"Failed to establish database connection: {e}")
return f"Failed to connect to database: {e}"
# Main application that runs Gradio UI and background tasks
async def main():
global db_session
engine = None
demo = gr.Blocks()
# Define the Gradio interface
with demo:
gr.Markdown("# Website Monitor and Chatbot")
with gr.Row():
with gr.Column():
gr.Markdown("## Database Settings")
db_host = gr.Textbox(label="Database Host", placeholder="localhost", value="localhost")
db_port = gr.Textbox(label="Database Port", placeholder="3306", value="3306")
db_user = gr.Textbox(label="Database User", placeholder="username", value="")
db_pass = gr.Textbox(label="Database Password", placeholder="password", type="password", value="")
db_name = gr.Textbox(label="Database Name", placeholder="database_name", value="monitoring")
db_status_textbox = gr.Textbox(label="Database Status", interactive=False)
status_text = gr.Textbox(label="Status", interactive=False)
gr.Markdown("## RSS Feed Reader Settings")
feed_target_url = gr.Textbox(label="RSS Feed Target URL", placeholder="http://yourwebsite.com/feed")
view_button = gr.Button("View Feed")
target_urls = gr.Textbox(
label="Target URLs (comma-separated)",
placeholder="https://example.com, https://another-site.com"
)
storage_location = gr.Textbox(
label="Storage Location (CSV file path)",
placeholder="/path/to/your/file.csv"
)
feed_rss_checkbox = gr.Checkbox(label="Enable RSS Feed")
start_button = gr.Button("Start Monitoring")
stop_button = gr.Button("Stop Monitoring")
with gr.Column():
feed_content = gr.JSON(label="RSS Feed Content")
chatbot_interface = gr.Chatbot(type='messages')
message_input = gr.Textbox(placeholder="Type your message here...")
send_button = gr.Button("Send")
# Define button actions
async def on_start_click(target_urls_str: str, storage_loc: str, feed_enabled: bool,
host: str, port: str, user: str, password: str, db_name: str):
urls = [url.strip() for url in target_urls_str.split(",")]
await set_db_connection(host, port, user, password, db_name) # Connect to the DB
asyncio.create_task(start_monitoring(urls, storage_loc, feed_enabled)) # Start monitoring
return "Monitoring started."
async def on_view_feed_click(feed_url: str):
# Logic to fetch and view RSS feed data based on URL
return await fetch_feed_content(feed_url)
stop_button.click(on_stop_click, outputs=[status_text])
view_button.click(on_view_feed_click, inputs=[feed_target_url], outputs=[feed_content])
send_button.click(
chatbot_response,
inputs=[message_input, chatbot_interface],
outputs=[chatbot_interface, message_input]
)
# Set up the timer for periodic updates
feed_updater = gr.Timer(interval=300)
feed_updater.tick(fn=update_feed_content, outputs=feed_content)
# Load and check database status when the UI is loaded
demo.load(update_db_status, outputs=db_status_textbox)
asyncio.create_task(periodic_update_with_error_handling()) # Run periodic updates in the background
# Launch the Gradio demo
await demo.launch()
async def fetch_feed_content(feed_url: str):
# Logic to fetch RSS feed content from the provided URL
# You would replace this with actual RSS fetching and parsing logic
return {
'title': 'Sample Feed',
'link': feed_url,
'items': [
{'title': 'Sample Item 1', 'link': feed_url + '/1', 'description': 'This is a sample item.', 'pubDate': '2024-01-01'},
{'title': 'Sample Item 2', 'link': feed_url + '/2', 'description': 'This is another sample item.', 'pubDate': '2024-01-02'}
]
}
async def start_monitoring(urls, storage_location, feed_enabled):
# Logic to start monitoring URLs and optionally save to CSV or enable RSS
print(f"Starting monitoring for {urls}, saving to {storage_location}, RSS enabled: {feed_enabled}")
return
def stop_monitoring(url):
# Logic to stop monitoring a specific URL
print(f"Stopping monitoring for {url}")
return
async def chatbot_response(message, chat_interface):
# Example chatbot logic to respond to a user message
response = f"Echo: {message}"
chat_interface.append((message, response))
return chat_interface, ""
# Launch the app using asyncio
if __name__ == "__main__":
asyncio.run(main()) |