AsmSafone commited on
Commit ·
67a7b45
1
Parent(s): 516913c
classify
Browse files
app.py
CHANGED
|
@@ -55,6 +55,13 @@ if TRANSFORMERS_AVAILABLE:
|
|
| 55 |
else:
|
| 56 |
print("Transformers not available, skipping model load.")
|
| 57 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
# Load Bangla Stopwords
|
| 59 |
stopwords_path = os.path.join(BASE_DIR, "bangla_stopwords.txt")
|
| 60 |
bangla_stopwords = set()
|
|
@@ -267,6 +274,71 @@ def extract_hashtags(text):
|
|
| 267 |
# -------------------------
|
| 268 |
# Figures builder
|
| 269 |
# -------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 270 |
def make_figures_from_post(post_record, comments_records):
|
| 271 |
"""
|
| 272 |
Build figures using only raw scraped fields.
|
|
@@ -640,9 +712,6 @@ def run_live_analysis(n_clicks, url):
|
|
| 640 |
return html.Div("Missing APIFY_TOKEN in environment.", style={"color": "red"}), "", no_update
|
| 641 |
|
| 642 |
status_msg = ""
|
| 643 |
-
if not nlp:
|
| 644 |
-
status_msg = " (Sentiment Model not loaded - skipping analysis)"
|
| 645 |
-
|
| 646 |
try:
|
| 647 |
post_data = scrape_facebook_post(url, token)
|
| 648 |
comments_data = scrape_facebook_comments(url, token)
|
|
@@ -666,9 +735,9 @@ def run_live_analysis(n_clicks, url):
|
|
| 666 |
"likes_count": c.get("likesCount", 0),
|
| 667 |
"date_created": c.get("date", ""),
|
| 668 |
"sentiment": label,
|
| 669 |
-
"emotion":
|
| 670 |
-
"tone":
|
| 671 |
-
"intent":
|
| 672 |
})
|
| 673 |
|
| 674 |
final_data = {
|
|
|
|
| 55 |
else:
|
| 56 |
print("Transformers not available, skipping model load.")
|
| 57 |
|
| 58 |
+
zsc = None
|
| 59 |
+
if TRANSFORMERS_AVAILABLE:
|
| 60 |
+
try:
|
| 61 |
+
zsc = pipeline("zero-shot-classification", model="joeddav/xlm-roberta-large-xnli", device=-1)
|
| 62 |
+
except Exception:
|
| 63 |
+
zsc = None
|
| 64 |
+
|
| 65 |
# Load Bangla Stopwords
|
| 66 |
stopwords_path = os.path.join(BASE_DIR, "bangla_stopwords.txt")
|
| 67 |
bangla_stopwords = set()
|
|
|
|
| 274 |
# -------------------------
|
| 275 |
# Figures builder
|
| 276 |
# -------------------------
|
| 277 |
+
def detect_emotion(text, sentiment):
|
| 278 |
+
t = normalize_text(text)
|
| 279 |
+
tl = t.lower()
|
| 280 |
+
if zsc and len(t) > 3:
|
| 281 |
+
labels = ["Joy", "Anger", "Sadness", "Fear", "Surprise", "Disgust", "Confusion", "Neutral"]
|
| 282 |
+
try:
|
| 283 |
+
r = zsc(t[:512], candidate_labels=labels, multi_label=False)
|
| 284 |
+
return str(r.get("labels", ["Neutral"])[0])
|
| 285 |
+
except Exception:
|
| 286 |
+
pass
|
| 287 |
+
if _RE_LAUGH.search(tl) or re.search(r"[😂🤣😊😄😁😃🙂]", t):
|
| 288 |
+
return "Joy"
|
| 289 |
+
if _RE_ANGER.search(t) or re.search(r"[💢😠😡👿]", t) or re.search(r"\b(রাগ|খারাপ|বিরক্ত|ঘৃণা|নিন্দা)\b", tl):
|
| 290 |
+
return "Anger"
|
| 291 |
+
if re.search(r"[😢😭😞☹️😔]", t) or re.search(r"\b(দুঃখ|কষ্ট|খারাপ লাগছে|মন খারাপ)\b", tl):
|
| 292 |
+
return "Sadness"
|
| 293 |
+
if "?" in t and re.search(r"\b(কেন|কি|কী|কিভাবে|কোথায়|কবে)\b", tl):
|
| 294 |
+
return "Confusion"
|
| 295 |
+
s = str(sentiment or "").lower()
|
| 296 |
+
if "pos" in s:
|
| 297 |
+
return "Joy"
|
| 298 |
+
if "neg" in s or s == "error":
|
| 299 |
+
return "Sadness"
|
| 300 |
+
return "Neutral"
|
| 301 |
+
|
| 302 |
+
def detect_tone(text):
|
| 303 |
+
t = normalize_text(text)
|
| 304 |
+
tl = t.lower()
|
| 305 |
+
if zsc and len(t) > 3:
|
| 306 |
+
labels = ["Formal", "Casual", "Critical", "Inquisitive", "Neutral", "Sarcastic"]
|
| 307 |
+
try:
|
| 308 |
+
r = zsc(t[:512], candidate_labels=labels, multi_label=False)
|
| 309 |
+
return str(r.get("labels", ["Neutral"])[0])
|
| 310 |
+
except Exception:
|
| 311 |
+
pass
|
| 312 |
+
if _RE_LAUGH.search(tl) or re.search(r"[😂🤣😜😝]", t):
|
| 313 |
+
return "Casual"
|
| 314 |
+
if re.search(r"\b(দয়া করে|অনুগ্রহ|স্যার|ম্যাডাম|জনাব|জনাবা)\b", tl):
|
| 315 |
+
return "Formal"
|
| 316 |
+
if _RE_ANGER.search(t) or re.search(r"\b(রাগ|নিন্দা|খারাপ|বিরক্ত)\b", tl):
|
| 317 |
+
return "Critical"
|
| 318 |
+
if "?" in t:
|
| 319 |
+
return "Inquisitive"
|
| 320 |
+
return "Neutral"
|
| 321 |
+
|
| 322 |
+
def detect_intent(text, sentiment):
|
| 323 |
+
t = normalize_text(text)
|
| 324 |
+
tl = t.lower()
|
| 325 |
+
if zsc and len(t) > 3:
|
| 326 |
+
labels = ["Question", "Request", "Praise", "Complaint", "Statement", "Suggestion"]
|
| 327 |
+
try:
|
| 328 |
+
r = zsc(t[:512], candidate_labels=labels, multi_label=False)
|
| 329 |
+
return str(r.get("labels", ["Statement"])[0])
|
| 330 |
+
except Exception:
|
| 331 |
+
pass
|
| 332 |
+
if "?" in t or re.search(r"\b(কেন|কি|কী|কিভাবে|কোথায়|কবে)\b", tl):
|
| 333 |
+
return "Question"
|
| 334 |
+
if re.search(r"\b(দয়া করে|অনুগ্রহ|please|করুন|শেয়ার|লাইক|subscribe)\b", tl):
|
| 335 |
+
return "Request"
|
| 336 |
+
if re.search(r"\b(ধন্যবাদ|শুভেচ্ছা|অভিনন্দন|ভাল|সুন্দর|great|awesome)\b", tl):
|
| 337 |
+
return "Praise"
|
| 338 |
+
if re.search(r"\b(সমস্যা|অভিযোগ|খারাপ|রাগ|বিরক্ত)\b", tl) or str(sentiment or "").lower().startswith("neg"):
|
| 339 |
+
return "Complaint"
|
| 340 |
+
return "Statement"
|
| 341 |
+
|
| 342 |
def make_figures_from_post(post_record, comments_records):
|
| 343 |
"""
|
| 344 |
Build figures using only raw scraped fields.
|
|
|
|
| 712 |
return html.Div("Missing APIFY_TOKEN in environment.", style={"color": "red"}), "", no_update
|
| 713 |
|
| 714 |
status_msg = ""
|
|
|
|
|
|
|
|
|
|
| 715 |
try:
|
| 716 |
post_data = scrape_facebook_post(url, token)
|
| 717 |
comments_data = scrape_facebook_comments(url, token)
|
|
|
|
| 735 |
"likes_count": c.get("likesCount", 0),
|
| 736 |
"date_created": c.get("date", ""),
|
| 737 |
"sentiment": label,
|
| 738 |
+
"emotion": detect_emotion(text, label),
|
| 739 |
+
"tone": detect_tone(text),
|
| 740 |
+
"intent": detect_intent(text, label)
|
| 741 |
})
|
| 742 |
|
| 743 |
final_data = {
|