uhhh lots of things
All checks were successful
Datadog Software Composition Analysis / Datadog SBOM Generation and Upload (push) Successful in 16s
Datadog Secrets Scanning / Datadog Static Analyzer (push) Successful in 14s
Datadog Static Analysis / Datadog Static Analyzer (push) Successful in 24s

This commit is contained in:
2025-03-08 11:17:24 -05:00
parent 0a6d5b8a90
commit c6f36d0408
7 changed files with 222 additions and 44 deletions

View File

@ -1,7 +1,11 @@
from dataclasses import dataclass
from src.config.config import Configuration
from src.rendering import GENERIC_FILE_MAPPING
from src.rendering.markdown import render_markdown, read_raw_markdown, rendered_markdown_to_plain_text
from src.rendering.markdown import (
render_markdown,
read_raw_markdown,
rendered_markdown_to_plain_text,
)
from enum import Enum
from PIL import Image
@ -16,9 +20,22 @@ class ImageMetadata:
alt: str
exif: dict
@dataclass
class MarkdownMetadata:
fontmatter: dict
"""
A class to represent metadata for a Markdown file.
Attributes:
----------
frontmatter : dict
A dictionary containing the front matter of the Markdown file.
content : str
The main content of the Markdown file.
preview : str
A preview or summary of the Markdown content.
"""
frontmatter: dict
content: str
preview: str
@ -30,6 +47,24 @@ class FileMetadata:
@dataclass
class TemplateFile:
"""
A class to represent a template file with its associated metadata.
Attributes:
----------
name (str): The name of the file.
path (str): The file path.
proper_name (str): The proper name of the file.
extension (str): The file extension.
categories (list[str]): A list of categories associated with the file.
date_modified (str): The date the file was last modified.
date_created (str): The date the file was created.
size_kb (int): The size of the file in kilobytes.
metadata (ImageMetadata | FileMetadata | None): Metadata associated with the file,
which can be either image metadata, file metadata, or None.
dir_item_count (int): The number of items in the directory if the file is a directory.
is_dir (bool): A flag indicating whether the file is a directory.
"""
name: str
path: str
proper_name: str
@ -51,9 +86,10 @@ class TemplateHelpers:
def __init__(self, config: Configuration):
self.config: Configuration = config
def _filter_hidden_files(self, files):
return [f for f in files if not f.name.startswith("___")]
def build_metadata_for_file(self, path: str, categories: list[str] = []):
"""Builds metadata for a file"""
def _build_metadata_for_file(self, path: str, categories: list[str] = []):
file_path = self.config.content_dir / path
for k in categories:
if k == "image":
@ -75,19 +111,37 @@ class TemplateHelpers:
ret = FileMetadata(None)
if file_path.suffix[1:].lower() == "md":
ret.typeMeta = MarkdownMetadata({}, "", "")
ret.typeMeta.fontmatter = frontmatter.load(file_path)
ret.typeMeta.frontmatter = frontmatter.load(file_path)
ret.typeMeta.content = render_markdown(file_path)
ret.typeMeta.rawContent = read_raw_markdown(file_path)
ret.typeMeta.rawText = rendered_markdown_to_plain_text(ret.typeMeta.content)
ret.typeMeta.rawText = rendered_markdown_to_plain_text(
ret.typeMeta.content
)
ret.typeMeta.preview = ret.typeMeta.rawText[:500] + "..."
return ret
return None
def get_folder_contents(self, path: str = ""):
"""Returns the contents of a folder as a list of TemplateFile objects
"""
Retrieve the contents of a folder and return a list of TemplateFile objects.
The metadata field is populated with the appropriate metadata object
Args:
path (str): The relative path to the folder within the content directory. Defaults to an empty string,
which refers to the root content directory.
Returns:
list: A list of TemplateFile objects representing the files and directories within the specified folder.
The function performs the following steps:
1. Constructs the full path to the folder by combining the content directory with the provided path.
2. Retrieves all files and directories within the specified folder.
3. Iterates over each file and directory, creating a TemplateFile object with metadata such as name,
path, proper name, extension, categories, date modified, date created, size in KB, metadata, directory
item count, and whether it is a directory.
4. If the item is a file, it assigns categories based on the file extension using a predefined mapping.
5. Builds additional metadata for each file.
6. Filters out hidden files from the list.
7. Returns the list of TemplateFile objects.
"""
search_contnet_path = self.config.content_dir / path
files = search_contnet_path.glob("*")
@ -110,30 +164,70 @@ class TemplateHelpers:
for k, v in GENERIC_FILE_MAPPING.items():
if f.suffix[1:].lower() in v:
t.categories.append(k)
t.metadata = self.build_metadata_for_file(f, t.categories)
t.metadata = self._build_metadata_for_file(f, t.categories)
ret.append(t)
ret = self._filter_hidden_files(ret)
return ret
def get_sibling_content_files(self, path: str = ""):
"""
Retrieves a list of sibling content files in the specified directory.
Args:
path (str): The relative path within the content directory to search for files.
Defaults to an empty string, which means the root of the content directory.
Returns:
list: A list of tuples, where each tuple contains the file name and its relative path
to the content directory. Only files that do not start with "___" are included.
"""
search_contnet_path = self.config.content_dir / path
files = search_contnet_path.glob("*")
return [
(file.name, str(file.relative_to(self.config.content_dir)))
for file in files
if file.is_file()
if file.is_file() and not file.name.startswith("___")
]
def get_text_document_preview(self, path: str):
"""
Generates a preview of the text document located at the given path.
This method reads the first 100 characters from the specified text file
and returns it as a string. The file path is constructed by combining
the content directory from the configuration with the provided path.
Args:
path (str): The relative path to the text document within the content directory.
Returns:
str: A string containing the first 100 characters of the text document.
Raises:
FileNotFoundError: If the file at the specified path does not exist.
IOError: If an I/O error occurs while reading the file.
"""
file_path = self.config.content_dir / path
with open(file_path, "r") as f:
content = f.read(100)
return content
def get_sibling_content_folders(self, path: str = ""):
"""
Retrieves a list of sibling content folders within a specified directory.
Args:
path (str): A relative path from the content directory to search within. Defaults to an empty string,
which means the search will be conducted in the content directory itself.
Returns:
list of tuple: A list of tuples where each tuple contains the folder name and its relative path
to the content directory. Only directories that do not start with "___" are included.
"""
search_contnet_path = self.config.content_dir / path
files = search_contnet_path.glob("*")
return [
(file.name, str(file.relative_to(self.config.content_dir)))
for file in files
if file.is_dir()
if file.is_dir() and not file.name.startswith("___")
]