diff --git a/.env.template b/.env.template deleted file mode 100644 index 1f80b25..0000000 --- a/.env.template +++ /dev/null @@ -1 +0,0 @@ -FABRIQUEDOC_ENDPOINT= diff --git a/.gitignore b/.gitignore index a8fba92..85e7c1d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ /.idea/ -/.env diff --git a/CHANGE b/CHANGE index d8263ee..e440e5c 100644 --- a/CHANGE +++ b/CHANGE @@ -1 +1 @@ -2 \ No newline at end of file +3 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index fafefc9..e8e283c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,7 +9,7 @@ COPY requirements.txt . RUN pip install -r requirements.txt # Copy the app's code -COPY *.py . +COPY main.py . # Set the entrypoint to run the app ENTRYPOINT [ "streamlit", "run" ] diff --git a/app_tab1.py b/app_tab1.py deleted file mode 100644 index 7abf730..0000000 --- a/app_tab1.py +++ /dev/null @@ -1,16 +0,0 @@ -import mdformat -import streamlit as st - -from demo_text import demo_text - - -def app_tab1(): - def button1_callback(): - st.session_state['markdown'] = mdformat.text(st.session_state['markdown'], - options={"number": True}) - - st.session_state['content'] = st.text_area( - "Entre ton texte ici. Les images sont dans ./images/", demo_text, - height=450, - key='markdown') - st.button("Formater le texte", on_click=button1_callback) diff --git a/app_tab2.py b/app_tab2.py deleted file mode 100644 index 11fd18a..0000000 --- a/app_tab2.py +++ /dev/null @@ -1,6 +0,0 @@ -import streamlit as st - - -def app_tab2(): - st.write("Aperçu") - st.markdown(st.session_state['content']) diff --git a/app_tab3.py b/app_tab3.py deleted file mode 100644 index 96845f1..0000000 --- a/app_tab3.py +++ /dev/null @@ -1,96 +0,0 @@ -import datetime - -import requests -import streamlit as st - -from models import DocumentSpecs - - -def app_tab3(): - st.header("Paramètres") - http_headers = {"Authorization": f"Bearer {st.session_state['bearer_token']}"} - # Styles - response_styles = requests.get(f"{st.session_state['fabriquedoc_endpoint']}/styles/", headers=http_headers).json() - styles = response_styles.get("styles") - selected_style = st.selectbox("Select a style:", styles) - # Formats - response_formats = requests.get(f"{st.session_state['fabriquedoc_endpoint']}/formats/{selected_style}/", headers=http_headers).json() - formats = response_formats.get("formats") - selected_format = st.selectbox("Select a format:", formats) - - # Autres paramètres - response_format_parameters = requests.get( - f"{st.session_state['fabriquedoc_endpoint']}/format_parameters/{selected_style}/{selected_format}/", headers=http_headers).json() - linkcolor = st.text_input("Link color:", - value=response_format_parameters.get("linkcolor")) - tocdepth = st.number_input("Table of Contents depth:", - value=int(response_format_parameters.get("tocdepth")), - min_value=1, - max_value=5, - step=1) - pdfengine = st.text_input("PDF engine:", - value=response_format_parameters.get("pdfengine")) - fontsize = st.number_input("Font size:", - value=int(response_format_parameters.get("fontsize")), - step=1) - paperwidth = st.number_input("Paper width:", - value=int(response_format_parameters.get("paperwidth")), - step=30) - paperheight = st.number_input("Paper height:", - value=int(response_format_parameters.get("paperheight")), - step=30) - ratio = st.number_input("Ratio:", - value=int(response_format_parameters.get("ratio")), - step=10) - margin = st.number_input("Margin:", - value=int(response_format_parameters.get("margin")), - step=10) - vmargin = st.number_input("Vertical margin:", - value=int(response_format_parameters.get("vmargin")), - step=10) - extension = "mp4" - fps = st.number_input("FPS:", - value=int(response_format_parameters.get("fps")), - step=1) - stilltime = st.number_input("Still time:", - value=int(response_format_parameters.get("stilltime")), - step=1) - - # Envoi - if st.button("Generate post"): - document_specs = DocumentSpecs( - format=selected_format, - style=selected_style, - linkcolor=linkcolor, - tocdepth=tocdepth, - pdfengine=pdfengine, - content=st.session_state['content'], - fontsize=fontsize, - paperwidth=paperwidth, - paperheight=paperheight, - ratio=ratio, - margin=margin, - vmargin=vmargin, - extension=extension, - fps=fps, - stilltime=stilltime - ) - - post_headers = http_headers | {"Content-Type": "application/json"} - # Send the POST request with the JSON data in the request body - response = requests.post(f"{st.session_state['fabriquedoc_endpoint']}/generer/", - json=document_specs.model_dump(), - headers=post_headers, - timeout=(30, 3000)) # 30 seconds connect timeout, 5 minutes read timeout - # Check the response status code - if 200 <= response.status_code <= 299: - # If the request is successful, get the file data from the response - file_data = response.content - datef = datetime.datetime.now().strftime("%m-%d-%Y") - - file_name = f"{document_specs.style}-{document_specs.format}-{datef}-output.zip" - - st.download_button('Télécharger', file_data, file_name=file_name) - else: - # If the request is unsuccessful, display the error status code and message - st.error(f"Request failed with status code {response.status_code}: {response.text}") \ No newline at end of file diff --git a/app_tab4.py b/app_tab4.py deleted file mode 100644 index 1a76488..0000000 --- a/app_tab4.py +++ /dev/null @@ -1,34 +0,0 @@ -import requests -import streamlit as st - - -def app_tab4(): - st.header("Images") - http_headers = {"Authorization": f"Bearer {st.session_state['bearer_token']}"} - - st.write("Images disponibles") - # list uploaded files with a request to the GET /images endpoint - response = requests.get(f"{st.session_state['fabriquedoc_endpoint']}/images/", headers=http_headers) - images = response.json()["images"] - selected_image = st.selectbox("Choisis une image:", images) - image_response = requests.get(f"{st.session_state['fabriquedoc_endpoint']}/images/{selected_image}", headers=http_headers) - image_data = image_response.content - st.image(image_data) - - st.write("Envoyer une image") - uploaded_files = st.file_uploader("Choisis un fichier image", - accept_multiple_files=True) - if uploaded_files is not None: - for uploaded_file in uploaded_files: - url = f"{st.session_state['fabriquedoc_endpoint']}/images/" - # Create a FormData object - files = {"file": uploaded_file} - - # Submit the file to the endpoint - response = requests.post(url, files=files, headers=http_headers) - - # Check the response status - if response.status_code < 300: - st.write(f"File {uploaded_file.name} sent successfully!") - else: - st.write(f"File {uploaded_file.name} upload failed.") diff --git a/demo_text.py b/demo_text.py deleted file mode 100644 index 3ce30ae..0000000 --- a/demo_text.py +++ /dev/null @@ -1,49 +0,0 @@ -demo_text = """ -## Guide rapide Markdown - -- Texte simple - - **Gras** - - *Italique* - - ~~Barré~~ - - `Code en ligne` - -::: {.center}\nCeci est centré\n::: - -- Titres - - # Titre 1 - - ## Titre 2 - - ### Titre 3 - - #### Titre 4 - - ##### Titre 5 - - ###### Titre 6 - -- Listes - - Liste non ordonnée - - Sous-élément - - Autre sous-élément - - Liste ordonnée - 1. Premier élément - 2. Deuxième élément - 3. Troisième élément - -- Liens - - [Lien texte](https://www.example.com) - - [Lien avec titre](https://www.example.com "Titre du lien") - - URL directe : - -- Images - - ![Texte alternatif](url-de-l-image.jpg) - - [![Image avec lien](url-de-l-image-miniature.jpg)](url-de-l-image-complete.jpg) - -- Citations - > Ceci est une citation - > - > Elle peut s'étendre sur plusieurs lignes - -- Code - ```python - def hello_world(): - print("Hello, World!") - ``` - -""" diff --git a/docker-run-macos.sh b/docker-run-macos.sh index 222100f..85647e7 100644 --- a/docker-run-macos.sh +++ b/docker-run-macos.sh @@ -1,5 +1,4 @@ -docker network create fabriquedoc docker stop fabriquedoc-frontend docker rm fabriquedoc-frontend # Ce programme sert à lancer le job_dispatcher dans un docker localement pour tester -docker run -p 8051:8051 --env-file=.env --name fabriquedoc-frontend --network fabriquedoc --env FABRIQUEDOC_ENDPOINT=http://fabriquedoc:8000 local/fabriquedoc-frontend \ No newline at end of file +docker run -p 8051:8051 --name fabriquedoc-frontend --network fabriquedoc --env FABRIQUEDOC_ENDPOINT=http://fabriquedoc:8000 local/fabriquedoc-frontend \ No newline at end of file diff --git a/docker-run.sh b/docker-run.sh index 2572b12..b79d113 100644 --- a/docker-run.sh +++ b/docker-run.sh @@ -1,4 +1,4 @@ docker stop fabriquedoc-frontend docker rm fabriquedoc-frontend # Ce programme sert à lancer le job_dispatcher dans un docker localement pour tester -docker run -p 8051:8051 --env-file=.env --name fabriquedoc-frontend --network host local/fabriquedoc-frontend \ No newline at end of file +docker run -p 8051:8051 --name fabriquedoc-frontend --network host local/fabriquedoc-frontend \ No newline at end of file diff --git a/login_form.py b/login_form.py deleted file mode 100644 index 5f9ec09..0000000 --- a/login_form.py +++ /dev/null @@ -1,23 +0,0 @@ -import streamlit as st -import requests - - -def login_form(): - with st.form(key='authentication'): - username = st.text_input("Username") - password = st.text_input("Password", type="password") - submit_button = st.form_submit_button(label='Login') - if submit_button: - # Send a POST request to your authentication endpoint - response = requests.post(f"{st.session_state['fabriquedoc_endpoint']}/token/", - data={"username": username, "password": password}) - if response.status_code == 200: - st.write("Connexion réussie!") - bearer_token = response.json()["access_token"] - # Store the bearer token in the session state - st.session_state['bearer_token'] = bearer_token - st.session_state['logged_in'] = True - else: - st.error("Connexion échouée!") - st.session_state['bearer_token'] = "" - st.session_state['logged_in'] = False diff --git a/main.py b/main.py index f929f09..40b1537 100644 --- a/main.py +++ b/main.py @@ -16,44 +16,192 @@ along with this program. If not, see . """ -import streamlit as st -import dotenv -import os -import app_tab1 -import app_tab2 -import app_tab3 -import app_tab4 -import login_form +import datetime + +import streamlit as st +import requests +from pydantic import BaseModel +import mdformat +import os + + +class DocumentSpecs(BaseModel): + format: str + style: str + linkcolor: str + tocdepth: int + pdfengine: str + content: str + fontsize: int + paperwidth: int + paperheight: int + ratio: int + margin: int + vmargin: int + extension: str + fps: int + stilltime: int + + +demo_text = """ +# Ceci est un titre\n +## Ceci est un sous-titre\n\n +Ceci est un paragraphe\n\n +## Ceci est un autre sous-titre\n\n +> Ceci est du code\n\n +Ceci est un emoji :heart_eyes:\n\n +::: {.center}\nCeci est centré\n::: +""" -if 'fabriquedoc_endpoint' not in st.session_state: - dotenv.load_dotenv() - st.session_state['fabriquedoc_endpoint'] = os.environ.get("FABRIQUEDOC_ENDPOINT", - "http://127.0.0.1:8000") if 'options' not in st.session_state: st.session_state['options'] = "" -if 'bearer_token' not in st.session_state: - st.session_state['bearer_token'] = "" -if 'logged_in' not in st.session_state: - st.session_state['logged_in'] = False st.title("Fabrique à documents") -st.write(f"Endpoint : {st.session_state['fabriquedoc_endpoint']}") +fabriquedoc_endpoint = os.environ.get("FABRIQUEDOC_ENDPOINT", "http://0.0.0.0:8000") -if not st.session_state['logged_in']: - login_form.login_form() +tab1, tab2, tab3, tab4 = st.tabs(["Markdown", "Aperçu", "Paramètres", "Images"]) -if st.session_state['logged_in']: - tab1, tab2, tab3, tab4 = st.tabs(["Markdown", "Aperçu", "Paramètres", "Images"]) +with tab1: + def button1_callback(): + st.session_state['markdown'] = mdformat.text(st.session_state['markdown'], + options={"number": True}) - with tab1: - app_tab1.app_tab1() - with tab2: - app_tab2.app_tab2() + content = st.text_area("Entre ton texte ici. Les images sont dans ./images/", demo_text, + height=450, + key='markdown') + st.button("Formater le texte", on_click=button1_callback) - with tab3: - app_tab3.app_tab3() +with tab2: + st.write("Aperçu") + st.markdown(content) - with tab4: - app_tab4.app_tab4() +with tab3: + st.header("Paramètres") + # Styles + response_styles = requests.get(f"{fabriquedoc_endpoint}/styles") + styles = response_styles.json()["styles"] + selected_style = st.selectbox("Select a style:", styles) + # Formats + response_formats = requests.get(f"{fabriquedoc_endpoint}/formats/{selected_style}/") + formats = response_formats.json()["formats"] + selected_format = st.selectbox("Select a format:", formats) + + # Autres paramètres + response_format_parameters = requests.get( + f"{fabriquedoc_endpoint}/format_parameters/{selected_style}/{selected_format}") + format_parameters = response_format_parameters.json() + st.write(format_parameters) + linkcolor = st.text_input("Link color:", + value=format_parameters.get("linkcolor")) + tocdepth = st.number_input("Table of Contents depth:", + value=int(format_parameters.get("tocdepth")), + min_value=1, + max_value=5, + step=1) + pdfengine = st.text_input("PDF engine:", + value=format_parameters.get("pdfengine")) + fontsize = st.number_input("Font size:", + value=int(format_parameters.get("fontsize")), + step=1) + paperwidth = st.number_input("Paper width:", + value=int(format_parameters.get("paperwidth")), + step=30) + paperheight = st.number_input("Paper height:", + value=int(format_parameters.get("paperheight")), + step=30) + ratio = st.number_input("Ratio:", + value=int(format_parameters.get("ratio")), + step=10) + margin = st.number_input("Margin:", + value=int(format_parameters.get("margin")), + step=10) + vmargin = st.number_input("Vertical margin:", + value=int(format_parameters.get("vmargin")), + step=10) + extension = st.selectbox("Extension:", ["png", "jpg", "pdf", "mp4"]) + if extension == "mp4": + fps = st.number_input("FPS:", + value=int(format_parameters.get("fps")), + step=1) + stilltime = st.number_input("Still time:", + value=int(format_parameters.get("stilltime")), + step=1) + else: + fps = 0 + stilltime = 0 + + # Envoi + if st.button("Generate post"): + document_specs = DocumentSpecs( + format=selected_format, + style=selected_style, + linkcolor=linkcolor, + tocdepth=tocdepth, + pdfengine=pdfengine, + content=content, + fontsize=fontsize, + paperwidth=paperwidth, + paperheight=paperheight, + ratio=ratio, + margin=margin, + vmargin=vmargin, + extension=extension, + fps=fps, + stilltime=stilltime + ) + + headers = {"Content-Type": "application/json"} + # Send the POST request with the JSON data in the request body + response = requests.get(f"{fabriquedoc_endpoint}/generer/", + json=document_specs.model_dump(), + headers=headers) + # Check the response status code + if 200 <= response.status_code <= 299: + # If the request is successful, get the file data from the response + file_data = response.content + datef = datetime.datetime.now().strftime("%m-%d-%Y") + + if document_specs.extension in ["jpg", 'png']: + extn = "zip" + else: + extn = document_specs.extension + + file_name = f"{document_specs.style}-{document_specs.format}-{datef}-output.{extn}" + + st.download_button('Télécharger', file_data, file_name=file_name) + else: + # If the request is unsuccessful, display the error status code and message + st.error(f"Request failed with status code {response.status_code}: {response.text}") + +with tab4: + st.header("Images") + + st.write("Images disponibles") + # list uploaded files with a request to the GET /images endpoint + response = requests.get(f"{fabriquedoc_endpoint}/images/") + images = response.json()["images"] + selected_image = st.selectbox("Choisis une image:", images) + image_response = requests.get(f"{fabriquedoc_endpoint}/images/{selected_image}") + image_data = image_response.content + st.image(image_data) + + st.write("Envoyer une image") + uploaded_files = st.file_uploader("Choisis un fichier image", + type=["png", "jpg", "jpeg"], + accept_multiple_files=True) + if uploaded_files is not None: + for uploaded_file in uploaded_files: + url = f"{fabriquedoc_endpoint}/images/" + # Create a FormData object + files = {"file": uploaded_file} + + # Submit the file to the endpoint + response = requests.post(url, files=files) + + # Check the response status + if response.status_code < 300: + st.write(f"File {uploaded_file.name} sent successfully!") + else: + st.write(f"File {uploaded_file.name} upload failed.") diff --git a/models.py b/models.py deleted file mode 100644 index f35183d..0000000 --- a/models.py +++ /dev/null @@ -1,19 +0,0 @@ -from pydantic import BaseModel - - -class DocumentSpecs(BaseModel): - format: str - style: str - linkcolor: str - tocdepth: int - pdfengine: str - content: str - fontsize: int - paperwidth: int - paperheight: int - ratio: int - margin: int - vmargin: int - extension: str - fps: int - stilltime: int diff --git a/requirements.txt b/requirements.txt index 6e92d1d..93e9fb5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,4 @@ -streamlit~=1.37.1 -requests~=2.31.0 -pydantic~=2.0.3 -mdformat~=0.7.17 -python-dotenv~=1.0.1 \ No newline at end of file +streamlit~=1.24.0 +requests~=2.28.2 +pydantic~=2.0.1 +mdformat~=0.7.16 \ No newline at end of file