| 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 - AI Notes Generator", |
| page_icon="π", |
| layout="wide", |
| initial_sidebar_state="collapsed" |
| ) |
|
|
| |
| st.markdown(""" |
| <style> |
| .stApp { |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
| } |
| .main-container { |
| background: rgba(255, 255, 255, 0.95); |
| border-radius: 20px; |
| padding: 2rem; |
| box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); |
| backdrop-filter: blur(10px); |
| } |
| h1 { |
| color: #667eea; |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; |
| font-weight: 700; |
| text-align: center; |
| margin-bottom: 0.5rem; |
| } |
| .subtitle { |
| text-align: center; |
| color: #6c757d; |
| font-size: 1.1rem; |
| margin-bottom: 2rem; |
| } |
| .stButton > button { |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
| color: white; |
| border: none; |
| border-radius: 10px; |
| padding: 0.6rem 2rem; |
| font-weight: 600; |
| transition: all 0.3s ease; |
| box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4); |
| } |
| .stButton > button:hover { |
| transform: translateY(-2px); |
| box-shadow: 0 6px 20px rgba(102, 126, 234, 0.6); |
| } |
| .topic-item { |
| background: white; |
| border-radius: 8px; |
| padding: 0.8rem 1rem; |
| margin: 0.5rem 0; |
| border-left: 3px solid #667eea; |
| box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); |
| } |
| .success-box { |
| background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%); |
| color: white; |
| padding: 1rem; |
| border-radius: 10px; |
| text-align: center; |
| font-weight: 600; |
| margin: 1rem 0; |
| } |
| .stProgress > div > div { |
| background: linear-gradient(90deg, #667eea 0%, #764ba2 100%); |
| } |
| .info-box { |
| background: linear-gradient(135deg, #667eea15 0%, #764ba215 100%); |
| border-radius: 10px; |
| padding: 1rem; |
| border-left: 4px solid #667eea; |
| margin: 1rem 0; |
| } |
| </style> |
| """, unsafe_allow_html=True) |
|
|
| |
| if 'topics' not in st.session_state: |
| st.session_state.topics = [] |
| if 'notes_generated' not in st.session_state: |
| st.session_state.notes_generated = False |
| if 'pdf_bytes' not in st.session_state: |
| st.session_state.pdf_bytes = None |
|
|
| |
| load_dotenv() |
|
|
| |
| groq_client = Groq(api_key=os.getenv("GROQ_API_KEY")) |
|
|
| GROQ_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_name, max_tokens=2048): |
| try: |
| response = groq_client.chat.completions.create( |
| model=model_name, |
| messages=[{"role": "user", "content": prompt}], |
| max_tokens=max_tokens, |
| temperature=0.8, |
| top_p=0.9, |
| ) |
| return response.choices[0].message.content |
| except Exception as e: |
| try: |
| response = groq_client.chat.completions.create( |
| model=GROQ_MODELS[0], |
| messages=[{"role": "user", "content": prompt}], |
| max_tokens=max_tokens, |
| temperature=0.8, |
| top_p=0.9, |
| ) |
| return response.choices[0].message.content |
| except Exception as e2: |
| return f"[Error: {e2}]" |
|
|
| |
| st.markdown("<h1>π Zouq-ul-ilm</h1>", unsafe_allow_html=True) |
| st.markdown("<p class='subtitle'>AI-Powered Notes Generator for Students</p>", unsafe_allow_html=True) |
|
|
| with st.container(): |
| st.markdown("<div class='main-container'>", unsafe_allow_html=True) |
|
|
| |
| st.markdown("### π Step 1: Upload Course Outline") |
| st.markdown("<div class='info-box'>Upload your course outline (PDF format) to extract topics automatically.</div>", unsafe_allow_html=True) |
|
|
| uploaded_file = st.file_uploader( |
| "Drag and drop your file here", |
| type=['pdf'], |
| help="Upload a PDF file containing your course outline" |
| ) |
|
|
| if uploaded_file is not None: |
| |
| file_bytes = uploaded_file.read() |
| st.success(f"β
File uploaded: {uploaded_file.name}") |
|
|
| |
| st.markdown("---") |
| st.markdown("### π Step 2: Extract Topics") |
|
|
| col1, col2, col3 = st.columns([1, 2, 1]) |
| with col2: |
| if st.button("π Extract Topics", use_container_width=True): |
| with st.spinner("π Analyzing course outline and extracting topics..."): |
| try: |
| extracted_text = "" |
| reader = PyPDF2.PdfReader(io.BytesIO(file_bytes)) |
| for i in range(len(reader.pages)): |
| page = reader.pages[i] |
| text1 = page.extract_text() |
| if not text1: |
| continue |
|
|
| response_text = groq_generate( |
| prompt=f"""Analyze the outline and write down topics that are included: |
| {text1} |
| I just need topics, not anything else. Follow strictly: |
| - Do NOT write the heading "topics included" |
| - Ignore attendance, presentation, book names, grading policy |
| - Just write short, simple topic names only""", |
| model_name=GROQ_MODELS[0], |
| max_tokens=300 |
| ) |
| extracted_text += response_text + "\n\n" |
| time.sleep(1) |
|
|
| topics_list = [line.strip() for line in extracted_text.split("\n") if line.strip()] |
| st.session_state.topics = list(topics_list) |
| st.success(f"β
Extracted {len(st.session_state.topics)} topics successfully!") |
| except Exception as e: |
| st.error(f"β Error extracting topics: {str(e)}") |
|
|
| |
| if st.session_state.topics: |
| st.markdown("---") |
| st.markdown("### βοΈ Step 3: Review & Edit Topics") |
| st.markdown("<div class='info-box'>Review the extracted topics below. You can add new topics or remove unwanted ones.</div>", unsafe_allow_html=True) |
|
|
| col1, col2 = st.columns([3, 1]) |
| with col1: |
| new_topic = st.text_input("Add a new topic", placeholder="Enter topic name...") |
| with col2: |
| st.markdown("<br>", unsafe_allow_html=True) |
| if st.button("β Add Topic"): |
| if new_topic and new_topic.strip(): |
| st.session_state.topics.append(new_topic.strip()) |
| st.rerun() |
|
|
| st.markdown("#### π Current Topics") |
| for idx, topic in enumerate(st.session_state.topics): |
| col1, col2 = st.columns([5, 1]) |
| with col1: |
| st.markdown(f"<div class='topic-item'>{idx + 1}. {topic}</div>", unsafe_allow_html=True) |
| with col2: |
| if st.button("ποΈ", key=f"delete_{idx}"): |
| st.session_state.topics.pop(idx) |
| st.rerun() |
|
|
| |
| st.markdown("---") |
| st.markdown("### π€ Step 4: Generate Comprehensive Notes") |
|
|
| col1, col2, col3 = st.columns([1, 2, 1]) |
| with col2: |
| if st.button("β¨ Generate Notes", use_container_width=True): |
| st.session_state.notes_generated = False |
| st.session_state.pdf_bytes = None |
|
|
| progress_bar = st.progress(0) |
| status_text = st.empty() |
|
|
| try: |
| ext_text = "" |
| total_topics = len(st.session_state.topics) |
| mod = 0 |
|
|
| for p, topic in enumerate(st.session_state.topics): |
| status_text.text(f"π Generating notes for topic {p + 1} of {total_topics}: {topic[:50]}...") |
| progress_bar.progress((p + 1) / total_topics) |
|
|
| if mod == 4: |
| mod = 1 |
| if p % 5 == 0: |
| mod = mod + 1 |
|
|
| current_model = GROQ_MODELS[mod] |
|
|
| response_text = groq_generate( |
| prompt=f"""Make detailed yet easy-to-understand notes on {topic}. |
| Cover all key points from a university syllabus in simple, clear language. |
| Ensure the notes are complete and informative for students exam preparation. |
| Include: definition, key concepts, types/categories if any, important points, and a brief summary.""", |
| model_name=current_model, |
| max_tokens=2048 |
| ) |
|
|
| if response_text: |
| ext_text += f"\n\n=== {topic.upper()} ===\n\n{response_text}\n\n" |
|
|
| time.sleep(2) |
|
|
| |
| status_text.text("π Creating PDF document...") |
| pdf_data = pdf.pdf1(ext_text) |
| st.session_state.pdf_bytes = pdf_data |
| st.session_state.notes_generated = True |
|
|
| progress_bar.progress(1.0) |
| status_text.empty() |
|
|
| st.markdown("<div class='success-box'>β
Notes generated successfully!</div>", unsafe_allow_html=True) |
| st.balloons() |
|
|
| except Exception as e: |
| st.error(f"β Error generating notes: {str(e)}") |
|
|
| |
| if st.session_state.notes_generated and st.session_state.pdf_bytes: |
| st.markdown("---") |
| st.markdown("### π₯ Step 5: Download Your Notes") |
|
|
| col1, col2, col3 = st.columns([1, 2, 1]) |
| with col2: |
| st.download_button( |
| label="π Download Notes (PDF)", |
| data=st.session_state.pdf_bytes, |
| file_name="my_course_notes.pdf", |
| mime="application/pdf", |
| use_container_width=True |
| ) |
|
|
| st.markdown("</div>", unsafe_allow_html=True) |
|
|
| |
| st.markdown("---") |
| st.markdown("<p style='text-align: center; color: white; padding: 1rem;'>Made with β€οΈ by Zouq-ul-ilm Team | Powered by Groq AI</p>", unsafe_allow_html=True) |