-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ feat(resume): enhance style selection and management
- implement user-driven style selection process with fallback - improve readability and logging during style selection - introduce flexibility by reading style directly from file ♻️ refactor(style_manager): streamline style management logic - remove unused imports and functions - simplify style path retrieval - refine error handling in style management 🐛 fix(pdf_generation): correct style path retrieval logic - ensure style is selected before PDF generation - adjust style CSS reading in resume_generator 🔧 chore(logging): improve logging configuration and readability - standardize log messages across modules and remove Italian comments
- Loading branch information
Showing
7 changed files
with
111 additions
and
111 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
src/libs/resume_and_cover_builder/resume_prompt/strings_feder-cr.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,126 +1,88 @@ | ||
# src/ai_hawk/libs/resume_and_cover_builder/style_manager.py | ||
import os | ||
from pathlib import Path | ||
from typing import Dict, List, Tuple, Optional | ||
import inquirer | ||
import webbrowser | ||
import sys | ||
import logging | ||
|
||
# Configura il logging | ||
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') | ||
# Configure logging | ||
logging.basicConfig(level=logging.DEBUG, format="%(asctime)s - %(levelname)s - %(message)s") | ||
|
||
|
||
class StyleManager: | ||
|
||
def __init__(self): | ||
self.styles_directory: Optional[Path] = None | ||
self.selected_style: Optional[str] = None | ||
current_file = Path(__file__).resolve() | ||
# Salire di 4 livelli per raggiungere la radice del progetto | ||
project_root = current_file.parent.parent.parent.parent # Adatta se la struttura cambia | ||
|
||
# Imposta la directory degli stili in modo robusto | ||
project_root = current_file.parent.parent.parent.parent | ||
self.styles_directory = project_root / "src" / "libs" / "resume_and_cover_builder" / "resume_style" | ||
logging.debug(f"Project root determinato come: {project_root}") | ||
logging.debug(f"Directory degli stili impostata su: {self.styles_directory}") | ||
|
||
logging.debug(f"Project root determined as: {project_root}") | ||
logging.debug(f"Styles directory set to: {self.styles_directory}") | ||
|
||
def get_styles(self) -> Dict[str, Tuple[str, str]]: | ||
""" | ||
Ottiene gli stili disponibili nella directory degli stili. | ||
Retrieve the available styles from the styles directory. | ||
Returns: | ||
Dict[str, Tuple[str, str]]: Un dizionario che mappa i nomi degli stili ai loro file e link degli autori. | ||
Dict[str, Tuple[str, str]]: A dictionary mapping style names to their file names and author links. | ||
""" | ||
styles_to_files = {} | ||
if not self.styles_directory: | ||
logging.warning("Directory degli stili non impostata.") | ||
logging.warning("Styles directory is not set.") | ||
return styles_to_files | ||
logging.debug(f"Leggendo la directory degli stili: {self.styles_directory}") | ||
logging.debug(f"Reading styles directory: {self.styles_directory}") | ||
try: | ||
files = [f for f in self.styles_directory.iterdir() if f.is_file()] | ||
logging.debug(f"Files trovati: {[f.name for f in files]}") | ||
logging.debug(f"Files found: {[f.name for f in files]}") | ||
for file_path in files: | ||
logging.debug(f"Processando file: {file_path}") | ||
with file_path.open('r', encoding='utf-8') as file: | ||
logging.debug(f"Processing file: {file_path}") | ||
with file_path.open("r", encoding="utf-8") as file: | ||
first_line = file.readline().strip() | ||
logging.debug(f"Prima linea del file {file_path.name}: {first_line}") | ||
logging.debug(f"First line of file {file_path.name}: {first_line}") | ||
if first_line.startswith("/*") and first_line.endswith("*/"): | ||
content = first_line[2:-2].strip() | ||
if '$' in content: | ||
style_name, author_link = content.split('$', 1) | ||
if "$" in content: | ||
style_name, author_link = content.split("$", 1) | ||
style_name = style_name.strip() | ||
author_link = author_link.strip() | ||
styles_to_files[style_name] = (file_path.name, author_link) | ||
logging.info(f"Aggiunto stile: {style_name} da {author_link}") | ||
logging.info(f"Added style: {style_name} by {author_link}") | ||
except FileNotFoundError: | ||
logging.error(f"Directory {self.styles_directory} non trovata.") | ||
logging.error(f"Directory {self.styles_directory} not found.") | ||
except PermissionError: | ||
logging.error(f"Permesso negato per accedere a {self.styles_directory}.") | ||
logging.error(f"Permission denied for accessing {self.styles_directory}.") | ||
except Exception as e: | ||
logging.error(f"Errore imprevisto durante la lettura degli stili: {e}") | ||
logging.error(f"Unexpected error while reading styles: {e}") | ||
return styles_to_files | ||
|
||
def format_choices(self, styles_to_files: Dict[str, Tuple[str, str]]) -> List[str]: | ||
""" | ||
Format the style choices for the user. | ||
Format the style choices for user presentation. | ||
Args: | ||
styles_to_files (Dict[str, Tuple[str, str]]): A dictionary mapping style names to their file names and author links. | ||
Returns: | ||
List[str]: A list of formatted style choices. | ||
""" | ||
return [f"{style_name} (style author -> {author_link})" for style_name, (file_name, author_link) in styles_to_files.items()] | ||
|
||
def get_style_path(self) -> Path: | ||
def set_selected_style(self, selected_style: str): | ||
""" | ||
Get the path to the selected style. | ||
Directly set the selected style. | ||
Args: | ||
selected_style (str): The selected style. | ||
Returns: | ||
Path: a Path object representing the path to the selected style file. | ||
selected_style (str): The name of the style to select. | ||
""" | ||
styles = self.get_styles() | ||
if self.selected_style not in styles: | ||
raise ValueError(f"Style '{self.selected_style}' not found.") | ||
file_name, _ = styles[self.selected_style] | ||
return self.styles_directory / file_name | ||
self.selected_style = selected_style | ||
logging.info(f"Selected style set to: {self.selected_style}") | ||
|
||
def choose_style(self) -> Optional[str]: | ||
def get_style_path(self) -> Optional[Path]: | ||
""" | ||
Prompt the user to select a style using inquirer. | ||
Get the path to the selected style. | ||
Returns: | ||
Optional[str]: The name of the selected style, or None if selection was canceled. | ||
Path: A Path object representing the path to the selected style file, or None if not found. | ||
""" | ||
styles = self.get_styles() | ||
if not styles: | ||
logging.warning("Nessuno stile disponibile per la selezione.") | ||
return None | ||
|
||
final_style_choice = "Crea il tuo stile di resume in CSS" | ||
formatted_choices = self.format_choices(styles) | ||
formatted_choices.append(final_style_choice) | ||
|
||
questions = [ | ||
inquirer.List( | ||
'selected_style', | ||
message="Quale stile vorresti adottare?", | ||
choices=formatted_choices | ||
) | ||
] | ||
|
||
answers = inquirer.prompt(questions) | ||
if answers and 'selected_style' in answers: | ||
selected_display = answers['selected_style'] | ||
if selected_display == final_style_choice: | ||
tutorial_url = "https://github.com/feder-cr/lib_resume_builder_AIHawk/blob/main/how_to_contribute/web_designer.md" | ||
logging.info("\nApro il tutorial nel tuo browser...") | ||
webbrowser.open(tutorial_url) | ||
sys.exit(0) | ||
else: | ||
# Estrai il nome dello stile dal formato "style_name (style author -> author_link)" | ||
style_name = selected_display.split(' (')[0] | ||
logging.info(f"Hai selezionato lo stile: {style_name}") | ||
self.selected_style = style_name | ||
return style_name | ||
else: | ||
logging.warning("Selezione annullata.") | ||
try: | ||
styles = self.get_styles() | ||
if self.selected_style not in styles: | ||
raise ValueError(f"Style '{self.selected_style}' not found.") | ||
file_name, _ = styles[self.selected_style] | ||
return self.styles_directory / file_name | ||
except Exception as e: | ||
logging.error(f"Error retrieving selected style: {e}") | ||
return None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters