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"") 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()