Script to convert an ics / iCalendar file to json. You’ll find a bash version arround here in another post too.
# Load required libraries
library(lubridate)
library(dplyr)
library(jsonlite)
library(tibble)
library(tidyr)
# Function to parse ICS file and convert to JSON
parse_ics_to_json <- function(file_path) {
# Read the ICS file
ics_content <- readLines(file_path)
# Initialize variables
events <- list()
current_event <- list()
# Loop through each line in the ICS file
for (line in ics_content) {
line <- trimws(line) # Trim whitespace
# Check for event start
if (line == "BEGIN:VEVENT") {
current_event <- list() # Reset current event
}
# Check for event details
if (grepl("^SUMMARY:", line)) {
current_event$summary <- sub("^SUMMARY:", "", line) %>% trimws()
}
if (grepl("^DTSTART(;VALUE=DATE)?:", line)) {
start_value <- sub("^DTSTART(;VALUE=DATE)?:", "", line) %>% trimws()
if (grepl("^\\d{8}$", start_value)) { # Check for date-only format
current_event$start <- paste0(start_value, "T000000") # Set time to start of the day
} else {
current_event$start <- start_value
}
}
if (grepl("^DTEND(;VALUE=DATE)?:", line)) {
end_value <- sub("^DTEND(;VALUE=DATE)?:", "", line) %>% trimws()
if (grepl("^\\d{8}$", end_value)) { # Check for date-only format
current_event$end <- paste0(end_value, "T000000") # Set time to end of the day, wrong set it to beginning otherwise you have a 2 day event and leave Z (time zone) away
} else {
current_event$end <- end_value
}
}
if (grepl("^LOCATION:", line)) {
current_event$location <- sub("^LOCATION:", "", line) %>% trimws()
}
# Check for event end
if (line == "END:VEVENT") {
if (length(current_event) > 0) {
events <- append(events, list(current_event)) # Add event to the list
}
}
}
# Check if any events were found
if (length(events) == 0) {
stop("No events found in the ICS file.")
}
events_df <- tibble(data = events)
events_df <- events_df |>
unnest_wider(data)
# Convert start and end to POSIXct
events_df$start <- ymd_hms(events_df$start, tz = 'CET')
events_df$end <- ymd_hms(events_df$end, tz = 'CET')
# Sort events by start date
events_df <- events_df %>% arrange(start)
# Format dates to German format
events_df$start <- format(events_df$start, "%d.%m.%Y %H:%M")
events_df$end <- format(events_df$end, "%d.%m.%Y %H:%M")
# Convert to JSON
json_output <- toJSON(events_df, pretty = TRUE, auto_unbox = TRUE)
return(json_output)
}
# Example usage
file_path <- "/home/files/google.ics" # Replace with your .ics file path
json_result <- parse_ics_to_json(file_path)
write(json_result, "/home/files/calendar.json")
# Print the JSON output
cat(json_result)