Created
January 24, 2025 20:12
-
-
Save WomB0ComB0/1713769f4eea4390572daec45e8eb54c to your computer and use it in GitHub Desktop.
Simple ICS file parser
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* A script to parse ICS (iCalendar) files and convert them to JSON format. | |
* Supports processing either a single file or scanning a directory for multiple .ics files. | |
* | |
* @module ics-parser | |
* | |
* Usage: | |
* - Process single file: node ics-parser.ts path/to/file.ics | |
* - Process all .ics files in root: node ics-parser.ts --root | |
* | |
* @requires icalts - For parsing ICS file content into object tree | |
* @requires bun - For file operations and shell commands | |
*/ | |
import { lines2tree } from 'icalts'; | |
import { $ } from 'bun'; | |
/** | |
* Processes one or more ICS files and converts them to JSON format. | |
* When processing multiple files, it will skip node_modules and .git directories. | |
* The output JSON files will be saved in the same location as the input files. | |
* | |
* @async | |
* @param {string} filePath - Path to a single .ics file, or directory path when useRoot is true | |
* @param {boolean} [useRoot=false] - When true, searches recursively from current directory for .ics files | |
* @returns {Promise<void>} Resolves when all files have been processed | |
* @throws {Error} If file reading or writing operations fail | |
* | |
* @example | |
* // Process a single file | |
* await processICSFiles('./calendar.ics'); | |
* | |
* @example | |
* // Process all .ics files in root directory | |
* await processICSFiles('./', true); | |
*/ | |
async function processICSFiles(filePath: string, useRoot = false): Promise<void> { | |
try { | |
let icsFiles; | |
if (useRoot) { | |
// Search for .ics files in the root directory, excluding node_modules and .git | |
icsFiles = (await $`find . -type d \( -name 'node_modules' -o -name '.git' \) -prune -o -type f -name '*.ics' -print`.text()) | |
.split('\n') | |
.filter(Boolean); | |
} else { | |
// Use the provided file path | |
icsFiles = [filePath]; | |
} | |
if (icsFiles.length === 0) { | |
console.error('No .ics files found.'); | |
return; | |
} | |
for (const file of icsFiles) { | |
const content = await Bun.file(file).text(); | |
const tree = lines2tree(content.split('\n')); | |
console.log(`Processed file: ${file}`); | |
console.log(tree); | |
const outputFilePath = file.replace(/\.ics$/, '.json'); | |
await Bun.write(outputFilePath, JSON.stringify(tree, null, 2)); | |
console.log(`JSON saved to: ${outputFilePath}`); | |
} | |
} catch (error) { | |
console.error('Error processing .ics files:', error); | |
} | |
} | |
// Parse command line arguments | |
const args = process.argv.slice(2); | |
const useRoot = args.includes('--root'); | |
const filePath = args.find(arg => !arg.startsWith('--')); | |
// Validate arguments and execute | |
if (!filePath && !useRoot) { | |
console.error('Please provide a file path or use the --root flag to search in the root directory.'); | |
process.exit(1); | |
} else { | |
(async () => { | |
await processICSFiles(filePath!, useRoot); | |
})(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment