""" Fabrique à documents Copyright (C) 2023 François Pelletier This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . """ import datetime import dotenv import streamlit as st import requests from pydantic import BaseModel import mdformat import os dotenv.load_dotenv() 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 'options' not in st.session_state: st.session_state['options'] = "" if 'bearer_token' not in st.session_state: st.session_state['bearer_token'] = "" st.title("Fabrique à documents") fabriquedoc_endpoint = os.environ.get("FABRIQUEDOC_ENDPOINT", "http://127.0.0.1:8000") st.write(f"Endpoint : {fabriquedoc_endpoint}") tab0, tab1, tab2, tab3, tab4 = st.tabs(["Login", "Markdown", "Aperçu", "Paramètres", "Images"]) with tab0: 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'{fabriquedoc_endpoint}/token/', data={"username": username, "password": password}) if response.status_code == 200: bearer_token = response.json()["access_token"] # Store the bearer token in the session state st.session_state['bearer_token'] = bearer_token with tab1: def button1_callback(): st.session_state['markdown'] = mdformat.text(st.session_state['markdown'], options={"number": True}) 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 tab2: st.write("Aperçu") st.markdown(content) with tab3: st.header("Paramètres") http_headers = {"Authorization": f"Bearer {st.session_state['bearer_token']}"} # Styles response_styles = requests.get(f"{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"{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"{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 = st.selectbox("Extension:", ["jpg", "pdf", "mp4"]) if 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) 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 ) post_headers = http_headers | {"Content-Type": "application/json"} # Send the POST request with the JSON data in the request body response = requests.post(f"{fabriquedoc_endpoint}/generer/", json=document_specs.model_dump(), headers=http_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"]: 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/", headers=http_headers) images = response.json()["images"] selected_image = st.selectbox("Choisis une image:", images) image_response = requests.get(f"{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", type=["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, 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.")