import os
import streamlit as st
from PyPDF2 import PdfReader, PdfWriter 
from langchain.text_splitter import CharacterTextSplitter
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import FAISS
from langchain.chains.question_answering import load_qa_chain
from langchain.llms import OpenAI
from langchain.callbacks import get_openai_callback

def ChatPDF(text):
    # st.write(text)
    
    #split into chunks
    text_splitter = CharacterTextSplitter(
        separator="\n",
        chunk_size = 1000,
        chunk_overlap = 200,
        length_function=len
    )

    chunks = text_splitter.split_text(text)
    # st.write(chunks)
    # creating embeddings

    OPENAI_API_KEY = st.text_input("OPENAI API KEY", type = "password")
    if OPENAI_API_KEY:
        embeddings = OpenAIEmbeddings(openai_api_key=OPENAI_API_KEY)
        # st.write("Embedding Created")
        # st.write(embeddings)
        knowledge_base = FAISS.from_texts(chunks, embeddings)
        st.write("Knowledge Base created ")
        #show user input

        def ask_question(i=0):
            user_question = st.text_input("Ask a question about your PDF?",key = i)
            if user_question:
                docs = knowledge_base.similarity_search(user_question)
                # st.write(docs)

                llm = OpenAI(openai_api_key=OPENAI_API_KEY)
                chain = load_qa_chain(llm, chain_type="stuff")
                with get_openai_callback() as cb:
                    response = chain.run(input_documents=docs, question=user_question)
                    print(cb)
                st.write(response)
                ask_question(i+1)
                
        ask_question()

def main():
    st.set_page_config(page_title="Ask ur PDF",
                       page_icon="📄")

    hide_st_style = """
            <style>
            #mainMenue {visibility: hidden;}
            footer {visibility: hidden;}
            #header {visibility: hidden;}
            </style>
    """
    st.markdown(hide_st_style, unsafe_allow_html=True)

    # st.write(st.set_page_config)
    st.header("Ask your PDF 🤔💭")
    
    #uploading file
    pdf = st.file_uploader("Upload your PDF ", type="pdf")

    # extract the text
    if pdf is not None:
        option = st.selectbox("What you want to do with PDF📜", [
            "Meta Data📂",
            "Extract Raw Text📄",
            "Extract Links🔗",
            "Extract Images🖼️",
            "Make PDF password protected🔐",
            "PDF Annotation📝",
            "ChatPDF💬"
            ])
        pdf_reader = PdfReader(pdf)
        text = ""
        for page in pdf_reader.pages:
            text += page.extract_text()
        if option == "Meta Data📂":
            st.write(pdf_reader.metadata)
        elif option == "Make PDF password protected🔐":
            pswd = st.text_input("Enter yourpass word", type="password")
            if pswd:
                with st.spinner("Encrypting..."):
                    pdf_writer = PdfWriter()
                    for page_num in range(len(pdf_reader.pages)):
                        pdf_writer.add_page(pdf_reader.pages[page_num])
                        
                    pdf_writer.encrypt(pswd)
                    with open(f"{pdf.name.split('.')[0]}_encrypted.pdf", "wb") as f:
                        pdf_writer.write(f)

                    st.success("Encryption Successful!")
                    st.download_button(
                        label="Download Encrypted PDF",
                        data=open(f"{pdf.name.split('.')[0]}_encrypted.pdf", "rb").read(),
                        file_name=f"{pdf.name.split('.')[0]}_encrypted.pdf",
                        mime="application/octet-stream",
                    )
                    try:
                        os.remove(f"{pdf.name.split('.')[0]}_encrypted.pdf")
                    except: pass
        elif option == "Extract Raw Text📄":
            st.write(text)
        elif option == "Extract Links🔗":
            for page in pdf_reader.pages:
                if "/Annots" in page:
                    for annot in page["/Annots"]:
                        subtype = annot.get_object()["/Subtype"]
                        if subtype == "/Link":
                            try:
                                st.write(annot.get_object()["/A"]["/URI"])
                            except: pass
        elif option == "Extract Images🖼️":
            for page in pdf_reader.pages:
                try:
                    for img in page.images:
                        st.write(img.name)
                        st.image(img.data)
                except: pass
        elif option == "PDF Annotation📝":
            for page in pdf_reader.pages:
                if "/Annots" in page:
                    for annot in page["/Annots"]:
                        obj = annot.get_object()
                        st.write(obj)
                        st.write("***********")
                        annotation = {"subtype": obj["/Subtype"], "location": obj["/Rect"]}
                        st.write(annotation)
        elif option == "ChatPDF💬":
            ChatPDF(text)
    

