207 lines
7.6 KiB
Python
207 lines
7.6 KiB
Python
"""
|
|
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 <https://www.gnu.org/licenses/>.
|
|
"""
|
|
|
|
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 'options' not in st.session_state:
|
|
st.session_state['options'] = ""
|
|
|
|
st.title("Fabrique à documents")
|
|
|
|
fabriquedoc_endpoint = os.environ.get("FABRIQUEDOC_ENDPOINT", "http://0.0.0.0:8000")
|
|
|
|
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})
|
|
|
|
|
|
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")
|
|
# 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.")
|