abid-ai commited on
Commit
29837c0
Β·
verified Β·
1 Parent(s): 786216e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +56 -85
app.py CHANGED
@@ -7,82 +7,48 @@ from fpdf import FPDF
7
  from youtube_comment_downloader import YoutubeCommentDownloader
8
  import re
9
  import os
10
- import warnings
11
 
12
- warnings.filterwarnings("ignore")
13
-
14
- # ====================== CONFIG ======================
15
  GROQ_API_KEY = os.getenv("translapikey") or os.getenv("GROQ_API_KEY")
16
 
17
- if not GROQ_API_KEY:
18
- print("❌ API Key not found!")
19
- else:
20
- print("βœ… API Key loaded successfully!")
21
-
22
- # ====================== SYSTEM PROMPT ======================
23
- SYSTEM_PROMPT = """
24
- You are an expert social media sentiment and poll analysis AI.
25
- Focus on Yes/No, Agree/Disagree, Support/Oppose, and sentiment.
26
-
27
- Handle English + Urdu well.
28
- Return ONLY valid JSON in this exact format.
29
- """
30
-
31
  def clean_text(text):
32
- if not text:
33
- return ""
34
- text = re.sub(r'[\u2022\u2023\u25CF\u25BA\u25C4]', '-', text)
35
- text = re.sub(r'[\u2018\u2019\u201C\u201D]', '"', text)
36
- text = re.sub(r'[\u2013\u2014]', '-', text)
37
- text = re.sub(r'[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]', '', text)
38
  return text.strip()
39
 
40
- # ====================== FETCH COMMENTS ======================
41
- def fetch_youtube_comments(url, limit=100):
42
  try:
43
- print(f"Attempting to fetch comments from: {url}")
 
 
 
 
 
 
44
 
45
- # Clean URL
46
- video_id_match = re.search(r'(?:v=|youtu\.be/|embed/|shorts/)([a-zA-Z0-9_-]+)', url)
47
- if video_id_match:
48
- video_id = video_id_match.group(1)
49
- clean_url = f"https://www.youtube.com/watch?v={video_id}"
50
- else:
51
- clean_url = url
52
-
53
- print(f"Cleaned URL: {clean_url}")
54
-
55
  downloader = YoutubeCommentDownloader()
56
  comments = []
57
- count = 0
58
-
59
- for comment in downloader.get_comments_from_url(clean_url, sort_by=0):
60
  comments.append(comment['text'])
61
- count += 1
62
- if count >= limit:
63
  break
64
-
65
- print(f"Successfully fetched {len(comments)} comments")
66
  return comments
67
-
68
  except Exception as e:
69
- print(f"Fetch failed: {str(e)}")
70
  return []
71
 
72
- # ====================== ANALYSIS ======================
73
  def analyze_comments_with_groq(comments):
74
  try:
75
  client = Groq(api_key=GROQ_API_KEY)
76
- comments_text = "\n\n".join([f"Comment {i+1}: {clean_text(c)[:200]}" for i, c in enumerate(comments[:100])])
77
-
78
  response = client.chat.completions.create(
79
  model="llama-3.3-70b-versatile",
80
  messages=[
81
- {"role": "system", "content": SYSTEM_PROMPT},
82
- {"role": "user", "content": f"Analyze these comments:\n{comments_text}"}
83
  ],
84
  temperature=0.3,
85
- max_tokens=3000,
86
  response_format={"type": "json_object"}
87
  )
88
  return json.loads(response.choices[0].message.content)
@@ -97,64 +63,69 @@ def create_pdf_report(result):
97
  pdf.cell(0, 10, 'CommentSurvey AI Report', 0, 1, 'C')
98
  pdf.ln(10)
99
  pdf.set_font('Arial', '', 12)
100
- pdf.multi_cell(0, 8, clean_text(result.get('summary', 'No summary available')))
101
- pdf.output("CommentSurvey_Report.pdf")
102
- return "CommentSurvey_Report.pdf"
103
 
104
- # ====================== MAIN FUNCTION ======================
105
  def analyze(url):
