import streamlit as st import PyPDF2 from groq import Groq import time import os from dotenv import load_dotenv import pdf import io st.set_page_config( page_title="Zouq-ul-ilm", page_icon="✦", layout="centered", initial_sidebar_state="collapsed", ) st.markdown(""" """, unsafe_allow_html=True) for k, v in [("topics", []), ("notes_generated", False), ("pdf_bytes", None)]: if k not in st.session_state: st.session_state[k] = v load_dotenv() groq_client = Groq(api_key=os.getenv("GROQ_API_KEY")) MODELS = [ "llama-3.3-70b-versatile", "llama3-70b-8192", "llama3-8b-8192", "gemma2-9b-it", "llama-3.1-8b-instant", ] def groq_generate(prompt, model, max_tokens=2048): for m in [model, MODELS[0]]: try: r = groq_client.chat.completions.create( model=m, messages=[{"role": "user", "content": prompt}], max_tokens=max_tokens, temperature=0.8, top_p=0.9, ) return r.choices[0].message.content except Exception: continue return "[Error]" st.markdown("""

Zouq‑ul‑ilm

Upload your course outline · Get exam-ready notes as a PDF

""", unsafe_allow_html=True) st.markdown('

Step 1 — Upload outline

', unsafe_allow_html=True) uploaded = st.file_uploader("Upload PDF", type=["pdf"], label_visibility="collapsed") if uploaded: file_bytes = uploaded.read() st.markdown(f'
✓ {uploaded.name}
', unsafe_allow_html=True) st.markdown('
', unsafe_allow_html=True) st.markdown('

Step 2 — Extract topics

', unsafe_allow_html=True) if st.button("Extract Topics", key="extract"): with st.spinner("Scanning with AI…"): try: raw = "" reader = PyPDF2.PdfReader(io.BytesIO(file_bytes)) for page in reader.pages: txt = page.extract_text() if not txt: continue raw += groq_generate( prompt=f"""List only the study topics from this course outline. Rules: no headings, no numbering, no book names, no grading info — just short topic names, one per line. {txt}""", model=MODELS[0], max_tokens=300, ) + "\n" time.sleep(1) st.session_state.topics = [l.strip() for l in raw.splitlines() if l.strip()] st.markdown(f'
✓ {len(st.session_state.topics)} topics found
', unsafe_allow_html=True) except Exception as e: st.markdown(f'
✗ {e}
', unsafe_allow_html=True) if st.session_state.topics: st.markdown('
', unsafe_allow_html=True) st.markdown('

Step 3 — Review topics

', unsafe_allow_html=True) c1, c2 = st.columns([5, 1]) with c1: new_t = st.text_input("Add topic", placeholder="e.g. Binary Search Trees", label_visibility="collapsed") with c2: if st.button("Add", key="add"): if new_t.strip(): st.session_state.topics.append(new_t.strip()) st.rerun() for i, topic in enumerate(st.session_state.topics): ca, cb = st.columns([8, 1]) with ca: st.markdown( f'
{i+1:02d}{topic}
', unsafe_allow_html=True, ) with cb: if st.button("✕", key=f"del_{i}"): st.session_state.topics.pop(i) st.rerun() st.markdown('
', unsafe_allow_html=True) st.markdown(f'

Step 4 — Generate notes ({len(st.session_state.topics)} topics)

', unsafe_allow_html=True) if st.button("Generate Notes PDF", key="generate"): st.session_state.notes_generated = False st.session_state.pdf_bytes = None bar = st.progress(0) status = st.empty() total = len(st.session_state.topics) body = "" try: for p, topic in enumerate(st.session_state.topics): status.markdown( f'
Writing: {topic[:60]} ({p+1}/{total})
', unsafe_allow_html=True, ) bar.progress((p + 1) / total) notes = groq_generate( prompt=f"""Write detailed, exam-ready university notes on: {topic} Include: definition, key concepts, types/categories, important points, brief summary. Use clear headings and bullet points. Keep language simple and student-friendly.""", model=MODELS[p % len(MODELS)], max_tokens=2048, ) if notes: body += f"\n\n=== {topic.upper()} ===\n\n{notes}\n\n" time.sleep(2) status.markdown('
Building PDF…
', unsafe_allow_html=True) st.session_state.pdf_bytes = pdf.pdf1(body) st.session_state.notes_generated = True bar.progress(1.0) status.empty() st.markdown('
✓ PDF ready — download below
', unsafe_allow_html=True) st.balloons() except Exception as e: st.markdown(f'
✗ {e}
', unsafe_allow_html=True) if st.session_state.notes_generated and st.session_state.pdf_bytes: st.markdown('
', unsafe_allow_html=True) st.markdown('

Step 5 — Download

', unsafe_allow_html=True) st.download_button( label="⬇ Download Notes PDF", data=st.session_state.pdf_bytes, file_name="zouq_ul_ilm_notes.pdf", mime="application/pdf", use_container_width=True, ) st.markdown('', unsafe_allow_html=True)