Hifzamudassar commited on
Commit
17beea8
·
verified ·
1 Parent(s): 21d31fe

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +121 -139
app.py CHANGED
@@ -1,52 +1,36 @@
1
- # ============================== #
2
- # AI Study Wizard v3 #
3
- # ============================== #
4
-
5
- import os
6
- import tempfile
7
- import random
8
- import pytesseract
9
- import requests
10
-
11
  from PIL import Image, ImageDraw, ImageFont
12
  from gtts import gTTS
13
-
14
- # Safe MoviePy Imports
15
  from moviepy.video.VideoClip import ImageClip
16
  from moviepy.audio.io.AudioFileClip import AudioFileClip
17
  from moviepy.video.compositing.concatenate import concatenate_videoclips
18
-
19
- # PDF support
20
  from pdf2image import convert_from_path
21
-
22
  import gradio as gr
23
  from urllib.parse import quote_plus
24
 
25
- # ==========================================================
26
- # HARD-CODED GROQ API KEY (Replace with your key)
27
- # ==========================================================
28
  GROQ_API_KEY = "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"
29
  GROQ_MODEL = "llama-3.3-70b-versatile"
30
 
31
- # ==========================================================
32
- # USERS DB / STATE
33
- # ==========================================================
34
  users_db = {}
35
  verification_codes = {}
36
 
37
- # ==========================================================
38
- # SIGNUP / VERIFY / LOGIN
39
- # ==========================================================
40
- def signup_user(username, email, password, contact):
41
- if email in users_db:
42
- return "Email already registered.", ""
43
-
44
- code = str(random.randint(100000, 999999))
45
- verification_codes[email] = code
46
- users_db[email] = {"username": username, "password": password, "contact": contact, "verified": False}
47
  return "Signup successful! Your verification code:", code
48
 
49
- def verify_user(email, code):
50
  if email not in users_db: return "Email not found."
51
  if users_db[email]["verified"]: return "Already verified."
52
  if verification_codes.get(email) == code:
@@ -55,176 +39,174 @@ def verify_user(email, code):
55
  return "Verification successful!"
56
  return "Invalid verification code."
57
 
58
- def login_user(email, password):
59
  user = users_db.get(email)
60
- if not user: return False, "User not found."
61
- if not user["verified"]: return False, "Account not verified."
62
- if user["password"] != password: return False, "Wrong password."
63
- return True, f"Welcome {user['username']}!"
64
-
65
- # ==========================================================
66
- # GROQ API CALL
67
- # ==========================================================
68
- def call_groq(prompt, max_tokens=600):
69
- url = "https://api.groq.com/openai/v1/chat/completions"
70
- headers = {"Authorization": f"Bearer {GROQ_API_KEY}", "Content-Type": "application/json"}
71
- payload = {"model": GROQ_MODEL, "messages":[{"role":"user","content":prompt}], "max_tokens": max_tokens}
72
  try:
73
- r = requests.post(url, json=payload, headers=headers)
74
  return r.json()["choices"][0]["message"]["content"]
75
  except Exception as e:
76
  return f"Groq API Error: {e}"
77
 
78
- # ==========================================================
79
- # ANSWER & MCQs
80
- # ==========================================================
81
  def answer_text_query(q):
82
  q = q.strip()
83
- if len(q.split()) < 5:
84
- prompt = f"Explain the following clearly and concisely for a beginner:\n\n{q}"
85
  else:
86
- prompt = f"Answer clearly:\n\n{q}"
87
  return call_groq(prompt)
88
 
89
- def generate_mcqs_from_text(text, n=5):
90
  return call_groq(f"Generate {n} MCQs with 4 options + correct answer:\n\n{text}")
91
 
92
- # ==========================================================
93
- # VIDEO GENERATION
94
- # ==========================================================
95
- def create_video_simple(text, tts_lang="en", preview=False):
96
  if not text.strip(): return None
97
- tmp = tempfile.gettempdir()
98
- lines = [l.strip() for l in text.split("\n") if l.strip()]
99
- if preview: lines = lines[:1]
100
- clips = []
101
- for i, line in enumerate(lines):
102
- img_path = os.path.join(tmp, f"slide_{i}.png")
103
- audio_path = os.path.join(tmp, f"audio_{i}.mp3")
104
- # Image
105
- W, H = 480, 360
106
- img = Image.new("RGB", (W,H), (255,182,193))
107
- draw = ImageDraw.Draw(img)
108
- try: font = ImageFont.truetype("DejaVuSans-Bold.ttf", 22)
109
- except: font = ImageFont.load_default()
110
- draw.text((20,20), line, fill="black", font=font)
111
  img.save(img_path)