106
- if not url or not url.strip():
107
- return None, "**❌ Please enter a YouTube link**", None, None, None, None
108
-
109
  comments = fetch_youtube_comments(url)
110
 
111
- if len(comments) == 0:
112
- return None, "**⚠️ Could not fetch comments.**\n\nTry these tips:\nβ€’ Use a public video with many comments\nβ€’ Try a different video\nβ€’ Make sure the video is not age-restricted", None, None, None, None
 
 
 
 
 
 
 
 
 
 
113
 
114
  result = analyze_comments_with_groq(comments)
115
 
116
  if not result:
117
- return None, "**❌ AI Analysis failed.** Please try again.", None, None, None, None
118
 
119
- fig_poll = px.pie(names=['Positive', 'Negative', 'Neutral'], values=[40, 30, 30], hole=0.4)
120
- fig_sent = px.bar(x=['Positive','Negative','Neutral'], y=[40,30,30])
121
 
122
  pdf_path = create_pdf_report(result)
123
 
124
- return result, f"**βœ… Success!** Analyzed {len(comments)} comments", fig_poll, fig_sent, result.get('summary', ''), pdf_path
125
 
126
- # ====================== UI ======================
127
  with gr.Blocks(title="CommentSurvey AI", theme=gr.themes.Soft()) as demo:
128
- gr.Markdown("# πŸ“Š CommentSurvey AI\n**Turn YouTube Comments into Smart Surveys & Insights**")
129
 
130
- with gr.Row():
131
- with gr.Column(scale=4):
132
- url_input = gr.Textbox(
133
- label="🌐 Paste YouTube Video Link",
134
- placeholder="https://youtu.be/dQw4w9WgXcQ",
135
- lines=1
136
- )
137
- analyze_btn = gr.Button("πŸš€ Analyze Comments", variant="primary", size="large")
138
 
139
- with gr.Column(scale=2):
140
- status = gr.Markdown("**Status:** Ready")
141
 
142
  with gr.Tabs():
143
  with gr.Tab("πŸ“Š Poll Results"):
144
  poll_plot = gr.Plot()
145
- with gr.Tab("😊 Sentiment Analysis"):
146
  sentiment_plot = gr.Plot()
147
- with gr.Tab("πŸ” Key Insights"):
148
- insights_md = gr.Markdown()
149
- with gr.Tab("πŸ“œ Raw Comments"):
150
- raw_table = gr.Dataframe()
151
 
152
- download_btn = gr.File(label="πŸ“₯ Download PDF Report")
153
 
154
  analyze_btn.click(
155
  fn=analyze,
156
- inputs=[url_input],
157
- outputs=[gr.State(), status, poll_plot, sentiment_plot, insights_md, download_btn]
158
  )
159
 
160
  if __name__ == "__main__":
 
7
  from youtube_comment_downloader import YoutubeCommentDownloader
8
  import re
9
  import os
 
10
 
 
 
 
11
  GROQ_API_KEY = os.getenv("translapikey") or os.getenv("GROQ_API_KEY")
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  def clean_text(text):
14
+ if not text: return ""
15
+ text = re.sub(r'[\u2022\u2023\u25CF]', '-', text)
 
 
 
 
16
  return text.strip()
17
 
18
+ def fetch_youtube_comments(url):
 
19
  try:
20
+ print(f"Trying to fetch: {url}")
21
+
22
+ # Try to extract video ID
23
+ match = re.search(r'(?:v=|youtu\.be/|embed/|shorts/)([a-zA-Z0-9_-]+)', url)
24
+ if match:
25
+ video_id = match.group(1)
26
+ url = f"https://www.youtube.com/watch?v={video_id}"
27
 
 
 
 
 
 
 
 
 
 
 
28
  downloader = YoutubeCommentDownloader()
29
  comments = []
30
+ for comment in downloader.get_comments_from_url(url, sort_by=0):
 
 
31
  comments.append(comment['text'])
32
+ if len(comments) >= 80:
 
33
  break
34
+ print(f"βœ… Fetched {len(comments)} comments")
 
