Automatically update folder icon from template

I have a project template that uses the QuickAdd API & OpenAI to define a project icon for the Banners plugin. The created note then serves as a folder note. I like the folder to have the same icon as the project, and until now I did it manually after the project’s creation.

This morning I realize I could automate it by updating the data.json file in the Iconize plugin directory. Here is the code in case someone else finds it helpful! It relies on several plugins at the same time so it’s not super time-proof, but when it breaks down I guess I’ll fix it.

Also, I don’t think it’ll work outside a desktop Mac/Linux environment. If anyone wants to make it work on mobile I’ll be much interested.

Here is the code for defining the new icon and calling the script:

const path = tp.file.path();  
const pathParts = path.split('/');  

// ask GPT-3.5 to choose an icon
const quickAddApi = app.plugins.plugins.quickadd.api;  
const model = "gpt-3.5-turbo";  
const settings = {  
    variableName: "emoji",  
    shouldAssignVariables: true,  
    modelOptions: {  
        temperature: 0.5,  
        max_tokens: 10,  
        frequency_penalty: 0.5,  
        presence_penalty: 0.5  
    },  
    showAssistantMessages: false,  
    systemPrompt: "Please respond with a single emoji to best illustrate the project name you were given. It must be a single emoji, without any other character. (Please have in mind that the project name is in French.)"  
};  
let aiResponse;
try {
    aiResponse = await quickAddApi.ai.prompt(projectName, model, settings);
} catch (error) {
    console.error('Error fetching AI response:', error);
}
const bannerIcon = aiResponse.emoji || '📂'; // fallback
console.log(bannerIcon);

// remove note file name
pathParts.pop();   

// join the array back into a string to get full path of parent folder   
let fullPath = pathParts.join('/');  

// obtain the vault's root path  
const vaultRootPath = app.vault.adapter.basePath + "/";   

// remove the vault's root path to get the relative path   
const relativeProjectPath = fullPath.replace(vaultRootPath, "");  

// call the templater user script to update Iconize
await tp.user.updateIconize(relativeProjectPath, bannerIcon);  

And here is the Templater script:

const fs = require('fs');
const path = require('path');

function updateIconize(projectPath, icon) {
    const iconizeDataPath = path.join(app.vault.adapter.basePath, '.obsidian', 'plugins', 'obsidian-icon-folder', 'data.json');
    try {
        // Read the existing data.json file
        const data = JSON.parse(fs.readFileSync(iconizeDataPath, 'utf8'));
        // Update the icon for the specified project path
        data[projectPath] = icon;
        // Write the updated data back to data.json
        fs.writeFileSync(iconizeDataPath, JSON.stringify(data, null, 2), 'utf8');
    } catch (error) {
        console.error('Error updating Iconize data.json:', error);
    }
}

module.exports = updateIconize;
1 Like