Anupam007 commited on
Commit
cd73647
·
verified ·
1 Parent(s): 84322b2

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +825 -0
app.py ADDED
@@ -0,0 +1,825 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ import time
4
+ import uuid
5
+ import datetime
6
+ import torch
7
+ import gradio as gr
8
+ import numpy as np
9
+ 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
+ nltk.download('vader_lexicon', quiet=True)
22
+ nltk.download('punkt', quiet=True)
23
+ nltk.download('stopwords', quiet=True)
24
+
25
+ # Check if GPU is available
26
+ print(f"GPU available: {torch.cuda.is_available()}")
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()
32
+
33
+ # Data storage
34
+ class DataStore:
35
+ def __init__(self):
36
+ self.users = {}
37
+ self.blogs = {}
38
+ self.comments = {}
39
+ self.chats = {}
40
+ self.user_interactions = {}
41
+ self.current_user_id = None
42
+ self.create_sample_data()
43
+
44
+ def create_sample_data(self):
45
+ user_ids = [self.add_user("admin", "admin123", "admin@example.com", "Admin User", "admin")]
46
+ user_ids.extend([self.add_user(f"blogger{i}", f"password{i}", f"blogger{i}@example.com", f"Blogger {i}", "blogger") for i in range(1, 4)])
47
+ user_ids.extend([self.add_user(f"reader{i}", f"password{i}", f"reader{i}@example.com", f"Reader {i}", "reader") for i in range(1, 6)])
48
+
49
+ blog_topics = [
50
+ "Machine Learning Fundamentals",
51
+ "Web Development Best Practices",
52
+ "Data Science in Practice",
53
+ "Python Programming Tips",
54
+ "Neural Networks Explained",
55
+ "Modern JavaScript Frameworks",
56
+ "Cloud Computing Services"
57
+ ]
58
+
59
+ blog_contents = [
60
+ "Machine learning is a branch of artificial intelligence that enables computers to learn from data without being explicitly programmed...",
61
+ "Web development involves creating websites and web applications using technologies like HTML, CSS, and JavaScript...",
62
+ "Data science combines domain expertise, programming skills, and knowledge of math and statistics to extract meaningful insights from data...",
63
+ "Python is a versatile programming language widely used in various domains including web development, data analysis, and artificial intelligence...",
64
+ "Neural networks are computing systems inspired by the biological neural networks that constitute animal brains...",
65
+ "Modern JavaScript frameworks like React, Vue, and Angular have revolutionized front-end web development...",
66
+ "Cloud computing services provide businesses with on-demand access to computing resources without direct active management by the user..."
67
+ ]
68
+
69
+ blog_ids = []
70
+ for i in range(len(blog_topics)):
71
+ author_id = user_ids[1 + (i % 3)]
72
+ blog_id = self.add_blog(blog_topics[i], blog_contents[i], author_id, ["tech", "programming"])
73
+ blog_ids.append(blog_id)
74
+ for j in range(3):
75
+ commenter_id = user_ids[4 + (j % 5)]
76
+ self.add_comment(blog_id, f"Great article on {blog_topics[i]}!", commenter_id)
77
+ for user_id in user_ids[4:]:
78
+ self.record_interaction(user_id, blog_id, np.random.randint(1, 10))
79
+
80
+ def add_user(self, username, password, email, display_name, role):
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
+ if pipeline is not None:
189
+ try:
190
+ self.sentiment_analyzer = pipeline("sentiment-analysis", model=self.sentiment_model_name, device=0 if torch.cuda.is_available() else -1)
191
+ except Exception as e:
192
+ print(f"Failed to initialize sentiment analyzer: {e}")
193
+ print("Falling back to NLTK sentiment analysis")
194
+ self.tfidf_vectorizer = TfidfVectorizer(max_features=1000)
195
+ self.blog_vectors = None
196
+ self.update_blog_vectors()
197
+
198
+ def update_blog_vectors(self):
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
+ body {
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
+ user_id_state = gr.State("")
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
+ # Launch the interface
820
+ def launch_app():
821
+ interface = create_interface()
822
+ interface.launch(share=False, server_port=None)
823
+
824
+ if __name__ == "__main__":
825
+ launch_app()