vitor Posted September 25, 2023 Posted September 25, 2023 Usage Convert CSV files to Alfred Snippet Collections via the Universal Action. The Snippet Collection will be saved to the Desktop and opened for import into Alfred if the option in set in the Workflow’s Configuration. Converting from a Snippet Collection to CSV is also available. Alternatively, search for CSV or Snippet Collection files via the csvsnip and snipcsv keywords. Import macOS Text Replacements as a new Alfred Snippet Collection via the trimport keyword. ⤓ Install on the Alfred Gallery | Source Send Me, cands and GatorMapi 3
vitor Posted November 19, 2023 Author Posted November 19, 2023 When reporting issues, please include your exact installed versions of:The Workflow.Alfred.macOS.In addition to:The debugger output. Perform the failing action, click “Copy” on the top right and paste it here.Details on what you did, what happened, and what you expected to happen. A short video of the steps with the debugger open may help to find the problem faster.Thank you. Accurate and thorough information is crucial for a proper diagnosis which allows me to help you better.
vitor Posted November 19, 2023 Author Posted November 19, 2023 Updated to 2023.2.Only consider JSON files when converting to CSV.Shorter Objective-C functions.
vitor Posted May 14 Author Posted May 14 Updated to 2024.1. Support importing macOS Text Replacements.
2pilvic Posted May 15 Posted May 15 I have a collection of snippets that I wanted to modify because I had added a suffix to each snippet that I wanted to remove. To do this, I exported the collection (with the same name +#2) and converted it to CSV using its 'snippets transformer' workflow with correct results. I opened the CSV file and modified the snippets (removing the incorrect suffix I had added to each one) and saved the file. Later, I performed the reverse process and converted the .CSV file back to a .alfredsnippets file using its workflow, which was then imported into Alfred 5. After installing the new collection (with #2), I added a (*) general suffix to it. However, when I try to expand text with a snippet from the collection, I get no results. I tried to delete the created collection, but it's impossible, and an error message appears in the top left corner saying: 'The file “XXX(2)” could not be moved to the trash.' What did I do wrong? Thanks
vitor Posted May 15 Author Posted May 15 That’s not going to be related to the workflow. If you cannot delete a snippet collection, and with that message, it’s likely that your syncing service is misbehaving. See https://www.alfredforum.com/topic/19602-cannot-delete-snippet-collection/ and https://www.alfredforum.com/topic/18173-unable-to-delete-personal-snippets/
2pilvic Posted May 16 Posted May 16 19 hours ago, vitor said: That’s not going to be related to the workflow. If you cannot delete a snippet collection, and with that message, it’s likely that your syncing service is misbehaving. See https://www.alfredforum.com/topic/19602-cannot-delete-snippet-collection/ and https://www.alfredforum.com/topic/18173-unable-to-delete-personal-snippets/ Indeed. It was all Dropbox's fault (in its new location). Thank you very much for everything. Great workflow.
TechnoWanderer42 Posted October 25 Posted October 25 Hello, After installing and running the Snippet Transformer, I encountered the following error when attempting to convert to CSV or a snippet format. Csv to snippet ERROR: Snippet Transformer[Run Script] /Users/xyz/Library/Caches/com.runningwithcrayons.Alfred/Workflow Scripts/67DE3916-CF39-47BA-B92A-EF43E2585640: execution error: Error: Error: exception raised by object: -[__NSCFString isFileReferenceURL]: unrecognized selector sent to instance 0x600002444210 (-2700) Snippet to CSV Error with the following script: [22:28:03.838] ERROR: Snippet Transformer[Run Script] /Users/thomasperso/Library/Caches/com.runningwithcrayons.Alfred/Workflow Scripts/D6DFAF6B-099A-46F4-860B-91A5C3CCDE5E: execution error: Error: Error: exception raised by object: -[__NSCFString isFileReferenceURL]: unrecognized selector sent to instance 0x600000f48150 (-2700) I have fixed the two JavaScript issues using ChatGPT. I confirm that this version is working well! CSV to snip. // Helpers function envVar(varName) { return $.NSProcessInfo .processInfo .environment .objectForKey(varName).js; } function runCommand(...arguments) { const task = $.NSTask.alloc.init; task.executableURL = $.NSURL.fileURLWithPath("/usr/bin/env"); task.arguments = arguments; task.launchAndReturnError(false); task.waitUntilExit; } function writeFile(path, text) { $(text).writeToFileAtomicallyEncodingError(path, true, $.NSUTF8StringEncoding, undefined); } // Main function run(argv) { const origData = JSON.parse(argv[0]); const fileManager = $.NSFileManager.defaultManager; const inputFile = envVar("input_file"); // Create an NSURL object from input_file const inputFileURL = $.NSURL.fileURLWithPath($(inputFile).stringByExpandingTildeInPath); const collectionName = inputFileURL.URLByDeletingPathExtension.lastPathComponent.js; const outDir = $("~/Desktop").stringByExpandingTildeInPath.js; const outFile = `${outDir}/${collectionName}.alfredsnippets`; const tmpDir = fileManager.URLForDirectoryInDomainAppropriateForURLCreateError( $.NSItemReplacementDirectory, $.NSUserDomainMask, $.NSURL.fileURLWithPath(outDir), true, undefined ).path.js; // Abort if output file exists if (fileManager.fileExistsAtPath(outFile)) { console.log(`File exists: ${outFile}`); return JSON.stringify({ alfredworkflow: { arg: outFile, variables: { file_exists: true } } }); } // Generate snippet JSON files origData.forEach(item => { const itemUID = $.NSUUID.UUID.UUIDString.js; const snippetObj = { alfredsnippet: { snippet: item["snippet"], uid: itemUID, name: item["name"], keyword: item["keyword"] } }; writeFile(`${tmpDir}/${itemUID}.json`, JSON.stringify(snippetObj)); }); // Archive the snippets into the output file runCommand("/usr/bin/ditto", "-ck", tmpDir, outFile); return JSON.stringify({ alfredworkflow: { arg: outFile, variables: { file_exists: false } } }); } Snip to CSV // Helpers function envVar(varName) { return $.NSProcessInfo .processInfo .environment .objectForKey(varName).js; } function runCommand(...arguments) { const task = $.NSTask.alloc.init; task.executableURL = $.NSURL.fileURLWithPath("/usr/bin/env"); task.arguments = arguments; task.launchAndReturnError(false); task.waitUntilExit; } function readFile(path) { return $.NSString.stringWithContentsOfFileEncodingError(path, $.NSUTF8StringEncoding, undefined).js; } // Main function run(argv) { const snippetsFile = argv[0]; const fileManager = $.NSFileManager.defaultManager; const inputFile = envVar("input_file"); // Create NSURL object from input_file const inputFileURL = $.NSURL.fileURLWithPath($(inputFile).stringByExpandingTildeInPath); const collectionName = inputFileURL.URLByDeletingPathExtension.lastPathComponent.js; const outDir = $("~/Desktop").stringByExpandingTildeInPath.js; const outFile = `${outDir}/${collectionName}.csv`; // Create NSURL for outDir and pass it correctly to URLForDirectoryInDomainAppropriateForURLCreateError const outDirURL = $.NSURL.fileURLWithPath(outDir); const tmpDir = fileManager.URLForDirectoryInDomainAppropriateForURLCreateError( $.NSItemReplacementDirectory, $.NSUserDomainMask, outDirURL, true, undefined ).path.js; const tmpDatabase = `${tmpDir}/${$.NSUUID.UUID.UUIDString.js}.sqlite3`; // Abort if output file exists if (fileManager.fileExistsAtPath(outFile)) { console.log(`File exists: ${outFile}`); return JSON.stringify({ alfredworkflow: { arg: outFile, variables: { file_exists: true } } }); } // Extract zip runCommand("/usr/bin/ditto", "-xk", snippetsFile, tmpDir); // Merge JSONs const jsonFiles = fileManager.contentsOfDirectoryAtURLIncludingPropertiesForKeysOptionsError( $.NSURL.fileURLWithPath(tmpDir), undefined, $.NSDirectoryEnumerationSkipsHiddenFiles, undefined ).js.map(p => p.path.js).filter(p => p.endsWith(".json")); const mergedData = jsonFiles.map(file => { const fullSnippet = JSON.parse(readFile(file)); const snippetContents = fullSnippet["alfredsnippet"]; delete snippetContents["uid"]; return snippetContents; }); // Create database runCommand("/usr/bin/sqlite3", tmpDatabase, "CREATE TABLE snippets ('name' TEXT, 'keyword' TEXT, 'snippet' TEXT)"); mergedData.forEach(snippetData => { const nameString = snippetData["name"].replaceAll("'", "''"); const keywordString = snippetData["keyword"].replaceAll("'", "''"); const snippetString = snippetData["snippet"].replaceAll("'", "''"); runCommand('/usr/bin/sqlite3', tmpDatabase, `INSERT INTO snippets (name, keyword, snippet) VALUES ('${nameString}', '${keywordString}', '${snippetString}')`); }); // Return path to database return JSON.stringify({ alfredworkflow: { arg: tmpDatabase, variables: { file_exists: false, out_file: outFile } } }); }
vitor Posted October 25 Author Posted October 25 Welcome @TechnoWanderer42, The auto-generated code messed up the organisation and introduced a bunch of unnecessary semicolons everywhere to essentially do a one-line change, so as you might understand I can’t take it as is. But I tested the current version in Sequoia and was able to reproduce the error, so I investigated the cause and made the fix myself in 2024.3, which I already released. For future reports, please see How to Ask for Help with a Workflow post for a primer on the information to include when asking for assistance as that would’ve been helpful to investigate this in the proper way. Understanding why a problem happens is more important than taking any resolution. Thank you. I also moved your post to the correct thread.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now