Merge pull request #37 from presenton/refactor_and_logs
refactor(fastapi),fix(fastapi):icons won't be downloaded during update,feat(electron):store child process logs
This commit is contained in:
commit
07e4e40086
7 changed files with 37 additions and 131 deletions
|
|
@ -12,4 +12,5 @@ export const nextjsDir = isDev ? path.join(baseDir, "servers/nextjs") : path.joi
|
|||
export const tempDir = path.join(app.getPath("temp"), "presenton")
|
||||
export const userDataDir = app.getPath("userData")
|
||||
export const downloadsDir = app.getPath("downloads")
|
||||
export const userConfigPath = path.join(userDataDir, "userConfig.json")
|
||||
export const userConfigPath = path.join(userDataDir, "userConfig.json")
|
||||
export const logsDir = path.join(userDataDir, "logs")
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
import { spawn } from "child_process";
|
||||
import { localhost } from "./constants";
|
||||
import { localhost, logsDir, userDataDir } from "./constants";
|
||||
import http from "http";
|
||||
import fs from "fs";
|
||||
|
||||
// @ts-ignore
|
||||
import handler from "serve-handler";
|
||||
import path from "path";
|
||||
|
||||
export async function startFastApiServer(
|
||||
directory: string,
|
||||
|
|
@ -30,10 +32,12 @@ export async function startFastApiServer(
|
|||
}
|
||||
);
|
||||
fastApiProcess.stdout.on("data", (data: any) => {
|
||||
fs.appendFileSync(path.join(logsDir, "fastapi-server.log"), data);
|
||||
console.log(`FastAPI: ${data}`);
|
||||
});
|
||||
fastApiProcess.stderr.on("data", (data: any) => {
|
||||
console.error(`FastAPI Error: ${data}`);
|
||||
fs.appendFileSync(path.join(logsDir, "fastapi-server.log"), data);
|
||||
console.error(`FastAPI: ${data}`);
|
||||
});
|
||||
// Wait for FastAPI server to start
|
||||
await waitForServer(`${localhost}:${port}/docs`);
|
||||
|
|
@ -60,10 +64,12 @@ export async function startNextJsServer(
|
|||
}
|
||||
);
|
||||
nextjsProcess.stdout.on("data", (data: any) => {
|
||||
fs.appendFileSync(path.join(logsDir, "nextjs-server.log"), data);
|
||||
console.log(`NextJS: ${data}`);
|
||||
});
|
||||
nextjsProcess.stderr.on("data", (data: any) => {
|
||||
console.error(`NextJS Error: ${data}`);
|
||||
fs.appendFileSync(path.join(logsDir, "nextjs-server.log"), data);
|
||||
console.error(`NextJS: ${data}`);
|
||||
});
|
||||
} else {
|
||||
// Start NextJS build server
|
||||
|
|
|
|||
|
|
@ -11,7 +11,12 @@ from api.routers.presentation.models import (
|
|||
)
|
||||
from api.services.logging import LoggingService
|
||||
from api.sql_models import PresentationSqlModel, SlideSqlModel
|
||||
from api.utils import download_files, get_presentation_dir, replace_file_name
|
||||
from api.utils import (
|
||||
download_files,
|
||||
get_presentation_dir,
|
||||
get_presentation_images_dir,
|
||||
replace_file_name,
|
||||
)
|
||||
from api.services.database import get_sql_session
|
||||
from api.services.instances import temp_file_service
|
||||
|
||||
|
|
@ -38,32 +43,27 @@ class UpdateSlideModelsHandler:
|
|||
presentation_id = self.data.presentation_id
|
||||
new_slides = self.data.slides
|
||||
|
||||
# Handle assets (images and icons)
|
||||
assets_local_paths = []
|
||||
assets_download_links = []
|
||||
images_dir = get_presentation_images_dir(self.presentation_id)
|
||||
|
||||
# Handle images
|
||||
images_local_paths = []
|
||||
images_download_links = []
|
||||
for new_slide in new_slides:
|
||||
new_images = new_slide.images or []
|
||||
new_icons = new_slide.icons or []
|
||||
|
||||
for new_assets, asset_type in [
|
||||
(new_images, "images"),
|
||||
(new_icons, "icons"),
|
||||
]:
|
||||
for i, asset in enumerate(new_assets):
|
||||
if asset.startswith("http"):
|
||||
parsed_url = unquote(urlparse(asset).path)
|
||||
image_name = replace_file_name(
|
||||
os.path.basename(parsed_url), str(uuid.uuid4())
|
||||
)
|
||||
asset_path = (
|
||||
f"{self.presentation_dir}/{asset_type}/{image_name}"
|
||||
)
|
||||
assets_local_paths.append(asset_path)
|
||||
assets_download_links.append(asset)
|
||||
getattr(new_slide, asset_type)[i] = asset_path
|
||||
for i, asset in enumerate(new_images):
|
||||
if asset.startswith("http"):
|
||||
parsed_url = unquote(urlparse(asset).path)
|
||||
image_name = replace_file_name(
|
||||
os.path.basename(parsed_url), str(uuid.uuid4())
|
||||
)
|
||||
image_path = os.path.join(images_dir, image_name)
|
||||
images_local_paths.append(image_path)
|
||||
images_download_links.append(asset)
|
||||
getattr(new_slide, "images")[i] = image_path
|
||||
|
||||
if assets_download_links:
|
||||
await download_files(assets_download_links, assets_local_paths)
|
||||
if images_download_links:
|
||||
await download_files(images_download_links, images_local_paths)
|
||||
|
||||
with get_sql_session() as sql_session:
|
||||
slide_sql_models = [
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
from enum import Enum
|
||||
import json
|
||||
from typing import List, Optional
|
||||
import uuid
|
||||
from pydantic import BaseModel, Field, model_validator
|
||||
|
||||
from graph_processor.utils import clip_text
|
||||
|
|
@ -69,8 +67,8 @@ class BarGraphDataModel(BaseModel):
|
|||
return [clip_text(category) for category in self.categories]
|
||||
|
||||
|
||||
# class ScatterChartDataModel(BaseModel):
|
||||
# series: List[ScatterSeriesModel]
|
||||
class ScatterChartDataModel(BaseModel):
|
||||
series: List[ScatterSeriesModel]
|
||||
|
||||
|
||||
class BubbleChartDataModel(BaseModel):
|
||||
|
|
@ -137,44 +135,6 @@ class GraphModel(BaseModel):
|
|||
| TableDataModel
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data):
|
||||
graph_model = cls(**data)
|
||||
graph_model.data = GRAPH_TYPE_MAPPING[graph_model.type](**data["data"])
|
||||
return graph_model
|
||||
|
||||
def to_create_dict(self, presentation: Optional[str] = None, auto_id: bool = False):
|
||||
temp = json.loads(self.model_dump_json())
|
||||
if presentation:
|
||||
temp["presentation"] = presentation
|
||||
|
||||
if not self.id:
|
||||
if auto_id:
|
||||
temp["id"] = str(uuid.uuid4())
|
||||
else:
|
||||
del temp["id"]
|
||||
|
||||
if "corrections" in temp:
|
||||
del temp["corrections"]
|
||||
|
||||
return temp
|
||||
|
||||
def to_update_dict(self):
|
||||
temp = self.to_create_dict()
|
||||
del temp["id"]
|
||||
return temp
|
||||
|
||||
def to_name_type_dict(self):
|
||||
return {
|
||||
"id": self.id,
|
||||
"name": self.name,
|
||||
"type": self.type.value,
|
||||
}
|
||||
|
||||
|
||||
class GraphCollectionModel(BaseModel):
|
||||
graphs: List[GraphModel]
|
||||
|
||||
|
||||
GRAPH_TYPE_MAPPING = {
|
||||
GraphTypeEnum.pie: PieChartDataModel,
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -1,70 +1,9 @@
|
|||
from enum import Enum
|
||||
from typing import List, Optional
|
||||
from typing import List
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from ppt_generator.models.other_models import SlideType
|
||||
|
||||
|
||||
class TitleWithGraphIdModel(BaseModel):
|
||||
title: str = Field(description="Title of slide containing graph")
|
||||
graph_id: Optional[str] = Field(
|
||||
default=None, description="Id of graph present in this slide"
|
||||
)
|
||||
|
||||
|
||||
class TitleWithGraphIdCollectionModel(BaseModel):
|
||||
items: List[TitleWithGraphIdModel]
|
||||
|
||||
|
||||
class PresentationTitlesModel(BaseModel):
|
||||
presentation_title: str = Field("Title of this presentation in about 3 to 8 words")
|
||||
titles: List[str] = Field(
|
||||
description="List of title of every slide in presentation in about 2 to 8 words"
|
||||
)
|
||||
# content: Optional[str] = Field(
|
||||
# default=None,
|
||||
# description="In-depth content extracted from prompt, images and documents in about 500 words in Markdown format",
|
||||
# )
|
||||
|
||||
|
||||
infographics_description = """
|
||||
Complete description of infographics charts in this slide.
|
||||
- Give out numbers and metrics with brief expalanation for the number.
|
||||
- This field should only be populated for slide type 10 and 11.
|
||||
- Be verbose in more than 60 words.
|
||||
- Do not hallucinate or make up numbers for infographics.
|
||||
- Do not give out the information with no numbers.
|
||||
Examples of infographics_information:
|
||||
1) Hillary's project completion increased to 35% and is expected to be finished by June 10th. On the other hand, Simon's project completion reached 80% and is expected to be completed by July 20th.
|
||||
2) The customer support ticket resolution rate increased to 75%, with 375 out of 500 tickets resolved, indicating strong progress. Meanwhile, the employee training program completion reached 3 out of 5 modules, with the remaining sessions expected to conclude by May 1st. On the other hand, the product development cycle progressed to 60%, with testing set to begin by June 20th.
|
||||
3) The monthly sales target reached $3,500, demonstrating strong progress toward the goal.
|
||||
4) The monthly sales target reached 85%, with $8,500 achieved out of a $10,000 goal, demonstrating strong progress. This indicates a steady upward trend in sales, with only $1,500 remaining to reach full completion.
|
||||
"""
|
||||
|
||||
graph_description = """
|
||||
Name of graph to be represented in this slide along with how it will be represented. It can be one or numtiple slides.
|
||||
Examples graph_information: - Graph "Vehicle Type Statistics" in whole as a bar graph
|
||||
- Table "Survey Result of 2024" from june to december as line chart
|
||||
- Graph "Customer Satisfaction" in whole as a pie chart, also add
|
||||
**Do not include graphs that were not submitted.**
|
||||
"""
|
||||
|
||||
|
||||
class BasicSlideConfiguration(BaseModel):
|
||||
title: str = Field("Title of this slide")
|
||||
info: str = Field(
|
||||
"Content and info for this slide in more than **200 words**. Give information in this format 1) 70 words about what this slides should signify. 2) another 70 words about the contents on the slide. 3) Another 70 words about elements of the slide."
|
||||
)
|
||||
type: SlideType
|
||||
graph_information: Optional[str] = Field(
|
||||
default=None, description=graph_description
|
||||
)
|
||||
infographics_numbers: Optional[str] = Field(
|
||||
description=infographics_description, default=None
|
||||
)
|
||||
|
||||
|
||||
class PresentationConfigurationModel(BaseModel):
|
||||
language: str = Field(description="Language of the presentation")
|
||||
number_of_slides: int = Field(description="Number of slides in the presentation")
|
||||
slides: List[BasicSlideConfiguration]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue