mirror of
https://github.com/walkxcode/dashboard-icons.git
synced 2025-01-12 03:07:26 +01:00
🚀 Much needed maintenance
This commit is contained in:
parent
98c3da01bc
commit
8d414fa3ef
12
scripts/TEMPLATE.md
Normal file
12
scripts/TEMPLATE.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
![jsDelivr hits (GitHub)](https://img.shields.io/jsdelivr/gh/hy/walkxcode/dashboard-icons?style=flat-square&color=%23A020F0)
|
||||||
|
|
||||||
|
## Dashboard Icons
|
||||||
|
|
||||||
|
The best source for dashboard icons.<br />
|
||||||
|
[**← Back to repository**](https://github.com/walkxcode/dashboard-icons/)
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
<!-- ICONS -->
|
||||||
|
|
||||||
|
<!-- END ICONS -->
|
||||||
|
</div>
|
157
scripts/convert_svg_assets.py
Normal file
157
scripts/convert_svg_assets.py
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
import hashlib
|
||||||
|
from pathlib import Path
|
||||||
|
from PIL import Image
|
||||||
|
import cairosvg
|
||||||
|
|
||||||
|
# Define paths
|
||||||
|
ROOT_DIR = Path(__file__).resolve().parent.parent
|
||||||
|
SVG_DIR = ROOT_DIR / "svg"
|
||||||
|
PNG_DIR = ROOT_DIR / "png"
|
||||||
|
WEBP_DIR = ROOT_DIR / "webp"
|
||||||
|
|
||||||
|
# Ensure the output folders exist
|
||||||
|
PNG_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
|
WEBP_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
# Track results
|
||||||
|
failed_files = []
|
||||||
|
converted_pngs = 0
|
||||||
|
converted_webps = 0
|
||||||
|
total_icons = 0
|
||||||
|
|
||||||
|
def file_size_readable(size_bytes):
|
||||||
|
"""Convert bytes to a human-readable format."""
|
||||||
|
for unit in ['B', 'KB', 'MB', 'GB']:
|
||||||
|
if size_bytes < 1024:
|
||||||
|
return f"{size_bytes:.2f} {unit}"
|
||||||
|
size_bytes /= 1024
|
||||||
|
|
||||||
|
def hash_file(file_path):
|
||||||
|
"""Generate an MD5 hash for a file."""
|
||||||
|
hash_md5 = hashlib.md5()
|
||||||
|
with open(file_path, "rb") as f:
|
||||||
|
for chunk in iter(lambda: f.read(4096), b""):
|
||||||
|
hash_md5.update(chunk)
|
||||||
|
return hash_md5.hexdigest()
|
||||||
|
|
||||||
|
def convert_to_kebab_case(name):
|
||||||
|
"""Convert a filename to kebab-case."""
|
||||||
|
cleaned = re.sub(r'[^a-zA-Z0-9\s-]', '', name)
|
||||||
|
kebab_case_name = re.sub(r'[\s_]+', '-', cleaned).lower()
|
||||||
|
return kebab_case_name
|
||||||
|
|
||||||
|
def rename_if_needed(file_path):
|
||||||
|
"""Ensure the filename is in kebab-case; rename if necessary."""
|
||||||
|
new_name = convert_to_kebab_case(file_path.stem) + file_path.suffix
|
||||||
|
new_path = file_path.parent / new_name
|
||||||
|
|
||||||
|
if new_path != file_path:
|
||||||
|
if new_path.exists():
|
||||||
|
raise FileExistsError(f"File conflict: {new_path} already exists.")
|
||||||
|
file_path.rename(new_path)
|
||||||
|
print(f"Renamed: {file_path} -> {new_path}")
|
||||||
|
|
||||||
|
return new_path
|
||||||
|
|
||||||
|
def needs_conversion(output_file, data=None):
|
||||||
|
"""Check if a file needs to be converted or overwritten."""
|
||||||
|
if output_file.exists():
|
||||||
|
if data:
|
||||||
|
existing_hash = hash_file(output_file)
|
||||||
|
new_hash = hashlib.md5(data).hexdigest()
|
||||||
|
return existing_hash != new_hash
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def convert_svg_to_png(svg_path, png_path):
|
||||||
|
"""Convert SVG to PNG."""
|
||||||
|
global converted_pngs
|
||||||
|
try:
|
||||||
|
png_data = cairosvg.svg2png(url=str(svg_path), output_height=512)
|
||||||
|
|
||||||
|
if needs_conversion(png_path, png_data):
|
||||||
|
with open(png_path, 'wb') as f:
|
||||||
|
f.write(png_data)
|
||||||
|
print(f"Converted PNG: {png_path} ({file_size_readable(png_path.stat().st_size)})")
|
||||||
|
converted_pngs += 1
|
||||||
|
else:
|
||||||
|
print(f"PNG already up-to-date: {png_path}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Failed to convert {svg_path} to PNG: {e}")
|
||||||
|
failed_files.append(svg_path)
|
||||||
|
|
||||||
|
def convert_png_to_webp(png_path, webp_path):
|
||||||
|
"""Convert PNG to WEBP."""
|
||||||
|
global converted_webps
|
||||||
|
try:
|
||||||
|
image = Image.open(png_path)
|
||||||
|
|
||||||
|
if needs_conversion(webp_path):
|
||||||
|
image.save(webp_path, format='WEBP')
|
||||||
|
print(f"Converted WEBP: {webp_path} ({file_size_readable(webp_path.stat().st_size)})")
|
||||||
|
converted_webps += 1
|
||||||
|
else:
|
||||||
|
print(f"WEBP already up-to-date: {webp_path}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Failed to convert {png_path} to WEBP: {e}")
|
||||||
|
failed_files.append(png_path)
|
||||||
|
|
||||||
|
def clean_up_files(folder, valid_basenames):
|
||||||
|
"""Remove files that no longer have corresponding SVG files."""
|
||||||
|
removed_files = 0
|
||||||
|
for file_path in folder.glob('*'):
|
||||||
|
if file_path.stem not in valid_basenames:
|
||||||
|
file_path.unlink()
|
||||||
|
print(f"Removed: {file_path}")
|
||||||
|
removed_files += 1
|
||||||
|
return removed_files
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Track valid basenames (existing SVG files)
|
||||||
|
valid_basenames = set()
|
||||||
|
|
||||||
|
# Process all SVG files
|
||||||
|
for svg_file in SVG_DIR.glob("*.svg"):
|
||||||
|
total_icons += 1
|
||||||
|
|
||||||
|
# Ensure the filename is in kebab-case
|
||||||
|
try:
|
||||||
|
svg_path = rename_if_needed(svg_file)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error renaming {svg_file}: {e}")
|
||||||
|
failed_files.append(svg_file)
|
||||||
|
continue
|
||||||
|
|
||||||
|
valid_basenames.add(svg_path.stem)
|
||||||
|
|
||||||
|
# Set paths for PNG and WEBP
|
||||||
|
png_path = PNG_DIR / f"{svg_path.stem}.png"
|
||||||
|
webp_path = WEBP_DIR / f"{svg_path.stem}.webp"
|
||||||
|
|
||||||
|
# Convert SVG to PNG
|
||||||
|
convert_svg_to_png(svg_path, png_path)
|
||||||
|
|
||||||
|
# Convert PNG to WEBP
|
||||||
|
if png_path.exists():
|
||||||
|
convert_png_to_webp(png_path, webp_path)
|
||||||
|
|
||||||
|
# Clean up unused files
|
||||||
|
removed_pngs = clean_up_files(PNG_DIR, valid_basenames)
|
||||||
|
removed_webps = clean_up_files(WEBP_DIR, valid_basenames)
|
||||||
|
|
||||||
|
# Display summary
|
||||||
|
if converted_pngs == 0 and converted_webps == 0 and removed_pngs == 0 and removed_webps == 0:
|
||||||
|
print("\nAll icons are already up-to-date.")
|
||||||
|
else:
|
||||||
|
print(f"\nConverted {converted_pngs} PNGs and {converted_webps} WEBPs out of {total_icons} icons.")
|
||||||
|
print(f"Removed {removed_pngs} PNGs and {removed_webps} WEBPs.")
|
||||||
|
|
||||||
|
# Display any failed conversions
|
||||||
|
if failed_files:
|
||||||
|
print("\nThe following files failed to convert:")
|
||||||
|
for file in failed_files:
|
||||||
|
print(file)
|
37
scripts/generate_file_tree.py
Normal file
37
scripts/generate_file_tree.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import os
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
def generate_folder_tree(paths):
|
||||||
|
tree = {}
|
||||||
|
for path in paths:
|
||||||
|
resolved_path = Path(path).resolve()
|
||||||
|
base_folder = resolved_path.name or Path.cwd().name
|
||||||
|
for root, _, files in os.walk(resolved_path):
|
||||||
|
relative_path = os.path.relpath(root, resolved_path)
|
||||||
|
key = base_folder if relative_path == '.' else os.path.join(base_folder, relative_path)
|
||||||
|
if files:
|
||||||
|
tree[key] = sorted(files) # Sort the list of files alphabetically
|
||||||
|
return tree
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Adjust paths to be one level up
|
||||||
|
folder_paths = sys.argv[1:]
|
||||||
|
folder_paths = [str(Path(path).resolve()) for path in folder_paths]
|
||||||
|
|
||||||
|
if not folder_paths:
|
||||||
|
print("Please provide at least one folder path.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Generate the combined folder tree
|
||||||
|
folder_tree = generate_folder_tree(folder_paths)
|
||||||
|
|
||||||
|
# Write the JSON structure to 'tree.json' in the root folder
|
||||||
|
root_dir = Path(__file__).resolve().parent.parent # Assuming script is in 'scripts' folder
|
||||||
|
tree_json_path = root_dir / 'tree.json'
|
||||||
|
|
||||||
|
with open(tree_json_path, 'w') as f:
|
||||||
|
json.dump(folder_tree, f, indent=4, sort_keys=True) # Sort the keys in the JSON output
|
||||||
|
|
||||||
|
print(f"Folder tree successfully written to '{tree_json_path}'.")
|
38
scripts/generate_icons_page.py
Normal file
38
scripts/generate_icons_page.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import pathlib
|
||||||
|
from pathlib import Path
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def generate_img_tag(file):
|
||||||
|
return (
|
||||||
|
f'<a href="https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/webp/{file.name}">'
|
||||||
|
f'<img src="https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/webp/{file.name}" '
|
||||||
|
f'alt="{file.stem}" height="50"></a>'
|
||||||
|
)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
root = pathlib.Path(__file__).parent.resolve()
|
||||||
|
template_path = root / "TEMPLATE.md"
|
||||||
|
icons_md_path = root.parent / "ICONS.md"
|
||||||
|
|
||||||
|
imgs = sorted((root.parent / "webp").glob("*.webp"))
|
||||||
|
img_tags = [generate_img_tag(x) for x in imgs]
|
||||||
|
|
||||||
|
# Read the template file
|
||||||
|
with open(template_path, "r", encoding="UTF-8") as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
|
||||||
|
# Find the line that starts with "<!-- ICONS -->"
|
||||||
|
try:
|
||||||
|
line_number = lines.index("<!-- ICONS -->\n")
|
||||||
|
except ValueError:
|
||||||
|
print("<!-- ICONS --> placeholder not found in TEMPLATE.md")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Insert the icons after the placeholder
|
||||||
|
lines.insert(line_number + 1, " ".join(img_tags) + "\n")
|
||||||
|
|
||||||
|
# Write the new ICONS.md file
|
||||||
|
with open(icons_md_path, "w", encoding="UTF-8") as f:
|
||||||
|
f.writelines(lines)
|
||||||
|
|
||||||
|
print("ICONS.md has been successfully generated.")
|
Loading…
Reference in New Issue
Block a user