feat: Add script categorization to auto-sync notifications

- Added loadCategories() method to load category definitions from metadata.json
- Added groupScriptsByCategory() method to group scripts by their categories
- Modified scriptDownloaderService to return full script objects instead of just names
- Updated notification format to show scripts grouped by category with proper formatting
- Scripts are now displayed as:
  **Category Name:**
  • Script Name 1
  • Script Name 2

This provides much better organization in notifications, making it easier to
see what types of scripts were downloaded or updated.
This commit is contained in:
Michel Roegl-Brunner
2025-10-24 12:53:07 +02:00
parent 82b2012f50
commit 7817ce3d8e
2 changed files with 75 additions and 4 deletions

View File

@@ -356,6 +356,46 @@ export class AutoSyncService {
}
}
/**
* Load categories from metadata.json
*/
loadCategories() {
try {
const metadataPath = join(process.cwd(), 'scripts', 'json', 'metadata.json');
const metadataContent = readFileSync(metadataPath, 'utf8');
const metadata = JSON.parse(metadataContent);
return metadata.categories || [];
} catch (error) {
console.error('Error loading categories:', error);
return [];
}
}
/**
* Group scripts by category
* @param {Array} scripts - Array of script objects
* @param {Array} categories - Array of category objects
*/
groupScriptsByCategory(scripts, categories) {
const categoryMap = new Map();
categories.forEach(cat => categoryMap.set(cat.id, cat.name));
const grouped = new Map();
scripts.forEach(script => {
const scriptCategories = script.categories || [0]; // Default to Miscellaneous (id: 0)
scriptCategories.forEach(catId => {
const categoryName = categoryMap.get(catId) || 'Miscellaneous';
if (!grouped.has(categoryName)) {
grouped.set(categoryName, []);
}
grouped.get(categoryName).push(script.name);
});
});
return grouped;
}
/**
* Send notification about sync results
* @param {Object} results - Sync results object
@@ -383,20 +423,51 @@ export class AutoSyncService {
body += '\n';
}
// Load categories for grouping
const categories = this.loadCategories();
// @ts-ignore - Dynamic property access
if (results.newScripts?.length > 0) {
// @ts-ignore - Dynamic property access
body += `New scripts downloaded: ${results.newScripts.length}\n`;
// Group new scripts by category
// @ts-ignore - Dynamic property access
body += `${results.newScripts.join('\n• ')}\n\n`;
const newScriptsGrouped = this.groupScriptsByCategory(results.newScripts, categories);
// Sort categories by name for consistent ordering
const sortedCategories = Array.from(newScriptsGrouped.keys()).sort();
sortedCategories.forEach(categoryName => {
const scripts = newScriptsGrouped.get(categoryName);
body += `\n**${categoryName}:**\n`;
scripts.forEach(scriptName => {
body += `${scriptName}\n`;
});
});
body += '\n';
}
// @ts-ignore - Dynamic property access
if (results.updatedScripts?.length > 0) {
// @ts-ignore - Dynamic property access
body += `Scripts updated: ${results.updatedScripts.length}\n`;
// Group updated scripts by category
// @ts-ignore - Dynamic property access
body += `${results.updatedScripts.join('\n• ')}\n\n`;
const updatedScriptsGrouped = this.groupScriptsByCategory(results.updatedScripts, categories);
// Sort categories by name for consistent ordering
const sortedCategories = Array.from(updatedScriptsGrouped.keys()).sort();
sortedCategories.forEach(categoryName => {
const scripts = updatedScriptsGrouped.get(categoryName);
body += `\n**${categoryName}:**\n`;
scripts.forEach(scriptName => {
body += `${scriptName}\n`;
});
});
body += '\n';
}
// @ts-ignore - Dynamic property access

View File

@@ -161,7 +161,7 @@ echo "Script downloaded: ${filePath}"
if (!isDownloaded) {
const result = await this.loadScript(script);
if (result.success) {
downloaded.push(script.name || script.slug);
downloaded.push(script); // Return full script object instead of just name
console.log(`Auto-downloaded new script: ${script.name || script.slug}`);
} else {
errors.push(`${script.name || script.slug}: ${result.message}`);
@@ -197,7 +197,7 @@ echo "Script downloaded: ${filePath}"
if (needsUpdate) {
const result = await this.loadScript(script);
if (result.success) {
updated.push(script.name || script.slug);
updated.push(script); // Return full script object instead of just name
console.log(`Auto-updated script: ${script.name || script.slug}`);
} else {
errors.push(`${script.name || script.slug}: ${result.message}`);