if __name__ == "__main__":
    main()

langchain.chains.question_answering.load_qa_chain langchain.text_splitter.CharacterTextSplitter langchain.llms.OpenAI langchain.callbacks.get_openai_callback langchain.vectorstores.FAISS.from_texts langchain.embeddings.openai.OpenAIEmbeddings
[((481, 579), 'langchain.text_splitter.CharacterTextSplitter', 'CharacterTextSplitter', ([], {'separator': '"""\n"""', 'chunk_size': '(1000)', 'chunk_overlap': '(200)', 'length_function': 'len'}), "(separator='\\n', chunk_size=1000, chunk_overlap=200,\n    length_function=len)\n", (502, 579), False, 'from langchain.text_splitter import CharacterTextSplitter\n'), ((745, 793), 'streamlit.text_input', 'st.text_input', (['"""OPENAI API KEY"""'], {'type': '"""password"""'}), "('OPENAI API KEY', type='password')\n", (758, 793), True, 'import streamlit as st\n'), ((1783, 1841), 'streamlit.set_page_config', 'st.set_page_config', ([], {'page_title': '"""Ask ur PDF"""', 'page_icon': '"""📄"""'}), "(page_title='Ask ur PDF', page_icon='📄')\n", (1801, 1841), True, 'import streamlit as st\n'), ((2081, 2131), 'streamlit.markdown', 'st.markdown', (['hide_st_style'], {'unsafe_allow_html': '(True)'}), '(hide_st_style, unsafe_allow_html=True)\n', (2092, 2131), True, 'import streamlit as st\n'), ((2175, 2203), 'streamlit.header', 'st.header', (['"""Ask your PDF 🤔💭"""'], {}), "('Ask your PDF 🤔💭')\n", (2184, 2203), True, 'import streamlit as st\n'), ((2242, 2290), 'streamlit.file_uploader', 'st.file_uploader', (['"""Upload your PDF """'], {'type': '"""pdf"""'}), "('Upload your PDF ', type='pdf')\n", (2258, 2290), True, 'import streamlit as st\n'), ((842, 889), 'langchain.embeddings.openai.OpenAIEmbeddings', 'OpenAIEmbeddings', ([], {'openai_api_key': 'OPENAI_API_KEY'}), '(openai_api_key=OPENAI_API_KEY)\n', (858, 889), False, 'from langchain.embeddings.openai import OpenAIEmbeddings\n'), ((989, 1025), 'langchain.vectorstores.FAISS.from_texts', 'FAISS.from_texts', (['chunks', 'embeddings'], {}), '(chunks, embeddings)\n', (1005, 1025), False, 'from langchain.vectorstores import FAISS\n'), ((1035, 1070), 'streamlit.write', 'st.write', (['"""Knowledge Base created """'], {}), "('Knowledge Base created ')\n", (1043, 1070), True, 'import streamlit as st\n'), ((2360, 2551), 'streamlit.selectbox', 'st.selectbox', (['"""What you want to do with PDF📜"""', "['Meta Data📂', 'Extract Raw Text📄', 'Extract Links🔗', 'Extract Images🖼️',\n    'Make PDF password protected🔐', 'PDF Annotation📝', 'ChatPDF💬']"], {}), "('What you want to do with PDF📜', ['Meta Data📂',\n    'Extract Raw Text📄', 'Extract Links🔗', 'Extract Images🖼️',\n    'Make PDF password protected🔐', 'PDF Annotation📝', 'ChatPDF💬'])\n", (2372, 2551), True, 'import streamlit as st\n'), ((2672, 2686), 'PyPDF2.PdfReader', 'PdfReader', (['pdf'], {}), '(pdf)\n', (2681, 2686), False, 'from PyPDF2 import PdfReader, PdfWriter\n'), ((1160, 1214), 'streamlit.text_input', 'st.text_input', (['"""Ask a question about your PDF?"""'], {'key': 'i'}), "('Ask a question about your PDF?', key=i)\n", (1173, 1214), True, 'import streamlit as st\n'), ((2835, 2864), 'streamlit.write', 'st.write', (['pdf_reader.metadata'], {}), '(pdf_reader.metadata)\n', (2843, 2864), True, 'import streamlit as st\n'), ((1378, 1415), 'langchain.llms.OpenAI', 'OpenAI', ([], {'openai_api_key': 'OPENAI_API_KEY'}), '(openai_api_key=OPENAI_API_KEY)\n', (1384, 1415), False, 'from langchain.llms import OpenAI\n'), ((1441, 1479), 'langchain.chains.question_answering.load_qa_chain', 'load_qa_chain', (['llm'], {'chain_type': '"""stuff"""'}), "(llm, chain_type='stuff')\n", (1454, 1479), False, 'from langchain.chains.question_answering import load_qa_chain\n'), ((1667, 1685), 'streamlit.write', 'st.write', (['response'], {}), '(response)\n', (1675, 1685), True, 'import streamlit as st\n'), ((2941, 2994), 'streamlit.text_input', 'st.text_input', (['"""Enter yourpass word"""'], {'type': '"""password"""'}), "('Enter yourpass word', type='password')\n", (2954, 2994), True, 'import streamlit as st\n'), ((1502, 1523), 'langchain.callbacks.get_openai_callback', 'get_openai_callback', ([], {}), '()\n', (1521, 1523), False, 'from langchain.callbacks import get_openai_callback\n'), ((4062, 4076), 'streamlit.write', 'st.write', (['text'], {}), '(text)\n', (4070, 4076), True, 'import streamlit as st\n'), ((3039, 3066), 'streamlit.spinner', 'st.spinner', (['"""Encrypting..."""'], {}), "('Encrypting...')\n", (3049, 3066), True, 'import streamlit as st\n'), ((3102, 3113), 'PyPDF2.PdfWriter', 'PdfWriter', ([], {}), '()\n', (3111, 3113), False, 'from PyPDF2 import PdfReader, PdfWriter\n'), ((3480, 3516), 'streamlit.success', 'st.success', (['"""Encryption Successful!"""'], {}), "('Encryption Successful!')\n", (3490, 3516), True, 'import streamlit as st\n'), ((4697, 4715), 'streamlit.write', 'st.write', (['img.name'], {}), '(img.name)\n', (4705, 4715), True, 'import streamlit as st\n'), ((4741, 4759), 'streamlit.image', 'st.image', (['img.data'], {}), '(img.data)\n', (4749, 4759), True, 'import streamlit as st\n'), ((5041, 5054), 'streamlit.write', 'st.write', (['obj'], {}), '(obj)\n', (5049, 5054), True, 'import streamlit as st\n'), ((5080, 5103), 'streamlit.write', 'st.write', (['"""***********"""'], {}), "('***********')\n", (5088, 5103), True, 'import streamlit as st\n'), ((5222, 5242), 'streamlit.write', 'st.write', (['annotation'], {}), '(annotation)\n', (5230, 5242), True, 'import streamlit as st\n')]