Added first controls

This commit is contained in:
2025-11-26 20:53:12 +01:00
parent 459c89bae2
commit ce5328fe34
68 changed files with 37849 additions and 87048 deletions

View File

@@ -17,5 +17,15 @@ Update the root folder in `update_icons.py` to point to the root folder of the i
##
```sh
python update_icons.py
```
python manage_icons.py --help
```
To list
```sh
python manage_icons.py list
```
To generate icons
```sh
python manage_icons.py generate --no-dry-run --suppress-suffix
```

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,154 @@
import os
from pathlib import Path
import typer
ROOT_FOLDER = "/home/kodjo/Dev/MyDocManager/src/frontend/node_modules/@sicons"
MAX_SIZE = 2000000
import re
def pascal_to_snake(name: str) -> str:
"""Convert a PascalCase or CamelCase string to snake_case."""
if name is None:
return None
name = name.strip()
# Insert underscore before capital letters (except the first one)
s1 = re.sub(r'(.)([A-Z][a-z]+)', r'\1_\2', name)
# Handle consecutive capital letters (like 'HTTPServer' -> 'http_server')
s2 = re.sub(r'([a-z0-9])([A-Z])', r'\1_\2', s1)
return s2.lower()
app = typer.Typer()
def list_sources(source_folder: str):
return os.listdir(source_folder)
def list_icons_from_source(source_folder: str, source: str):
res = []
for f in os.listdir(f"{source_folder}/{source}"):
if f.endswith(".svg"):
res.append(f)
return res
def read_content(source_folder: str, source: str, file_name: str):
with open(f"{source_folder}/{source}/{file_name}", "r") as f:
return f.read().strip()
def get_dir_size(path: str | Path) -> int:
p = Path(path)
if p.is_file():
return p.stat().st_size
elif p.is_dir():
return sum(f.stat().st_size for f in p.rglob('*') if f.is_file())
else:
raise FileNotFoundError(f"Path not found: {path}")
def sizeof_fmt(num, suffix="B"):
for unit in ["", "K", "M", "G", "T"]:
if abs(num) < 1024.0:
return f"{num:3.1f}{unit}{suffix}"
num /= 1024.0
return f"{num:.1f}P{suffix}"
def init_buffer(source_folder: str, source: str):
buffer = ""
readme_file_path = f"{source_folder}/{source}/README.md"
if os.path.exists(readme_file_path):
with open(readme_file_path, "r") as f_readme:
for line in f_readme:
if line.startswith("#"):
buffer += line
else:
buffer += f"# {line}"
buffer += "\n\n"
buffer += "from fastcore.basics import NotStr\n\n"
return buffer
def flush(dry_run, suppress_suffix, source_folder: str, target_folder: str, buffer: str, size: int, part: int, source: str):
suffix = '' if suppress_suffix else f"_test"
outfile = f"{source}{suffix}.py" if part == 0 else f"{source}_p{part}{suffix}.py"
if not dry_run:
output_path = f"{target_folder}/{outfile}" if part == 0 else f"{target_folder}/{outfile}"
with open(output_path, "w") as f:
f.write(buffer)
typer.echo(f" Generated {source} as {outfile} ({sizeof_fmt(size)}, max={sizeof_fmt(MAX_SIZE)})")
return init_buffer(source_folder, source), 0, part + 1
@app.command("list")
def list_icons(
source: str = typer.Argument(None, help="The source file to list icons from"),
source_folder: str = typer.Option(ROOT_FOLDER, help="The source folder containing icons"),
count: bool = typer.Option(False, help="Counts the number of items"),
size: bool = typer.Option(False, help="Gets the size of the items"),
):
res = []
if source:
res.extend(list_icons_from_source(source_folder, source))
else:
res.extend(list_sources(source_folder))
if count:
typer.echo(len(res))
return
if size:
path = f"{source_folder}/{source}" if source else f"{source_folder}"
size = get_dir_size(path)
typer.echo(sizeof_fmt(size))
return
for r in res:
typer.echo(r)
@app.command("generate")
def generate_icons(
source: str = typer.Argument(None, help="The source file to list icons from"),
source_folder: str = typer.Option(ROOT_FOLDER, help="The source folder containing icons"),
target_folder: str = typer.Option(".", help="The folder where to create the python files."),
top: int = typer.Option(0, help="The number of top items to generate"),
dry_run: bool = typer.Option(True, help="Does not generate the icons"),
suppress_suffix: bool = typer.Option(False, help="Does not add the suffix to the icon names"),
):
sources = [source] if source else list_sources(source_folder)
for current_source in sources:
typer.echo(f"Generating icons for {current_source}")
buffer = init_buffer(source_folder, current_source)
size = 0
part = 0
for index, svg_file in enumerate(list_icons_from_source(source_folder, current_source)):
if 0 < top <= index:
break
icon_name = os.path.splitext(os.path.basename(svg_file))[0]
svg_content = read_content(source_folder, current_source, svg_file)
svg_content = svg_content.replace("<svg ", f'<svg name="{current_source}-{icon_name}" ').replace("\n", "")
content = f"{pascal_to_snake(icon_name)} = NotStr('''{svg_content}''')"
buffer += f"{content}\n"
size += len(content)
if size > MAX_SIZE:
buffer, size, part = flush(dry_run, suppress_suffix, source_folder, target_folder, buffer, size, part,
current_source)
flush(dry_run, suppress_suffix, source_folder, target_folder, buffer, size, part, current_source)
if __name__ == "__main__":
app()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff