Action

Process Time Blocks

Posted by Andrew Payne, Last update about 2 hours ago

This action parses lines starting with + and formatted as “+HH:MM-HH:MM Description” and creates calendar events in the "Time Blocks” calendar. It puts brackets around processed Time Blocks markers to indicate it has been processed and allows for running the script again without adding duplicates.

Steps

  • script

    // Get the draft content
    let content = draft.content;
    let lines = content.split('\n');
    
    // Calendar name
    const calendarName = "Time Blocks";
    
    // Get the calendar
    let calendar = Calendar.findOrCreate(calendarName);
    
    // Counter for successful additions
    let addedCount = 0;
    let errors = [];
    
    // Regular expression to match time block format: +HH:MM-HH:MM Description
    // Matches: +17:00-19:00 Work at Home
    const timeBlockRegex = /^\+(\d{1,2}):(\d{2})-(\d{1,2}):(\d{2})\s+(.+)$/;
    
    // Array to store modified lines
    let modifiedLines = [];
    
    // Get today's date
    let today = new Date();
    today.setHours(0, 0, 0, 0);
    
    // Process each line
    for (let line of lines) {
        let originalLine = line;
        line = line.trim();
        
        // Skip empty lines
        if (line.length === 0) {
            modifiedLines.push(originalLine);
            continue;
        }
        
        // Check if line matches time block format
        let match = line.match(timeBlockRegex);
        
        if (match) {
            // Extract time components and description
            let startHour = parseInt(match[1]);
            let startMinute = parseInt(match[2]);
            let endHour = parseInt(match[3]);
            let endMinute = parseInt(match[4]);
            let description = match[5].trim();
            
            // Validate time values
            if (startHour < 0 || startHour > 23 || endHour < 0 || endHour > 23 ||
                startMinute < 0 || startMinute > 59 || endMinute < 0 || endMinute > 59) {
                errors.push(`Invalid time in: ${line}`);
                modifiedLines.push(originalLine);
                continue;
            }
            
            // Create start and end dates
            let startDate = new Date(today);
            startDate.setHours(startHour, startMinute, 0, 0);
            
            let endDate = new Date(today);
            endDate.setHours(endHour, endMinute, 0, 0);
            
            // Check if end time is before start time (might span to next day)
            if (endDate <= startDate) {
                endDate.setDate(endDate.getDate() + 1);
            }
            
            // Create the event
            let event = calendar.createEvent();
            event.title = description;
            event.startDate = startDate;
            event.endDate = endDate;
            event.isAllDay = false;
            
            // Save the event
            let success = event.update();
            
            if (success) {
                addedCount++;
                // Mark as processed by changing + to [+]
                let processedLine = originalLine.replace(/^\s*\+/, match => match.replace('+', '[+]'));
                modifiedLines.push(processedLine);
            } else {
                errors.push(`Failed to create event: ${line}`);
                modifiedLines.push(originalLine);
            }
        } else {
            // Keep non-matching lines unchanged
            modifiedLines.push(originalLine);
        }
    }
    
    // Show results
    if (addedCount > 0 || errors.length > 0) {
        // Update the draft with processed markers
        draft.content = modifiedLines.join('\n');
        draft.update();
        
        let message = "";
        
        if (addedCount > 0) {
            message += `✓ Added ${addedCount} time block${addedCount > 1 ? 's' : ''} to "${calendarName}" calendar.\n\n`;
        }
        
        if (errors.length > 0) {
            message += `⚠️ Errors:\n${errors.join('\n')}`;
        }
        
        app.displayInfoMessage(message);
    } else {
        app.displayWarningMessage("No time blocks found. Format: +HH:MM-HH:MM Description");
    }
    
    // Mark action as successful if at least one event was added
    context.succeed = addedCount > 0;

Options

  • After Success Default
    Notification Info
    Log Level Info
Items available in the Drafts Directory are uploaded by community members. Use appropriate caution reviewing downloaded items before use.