Hifzamudassar's picture
Update app.py
82bb22c verified
import os, tempfile, random, pytesseract, requests
from PIL import Image, ImageDraw, ImageFont
from gtts import gTTS
from moviepy.video.VideoClip import ImageClip
from moviepy.audio.io.AudioFileClip import AudioFileClip
from moviepy.video.compositing.concatenate import concatenate_videoclips
from pdf2image import convert_from_path
import gradio as gr
from urllib.parse import quote_plus
# =====================
# HARD-CODED API KEY
# =====================
GROQ_API_KEY = "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"
GROQ_MODEL = "llama-3.3-70b-versatile"
# =====================
# USERS DB
# =====================
users_db = {}
verification_codes = {}
# =====================
# SIGNUP / VERIFY / LOGIN
# =====================
def signup_user(username,email,password,contact):
if email in users_db: return "Email already registered.",""
code = str(random.randint(100000,999999))
verification_codes[email]=code
users_db[email] = {"username":username,"password":password,"contact":contact,"verified":False}
return "Signup successful! Your verification code:", code
def verify_user(email,code):
if email not in users_db: return "Email not found."
if users_db[email]["verified"]: return "Already verified."
if verification_codes.get(email) == code:
users_db[email]["verified"] = True
verification_codes.pop(email)
return "Verification successful!"
return "Invalid verification code."
def login_user(email,password):
user = users_db.get(email)
if not user: return False,"User not found."
if not user["verified"]: return False,"Account not verified."
if user["password"] != password: return False,"Wrong password."
return True,f"Welcome {user['username']}!"
# =====================
# GROQ API
# =====================
def call_groq(prompt,max_tokens=600):
url="https://api.groq.com/openai/v1/chat/completions"
headers={"Authorization":f"Bearer {GROQ_API_KEY}","Content-Type":"application/json"}
payload={"model":GROQ_MODEL,"messages":[{"role":"user","content":prompt}],"max_tokens":max_tokens}
try:
r=requests.post(url,json=payload,headers=headers,timeout=30)
return r.json()["choices"][0]["message"]["content"]
except Exception as e:
return f"Groq API Error: {e}"
# =====================
# ANSWERS / MCQs
# =====================
def answer_text_query(q):
q = q.strip()
if len(q.split()) < 6:
prompt=f"Explain clearly in detail for beginners:\n\n{q}"
else:
prompt=f"Answer concisely:\n\n{q}"
return call_groq(prompt)
def generate_mcqs_from_text(text,n=5):
return call_groq(f"Generate {n} MCQs with 4 options + correct answer:\n\n{text}")
# =====================
# VIDEO
# =====================
def create_video_simple(text,tts_lang="en",preview=False):
if not text.strip(): return None
tmp=tempfile.gettempdir()
lines=[l.strip() for l in text.splitlines() if l.strip()] or [p.strip() for p in text.split('.') if p.strip()]
if preview: lines=lines[:1]
clips=[]
for i,line in enumerate(lines):
W,H=480,360
img_path=os.path.join(tmp,f"slide_{i}.png")
audio_path=os.path.join(tmp,f"audio_{i}.mp3")
img=Image.new("RGB",(W,H),(255,182,193))
draw=ImageDraw.Draw(img)
try: font=ImageFont.truetype("DejaVuSans-Bold.ttf",22)
except: font=ImageFont.load_default()
draw.text((20,20),line,fill="black",font=font)
img.save(img_path)
gTTS(text=line,lang=tts_lang).save(audio_path)
duration=max(3,min(len(line)//10+3,10))
clip=ImageClip(img_path).set_duration(duration).set_audio(AudioFileClip(audio_path))
clips.append(clip)
out=os.path.join(tmp,"preview.mp4" if preview else "full.mp4")
final=concatenate_videoclips(clips,method="compose")
final.write_videofile(out,fps=24,codec="libx264",audio_codec="aac",verbose=False)
return out
# =====================
# NOTES & FLOWCHART
# =====================
def generate_notes_flowchart(text):
notes=call_groq(f"Summarize into bullet study notes:\n\n{text}")
img=Image.new("RGB",(480,360),(144,238,144))
draw=ImageDraw.Draw(img)
try: font=ImageFont.truetype("DejaVuSans.ttf",16)
except: font=ImageFont.load_default()
y=20
for line in notes.split("\n"):
if y>330: break
draw.text((10,y),line,fill="black",font=font)
y+=18
return notes,img
# =====================
# FILE OCR (Safe)
# =====================
def extract_text_from_file(file):
try:
if file.name.endswith(".pdf"):
pages=convert_from_path(file.name)
text=""
for page in pages:
text+=pytesseract.image_to_string(page)+"\n"
return text
else:
img = Image.open(file.name)
return pytesseract.image_to_string(img)
except Exception as e:
return f"Error reading file: {e}"
# =====================
# LINKS
# =====================
def get_youtube_link(q): return f"https://www.youtube.com/results?search_query={quote_plus(q)}"
def get_google_link(q): return f"https://www.google.com/search?q={quote_plus(q)}"
def get_links_clickable(topic):
yt="\n".join([f"[YouTube {i+1}]({get_youtube_link(topic)})" for i in range(3)])
gg="\n".join([f"[Google {i+1}]({get_google_link(topic)})" for i in range(3)])
return yt,gg
# =====================
# GRADIENT BACKGROUND
# =====================
custom_css="""
body {background: linear-gradient(to bottom right, #90ee90, #ffb6c1);}
"""
# =====================
# UPLOAD PROCESS (Fixed)
# =====================
def process_file(file, options, lg):
text=""
mcq=""
prev=None
full=None
notes=""
flow=None
if file is None:
return "No file uploaded.","",None,None,"",None
# Extract text safely
try:
if file.name.endswith(".pdf"):
pages=convert_from_path(file.name)
for page in pages:
text+=pytesseract.image_to_string(page)+"\n"
else:
img = Image.open(file.name)
text = pytesseract.image_to_string(img)
except Exception as e:
text=f"Error extracting text: {e}"
# Generate MCQs
if "MCQs" in options and text.strip():
try:
mcq = generate_mcqs_from_text(text)
except Exception as e:
mcq=f"Error generating MCQs: {e}"
# Generate Video
if "Video" in options and text.strip():
try:
prev=create_video_simple(text,lg,preview=True)
full=create_video_simple(text,lg)
except Exception as e:
prev=None
full=None
text += f"\n[Video error: {e}]"
# Generate Notes & Flowchart
if "Notes" in options and text.strip():
try:
notes,flow = generate_notes_flowchart(text)
except Exception as e:
notes=""
flow=None
text += f"\n[Notes/Flowchart error: {e}]"
return text, mcq, prev, full, notes, flow
# =====================
# GRADIO UI
# =====================
with gr.Blocks() as demo:
gr.HTML(f"<style>{custom_css}</style>")
gr.Markdown("## 🌸 AI Study Wizard — Pink + Green Gradient")
# SIGNUP
with gr.Tab("Sign Up"):
su_name=gr.Textbox(label="Username")
su_email=gr.Textbox(label="Email")
su_pass=gr.Textbox(label="Password",type="password")
su_contact=gr.Textbox(label="Contact Number")
su_btn=gr.Button("Sign Up")
su_msg=gr.Textbox(label="Message",interactive=False)
su_code=gr.Textbox(label="Verification Code",interactive=False)
su_btn.click(signup_user,[su_name,su_email,su_pass,su_contact],[su_msg,su_code])
# VERIFY
with gr.Tab("Verify"):
v_email=gr.Textbox(label="Email")
v_code=gr.Textbox(label="Verification Code")
v_btn=gr.Button("Verify")
v_msg=gr.Textbox(label="Status",interactive=False)
v_btn.click(verify_user,[v_email,v_code],v_msg)
# LOGIN
with gr.Tab("Login"):
li_email=gr.Textbox(label="Email")
li_pass=gr.Textbox(label="Password",type="password")
li_btn=gr.Button("Login")
li_msg=gr.Textbox(label="Login Status")
def login_wrap(e,p): ok,msg=login_user(e,p); return msg
li_btn.click(login_wrap,[li_email,li_pass],li_msg)
# ASK QUESTION
with gr.Tab("Ask Question"):
q_in=gr.Textbox(label="Ask Question")
a_out=gr.Textbox(label="Answer",lines=12)
m_out=gr.Textbox(label="MCQs",lines=12)
pv=gr.Video(label="Preview Video",width=640,height=360)
fv=gr.Video(label="Full Video",width=640,height=360)
ask_btn=gr.Button("Generate")
def run_question(q):
ans=answer_text_query(q)
mcqs=generate_mcqs_from_text(ans)
return ans,mcqs,create_video_simple(ans,preview=True),create_video_simple(ans)
ask_btn.click(run_question,q_in,[a_out,m_out,pv,fv])
# UPLOAD
with gr.Tab("Upload PDF/Image"):
f_in=gr.File()
opts=gr.CheckboxGroup(["Extracted Text","MCQs","Video","Notes"])
lang=gr.Dropdown(["en","ur","hi"],value="en",label="Video Language")
t_out=gr.Textbox(label="Extracted Text",lines=12)
mc_out=gr.Textbox(label="MCQs",lines=12)
pv2=gr.Video(label="Preview Video",width=640,height=360)
fv2=gr.Video(label="Full Video",width=640,height=360)
notes_out=gr.Textbox(label="Notes",lines=12)
flow_out=gr.Image(label="Flowchart",type="pil")
btn=gr.Button("Process")
btn.click(process_file,[f_in,opts,lang],[t_out,mc_out,pv2,fv2,notes_out,flow_out])
# LINKS
with gr.Tab("Search Links"):
topic=gr.Textbox(label="Topic")
yt=gr.Markdown()
gg=gr.Markdown()
link_btn=gr.Button("Get Links")
link_btn.click(get_links_clickable,topic,[yt,gg])
demo.launch()