112
- # Audio
113
- gTTS(text=line, lang=tts_lang).save(audio_path)
114
- duration = max(3, min(len(line)//10+2, 8))
115
- clip = ImageClip(img_path).set_duration(duration).set_audio(AudioFileClip(audio_path))
116
  clips.append(clip)
117
- out_path = os.path.join(tmp, "prev.mp4" if preview else "full.mp4")
118
- final = concatenate_videoclips(clips, method="compose")
119
- final.write_videofile(out_path, fps=24, codec="libx264", audio_codec="aac", verbose=False)
120
- return out_path
121
-
122
- # ==========================================================
123
- # NOTES + FLOWCHART
124
- # ==========================================================
125
  def generate_notes_flowchart(text):
126
- notes = call_groq(f"Summarize into bullet study notes:\n\n{text}")
127
- img = Image.new("RGB", (480,360), (144,238,144))
128
- draw = ImageDraw.Draw(img)
129
- try: font = ImageFont.truetype("DejaVuSans.ttf", 16)
130
- except: font = ImageFont.load_default()
131
- y = 20
132
  for line in notes.split("\n"):
133
  if y>330: break
134
- draw.text((10,y), line, fill="black", font=font)
135
  y+=18
136
  return notes,img
137
 
138
- # ==========================================================
139
- # FILE OCR (PDF + IMAGE)
140
- # ==========================================================
141
  def extract_text_from_file(file):
142
  if file.name.endswith(".pdf"):
143
- pages = convert_from_path(file.name)
144
  text=""
145
  for page in pages:
146
- text += pytesseract.image_to_string(page) + "\n"
147
  return text
148
  else:
149
  return pytesseract.image_to_string(Image.open(file.name))
150
 
151
- # ==========================================================
152
- # LINKS
153
- # ==========================================================
154
  def get_youtube_link(q): return f"https://www.youtube.com/results?search_query={quote_plus(q)}"
155
  def get_google_link(q): return f"https://www.google.com/search?q={quote_plus(q)}"
156
  def get_links_clickable(topic):
157
- yt = "\n".join([f"[YouTube {i+1}]({get_youtube_link(topic)})" for i in range(3)])
158
- gg = "\n".join([f"[Google {i+1}]({get_google_link(topic)})" for i in range(3)])
159
  return yt,gg
160
 
161
- # ==========================================================
162
- # GRADIENT BACKGROUND
163
- # ==========================================================
164
- custom_css = """
165
  body {background: linear-gradient(to bottom right, #90ee90, #ffb6c1);}
166
  """
167
 
168
- # ==========================================================
169
- # GRADIO APP
170
- # ==========================================================
171
  with gr.Blocks(css=custom_css) as demo:
172
- gr.Markdown("## 🌸 **AI Study Wizard** — Pink + Green Themed")
173
 
174
- # -------- SIGNUP -------- #
175
  with gr.Tab("Sign Up"):
176
  su_name=gr.Textbox(label="Username")
177
  su_email=gr.Textbox(label="Email")
178
- su_pass=gr.Textbox(label="Password", type="password")
179
  su_contact=gr.Textbox(label="Contact Number")
180
  su_btn=gr.Button("Sign Up")
181
- su_msg=gr.Textbox(label="Message", interactive=False)
182
- su_code=gr.Textbox(label="Verification Code", interactive=False)
183
- su_btn.click(signup_user, inputs=[su_name,su_email,su_pass,su_contact], outputs=[su_msg,su_code])
184
 
185
- # -------- VERIFY -------- #
186
  with gr.Tab("Verify"):
187
  v_email=gr.Textbox(label="Email")
188
  v_code=gr.Textbox(label="Verification Code")
189
  v_btn=gr.Button("Verify")
190
- v_msg=gr.Textbox(label="Status", interactive=False)
191
- v_btn.click(verify_user, inputs=[v_email,v_code], outputs=v_msg)
192
 
193
- # -------- LOGIN -------- #
194
  with gr.Tab("Login"):
195
  li_email=gr.Textbox(label="Email")
196
- li_pass=gr.Textbox(label="Password", type="password")
197
  li_btn=gr.Button("Login")
198
  li_msg=gr.Textbox(label="Login Status")
199
  def login_wrap(e,p): ok,msg=login_user(e,p); return msg
200
- li_btn.click(login_wrap, inputs=[li_email,li_pass], outputs=li_msg)
201
 
202
- # -------- QUESTION -------- #
203
  with gr.Tab("Ask Question"):
204
- q_in=gr.Textbox(label="Ask Any Question")
205
- a_out=gr.Textbox(label="Answer", lines=12)
206
- m_out=gr.Textbox(label="MCQs", lines=12)
207
- pv=gr.Video(label="Preview Video", width=640, height=360)
208
- fv=gr.Video(label="Full Video", width=640, height=360)
209
  ask_btn=gr.Button("Generate")
210
  def run_question(q):
211
  ans=answer_text_query(q)
212
  mcqs=generate_mcqs_from_text(ans)
213
  return ans,mcqs,create_video_simple(ans,preview=True),create_video_simple(ans)
214
- ask_btn.click(run_question, inputs=q_in, outputs=[a_out,m_out,pv,fv])
215
 
216
- # -------- UPLOAD -------- #
217
- with gr.Tab("Upload Document (PDF/Image)"):
218
  f_in=gr.File()
219
  opts=gr.CheckboxGroup(["Extracted Text","MCQs","Video","Notes"])
220
- lang=gr.Dropdown(["en","ur","hi"], value="en", label="Video Language")
221
- t_out=gr.Textbox(label="Extracted Text", lines=12)
222
- mc_out=gr.Textbox(label="MCQs", lines=12)
223
- pv2=gr.Video(label="Preview Video", width=640, height=360)
224
- fv2=gr.Video(label="Full Video", width=640, height=360)
225
- notes_out=gr.Textbox(label="Notes", lines=12)
226
- flow_out=gr.Image(label="Flowchart", type="pil")
227
- def process_file(file, options, lg):
228
  text=extract_text_from_file(file)
229
  mcq=""
230
  prev=None
@@ -239,14 +221,14 @@ with gr.Blocks(css=custom_css) as demo:
239
  notes,flow=generate_notes_flowchart(text)
240
  return text,mcq,prev,full,notes,flow
241
  btn=gr.Button("Process")
242
- btn.click(process_file, inputs=[f_in,opts,lang], outputs=[t_out,mc_out,pv2,fv2,notes_out,flow_out])
243
 
244
- # -------- LINKS -------- #
245
  with gr.Tab("Search Links"):
246
  topic=gr.Textbox(label="Topic")
247
  yt=gr.Markdown()
248
  gg=gr.Markdown()
249
  link_btn=gr.Button("Get Links")
250
- link_btn.click(get_links_clickable, inputs=topic, outputs=[yt,gg])
251
 
252
  demo.launch()
 
1
+ import os, tempfile, random, pytesseract, requests
 
 
 
 
 
 
 
 
 
2
  from PIL import Image, ImageDraw, ImageFont
3
  from gtts import gTTS
 
 
4
  from moviepy.video.VideoClip import ImageClip
5
  from moviepy.audio.io.AudioFileClip import AudioFileClip
6
  from moviepy.video.compositing.concatenate import concatenate_videoclips
 
 
7
  from pdf2image import convert_from_path
 
8
  import gradio as gr
9
  from urllib.parse import quote_plus
10
 
11
+ # =====================
12
+ # HARD-CODED API KEY
13
+ # =====================
14
  GROQ_API_KEY = "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"
15
  GROQ_MODEL = "llama-3.3-70b-versatile"
16
 
17
+ # =====================
18
+ # USERS DB
19
+ # =====================
20
  users_db = {}
21
  verification_codes = {}
22
 
23
+ # =====================
24
+ # SIGNUP / VERIFY / LOGIN
25
+ # =====================
26
+ def signup_user(username,email,password,contact):
27
+ if email in users_db: return "Email already registered.",""
28
+ code = str(random.randint(100000,999999))
29
+ verification_codes[email]=code
30
+ users_db[email] = {"username":username,"password":password,"contact":contact,"verified":False}
 
 
31
  return "Signup successful! Your verification code:", code
32
 
33
+ def verify_user(email,code):
34
  if email not in users_db: return "Email not found."
35
  if users_db[email]["verified"]: return "Already verified."
36
  if verification_codes.get(email) == code:
 
39
  return "Verification successful!"
40
  return "Invalid verification code."
41
 
42
+ def login_user(email,password):
43
  user = users_db.get(email)
44
+ if not user: return False,"User not found."
45
+ if not user["verified"]: return False,"Account not verified."
46
+ if user["password"] != password: return False,"Wrong password."
47
+ return True,f"Welcome {user['username']}!"
48
+
49
+ # =====================
50
+ # GROQ API
51
+ # =====================
52
+ def call_groq(prompt,max_tokens=600):
53
+ url="https://api.groq.com/openai/v1/chat/completions"
54
+ headers={"Authorization":f"Bearer {GROQ_API_KEY}","Content-Type":"application/json"}
55
+ payload={"model":GROQ_MODEL,"messages":[{"role":"user","content":prompt}],"max_tokens":max_tokens}
56
  try:
57
+ r=requests.post(url,json=payload,headers=headers,timeout=30)
58
  return r.json()["choices"][0]["message"]["content"]
59
  except Exception as e:
60
  return f"Groq API Error: {e}"
61
 
62
+ # =====================
63
+ # ANSWERS / MCQs
64
+ # =====================
65
  def answer_text_query(q):
66
  q = q.strip()
67
+ if len(q.split()) < 6:
68
+ prompt=f"Explain clearly in detail for beginners:\n\n{q}"
69
  else:
70
+ prompt=f"Answer concisely:\n\n{q}"
71
  return call_groq(prompt)
72
 
73
+ def generate_mcqs_from_text(text,n=5):
74
  return call_groq(f"Generate {n} MCQs with 4 options + correct answer:\n\n{text}")
75
 
76
+ # =====================
77
+ # VIDEO
78
+ # =====================
79
+ def create_video_simple(text,tts_lang="en",preview=False):
80
  if not text.strip(): return None
81
+ tmp=tempfile.gettempdir()
82
+ lines=[l.strip() for l in text.splitlines() if l.strip()] or [p.strip() for p in text.split('.') if p.strip()]
83
+ if preview: lines=lines[:1]
84
+ clips=[]
85
+ for i,line in enumerate(lines):
86
+ W,H=480,360
87
+ img_path=os.path.join(tmp,f"slide_{i}.png")
88
+ audio_path=os.path.join(tmp,f"audio_{i}.mp3")
89
+ img=Image.new("RGB",(W,H),(255,182,193))
90
+ draw=ImageDraw.Draw(img)
91
+ try: font=ImageFont.truetype("DejaVuSans-Bold.ttf",22)
92
+ except: font=ImageFont.load_default()
93
+ draw.text((20,20),line,fill="black",font=font)
 
94
  img.save(img_path)
95
+ gTTS(text=line,lang=tts_lang).save(audio_path)
96
+ duration=max(3,min(len(line)//10+3,10))
97
+ clip=ImageClip(img_path).set_duration(duration).set_audio(AudioFileClip(audio_path))
 
98
  clips.append(clip)
99
+ out=os.path.join(tmp,"preview.mp4" if preview else "full.mp4")
100
+ final=concatenate_videoclips(clips,method="compose")
101
+ final.write_videofile(out,fps=24,codec="libx264",audio_codec="aac",verbose=False)
102
+ return out
103
+
104
+ # =====================
105
+ # NOTES & FLOWCHART
106
+ # =====================
107
  def generate_notes_flowchart(text):
108
+ notes=call_groq(f"Summarize into bullet study notes:\n\n{text}")
109
+ img=Image.new("RGB",(480,360),(144,238,144))
110
+ draw=ImageDraw.Draw(img)
111
+ try: font=ImageFont.truetype("DejaVuSans.ttf",16)
112
+ except: font=ImageFont.load_default()
113
+ y=20
114
  for line in notes.split("\n"):
115
  if y>330: break
116
+ draw.text((10,y),line,fill="black",font=font)
117
  y+=18
118
  return notes,img
119
 
120
+ # =====================
121
+ # FILE OCR
122
+ # =====================
123
  def extract_text_from_file(file):
124
  if file.name.endswith(".pdf"):
125
+ pages=convert_from_path(file.name)
126
  text=""
127
  for page in pages:
128
+ text+=pytesseract.image_to_string(page)+"\n"
129
  return text
130
  else:
131
  return pytesseract.image_to_string(Image.open(file.name))
132
 
133
+ # =====================
134
+ # LINKS
135
+ # =====================
136
  def get_youtube_link(q): return f"https://www.youtube.com/results?search_query={quote_plus(q)}"
137
  def get_google_link(q): return f"https://www.google.com/search?q={quote_plus(q)}"
138
  def get_links_clickable(topic):
139
+ yt="\n".join([f"[YouTube {i+1}]({get_youtube_link(topic)})" for i in range(3)])
140
+ gg="\n".join([f"[Google {i+1}]({get_google_link(topic)})" for i in range(3)])
141
  return yt,gg
142
 
143
+ # =====================
144
+ # GRADIENT BACKGROUND
145
+ # =====================
146
+ custom_css="""
147
  body {background: linear-gradient(to bottom right, #90ee90, #ffb6c1);}
148
  """
149
 
150
+ # =====================
151
+ # GRADIO UI
152
+ # =====================
153
  with gr.Blocks(css=custom_css) as demo:
154
+ gr.Markdown("## 🌸 AI Study Wizard — Pink + Green Gradient")
155
 
156
+ # SIGNUP
157
  with gr.Tab("Sign Up"):
158
  su_name=gr.Textbox(label="Username")
159
  su_email=gr.Textbox(label="Email")
160
+ su_pass=gr.Textbox(label="Password",type="password")
161
  su_contact=gr.Textbox(label="Contact Number")
162
  su_btn=gr.Button("Sign Up")
163
+ su_msg=gr.Textbox(label="Message",interactive=False)
164
+ su_code=gr.Textbox(label="Verification Code",interactive=False)
165
+ su_btn.click(signup_user,[su_name,su_email,su_pass,su_contact],[su_msg,su_code])
166
 
167
+ # VERIFY
168
  with gr.Tab("Verify"):
169
  v_email=gr.Textbox(label="Email")
170
  v_code=gr.Textbox(label="Verification Code")
171
  v_btn=gr.Button("Verify")
172
+ v_msg=gr.Textbox(label="Status",interactive=False)
173
+ v_btn.click(verify_user,[v_email,v_code],v_msg)
174
 
175
+ # LOGIN
176
  with gr.Tab("Login"):
177
  li_email=gr.Textbox(label="Email")
178
+ li_pass=gr.Textbox(label="Password",type="password")
179
  li_btn=gr.Button("Login")
180
  li_msg=gr.Textbox(label="Login Status")
181
  def login_wrap(e,p): ok,msg=login_user(e,p); return msg
182
+ li_btn.click(login_wrap,[li_email,li_pass],li_msg)
183
 
184
+ # ASK QUESTION
185
  with gr.Tab("Ask Question"):
186
+ q_in=gr.Textbox(label="Ask Question")
187
+ a_out=gr.Textbox(label="Answer",lines=12)
188
+ m_out=gr.Textbox(label="MCQs",lines=12)
189
+ pv=gr.Video(label="Preview Video",width=640,height=360)
190
+ fv=gr.Video(label="Full Video",width=640,height=360)
191
  ask_btn=gr.Button("Generate")
192
  def run_question(q):
193
  ans=answer_text_query(q)
194
  mcqs=generate_mcqs_from_text(ans)
195
  return ans,mcqs,create_video_simple(ans,preview=True),create_video_simple(ans)
196
+ ask_btn.click(run_question,q_in,[a_out,m_out,pv,fv])
197
 
198
+ # UPLOAD
199
+ with gr.Tab("Upload PDF/Image"):
200
  f_in=gr.File()
201
  opts=gr.CheckboxGroup(["Extracted Text","MCQs","Video","Notes"])
202
+ lang=gr.Dropdown(["en","ur","hi"],value="en",label="Video Language")
203
+ t_out=gr.Textbox(label="Extracted Text",lines=12)
204
+ mc_out=gr.Textbox(label="MCQs",lines=12)
205
+ pv2=gr.Video(label="Preview Video",width=640,height=360)
206
+ fv2=gr.Video(label="Full Video",width=640,height=360)
207
+ notes_out=gr.Textbox(label="Notes",lines=12)
208
+ flow_out=gr.Image(label="Flowchart",type="pil")
209
+ def process_file(file,options,lg):
210
  text=extract_text_from_file(file)
211
  mcq=""
212
  prev=None
 
221
  notes,flow=generate_notes_flowchart(text)
222
  return text,mcq,prev,full,notes,flow
223
  btn=gr.Button("Process")
224
+ btn.click(process_file,[f_in,opts,lang],[t_out,mc_out,pv2,fv2,notes_out,flow_out])
225
 
226
+ # LINKS
227
  with gr.Tab("Search Links"):
228
  topic=gr.Textbox(label="Topic")
229
  yt=gr.Markdown()
230
  gg=gr.Markdown()
231
  link_btn=gr.Button("Get Links")
232
+ link_btn.click(get_links_clickable,topic,[yt,gg])
233
 
234
  demo.launch()