Hifzamudassar commited on
Commit
0a99908
·
verified ·
1 Parent(s): ce729e0

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +272 -0
app.py ADDED
@@ -0,0 +1,272 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # =========================== #
2
+ # Install Packages #
3
+ # =========================== #
4
+ import os, tempfile, random
5
+ from PIL import Image, ImageDraw, ImageFont
6
+ import pytesseract
7
+ from gtts import gTTS
8
+ from moviepy.editor import ImageClip, AudioFileClip, concatenate_videoclips
9
+ import gradio as gr
10
+ from urllib.parse import quote_plus
11
+ import requests
12
+
13
+ # =========================== #
14
+ # Users DB & States #
15
+ # =========================== #
16
+ users_db = {}
17
+ verification_codes = {}
18
+
19
+ # =========================== #
20
+ # Signup & Verification #
21
+ # =========================== #
22
+ def signup_user(username,email,password,contact):
23
+ if email in users_db:
24
+ return "Email already registered. Please login.", ""
25
+ code = str(random.randint(100000,999999))
26
+ verification_codes[email] = code
27
+ users_db[email] = {"username":username,"password":password,"contact":contact,"verified":False}
28
+ return f"Signup successful! Your verification code (demo) is:", code
29
+
30
+ def verify_user(email,code):
31
+ if email not in users_db:
32
+ return "Email not found."
33
+ if users_db[email]["verified"]:
34
+ return "Already verified."
35
+ if verification_codes.get(email) == code:
36
+ users_db[email]["verified"] = True
37
+ verification_codes.pop(email)
38
+ return "Verification successful! You can now login."
39
+ return "Invalid verification code."
40
+
41
+ def login_user(email,password):
42
+ user = users_db.get(email)
43
+ if not user: return False,"User not found."
44
+ if not user["verified"]: return False,"Not verified."
45
+ if user["password"] != password: return False,"Incorrect password."
46
+ return True,f"Welcome {user['username']}!"
47
+
48
+ # =========================== #
49
+ # Groq API Functions #
50
+ # =========================== #
51
+ GROQ_API_KEY = "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"
52
+ GROQ_MODEL = "llama-3.3-70b-versatile"
53
+
54
+ def call_groq(prompt,max_tokens=600):
55
+ url = "https://api.groq.com/openai/v1/chat/completions"
56
+ headers = {"Authorization":f"Bearer {GROQ_API_KEY}", "Content-Type":"application/json"}
57
+ payload = {
58
+ "model":GROQ_MODEL,
59
+ "messages":[{"role":"user","content":prompt}],
60
+ "max_tokens":max_tokens
61
+ }
62
+ try:
63
+ r = requests.post(url,json=payload,headers=headers,timeout=30)
64
+ if r.status_code == 200:
65
+ return r.json().get("choices",[{}])[0].get("message",{}).get("content","")
66
+ return f"[Model error {r.status_code}] {r.text}"
67
+ except Exception as e:
68
+ return f"[API error] {e}"
69
+
70
+ def generate_mcqs_from_text(text,n=5):
71
+ if not text.strip(): return "No text provided."
72
+ prompt=f"Create {n} MCQs with 4 options and correct answer:\n\n{text}"
73
+ return call_groq(prompt)
74
+
75
+ def answer_text_query(query):
76
+ if not query.strip(): return "No question provided."
77
+ prompt=f"Answer clearly and concisely:\n\n{query}"
78
+ return call_groq(prompt)
79
+
80
+ # =========================== #
81
+ # Video Generation #
82
+ # =========================== #
83
+ def create_video_simple(text,tts_lang="en",preview=False):
84
+ if not text.strip(): return None
85
+ tmp=tempfile.gettempdir()
86
+ lines=[l.strip() for l in text.splitlines() if l.strip()] or [p.strip() for p in text.split('.') if p.strip()]
87
+ if preview: lines=lines[:1]
88
+
89
+ max_slides = 3 if not preview else 1
90
+ chunk_size = max(1,(len(lines)+max_slides-1)//max_slides)
91
+ clips=[]
92
+ try:
93
+ for i in range(0,len(lines),chunk_size):
94
+ chunk = " ".join(lines[i:i+chunk_size]).strip()
95
+ if not chunk: continue
96
+ slide_path=os.path.join(tmp,f"slide_{i}.png")
97
+ W,H=(480,320)
98
+ img=Image.new("RGB",(W,H),(255,182,193))
99
+ draw=ImageDraw.Draw(img)
100
+
101
+ try:
102
+ font = ImageFont.truetype("DejaVuSans-Bold.ttf",18)
103
+ title_font = ImageFont.truetype("DejaVuSans-Bold.ttf",24)
104
+ except:
105
+ font=ImageFont.load_default()
106
+ title_font=ImageFont.load_default()
107
+
108
+ title_text="You are looking beautiful"
109
+ tw,th=draw.textsize(title_text,font=title_font)
110
+ draw.text(((W-tw)/2,10),title_text,fill="darkblue",font=title_font)
111
+
112
+ margin=20
113
+ max_w=W-2*margin
114
+ words=chunk.split()
115
+ line=""
116
+ y=60
117
+ for w in words:
118
+ test=(line+" "+w).strip()
119
+ if draw.textsize(test,font=font)[0]<=max_w: line=test
120
+ else:
121
+ draw.text((margin,y),line,fill="black",font=font)
122
+ y+=22
123
+ line=w
124
+ if line: draw.text((margin,y),line,fill="black",font=font)
125
+ img.save(slide_path)
126
+
127
+ audio_path=os.path.join(tmp,f"audio_{i}.mp3")
128
+ gTTS(text=chunk,lang=tts_lang).save(audio_path)
129
+
130
+ duration=max(2,min(len(chunk)//12+3,8))
131
+ clip=ImageClip(slide_path).set_duration(duration).set_audio(AudioFileClip(audio_path))
132
+ clips.append(clip)
133
+
134
+ if not clips: return None
135
+ final=concatenate_videoclips(clips,method="compose")
136
+ out=os.path.join(tmp,"output_video.mp4") if not preview else os.path.join(tmp,"preview_video.mp4")
137
+ final.write_videofile(out,fps=24,codec="libx264",audio_codec="aac",verbose=False,logger=None)
138
+ return out
139
+ except:
140
+ return None
141
+
142
+ # =========================== #
143
+ # Notes + Flowchart #
144
+ # =========================== #
145
+ def generate_notes_flowchart(text):
146
+ if not text.strip(): return "No text provided.",None
147
+ notes=call_groq(f"Summarize into concise study notes:\n\n{text}",max_tokens=500)
148
+ img=Image.new("RGB",(480,320),(144,238,144))
149
+ draw=ImageDraw.Draw(img)
150
+ try: font = ImageFont.truetype("DejaVuSans.ttf",16)
151
+ except: font=ImageFont.load_default()
152
+
153
+ y=20
154
+ for line in notes.split("\n"):
155
+ if line.strip():
156
+ draw.text((10,y),line.strip(),fill="black",font=font)
157
+ y+=18
158
+ if y>280: break
159
+ return notes,img
160
+
161
+ # =========================== #
162
+ # Search Links #
163
+ # =========================== #
164
+ def get_youtube_link(q): return f"https://www.youtube.com/results?search_query={quote_plus(q)}"
165
+ def get_google_link(q): return f"https://www.google.com/search?q={quote_plus(q)}"
166
+
167
+ def get_links_clickable(topic):
168
+ if not topic.strip(): return "No topic provided.",""
169
+ yt_links=[f"[YouTube Result {i+1}]({get_youtube_link(topic)})" for i in range(3)]
170
+ gg_links=[f"[Google Result {i+1}]({get_google_link(topic)})" for i in range(3)]
171
+ return "\n".join(yt_links), "\n".join(gg_links)
172
+
173
+ # =========================== #
174
+ # Gradio Frontend #
175
+ # =========================== #
176
+ with gr.Blocks() as demo:
177
+
178
+ gr.Markdown("## 🌟 Professional AI Assistant Demo (Hackathon)")
179
+
180
+ with gr.Tab("Step 1: Sign Up"):
181
+ su_name = gr.Textbox(label="Username")
182
+ su_email = gr.Textbox(label="Email")
183
+ su_pass = gr.Textbox(label="Password",type="password")
184
+ su_contact = gr.Textbox(label="Contact Number")
185
+ su_btn = gr.Button("Sign Up")
186
+ su_msg = gr.Textbox(label="Message",interactive=False)
187
+ su_code = gr.Textbox(label="Your verification code (demo)",interactive=False)
188
+ su_btn.click(signup_user,inputs=[su_name,su_email,su_pass,su_contact],outputs=[su_msg,su_code])
189
+
190
+ with gr.Tab("Step 2: Verify"):
191
+ verify_email = gr.Textbox(label="Email")
192
+ verify_code = gr.Textbox(label="Enter verification code")
193
+ verify_btn = gr.Button("Verify")
194
+ verify_msg = gr.Textbox(label="Verification Status",interactive=False)
195
+ verify_btn.click(verify_user,inputs=[verify_email,verify_code],outputs=[verify_msg])
196
+
197
+ with gr.Tab("Step 3: Login"):
198
+ li_email = gr.Textbox(label="Email")
199
+ li_pass = gr.Textbox(label="Password",type="password")
200
+ li_btn = gr.Button("Login")
201
+ li_msg = gr.Textbox(label="Login Status",interactive=False)
202
+ li_success = gr.State(False)
203
+
204
+ def login_wrapper(email,password):
205
+ success,msg=login_user(email,password)
206
+ return msg,success
207
+
208
+ li_btn.click(login_wrapper,inputs=[li_email,li_pass],outputs=[li_msg,li_success])
209
+
210
+ with gr.Tab("Step 4: Ask Question"):
211
+ q_in = gr.Textbox(label="Type your question")
212
+ ans_out = gr.Textbox(label="Answer",lines=12)
213
+ mcq_out = gr.Textbox(label="MCQs",lines=12)
214
+ preview_q_vid = gr.Video(label="Preview Video")
215
+ full_q_vid = gr.Video(label="Full Video")
216
+ q_btn = gr.Button("Get Answer")
217
+
218
+ def process_question(q):
219
+ ans = answer_text_query(q)
220
+ mcq = generate_mcqs_from_text(ans)
221
+ preview = create_video_simple(ans,preview=True)
222
+ full = create_video_simple(ans,preview=False)
223
+ return ans,mcq,preview,full
224
+
225
+ q_btn.click(process_question,inputs=[q_in],outputs=[ans_out,mcq_out,preview_q_vid,full_q_vid])
226
+
227
+ with gr.Tab("Step 5: Upload Document"):
228
+ file_in = gr.File(label="Upload page image")
229
+ sel = gr.CheckboxGroup(["Extracted Text","MCQs","Video","Notes & Flowchart"])
230
+ lang = gr.Dropdown(label="Video language",choices=["en","ur","hi"],value="en")
231
+ out_text = gr.Textbox(label="Extracted / Answer Text",lines=12)
232
+ out_mcq = gr.Textbox(label="MCQs",lines=12)
233
+ preview_vid = gr.Video(label="Preview Video")
234
+ full_vid = gr.Video(label="Full Video")
235
+ notes_out = gr.Textbox(label="Notes",lines=12)
236
+ flowchart_out = gr.Image(label="Flowchart")
237
+
238
+ def process_upload(file,outputs_selected,lang_code):
239
+ text=""
240
+ try: text=pytesseract.image_to_string(Image.open(file.name))
241
+ except: text=""
242
+
243
+ mcq_text=""
244
+ preview_path=None
245
+ video_path=None
246
+ notes_text=""
247
+ flowchart_img=None
248
+
249
+ if "MCQs" in outputs_selected and text.strip():
250
+ mcq_text=generate_mcqs_from_text(text)
251
+
252
+ if "Video" in outputs_selected and text.strip():
253
+ preview_path=create_video_simple(text,tts_lang=lang_code,preview=True)
254
+ video_path=create_video_simple(text,tts_lang=lang_code,preview=False)
255
+
256
+ if "Notes & Flowchart" in outputs_selected and text.strip():
257
+ notes_text,flowchart_img=generate_notes_flowchart(text)
258
+
259
+ return text or "",mcq_text or "",preview_path,video_path,notes_text,flowchart_img
260
+
261
+ btn = gr.Button("Process")
262
+ btn.click(process_upload,inputs=[file_in,sel,lang],
263
+ outputs=[out_text,out_mcq,preview_vid,full_vid,notes_out,flowchart_out])
264
+
265
+ with gr.Tab("Step 6: Links"):
266
+ topic = gr.Textbox(label="Search topic")
267
+ yt = gr.Markdown(label="YouTube links")
268
+ gg = gr.Markdown(label="Google links")
269
+ sbtn = gr.Button("Get Links")
270
+ sbtn.click(get_links_clickable,inputs=[topic],outputs=[yt,gg])
271
+
272
+ demo.launch(share=True)