diff --git a/api/api.py b/api/api.py new file mode 100644 index 0000000..04e3755 --- /dev/null +++ b/api/api.py @@ -0,0 +1,6 @@ +from fastapi import APIRouter +from api.endpoints import reports, templates + +api_router = APIRouter() +api_router.include_router(reports.router, tags=["Report"]) +api_router.include_router(templates.router, prefix="/templates", tags=["Template"]) \ No newline at end of file diff --git a/api/endpoints/reports.py b/api/endpoints/reports.py new file mode 100644 index 0000000..d94436d --- /dev/null +++ b/api/endpoints/reports.py @@ -0,0 +1,34 @@ +from fastapi import APIRouter +from fastapi.responses import FileResponse +import csv, time +from models.Request import ReportCreateRequest +from helpers.render import RenderClass +from helpers.docx2pdf import Converter + +router = APIRouter() + +# Crete PDF Report +@router.post("/pdf",summary="Creates a pdf report.", tags=["Report"]) +def CreatePDFReport(body: ReportCreateRequest): + timestamp = time.time() + RenderClass.render(body, timestamp) + return FileResponse(Converter.docx2pdf(timestamp)) + +# Crete CSV Report +@router.post("/csv",summary="Creates a csv report.", tags=["Report"]) +def CreateCSVReport(body: ReportCreateRequest): + filename = time.time() + with open("./reports/%d.csv" % filename, 'w', encoding='UTF8', newline='') as f: + writer = csv.writer(f, delimiter=body.Seperator) + row = ["sep=" + body.Seperator] + + writer.writerow(row) + writer.writerow([body.Header]) + writer.writerow(body.ReadableColumns) + for data in body.Data: + row = [] + for column in body.Columns: + row.append(data[column]) + writer.writerow(row) + + return FileResponse("./reports/%d.csv" % filename) \ No newline at end of file diff --git a/api/endpoints/templates.py b/api/endpoints/templates.py new file mode 100644 index 0000000..f50098d --- /dev/null +++ b/api/endpoints/templates.py @@ -0,0 +1,73 @@ +from fastapi import UploadFile, File, APIRouter +from helpers.docx2pdf import Converter +import os, base64 +from pdf2image import convert_from_path + +router = APIRouter() + +# Lists all templates +@router.get("/",summary="Lists all templates.", tags=["Template"]) +def ListTemplates(): + base_path = os.getcwd() + "/templates/" + result = [] + + for file in [f for f in os.listdir(base_path)]: + res = dict() + file_stats = os.stat(base_path+ file) + if os.path.splitext(file)[1] == ".docx": + res["name"] = file + res["size"] = file_stats.st_size + result.append(res) + + return result + +# Get single template +@router.get("/{name}",summary="Get single template.", tags=["Template"]) +def GetTemplate(name: str): + base_path = os.getcwd() + "/templates/" + name + file_stats = os.stat(base_path) + res = dict() + res["name"] = name + res["size"] = file_stats.st_size + + return res + +# Get template's preview +@router.get("/preview/{name}",summary="Get template's preview.", tags=["Template"]) +def PreviewTemplate(name: str): + base_path = os.getcwd() + "/templates/" + name + pdf_path = Converter.docx2preview(base_path) + pdf_path = pdf_path.replace("docx", "pdf") + + pages = convert_from_path(pdf_path) + name = name.replace(".docx", ".png") + pages[0].save(name, 'png') + with open(name, "rb") as image_file: + encoded_string = base64.b64encode(image_file.read()) + response = dict() + response["encoded"] = encoded_string + return response + +# Delete template +@router.delete("/{name}",summary="Deletes a template.", tags=["Template"]) +def DeleteTemplate(name: str): + os.remove(os.getcwd() + "/templates/" + name) + return "Item deleted successfully." + +# Upload new template +@router.post("/", summary="Uploads new template.", tags=["Template"]) +def SaveTemplate(file: UploadFile = File(...)): + try: + contents = file.file.read() + name = file.filename.replace(" ", "_") + name = file.filename.replace("-", "_") + + with open(name, 'wb') as f: + f.write(contents) + except Exception: + return {"message": "There was an error uploading the file"} + finally: + file.file.close() + os.rename(name, "./templates/" + name) + + return {"message": f"Successfully uploaded {name}"} \ No newline at end of file diff --git a/main.py b/main.py index 435aed5..c7ded55 100644 --- a/main.py +++ b/main.py @@ -1,106 +1,11 @@ -from fastapi import FastAPI, UploadFile, File -from fastapi.responses import FileResponse -from models.Request import ReportCreateRequest -from helpers.render import RenderClass -from helpers.docx2pdf import Converter +from fastapi import FastAPI import uvicorn -import os, base64 -import csv, time -from pdf2image import convert_from_path +from api import api - -app = FastAPI() - -@app.post("/pdf",summary="Creates a pdf report.", tags=["Report"]) -def CreatePDFReport(body: ReportCreateRequest): - timestamp = time.time() - RenderClass.render(body, timestamp) - return FileResponse(Converter.docx2pdf(timestamp)) - -@app.post("/csv",summary="Creates a csv report.", tags=["Report"]) -def CreatePDFReport(body: ReportCreateRequest): - filename = time.time() - with open("./reports/%d.csv" % filename, 'w', encoding='UTF8', newline='') as f: - writer = csv.writer(f, delimiter=body.Seperator) - row = ["sep=" + body.Seperator] - - writer.writerow(row) - writer.writerow([body.Header]) - writer.writerow(body.ReadableColumns) - for data in body.Data: - row = [] - for column in body.Columns: - row.append(data[column]) - writer.writerow(row) - - return FileResponse("./reports/%d.csv" % filename) - -# Lists all templates -@app.get("/templates",summary="Lists all templates.", tags=["Template"]) -def ListTemplates(): - base_path = os.getcwd() + "/templates/" - result = [] - - for file in [f for f in os.listdir(base_path)]: - res = dict() - file_stats = os.stat(base_path+ file) - if os.path.splitext(file)[1] == ".docx": - res["name"] = file - res["size"] = file_stats.st_size - result.append(res) - - return result - -# Get single template -@app.get("/templates/{name}",summary="Get single template.", tags=["Template"]) -def ListTemplates(name: str): - base_path = os.getcwd() + "/templates/" + name - file_stats = os.stat(base_path) - res = dict() - res["name"] = name - res["size"] = file_stats.st_size - - return res - -# Get template's preview -@app.get("/templates/preview/{name}",summary="Get template's preview.", tags=["Template"]) -def TemplatePreview(name: str): - base_path = os.getcwd() + "/templates/" + name - pdf_path = Converter.docx2preview(base_path) - pdf_path = pdf_path.replace("docx", "pdf") - - pages = convert_from_path(pdf_path) - name = name.replace(".docx", ".png") - pages[0].save(name, 'png') - with open(name, "rb") as image_file: - encoded_string = base64.b64encode(image_file.read()) - response = dict() - response["encoded"] = encoded_string - return response - -# Delete template -@app.delete("/templates/{name}",summary="Deletes a template.", tags=["Template"]) -def ListTemplates(name: str): - os.remove(os.getcwd() + "/templates/" + name) - return "Item deleted successfully." - -# Upload new template -@app.post("/templates", summary="Uploads new template.", tags=["Template"]) -def SaveTemplate(file: UploadFile = File(...)): - try: - contents = file.file.read() - name = file.filename.replace(" ", "_") - name = file.filename.replace("-", "_") - - with open(name, 'wb') as f: - f.write(contents) - except Exception: - return {"message": "There was an error uploading the file"} - finally: - file.file.close() - os.rename(name, "./templates/" + name) - - return {"message": f"Successfully uploaded {name}"} +app = FastAPI( + title="Report Engine" +) +app.include_router(api.api_router) def serve(): """Serve the web application."""