Spaces:
Build error
Build error
Update app.py
Browse files
app.py
CHANGED
|
@@ -10,22 +10,27 @@ import nltk
|
|
| 10 |
from nltk.sentiment import SentimentIntensityAnalyzer
|
| 11 |
from sklearn.feature_extraction.text import TfidfVectorizer
|
| 12 |
from sklearn.metrics.pairwise import cosine_similarity
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
try:
|
| 14 |
-
from transformers import pipeline
|
|
|
|
| 15 |
except ImportError as e:
|
| 16 |
print(f"Failed to import transformers: {e}")
|
| 17 |
-
print("Attempting to use a fallback model or configuration...")
|
| 18 |
pipeline = None
|
| 19 |
|
| 20 |
-
# Download NLTK resources
|
| 21 |
-
|
| 22 |
-
nltk.download('
|
| 23 |
-
nltk.download('
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
print(f"
|
| 27 |
-
if torch.cuda.is_available():
|
| 28 |
-
print(f"GPU name: {torch.cuda.get_device_name(0)}")
|
| 29 |
|
| 30 |
# Initialize sentiment analyzer
|
| 31 |
sia = SentimentIntensityAnalyzer()
|
|
@@ -77,749 +82,70 @@ class DataStore:
|
|
| 77 |
for user_id in user_ids[4:]:
|
| 78 |
self.record_interaction(user_id, blog_id, np.random.randint(1, 10))
|
| 79 |
|
| 80 |
-
|
| 81 |
-
user_id = str(uuid.uuid4())
|
| 82 |
-
self.users[user_id] = {
|
| 83 |
-
"id": user_id,
|
| 84 |
-
"username": username,
|
| 85 |
-
"password": password,
|
| 86 |
-
"email": email,
|
| 87 |
-
"display_name": display_name,
|
| 88 |
-
"role": role,
|
| 89 |
-
"created_at": datetime.datetime.now().isoformat(),
|
| 90 |
-
"badges": []
|
| 91 |
-
}
|
| 92 |
-
return user_id
|
| 93 |
-
|
| 94 |
-
def add_blog(self, title, content, author_id, tags):
|
| 95 |
-
blog_id = str(uuid.uuid4())
|
| 96 |
-
self.blogs[blog_id] = {
|
| 97 |
-
"id": blog_id,
|
| 98 |
-
"title": title,
|
| 99 |
-
"content": content,
|
| 100 |
-
"author_id": author_id,
|
| 101 |
-
"tags": tags,
|
| 102 |
-
"created_at": datetime.datetime.now().isoformat(),
|
| 103 |
-
"updated_at": datetime.datetime.now().isoformat(),
|
| 104 |
-
"comments": [],
|
| 105 |
-
"likes": 0,
|
| 106 |
-
"views": 0
|
| 107 |
-
}
|
| 108 |
-
return blog_id
|
| 109 |
-
|
| 110 |
-
def add_comment(self, blog_id, content, user_id):
|
| 111 |
-
comment_id = str(uuid.uuid4())
|
| 112 |
-
self.comments[comment_id] = {
|
| 113 |
-
"id": comment_id,
|
| 114 |
-
"blog_id": blog_id,
|
| 115 |
-
"content": content,
|
| 116 |
-
"user_id": user_id,
|
| 117 |
-
"created_at": datetime.datetime.now().isoformat()
|
| 118 |
-
}
|
| 119 |
-
self.blogs[blog_id]["comments"].append(comment_id)
|
| 120 |
-
return comment_id
|
| 121 |
-
|
| 122 |
-
def add_chat_message(self, chat_id, content, user_id):
|
| 123 |
-
if chat_id not in self.chats:
|
| 124 |
-
self.chats[chat_id] = {
|
| 125 |
-
"id": chat_id,
|
| 126 |
-
"messages": [],
|
| 127 |
-
"participants": []
|
| 128 |
-
}
|
| 129 |
-
message_id = str(uuid.uuid4())
|
| 130 |
-
message = {
|
| 131 |
-
"id": message_id,
|
| 132 |
-
"content": content,
|
| 133 |
-
"user_id": user_id,
|
| 134 |
-
"created_at": datetime.datetime.now().isoformat()
|
| 135 |
-
}
|
| 136 |
-
self.chats[chat_id]["messages"].append(message)
|
| 137 |
-
if user_id not in self.chats[chat_id]["participants"]:
|
| 138 |
-
self.chats[chat_id]["participants"].append(user_id)
|
| 139 |
-
return message_id
|
| 140 |
-
|
| 141 |
-
def record_interaction(self, user_id, blog_id, interaction_value):
|
| 142 |
-
if user_id not in self.user_interactions:
|
| 143 |
-
self.user_interactions[user_id] = {}
|
| 144 |
-
if blog_id not in self.user_interactions[user_id]:
|
| 145 |
-
self.user_interactions[user_id][blog_id] = 0
|
| 146 |
-
self.user_interactions[user_id][blog_id] += interaction_value
|
| 147 |
-
|
| 148 |
-
def authenticate_user(self, username, password):
|
| 149 |
-
for user_id, user in self.users.items():
|
| 150 |
-
if user["username"] == username and user["password"] == password:
|
| 151 |
-
return user_id
|
| 152 |
-
return None
|
| 153 |
-
|
| 154 |
-
def get_user_blogs(self, user_id):
|
| 155 |
-
return {blog_id: blog for blog_id, blog in self.blogs.items() if blog["author_id"] == user_id}
|
| 156 |
-
|
| 157 |
-
def get_all_blogs(self):
|
| 158 |
-
return self.blogs
|
| 159 |
-
|
| 160 |
-
def get_blog_by_id(self, blog_id):
|
| 161 |
-
return self.blogs.get(blog_id)
|
| 162 |
-
|
| 163 |
-
def get_user_by_id(self, user_id):
|
| 164 |
-
return self.users.get(user_id)
|
| 165 |
-
|
| 166 |
-
def get_chat_by_id(self, chat_id):
|
| 167 |
-
return self.chats.get(chat_id)
|
| 168 |
-
|
| 169 |
-
def get_comments_for_blog(self, blog_id):
|
| 170 |
-
blog = self.blogs.get(blog_id)
|
| 171 |
-
if not blog:
|
| 172 |
-
return []
|
| 173 |
-
comments = []
|
| 174 |
-
for comment_id in blog["comments"]:
|
| 175 |
-
comment = self.comments.get(comment_id)
|
| 176 |
-
if comment:
|
| 177 |
-
comments.append(comment)
|
| 178 |
-
return comments
|
| 179 |
|
| 180 |
# Initialize data store
|
| 181 |
data_store = DataStore()
|
| 182 |
|
| 183 |
-
# Machine Learning Models
|
| 184 |
class MLModels:
|
| 185 |
def __init__(self):
|
| 186 |
self.sentiment_model_name = "distilbert-base-uncased-finetuned-sst-2-english"
|
| 187 |
self.sentiment_analyzer = None
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 194 |
self.tfidf_vectorizer = TfidfVectorizer(max_features=1000)
|
| 195 |
self.blog_vectors = None
|
| 196 |
self.update_blog_vectors()
|
| 197 |
|
| 198 |
-
|
| 199 |
-
blog_contents = [f"{blog['title']} {' '.join(blog['tags'])} {blog['content']}"
|
| 200 |
-
for blog in data_store.blogs.values()]
|
| 201 |
-
if blog_contents:
|
| 202 |
-
self.blog_vectors = self.tfidf_vectorizer.fit_transform(blog_contents)
|
| 203 |
-
else:
|
| 204 |
-
self.blog_vectors = None
|
| 205 |
-
|
| 206 |
-
def analyze_sentiment(self, text):
|
| 207 |
-
if self.sentiment_analyzer is not None:
|
| 208 |
-
try:
|
| 209 |
-
result = self.sentiment_analyzer(text, truncation=True, max_length=512)[0]
|
| 210 |
-
score = result["score"] if result["label"] == "POSITIVE" else 1 - result["score"]
|
| 211 |
-
return {
|
| 212 |
-
"score": float(score),
|
| 213 |
-
"label": result["label"].lower(),
|
| 214 |
-
"is_inappropriate": score < 0.2
|
| 215 |
-
}
|
| 216 |
-
except Exception as e:
|
| 217 |
-
print(f"Sentiment analysis failed: {e}")
|
| 218 |
-
vader_scores = sia.polarity_scores(text)
|
| 219 |
-
score = (vader_scores['compound'] + 1) / 2
|
| 220 |
-
return {
|
| 221 |
-
"score": float(score),
|
| 222 |
-
"label": "positive" if score > 0.5 else "negative",
|
| 223 |
-
"is_inappropriate": score < 0.2
|
| 224 |
-
}
|
| 225 |
-
|
| 226 |
-
def recommend_blogs(self, user_id, limit=5):
|
| 227 |
-
if user_id not in data_store.user_interactions or len(data_store.user_interactions[user_id]) < 2:
|
| 228 |
-
return self.content_based_recommendations(user_id, limit)
|
| 229 |
-
else:
|
| 230 |
-
return self.collaborative_filtering(user_id, limit)
|
| 231 |
-
|
| 232 |
-
def content_based_recommendations(self, user_id, limit=5):
|
| 233 |
-
user_blogs = data_store.user_interactions.get(user_id, {})
|
| 234 |
-
if not user_blogs:
|
| 235 |
-
blog_ids = list(data_store.blogs.keys())
|
| 236 |
-
np.random.shuffle(blog_ids)
|
| 237 |
-
return blog_ids[:limit]
|
| 238 |
-
user_profile = np.zeros(self.blog_vectors.shape[1])
|
| 239 |
-
total_interactions = 0
|
| 240 |
-
for blog_id, interaction_count in user_blogs.items():
|
| 241 |
-
blog_idx = list(data_store.blogs.keys()).index(blog_id)
|
| 242 |
-
user_profile += interaction_count
|
| 243 |
-
total_interactions += interaction_count
|
| 244 |
-
if total_interactions > 0:
|
| 245 |
-
user_profile /= total_interactions
|
| 246 |
-
similarities = []
|
| 247 |
-
for i, blog_id in enumerate(data_store.blogs.keys()):
|
| 248 |
-
if blog_id not in user_blogs:
|
| 249 |
-
blog_vector = self.blog_vectors[i].toarray()[0]
|
| 250 |
-
similarity = np.dot(user_profile, blog_vector) / (np.linalg.norm(user_profile) * np.linalg.norm(blog_vector) + 1e-8)
|
| 251 |
-
similarities.append((blog_id, similarity))
|
| 252 |
-
similarities.sort(key=lambda x: x[1], reverse=True)
|
| 253 |
-
return [blog_id for blog_id, _ in similarities[:limit]]
|
| 254 |
-
|
| 255 |
-
def collaborative_filtering(self, user_id, limit=5):
|
| 256 |
-
user_ids = list(data_store.user_interactions.keys())
|
| 257 |
-
blog_ids = list(data_store.blogs.keys())
|
| 258 |
-
if user_id not in user_ids:
|
| 259 |
-
return self.content_based_recommendations(user_id, limit)
|
| 260 |
-
interaction_matrix = np.zeros((len(user_ids), len(blog_ids)))
|
| 261 |
-
for i, u_id in enumerate(user_ids):
|
| 262 |
-
for j, b_id in enumerate(blog_ids):
|
| 263 |
-
interaction_matrix[i, j] = data_store.user_interactions.get(u_id, {}).get(b_id, 0)
|
| 264 |
-
user_similarity = cosine_similarity(interaction_matrix)
|
| 265 |
-
user_idx = user_ids.index(user_id)
|
| 266 |
-
similar_users = [(user_ids[i], user_similarity[user_idx, i])
|
| 267 |
-
for i in range(len(user_ids)) if i != user_idx]
|
| 268 |
-
similar_users.sort(key=lambda x: x[1], reverse=True)
|
| 269 |
-
recommendations = {}
|
| 270 |
-
for similar_user_id, similarity in similar_users[:5]:
|
| 271 |
-
similar_user_idx = user_ids.index(similar_user_id)
|
| 272 |
-
for j, blog_id in enumerate(blog_ids):
|
| 273 |
-
if blog_id in data_store.user_interactions.get(user_id, {}):
|
| 274 |
-
continue
|
| 275 |
-
if interaction_matrix[similar_user_idx, j] > 0:
|
| 276 |
-
if blog_id not in recommendations:
|
| 277 |
-
recommendations[blog_id] = 0
|
| 278 |
-
recommendations[blog_id] += similarity * interaction_matrix[similar_user_idx, j]
|
| 279 |
-
sorted_recommendations = sorted(recommendations.items(), key=lambda x: x[1], reverse=True)
|
| 280 |
-
return [blog_id for blog_id, _ in sorted_recommendations[:limit]]
|
| 281 |
-
|
| 282 |
-
def moderate_text(self, text):
|
| 283 |
-
sentiment_result = self.analyze_sentiment(text)
|
| 284 |
-
is_inappropriate = sentiment_result["is_inappropriate"]
|
| 285 |
-
banned_words = ["hate", "spam", "offensive", "racist", "sexist"]
|
| 286 |
-
contains_banned_words = any(word in text.lower() for word in banned_words)
|
| 287 |
-
return {
|
| 288 |
-
"is_flagged": is_inappropriate or contains_banned_words,
|
| 289 |
-
"sentiment": sentiment_result["label"],
|
| 290 |
-
"confidence": sentiment_result["score"]
|
| 291 |
-
}
|
| 292 |
|
| 293 |
# Initialize ML models
|
| 294 |
ml_models = MLModels()
|
| 295 |
|
| 296 |
-
# Custom CSS
|
| 297 |
custom_css = """
|
| 298 |
-
|
| 299 |
-
font-family: 'Arial', sans-serif;
|
| 300 |
-
background-color: #f4f7fb;
|
| 301 |
-
}
|
| 302 |
-
.header {
|
| 303 |
-
background-color: #2c3e50;
|
| 304 |
-
color: white;
|
| 305 |
-
padding: 15px;
|
| 306 |
-
text-align: center;
|
| 307 |
-
border-radius: 8px;
|
| 308 |
-
margin-bottom: 20px;
|
| 309 |
-
}
|
| 310 |
-
.card {
|
| 311 |
-
background-color: white;
|
| 312 |
-
border-radius: 8px;
|
| 313 |
-
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
|
| 314 |
-
padding: 15px;
|
| 315 |
-
margin-bottom: 15px;
|
| 316 |
-
transition: transform 0.2s;
|
| 317 |
-
}
|
| 318 |
-
.card:hover {
|
| 319 |
-
transform: translateY(-2px);
|
| 320 |
-
}
|
| 321 |
-
.gr-button {
|
| 322 |
-
background-color: #3498db;
|
| 323 |
-
color: white;
|
| 324 |
-
border: none;
|
| 325 |
-
border-radius: 5px;
|
| 326 |
-
padding: 10px 20px;
|
| 327 |
-
font-size: 16px;
|
| 328 |
-
cursor: pointer;
|
| 329 |
-
transition: background-color 0.2s;
|
| 330 |
-
}
|
| 331 |
-
.gr-button:hover {
|
| 332 |
-
background-color: #2980b9;
|
| 333 |
-
}
|
| 334 |
-
.gr-button.secondary {
|
| 335 |
-
background-color: #7f8c8d;
|
| 336 |
-
}
|
| 337 |
-
.gr-button.secondary:hover {
|
| 338 |
-
background-color: #636e72;
|
| 339 |
-
}
|
| 340 |
-
.gr-textbox {
|
| 341 |
-
border-radius: 5px;
|
| 342 |
-
border: 1px solid #dcdcdc;
|
| 343 |
-
padding: 10px;
|
| 344 |
-
}
|
| 345 |
-
.tab-nav button {
|
| 346 |
-
border-radius: 5px 5px 0 0 !important;
|
| 347 |
-
}
|
| 348 |
-
.tab-nav button[aria-selected="true"] {
|
| 349 |
-
background-color: #3498db !important;
|
| 350 |
-
color: white !important;
|
| 351 |
-
}
|
| 352 |
-
@media (max-width: 768px) {
|
| 353 |
-
.card {
|
| 354 |
-
padding: 10px;
|
| 355 |
-
}
|
| 356 |
-
.gr-button {
|
| 357 |
-
padding: 8px 15px;
|
| 358 |
-
font-size: 14px;
|
| 359 |
-
}
|
| 360 |
-
}
|
| 361 |
"""
|
| 362 |
|
| 363 |
-
# Gradio Interface
|
| 364 |
def create_interface():
|
| 365 |
with gr.Blocks(css=custom_css) as interface:
|
| 366 |
-
|
| 367 |
-
|
| 368 |
-
# Header
|
| 369 |
-
gr.Markdown("<div class='header'><h1>BlogSphere</h1><p>Your hub for tech insights and discussions</p></div>")
|
| 370 |
-
|
| 371 |
-
# Authentication
|
| 372 |
-
with gr.Group() as auth_group:
|
| 373 |
-
with gr.Row():
|
| 374 |
-
with gr.Column(scale=1, min_width=300):
|
| 375 |
-
gr.Markdown("## Sign In")
|
| 376 |
-
username_input = gr.Textbox(label="Username", placeholder="Enter your username")
|
| 377 |
-
password_input = gr.Textbox(label="Password", type="password", placeholder="Enter your password")
|
| 378 |
-
login_button = gr.Button("Login")
|
| 379 |
-
login_status = gr.Textbox(label="Status", interactive=False, placeholder="Login status will appear here")
|
| 380 |
-
|
| 381 |
-
# Main interface
|
| 382 |
-
with gr.Group(visible=False) as main_group:
|
| 383 |
-
current_blog_id = gr.State("")
|
| 384 |
-
current_chat_id = gr.State("")
|
| 385 |
-
|
| 386 |
-
# Navigation bar
|
| 387 |
-
with gr.Row():
|
| 388 |
-
refresh_button = gr.Button("Refresh Content", variant="secondary")
|
| 389 |
-
|
| 390 |
-
# Tabs
|
| 391 |
-
with gr.Tabs() as tabs:
|
| 392 |
-
# Blog Feed Tab
|
| 393 |
-
with gr.TabItem("Blog Feed"):
|
| 394 |
-
gr.Markdown("## Explore Blogs")
|
| 395 |
-
with gr.Row():
|
| 396 |
-
with gr.Column(scale=3):
|
| 397 |
-
blog_list = gr.HTML()
|
| 398 |
-
blog_refresh_button = gr.Button("Load More Blogs", variant="secondary")
|
| 399 |
-
|
| 400 |
-
with gr.Column(scale=1):
|
| 401 |
-
gr.Markdown("## Recommended For You")
|
| 402 |
-
recommended_blogs = gr.HTML()
|
| 403 |
-
|
| 404 |
-
with gr.Row():
|
| 405 |
-
with gr.Column():
|
| 406 |
-
gr.Markdown("## Blog Content")
|
| 407 |
-
blog_title = gr.Textbox(label="Title", interactive=False)
|
| 408 |
-
blog_author = gr.Textbox(label="Author", interactive=False)
|
| 409 |
-
blog_content = gr.Textbox(label="Content", lines=10, interactive=False)
|
| 410 |
-
blog_tags = gr.Textbox(label="Tags", interactive=False)
|
| 411 |
-
|
| 412 |
-
with gr.Accordion("Comments", open=False):
|
| 413 |
-
blog_comments = gr.HTML()
|
| 414 |
-
new_comment = gr.Textbox(label="Add a comment", placeholder="Write your comment here")
|
| 415 |
-
submit_comment = gr.Button("Submit Comment")
|
| 416 |
-
|
| 417 |
-
# My Blogs Tab
|
| 418 |
-
with gr.TabItem("My Blogs"):
|
| 419 |
-
gr.Markdown("## My Published Blogs")
|
| 420 |
-
my_blogs_list = gr.HTML()
|
| 421 |
-
|
| 422 |
-
with gr.Accordion("Create New Blog", open=False):
|
| 423 |
-
new_blog_title = gr.Textbox(label="Title", placeholder="Enter blog title")
|
| 424 |
-
new_blog_content = gr.Textbox(label="Content", lines=10, placeholder="Write your blog content here")
|
| 425 |
-
new_blog_tags = gr.Textbox(label="Tags", placeholder="Enter tags, separated by commas")
|
| 426 |
-
create_blog_button = gr.Button("Publish Blog")
|
| 427 |
-
blog_create_status = gr.Textbox(label="Status", interactive=False)
|
| 428 |
-
|
| 429 |
-
# Chat Tab
|
| 430 |
-
with gr.TabItem("Chat"):
|
| 431 |
-
with gr.Row():
|
| 432 |
-
with gr.Column(scale=1):
|
| 433 |
-
gr.Markdown("## Chat Rooms")
|
| 434 |
-
chat_list = gr.HTML()
|
| 435 |
-
new_chat_name = gr.Textbox(label="New Chat Room Name", placeholder="Enter chat room name")
|
| 436 |
-
create_chat_button = gr.Button("Create Chat Room")
|
| 437 |
-
|
| 438 |
-
with gr.Column(scale=2):
|
| 439 |
-
gr.Markdown("## Chat")
|
| 440 |
-
chat_messages = gr.Chatbot(label="Messages")
|
| 441 |
-
new_message = gr.Textbox(label="Message", placeholder="Type your message")
|
| 442 |
-
send_message_button = gr.Button("Send")
|
| 443 |
-
moderation_status = gr.Textbox(label="Moderation Status", interactive=False)
|
| 444 |
-
|
| 445 |
-
# Profile Tab
|
| 446 |
-
with gr.TabItem("Profile"):
|
| 447 |
-
gr.Markdown("## User Profile")
|
| 448 |
-
display_name = gr.Textbox(label="Display Name", placeholder="Enter display name")
|
| 449 |
-
email = gr.Textbox(label="Email", placeholder="Enter email")
|
| 450 |
-
user_role = gr.Textbox(label="Role", interactive=False)
|
| 451 |
-
user_badges = gr.Textbox(label="Badges", interactive=False)
|
| 452 |
-
update_profile_button = gr.Button("Update Profile")
|
| 453 |
-
profile_update_status = gr.Textbox(label="Status", interactive=False)
|
| 454 |
-
logout_button = gr.Button("Logout", variant="secondary")
|
| 455 |
-
|
| 456 |
-
# Helper functions
|
| 457 |
-
def format_blog_card(blog_id, blog, author_name, is_recommended=False):
|
| 458 |
-
title = blog["title"]
|
| 459 |
-
tags = ", ".join(blog["tags"])
|
| 460 |
-
likes = blog["likes"]
|
| 461 |
-
views = blog["views"]
|
| 462 |
-
snippet = blog["content"][:100] + "..." if len(blog["content"]) > 100 else blog["content"]
|
| 463 |
-
return f"""
|
| 464 |
-
<div class='card' onclick='selectBlog("{blog_id}")'>
|
| 465 |
-
<h3>{title}</h3>
|
| 466 |
-
<p><b>Author:</b> {author_name}</p>
|
| 467 |
-
<p>{snippet}</p>
|
| 468 |
-
<p><b>Tags:</b> {tags}</p>
|
| 469 |
-
<p><b>Likes:</b> {likes} | <b>Views:</b> {views}</p>
|
| 470 |
-
</div>
|
| 471 |
-
"""
|
| 472 |
-
|
| 473 |
-
def format_comment_card(comment, user_name):
|
| 474 |
-
content = comment["content"]
|
| 475 |
-
date = comment["created_at"]
|
| 476 |
-
return f"""
|
| 477 |
-
<div class='card'>
|
| 478 |
-
<p><b>{user_name}</b> - {date}</p>
|
| 479 |
-
<p>{content}</p>
|
| 480 |
-
</div>
|
| 481 |
-
"""
|
| 482 |
-
|
| 483 |
-
def format_chat_room_card(chat_id, participants):
|
| 484 |
-
return f"""
|
| 485 |
-
<div class='card' onclick='selectChat("{chat_id}")'>
|
| 486 |
-
<h4>Chat Room {chat_id[:8]}</h4>
|
| 487 |
-
<p><b>Participants:</b> {', '.join(participants)}</p>
|
| 488 |
-
</div>
|
| 489 |
-
"""
|
| 490 |
-
|
| 491 |
-
# Functions
|
| 492 |
-
def login(username, password):
|
| 493 |
-
user_id = data_store.authenticate_user(username, password)
|
| 494 |
-
if user_id:
|
| 495 |
-
user = data_store.get_user_by_id(user_id)
|
| 496 |
-
data_store.current_user_id = user_id
|
| 497 |
-
recommended = load_recommended_blogs(user_id)
|
| 498 |
-
user_blogs = load_user_blogs(user_id)
|
| 499 |
-
profile_data = load_user_profile(user_id)
|
| 500 |
-
chat_rooms = load_chat_rooms()
|
| 501 |
-
return (
|
| 502 |
-
user_id,
|
| 503 |
-
f"Welcome back, {user['display_name']}!",
|
| 504 |
-
gr.update(visible=False),
|
| 505 |
-
gr.update(visible=True),
|
| 506 |
-
recommended,
|
| 507 |
-
user_blogs,
|
| 508 |
-
chat_rooms,
|
| 509 |
-
profile_data[0],
|
| 510 |
-
profile_data[1],
|
| 511 |
-
profile_data[2],
|
| 512 |
-
profile_data[3]
|
| 513 |
-
)
|
| 514 |
-
else:
|
| 515 |
-
return "", "Invalid username or password", gr.update(visible=True), gr.update(visible=False), "", "", "", "", "", "", ""
|
| 516 |
-
|
| 517 |
-
def load_blogs():
|
| 518 |
-
blogs = data_store.get_all_blogs()
|
| 519 |
-
blog_html = ""
|
| 520 |
-
for blog_id, blog in blogs.items():
|
| 521 |
-
author = data_store.get_user_by_id(blog["author_id"])
|
| 522 |
-
author_name = author["display_name"] if author else "Unknown"
|
| 523 |
-
blog_html += format_blog_card(blog_id, blog, author_name)
|
| 524 |
-
return blog_html
|
| 525 |
-
|
| 526 |
-
def load_recommended_blogs(user_id):
|
| 527 |
-
if not user_id:
|
| 528 |
-
return ""
|
| 529 |
-
recommended_blog_ids = ml_models.recommend_blogs(user_id)
|
| 530 |
-
recommended_html = ""
|
| 531 |
-
for blog_id in recommended_blog_ids:
|
| 532 |
-
blog = data_store.get_blog_by_id(blog_id)
|
| 533 |
-
if blog:
|
| 534 |
-
author = data_store.get_user_by_id(blog["author_id"])
|
| 535 |
-
author_name = author["display_name"] if author else "Unknown"
|
| 536 |
-
recommended_html += format_blog_card(blog_id, blog, author_name, is_recommended=True)
|
| 537 |
-
return recommended_html
|
| 538 |
-
|
| 539 |
-
def view_blog(blog_id):
|
| 540 |
-
if not blog_id:
|
| 541 |
-
return "", "", "", "", ""
|
| 542 |
-
blog = data_store.get_blog_by_id(blog_id)
|
| 543 |
-
if not blog:
|
| 544 |
-
return "", "", "", "", ""
|
| 545 |
-
blog["views"] += 1
|
| 546 |
-
if data_store.current_user_id:
|
| 547 |
-
data_store.record_interaction(data_store.current_user_id, blog_id, 1)
|
| 548 |
-
author = data_store.get_user_by_id(blog["author_id"])
|
| 549 |
-
author_name = author["display_name"] if author else "Unknown"
|
| 550 |
-
comments_data = ""
|
| 551 |
-
for comment_id in blog["comments"]:
|
| 552 |
-
comment = data_store.comments.get(comment_id)
|
| 553 |
-
if comment:
|
| 554 |
-
comment_user = data_store.get_user_by_id(comment["user_id"])
|
| 555 |
-
user_name = comment_user["display_name"] if comment_user else "Unknown"
|
| 556 |
-
comments_data += format_comment_card(comment, user_name)
|
| 557 |
-
return (
|
| 558 |
-
blog_id,
|
| 559 |
-
blog["title"],
|
| 560 |
-
author_name,
|
| 561 |
-
blog["content"],
|
| 562 |
-
", ".join(blog["tags"]),
|
| 563 |
-
comments_data
|
| 564 |
-
)
|
| 565 |
-
|
| 566 |
-
def add_comment(blog_id, comment_text, user_id):
|
| 567 |
-
if not user_id:
|
| 568 |
-
return "Please log in to comment", ""
|
| 569 |
-
if not blog_id:
|
| 570 |
-
return "Please select a blog first", ""
|
| 571 |
-
moderation_result = ml_models.moderate_text(comment_text)
|
| 572 |
-
if moderation_result["is_flagged"]:
|
| 573 |
-
return "Your comment has been flagged for inappropriate content", ""
|
| 574 |
-
data_store.add_comment(blog_id, comment_text, user_id)
|
| 575 |
-
data_store.record_interaction(user_id, blog_id, 2)
|
| 576 |
-
comments_data = ""
|
| 577 |
-
blog = data_store.get_blog_by_id(blog_id)
|
| 578 |
-
for comment_id in blog["comments"]:
|
| 579 |
-
comment = data_store.comments.get(comment_id)
|
| 580 |
-
if comment:
|
| 581 |
-
comment_user = data_store.get_user_by_id(comment["user_id"])
|
| 582 |
-
user_name = comment_user["display_name"] if comment_user else "Unknown"
|
| 583 |
-
comments_data += format_comment_card(comment, user_name)
|
| 584 |
-
return "Comment added successfully", comments_data
|
| 585 |
-
|
| 586 |
-
def load_user_blogs(user_id):
|
| 587 |
-
if not user_id:
|
| 588 |
-
return ""
|
| 589 |
-
user_blogs = data_store.get_user_blogs(user_id)
|
| 590 |
-
blogs_html = ""
|
| 591 |
-
for blog_id, blog in user_blogs.items():
|
| 592 |
-
author = data_store.get_user_by_id(blog["author_id"])
|
| 593 |
-
author_name = author["display_name"] if author else "Unknown"
|
| 594 |
-
blogs_html += format_blog_card(blog_id, blog, author_name)
|
| 595 |
-
return blogs_html
|
| 596 |
-
|
| 597 |
-
def create_blog(title, content, tags, user_id):
|
| 598 |
-
if not user_id:
|
| 599 |
-
return "Please log in to create a blog"
|
| 600 |
-
if not title or not content:
|
| 601 |
-
return "Title and content are required"
|
| 602 |
-
moderation_result = ml_models.moderate_text(content)
|
| 603 |
-
if moderation_result["is_flagged"]:
|
| 604 |
-
return "Your blog has been flagged for inappropriate content"
|
| 605 |
-
tag_list = [tag.strip() for tag in tags.split(",") if tag.strip()]
|
| 606 |
-
blog_id = data_store.add_blog(title, content, user_id, tag_list)
|
| 607 |
-
ml_models.update_blog_vectors()
|
| 608 |
-
return f"Blog created successfully with ID: {blog_id}"
|
| 609 |
-
|
| 610 |
-
def load_chat_rooms():
|
| 611 |
-
chat_html = ""
|
| 612 |
-
for chat_id, chat in data_store.chats.items():
|
| 613 |
-
participants = []
|
| 614 |
-
for user_id in chat["participants"]:
|
| 615 |
-
user = data_store.get_user_by_id(user_id)
|
| 616 |
-
if user:
|
| 617 |
-
participants.append(user["display_name"])
|
| 618 |
-
chat_html += format_chat_room_card(chat_id, participants)
|
| 619 |
-
return chat_html
|
| 620 |
-
|
| 621 |
-
def create_chat_room(name, user_id):
|
| 622 |
-
if not user_id:
|
| 623 |
-
return "Please log in to create a chat room", ""
|
| 624 |
-
chat_id = str(uuid.uuid4())
|
| 625 |
-
data_store.chats[chat_id] = {
|
| 626 |
-
"id": chat_id,
|
| 627 |
-
"name": name,
|
| 628 |
-
"messages": [],
|
| 629 |
-
"participants": [user_id],
|
| 630 |
-
"created_at": datetime.datetime.now().isoformat()
|
| 631 |
-
}
|
| 632 |
-
return chat_id, load_chat_rooms()
|
| 633 |
-
|
| 634 |
-
def view_chat(chat_id):
|
| 635 |
-
if not chat_id:
|
| 636 |
-
return [], ""
|
| 637 |
-
chat = data_store.get_chat_by_id(chat_id)
|
| 638 |
-
if not chat:
|
| 639 |
-
return [], ""
|
| 640 |
-
messages_data = []
|
| 641 |
-
for message in chat["messages"]:
|
| 642 |
-
user = data_store.get_user_by_id(message["user_id"])
|
| 643 |
-
user_name = user["display_name"] if user else "Unknown"
|
| 644 |
-
messages_data.append([f"{user_name} ({message['created_at']})", message["content"]])
|
| 645 |
-
return messages_data, chat_id
|
| 646 |
-
|
| 647 |
-
def send_message(chat_id, message, user_id):
|
| 648 |
-
if not user_id:
|
| 649 |
-
return "Please log in to send messages", []
|
| 650 |
-
if not chat_id:
|
| 651 |
-
return "Please select a chat room first", []
|
| 652 |
-
moderation_result = ml_models.moderate_text(message)
|
| 653 |
-
if moderation_result["is_flagged"]:
|
| 654 |
-
return "Your message has been flagged for inappropriate content", []
|
| 655 |
-
data_store.add_chat_message(chat_id, message, user_id)
|
| 656 |
-
chat = data_store.get_chat_by_id(chat_id)
|
| 657 |
-
messages_data = []
|
| 658 |
-
for msg in chat["messages"]:
|
| 659 |
-
user = data_store.get_user_by_id(msg["user_id"])
|
| 660 |
-
user_name = user["display_name"] if user else "Unknown"
|
| 661 |
-
messages_data.append([f"{user_name} ({msg['created_at']})", msg["content"]])
|
| 662 |
-
return "Message sent successfully", messages_data
|
| 663 |
-
|
| 664 |
-
def load_user_profile(user_id):
|
| 665 |
-
if not user_id:
|
| 666 |
-
return "", "", "", ""
|
| 667 |
-
user = data_store.get_user_by_id(user_id)
|
| 668 |
-
if user:
|
| 669 |
-
return user["display_name"], user["email"], user["role"], ", ".join(user["badges"])
|
| 670 |
-
return "", "", "", ""
|
| 671 |
-
|
| 672 |
-
def update_profile(display_name, email, user_id):
|
| 673 |
-
if not user_id:
|
| 674 |
-
return "Please log in to update your profile"
|
| 675 |
-
user = data_store.get_user_by_id(user_id)
|
| 676 |
-
if user:
|
| 677 |
-
user["display_name"] = display_name
|
| 678 |
-
user["email"] = email
|
| 679 |
-
return "Profile updated successfully"
|
| 680 |
-
return "User not found"
|
| 681 |
-
|
| 682 |
-
def logout():
|
| 683 |
-
data_store.current_user_id = None
|
| 684 |
-
return "", gr.update(visible=True), gr.update(visible=False), "", "", "", "", "", "", ""
|
| 685 |
-
|
| 686 |
-
def refresh_content(user_id):
|
| 687 |
-
if not user_id:
|
| 688 |
-
return "", "", ""
|
| 689 |
-
return (
|
| 690 |
-
load_recommended_blogs(user_id),
|
| 691 |
-
load_user_blogs(user_id),
|
| 692 |
-
load_chat_rooms()
|
| 693 |
-
)
|
| 694 |
-
|
| 695 |
-
# JavaScript for click events
|
| 696 |
-
js_select_blog = """
|
| 697 |
-
function selectBlog(blogId) {
|
| 698 |
-
document.querySelector('input[name="blog_id"]').value = blogId;
|
| 699 |
-
document.querySelector('input[name="blog_id"]').dispatchEvent(new Event('input'));
|
| 700 |
-
}
|
| 701 |
-
"""
|
| 702 |
-
js_select_chat = """
|
| 703 |
-
function selectChat(chatId) {
|
| 704 |
-
document.querySelector('input[name="chat_id"]').value = chatId;
|
| 705 |
-
document.querySelector('input[name="chat_id"]').dispatchEvent(new Event('input'));
|
| 706 |
-
}
|
| 707 |
-
"""
|
| 708 |
-
|
| 709 |
-
# Hidden inputs for JavaScript events
|
| 710 |
-
blog_id_input = gr.Textbox(value="", label="Blog ID", name="blog_id", visible=False)
|
| 711 |
-
chat_id_input = gr.Textbox(value="", label="Chat ID", name="chat_id", visible=False)
|
| 712 |
-
|
| 713 |
-
# Connect events
|
| 714 |
-
login_button.click(
|
| 715 |
-
fn=login,
|
| 716 |
-
inputs=[username_input, password_input],
|
| 717 |
-
outputs=[
|
| 718 |
-
user_id_state,
|
| 719 |
-
login_status,
|
| 720 |
-
auth_group,
|
| 721 |
-
main_group,
|
| 722 |
-
recommended_blogs,
|
| 723 |
-
my_blogs_list,
|
| 724 |
-
chat_list,
|
| 725 |
-
display_name,
|
| 726 |
-
email,
|
| 727 |
-
user_role,
|
| 728 |
-
user_badges
|
| 729 |
-
],
|
| 730 |
-
show_progress=True
|
| 731 |
-
)
|
| 732 |
-
|
| 733 |
-
blog_refresh_button.click(
|
| 734 |
-
fn=load_blogs,
|
| 735 |
-
inputs=[],
|
| 736 |
-
outputs=[blog_list],
|
| 737 |
-
show_progress=True
|
| 738 |
-
)
|
| 739 |
-
|
| 740 |
-
blog_id_input.input(
|
| 741 |
-
fn=view_blog,
|
| 742 |
-
inputs=[blog_id_input],
|
| 743 |
-
outputs=[current_blog_id, blog_title, blog_author, blog_content, blog_tags, blog_comments],
|
| 744 |
-
_js=js_select_blog
|
| 745 |
-
)
|
| 746 |
-
|
| 747 |
-
submit_comment.click(
|
| 748 |
-
fn=add_comment,
|
| 749 |
-
inputs=[current_blog_id, new_comment, user_id_state],
|
| 750 |
-
outputs=[blog_create_status, blog_comments],
|
| 751 |
-
show_progress=True
|
| 752 |
-
)
|
| 753 |
-
|
| 754 |
-
create_blog_button.click(
|
| 755 |
-
fn=create_blog,
|
| 756 |
-
inputs=[new_blog_title, new_blog_content, new_blog_tags, user_id_state],
|
| 757 |
-
outputs=[blog_create_status],
|
| 758 |
-
show_progress=True
|
| 759 |
-
)
|
| 760 |
-
|
| 761 |
-
create_chat_button.click(
|
| 762 |
-
fn=create_chat_room,
|
| 763 |
-
inputs=[new_chat_name, user_id_state],
|
| 764 |
-
outputs=[current_chat_id, chat_list],
|
| 765 |
-
show_progress=True
|
| 766 |
-
)
|
| 767 |
-
|
| 768 |
-
chat_id_input.input(
|
| 769 |
-
fn=view_chat,
|
| 770 |
-
inputs=[chat_id_input],
|
| 771 |
-
outputs=[chat_messages, current_chat_id],
|
| 772 |
-
_js=js_select_chat
|
| 773 |
-
)
|
| 774 |
-
|
| 775 |
-
send_message_button.click(
|
| 776 |
-
fn=send_message,
|
| 777 |
-
inputs=[current_chat_id, new_message, user_id_state],
|
| 778 |
-
outputs=[moderation_status, chat_messages],
|
| 779 |
-
show_progress=True
|
| 780 |
-
)
|
| 781 |
-
|
| 782 |
-
update_profile_button.click(
|
| 783 |
-
fn=update_profile,
|
| 784 |
-
inputs=[display_name, email, user_id_state],
|
| 785 |
-
outputs=[profile_update_status],
|
| 786 |
-
show_progress=True
|
| 787 |
-
)
|
| 788 |
-
|
| 789 |
-
logout_button.click(
|
| 790 |
-
fn=logout,
|
| 791 |
-
inputs=[],
|
| 792 |
-
outputs=[
|
| 793 |
-
user_id_state,
|
| 794 |
-
auth_group,
|
| 795 |
-
main_group,
|
| 796 |
-
recommended_blogs,
|
| 797 |
-
my_blogs_list,
|
| 798 |
-
chat_list,
|
| 799 |
-
display_name,
|
| 800 |
-
email,
|
| 801 |
-
user_role,
|
| 802 |
-
user_badges
|
| 803 |
-
],
|
| 804 |
-
show_progress=True
|
| 805 |
-
)
|
| 806 |
-
|
| 807 |
-
refresh_button.click(
|
| 808 |
-
fn=refresh_content,
|
| 809 |
-
inputs=[user_id_state],
|
| 810 |
-
outputs=[recommended_blogs, my_blogs_list, chat_list],
|
| 811 |
-
show_progress=True
|
| 812 |
-
)
|
| 813 |
-
|
| 814 |
-
# Initial load
|
| 815 |
-
blog_list.value = load_blogs()
|
| 816 |
-
|
| 817 |
return interface
|
| 818 |
|
| 819 |
-
#
|
| 820 |
def launch_app():
|
| 821 |
-
|
| 822 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 823 |
|
| 824 |
if __name__ == "__main__":
|
| 825 |
launch_app()
|
|
|
|
| 10 |
from nltk.sentiment import SentimentIntensityAnalyzer
|
| 11 |
from sklearn.feature_extraction.text import TfidfVectorizer
|
| 12 |
from sklearn.metrics.pairwise import cosine_similarity
|
| 13 |
+
import sys
|
| 14 |
+
|
| 15 |
+
# Debugging info
|
| 16 |
+
print("Python version:", sys.version)
|
| 17 |
+
print("PyTorch version:", torch.__version__)
|
| 18 |
+
print("CUDA available:", torch.cuda.is_available())
|
| 19 |
+
|
| 20 |
try:
|
| 21 |
+
from transformers import pipeline, __version__ as transformers_version
|
| 22 |
+
print("Transformers version:", transformers_version)
|
| 23 |
except ImportError as e:
|
| 24 |
print(f"Failed to import transformers: {e}")
|
|
|
|
| 25 |
pipeline = None
|
| 26 |
|
| 27 |
+
# Download NLTK resources with error handling
|
| 28 |
+
try:
|
| 29 |
+
nltk.download('vader_lexicon', quiet=True)
|
| 30 |
+
nltk.download('punkt', quiet=True)
|
| 31 |
+
nltk.download('stopwords', quiet=True)
|
| 32 |
+
except Exception as e:
|
| 33 |
+
print(f"Error downloading NLTK data: {e}")
|
|
|
|
|
|
|
| 34 |
|
| 35 |
# Initialize sentiment analyzer
|
| 36 |
sia = SentimentIntensityAnalyzer()
|
|
|
|
| 82 |
for user_id in user_ids[4:]:
|
| 83 |
self.record_interaction(user_id, blog_id, np.random.randint(1, 10))
|
| 84 |
|
| 85 |
+
# [Rest of your DataStore methods remain unchanged...]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
|
| 87 |
# Initialize data store
|
| 88 |
data_store = DataStore()
|
| 89 |
|
| 90 |
+
# Machine Learning Models with improved error handling
|
| 91 |
class MLModels:
|
| 92 |
def __init__(self):
|
| 93 |
self.sentiment_model_name = "distilbert-base-uncased-finetuned-sst-2-english"
|
| 94 |
self.sentiment_analyzer = None
|
| 95 |
+
|
| 96 |
+
# Initialize with proper device handling
|
| 97 |
+
try:
|
| 98 |
+
device = -1 # Default to CPU
|
| 99 |
+
if torch.cuda.is_available():
|
| 100 |
+
device = 0
|
| 101 |
+
print(f"Using GPU (device {device})")
|
| 102 |
+
else:
|
| 103 |
+
print("Using CPU")
|
| 104 |
+
|
| 105 |
+
self.sentiment_analyzer = pipeline(
|
| 106 |
+
"sentiment-analysis",
|
| 107 |
+
model=self.sentiment_model_name,
|
| 108 |
+
device=device
|
| 109 |
+
)
|
| 110 |
+
except Exception as e:
|
| 111 |
+
print(f"Failed to initialize sentiment analyzer: {e}")
|
| 112 |
+
print("Falling back to NLTK sentiment analysis")
|
| 113 |
+
self.sentiment_analyzer = None
|
| 114 |
+
|
| 115 |
self.tfidf_vectorizer = TfidfVectorizer(max_features=1000)
|
| 116 |
self.blog_vectors = None
|
| 117 |
self.update_blog_vectors()
|
| 118 |
|
| 119 |
+
# [Rest of your MLModels methods remain unchanged...]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
|
| 121 |
# Initialize ML models
|
| 122 |
ml_models = MLModels()
|
| 123 |
|
| 124 |
+
# Custom CSS (unchanged)
|
| 125 |
custom_css = """
|
| 126 |
+
/* Your existing CSS here */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 127 |
"""
|
| 128 |
|
| 129 |
+
# Gradio Interface (unchanged except for launch settings)
|
| 130 |
def create_interface():
|
| 131 |
with gr.Blocks(css=custom_css) as interface:
|
| 132 |
+
# [Your existing interface code...]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 133 |
return interface
|
| 134 |
|
| 135 |
+
# Updated launch function
|
| 136 |
def launch_app():
|
| 137 |
+
try:
|
| 138 |
+
interface = create_interface()
|
| 139 |
+
# Settings optimized for Hugging Face Spaces
|
| 140 |
+
interface.launch(
|
| 141 |
+
server_name="0.0.0.0",
|
| 142 |
+
server_port=7860,
|
| 143 |
+
share=False,
|
| 144 |
+
show_error=True
|
| 145 |
+
)
|
| 146 |
+
except Exception as e:
|
| 147 |
+
print(f"Failed to launch app: {e}")
|
| 148 |
+
raise
|
| 149 |
|
| 150 |
if __name__ == "__main__":
|
| 151 |
launch_app()
|