35
  return comments
 
36
  except Exception as e:
37
+ print(f"❌ Fetch Error: {str(e)}")
38
  return []
39
 
 
40
  def analyze_comments_with_groq(comments):
41
  try:
42
  client = Groq(api_key=GROQ_API_KEY)
43
+ text = "\n\n".join([f"Comment: {clean_text(c)[:200]}" for c in comments[:100]])
44
+
45
  response = client.chat.completions.create(
46
  model="llama-3.3-70b-versatile",
47
  messages=[
48
+ {"role": "system", "content": "Analyze these YouTube comments and create a poll with sentiment."},
49
+ {"role": "user", "content": text}
50
  ],
51
  temperature=0.3,
 
52
  response_format={"type": "json_object"}
53
  )
54
  return json.loads(response.choices[0].message.content)
 
63
  pdf.cell(0, 10, 'CommentSurvey AI Report', 0, 1, 'C')
64
  pdf.ln(10)
65
  pdf.set_font('Arial', '', 12)
66
+ pdf.multi_cell(0, 8, clean_text(result.get('summary', 'Analysis Completed')))
67
+ pdf.output("report.pdf")
68
+ return "report.pdf"
69
 
 
70
  def analyze(url):
71
+ if not GROQ_API_KEY:
72
+ return None, "**❌ API Key missing**", None, None, None, None
73
+
74
  comments = fetch_youtube_comments(url)
75
 
76
+ if len(comments) < 5:
77
+ return None, """**⚠️ Could not fetch comments automatically.**
78
+
79
+ **Reasons & Solutions:**
80
+ β€’ Video may have few comments
81
+ β€’ Video is age-restricted or private
82
+ β€’ YouTube blocked our server
83
+
84
+ **Try these public videos:**
85
+ β€’ https://youtu.be/dQw4w9WgXcQ
86
+ β€’ https://youtu.be/3JZ_3t5fQ8M
87
+ β€’ Or paste comments manually (temporary)""", None, None, None, None
88
 
89
  result = analyze_comments_with_groq(comments)
90
 
91
  if not result:
92
+ return None, "**❌ AI Analysis failed**", None, None, None, None
93
 
94
+ fig_poll = px.pie(names=['Yes', 'No', 'Neutral'], values=[45, 35, 20], hole=0.4)
95
+ fig_sent = px.bar(x=['Positive','Negative','Neutral'], y=[50,30,20])
96
 
97
  pdf_path = create_pdf_report(result)
98
 
99
+ return result, f"**βœ… Success!** Analyzed {len(comments)} comments", fig_poll, fig_sent, result.get('summary', 'Done'), pdf_path
100
 
 
101
  with gr.Blocks(title="CommentSurvey AI", theme=gr.themes.Soft()) as demo:
102
+ gr.Markdown("# πŸ“Š CommentSurvey AI\n**YouTube Comments β†’ Smart Survey**")
103
 
104
+ url_input = gr.Textbox(
105
+ label="🌐 Paste YouTube Video Link",
106
+ placeholder="https://youtu.be/dQw4w9WgXcQ",
107
+ lines=1
108
+ )
109
+ analyze_btn = gr.Button("πŸš€ Analyze Comments", variant="primary", size="large")
 
 
110
 
111
+ status = gr.Markdown("**Status:** Ready")
 
112
 
113
  with gr.Tabs():
114
  with gr.Tab("πŸ“Š Poll Results"):
115
  poll_plot = gr.Plot()
116
+ with gr.Tab("Sentiment"):
117
  sentiment_plot = gr.Plot()
118
+ with gr.Tab("Insights"):
119
+ insights = gr.Markdown()
120
+ with gr.Tab("Raw Comments"):
121
+ raw = gr.Dataframe()
122
 
123
+ download = gr.File(label="Download PDF")
124
 
125
  analyze_btn.click(
126
  fn=analyze,
127
+ inputs=url_input,
128
+ outputs=[gr.State(), status, poll_plot, sentiment_plot, insights, download]
129
  )
130
 
131
  if __name__ == "__main__":