Skip to content

Commit

Permalink
Build calendar and schedule dynamically
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewheiss committed May 29, 2023
1 parent 93696bc commit cd97b2c
Show file tree
Hide file tree
Showing 5 changed files with 370 additions and 34 deletions.
109 changes: 109 additions & 0 deletions R/tar_calendar.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
suppressPackageStartupMessages(library(lubridate))
library(glue)
library(calendar)

# Once again, {targets} needs the path of the saved file so we return it here
save_ical <- function(df, path) {
calendar::ic_write(df, path)
return(path)
}

# Read the schedule CSV file and create/format columns for displaying on the
# schedule page. Returns a data frame with all rows nested by group to make it
# easier to display the schedule by group
build_schedule_for_page <- function(schedule_file) {
schedule <- read_csv(schedule_file, show_col_types = FALSE) %>%
# read_csv() parses the deadline "11:59 PM" as an hms object, which is fine,
# and there's a format.hms() function that *should* allow for formatting
# with strptime, but it doesn't---format.hms() just coerces the whole thing
# to character. So here I add the deadline time to the deadline date with
# update() and then format it with format.Date()
mutate(deadline_actual = update(date, hour = hour(deadline), minute = minute(deadline)),
deadline_nice = format(deadline_actual, "%I:%M %p")) %>%
mutate(group = fct_inorder(group)) %>%
mutate(var_note = ifelse(!is.na(note),
glue('<br><span class="content-note">{note}</span>'),
glue(""))) %>%
mutate(var_flag_start = ifelse(!is.na(flag) & flag == TRUE, '<span class="content-flag"><i class="fas fa-star"></i>&ensp;', "")) %>%
mutate(var_flag_end = ifelse(!is.na(flag) & flag == TRUE, "</span>", "")) %>%
mutate(var_title = ifelse(!is.na(content),
glue('<span class="content-title">{var_flag_start}{title}{var_flag_end}</span>'),
glue('{var_flag_start}{title}{var_flag_end}'))) %>%
mutate(var_deadline = ifelse(!is.na(deadline),
glue('&emsp;&emsp;<small>(submit by {deadline_nice})</small>'),
glue(""))) %>%
mutate(var_content = ifelse(!is.na(content),
glue('<a href="{content}.qmd"><i class="fa-solid fa-book-open-reader fa-lg"></i></a>'),
glue('<font color="#e9ecef"><i class="fa-solid fa-book-open-reader fa-lg"></i></font>'))) %>%
mutate(var_lesson = ifelse(!is.na(lesson),
glue('<a href="{lesson}.qmd"><i class="fa-solid fa-chalkboard-teacher fa-lg"></i></a>'),
glue('<font color="#e9ecef"><i class="fa-solid fa-chalkboard-teacher fa-lg"></i></font>'))) %>%
mutate(var_example = ifelse(!is.na(example),
glue('<a href="{example}.qmd"><i class="fa-solid fa-laptop-code fa-lg"></i></a>'),
glue('<font color="#e9ecef"><i class="fa-solid fa-laptop-code fa-lg"></i></font>'))) %>%
mutate(var_assignment = ifelse(!is.na(assignment),
glue('<a href="{assignment}.qmd"><i class="fa-solid fa-pen-ruler fa-lg"></i></a>'),
glue('<font color="#e9ecef"><i class="fa-solid fa-pen-ruler fa-lg"></i></font>'))) %>%
mutate(date_range = ifelse(!is.na(end_date),
glue('{format(date, "%B %e")}–{format(end_date, "%B %e")}'), NA)) %>%
mutate(col_date = case_when(
!is.na(content) ~ ifelse(is.na(date_range),
glue('<span class="content-session">({session})</span>'),
glue('<span class="content-date">{date_range}</span><br><span class="content-session">({session})</span>')),
is.na(content) & !is.na(date_range) ~ glue('<span class="content-date">{date_range}</span>'),
TRUE ~ glue('<span class="content-date">{format(date, "%B %e")}</span>')
)) %>%
mutate(col_title = glue('{var_title}{var_deadline}{var_note}')) %>%
mutate(
col_content = var_content,
col_lesson = var_lesson,
col_example = var_example,
col_assignment = var_assignment
)

schedule_nested <- schedule %>%
select(group,
` ` = col_date, Title = col_title,
Content = col_content, Lesson = col_lesson,
Example = col_example, Assignment = col_assignment) %>%
group_by(group) %>%
nest()

return(schedule_nested)
}

# Read the schedule CSV file and create a dataset formatted as iCal data that
# calendar::ic_write() can use
build_ical <- function(schedule_file, base_url, page_suffix, content_number) {
dtstamp <- ic_char_datetime(now("UTC"), zulu = TRUE)

schedule <- read_csv(schedule_file, show_col_types = FALSE) %>%
mutate(session = if_else(is.na(content), glue(""), glue("({session}) "))) %>%
mutate(summary = glue("{content_number}: {session}{title}")) %>%
mutate(date_start_dt = date,
date_end_dt = date) %>%
mutate(date_start_cal = map(date_start_dt, ~as.POSIXct(., format = "%B %d, %Y")),
date_end_cal = map(date_end_dt, ~as.POSIXct(., format = "%B %d, %Y"))) %>%
mutate(url = coalesce(content, assignment),
url = if_else(is.na(url), glue(""), glue("{base_url}{url}{page_suffix}")))

schedule_ics <- schedule %>%
mutate(id = row_number()) %>%
group_by(id) %>%
nest() %>%
mutate(ical = map(data,
~ic_event(start = .$date_start_cal[[1]],
end = .$date_end_cal[[1]] + 24*60*60,
summary = .$summary[[1]],
more_properties = TRUE,
event_properties = c("DESCRIPTION" = .$url[[1]],
"DTSTAMP" = dtstamp)))) %>%
ungroup() %>%
select(-id, -data) %>%
unnest(ical) %>%
ical() %>%
rename(`DTSTART;VALUE=DATE` = DTSTART,
`DTEND;VALUE=DATE` = DTEND)

return(schedule_ics)
}
36 changes: 18 additions & 18 deletions _targets.R
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ tar_option_set(
here_rel <- function(...) {fs::path_rel(here::here(...))}

# Load functions for the pipeline
# source("R/tar_calendar.R")
source("R/tar_calendar.R")
source("R/tar_slides.R")
source("R/tar_projects.R")
source("R/tar_data.R")
Expand Down Expand Up @@ -102,23 +102,23 @@ list(


## Class schedule calendar ----
# tar_target(schedule_file, here_rel("data", "schedule.csv"), format = "file"),
# tar_target(schedule_page_data, build_schedule_for_page(schedule_file)),
# tar_target(
# schedule_ical_data,
# build_ical(
# schedule_file, base_url,
# page_suffix, class_number
# )
# ),
# tar_target(
# schedule_ical_file,
# save_ical(
# schedule_ical_data,
# here_rel("files", "schedule.ics")
# ),
# format = "file"
# ),
tar_target(schedule_file, here_rel("data", "schedule.csv"), format = "file"),
tar_target(schedule_page_data, build_schedule_for_page(schedule_file)),
tar_target(
schedule_ical_data,
build_ical(
schedule_file, base_url,
page_suffix, class_number
)
),
tar_target(
schedule_ical_file,
save_ical(
schedule_ical_data,
here_rel("files", "schedule.ics")
),
format = "file"
),


## Knit the README ----
Expand Down
26 changes: 26 additions & 0 deletions data/schedule.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
group,session,date,end_date,title,flag,deadline,content,lesson,example,assignment,note
Foundations,Session 1,2023-06-05,2023-06-09,"Truth, beauty, and data + R and tidyverse",,,content/01-content,lesson/01-lesson,example/01-example,assignment/01-exercise,
Foundations,Session 2,2023-06-05,2023-06-09,Graphic design,,,content/02-content,lesson/02-lesson,example/02-example,assignment/02-exercise,
Foundations,,2023-06-12,,Assignments for sessions 1 and 2 due,,11:59 PM,,,,,
Foundations,Session 3,2023-06-12,2023-06-16,Mapping data to graphics,,,content/03-content,lesson/03-lesson,example/03-example,assignment/03-exercise,
Core types of graphics,Session 4,2023-06-12,2023-06-16,Amounts and proportions,,,content/04-content,lesson/04-lesson,example/04-example,assignment/04-exercise,
Core types of graphics,,2023-06-19,,Assignments for sessions 3 and 4 due,,11:59 PM,,,,,
Core types of graphics,Session 5,2023-06-19,2023-06-23,Themes,,,content/05-content,lesson/05-lesson,example/05-example,assignment/05-exercise,
Core types of graphics,Session 6,2023-06-19,2023-06-23,Uncertainty,,,content/06-content,lesson/06-lesson,example/06-example,assignment/06-exercise,
Core types of graphics,,2023-06-19,,Assignments for sessions 5 and 6 due,,11:59 PM,,,,,
Core types of graphics,Session 7,2023-06-26,2023-06-30,Relationships,,,content/07-content,lesson/07-lesson,example/07-example,assignment/07-exercise,
Core types of graphics,Session 8,2023-06-26,2023-06-30,Comparisons,,,content/08-content,lesson/08-lesson,example/08-example,assignment/08-exercise,
Core types of graphics,,2023-07-03,,Assignments for sessions 7 and 8 due,,11:59 PM,,,,,
Core types of graphics,,2023-07-03,,Mini project 1 due,TRUE,11:59 PM,,,,assignment/01-mini-project,
Special applications,Session 9,2023-07-03,2023-07-07,Annotations,,,content/09-content,lesson/09-lesson,example/09-example,assignment/09-exercise,
Special applications,Session 10,2023-07-03,2023-07-07,Interactivity,,,content/09-content,lesson/10-lesson,example/10-example,assignment/10-exercise,
Special applications,,2023-07-10,,Assignments for sessions 9 and 10 due,,11:59 PM,,,,,
Special applications,Session 11,2023-07-10,2023-07-14,Time,,,content/11-content,lesson/11-lesson,example/11-example,assignment/11-exercise,
Special applications,Session 12,2023-07-10,2023-07-14,Space,,,content/12-content,lesson/12-lesson,example/12-example,assignment/12-exercise,
Special applications,,2023-07-17,,Assignments for sessions 11 and 12 due,,11:59 PM,,,,,
Special applications,,2023-07-17,,Mini project 2 due,TRUE,11:59 PM,,,,assignment/02-mini-project,
Special applications,Session 13,2023-07-17,2023-07-21,Text,,,content/13-content,lesson/13-lesson,example/13-example,assignment/13-exercise,
Special applications,Session 14,2023-07-17,2023-07-21,Enhancing graphics,,,content/14-content,lesson/14-lesson,example/14-example,assignment/14-exercise,
Special applications,,2023-07-24,,Assignments for sessions 13 and 14 due,,11:59 PM,,,,,
Conclusions,Session 15,2023-07-24,2023-07-25,"Truth, beauty, and data revisited",,,content/15-content,lesson/15-lesson,example/15-example,assignment/15-exercise,
Conclusions,,2023-07-30,,Final project due,TRUE,11:59 PM,,,,assignment/final-project,
206 changes: 206 additions & 0 deletions files/schedule.ics
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
BEGIN:VCALENDAR
PRODID:ATFutures/calendar
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
BEGIN:VEVENT
UID:ical-b3c3807e-2c30-4e80-b7e0-0042b9fd82e7
DTSTART;VALUE=DATE:20230605
DTEND;VALUE=DATE:20230606
SUMMARY:PMAP 8101: (Session 1) Truth, beauty, and data + R and tidyverse
DESCRIPTION:https://datavizs23.classes.andrewheiss.com/content/01-content.html
DTSTAMP:20230529T203523Z
END:VEVENT
BEGIN:VEVENT
UID:ical-9d800bf1-d251-42e9-926e-6b894833667b
DTSTART;VALUE=DATE:20230605
DTEND;VALUE=DATE:20230606
SUMMARY:PMAP 8101: (Session 2) Graphic design
DESCRIPTION:https://datavizs23.classes.andrewheiss.com/content/02-content.html
DTSTAMP:20230529T203523Z
END:VEVENT
BEGIN:VEVENT
UID:ical-4612ecf7-cd10-453d-b877-49ce8939e5ac
DTSTART;VALUE=DATE:20230612
DTEND;VALUE=DATE:20230613
SUMMARY:PMAP 8101: Assignments for sessions 1 and 2 due
DESCRIPTION:
DTSTAMP:20230529T203523Z
END:VEVENT
BEGIN:VEVENT
UID:ical-757f0ff1-d229-4a3f-9208-6d0c30f6ba63
DTSTART;VALUE=DATE:20230612
DTEND;VALUE=DATE:20230613
SUMMARY:PMAP 8101: (Session 3) Mapping data to graphics
DESCRIPTION:https://datavizs23.classes.andrewheiss.com/content/03-content.html
DTSTAMP:20230529T203523Z
END:VEVENT
BEGIN:VEVENT
UID:ical-46fb07e2-531b-4ccd-b3d0-2eeb7f70313c
DTSTART;VALUE=DATE:20230612
DTEND;VALUE=DATE:20230613
SUMMARY:PMAP 8101: (Session 4) Amounts and proportions
DESCRIPTION:https://datavizs23.classes.andrewheiss.com/content/04-content.html
DTSTAMP:20230529T203523Z
END:VEVENT
BEGIN:VEVENT
UID:ical-7104f949-8f30-40ec-8bba-484934ef83b5
DTSTART;VALUE=DATE:20230619
DTEND;VALUE=DATE:20230620
SUMMARY:PMAP 8101: Assignments for sessions 3 and 4 due
DESCRIPTION:
DTSTAMP:20230529T203523Z
END:VEVENT
BEGIN:VEVENT
UID:ical-ca454b77-a7b7-4110-99a7-b295d4269c7a
DTSTART;VALUE=DATE:20230619
DTEND;VALUE=DATE:20230620
SUMMARY:PMAP 8101: (Session 5) Themes
DESCRIPTION:https://datavizs23.classes.andrewheiss.com/content/05-content.html
DTSTAMP:20230529T203523Z
END:VEVENT
BEGIN:VEVENT
UID:ical-c4ea9e2d-5dff-4f03-a994-3f4f2cbea56f
DTSTART;VALUE=DATE:20230619
DTEND;VALUE=DATE:20230620
SUMMARY:PMAP 8101: (Session 6) Uncertainty
DESCRIPTION:https://datavizs23.classes.andrewheiss.com/content/06-content.html
DTSTAMP:20230529T203523Z
END:VEVENT
BEGIN:VEVENT
UID:ical-308f1607-84ca-48a6-9035-2547a9e15898
DTSTART;VALUE=DATE:20230619
DTEND;VALUE=DATE:20230620
SUMMARY:PMAP 8101: Assignments for sessions 5 and 6 due
DESCRIPTION:
DTSTAMP:20230529T203523Z
END:VEVENT
BEGIN:VEVENT
UID:ical-f7fbfadb-0a2b-4a2e-8558-91e3c492d6c0
DTSTART;VALUE=DATE:20230626
DTEND;VALUE=DATE:20230627
SUMMARY:PMAP 8101: (Session 7) Relationships
DESCRIPTION:https://datavizs23.classes.andrewheiss.com/content/07-content.html
DTSTAMP:20230529T203523Z
END:VEVENT
BEGIN:VEVENT
UID:ical-3ab3c996-1738-49ae-9bfb-bc8a22917f41
DTSTART;VALUE=DATE:20230626
DTEND;VALUE=DATE:20230627
SUMMARY:PMAP 8101: (Session 8) Comparisons
DESCRIPTION:https://datavizs23.classes.andrewheiss.com/content/08-content.html
DTSTAMP:20230529T203523Z
END:VEVENT
BEGIN:VEVENT
UID:ical-f8ad53fd-3810-4cbd-b407-ae2e0420ec2c
DTSTART;VALUE=DATE:20230703
DTEND;VALUE=DATE:20230704
SUMMARY:PMAP 8101: Assignments for sessions 7 and 8 due
DESCRIPTION:
DTSTAMP:20230529T203523Z
END:VEVENT
BEGIN:VEVENT
UID:ical-4292cc16-a9b9-4b5f-b9ca-8d58df67d09a
DTSTART;VALUE=DATE:20230703
DTEND;VALUE=DATE:20230704
SUMMARY:PMAP 8101: Mini project 1 due
DESCRIPTION:https://datavizs23.classes.andrewheiss.com/assignment/01-mini-project.html
DTSTAMP:20230529T203523Z
END:VEVENT
BEGIN:VEVENT
UID:ical-9ef6a241-2835-4010-b7de-eb89c2e57ab7
DTSTART;VALUE=DATE:20230703
DTEND;VALUE=DATE:20230704
SUMMARY:PMAP 8101: (Session 9) Annotations
DESCRIPTION:https://datavizs23.classes.andrewheiss.com/content/09-content.html
DTSTAMP:20230529T203523Z
END:VEVENT
BEGIN:VEVENT
UID:ical-63c40e62-bf80-4435-aab2-8a1a034572d4
DTSTART;VALUE=DATE:20230703
DTEND;VALUE=DATE:20230704
SUMMARY:PMAP 8101: (Session 10) Interactivity
DESCRIPTION:https://datavizs23.classes.andrewheiss.com/content/09-content.html
DTSTAMP:20230529T203523Z
END:VEVENT
BEGIN:VEVENT
UID:ical-676749d9-122a-4a0b-89eb-228974d39549
DTSTART;VALUE=DATE:20230710
DTEND;VALUE=DATE:20230711
SUMMARY:PMAP 8101: Assignments for sessions 9 and 10 due
DESCRIPTION:
DTSTAMP:20230529T203523Z
END:VEVENT
BEGIN:VEVENT
UID:ical-b9a021f6-65e1-4662-8672-d61bdf262c5d
DTSTART;VALUE=DATE:20230710
DTEND;VALUE=DATE:20230711
SUMMARY:PMAP 8101: (Session 11) Time
DESCRIPTION:https://datavizs23.classes.andrewheiss.com/content/11-content.html
DTSTAMP:20230529T203523Z
END:VEVENT
BEGIN:VEVENT
UID:ical-76f5740f-3da5-4387-a078-fa58b0380396
DTSTART;VALUE=DATE:20230710
DTEND;VALUE=DATE:20230711
SUMMARY:PMAP 8101: (Session 12) Space
DESCRIPTION:https://datavizs23.classes.andrewheiss.com/content/12-content.html
DTSTAMP:20230529T203523Z
END:VEVENT
BEGIN:VEVENT
UID:ical-9aeae366-313c-4d09-9117-42c3ea187374
DTSTART;VALUE=DATE:20230717
DTEND;VALUE=DATE:20230718
SUMMARY:PMAP 8101: Assignments for sessions 11 and 12 due
DESCRIPTION:
DTSTAMP:20230529T203523Z
END:VEVENT
BEGIN:VEVENT
UID:ical-e860bab1-7822-4c90-b99f-2c1dda7049c6
DTSTART;VALUE=DATE:20230717
DTEND;VALUE=DATE:20230718
SUMMARY:PMAP 8101: Mini project 2 due
DESCRIPTION:https://datavizs23.classes.andrewheiss.com/assignment/02-mini-project.html
DTSTAMP:20230529T203523Z
END:VEVENT
BEGIN:VEVENT
UID:ical-c4d35b56-6b61-4be4-a823-edcf20a7d690
DTSTART;VALUE=DATE:20230717
DTEND;VALUE=DATE:20230718
SUMMARY:PMAP 8101: (Session 13) Text
DESCRIPTION:https://datavizs23.classes.andrewheiss.com/content/13-content.html
DTSTAMP:20230529T203523Z
END:VEVENT
BEGIN:VEVENT
UID:ical-6c8566b6-e60e-47e0-9d6d-2bc501b1e4f9
DTSTART;VALUE=DATE:20230717
DTEND;VALUE=DATE:20230718
SUMMARY:PMAP 8101: (Session 14) Enhancing graphics
DESCRIPTION:https://datavizs23.classes.andrewheiss.com/content/14-content.html
DTSTAMP:20230529T203523Z
END:VEVENT
BEGIN:VEVENT
UID:ical-173e5b51-f991-4bbe-929c-123572fb239f
DTSTART;VALUE=DATE:20230724
DTEND;VALUE=DATE:20230725
SUMMARY:PMAP 8101: Assignments for sessions 13 and 14 due
DESCRIPTION:
DTSTAMP:20230529T203523Z
END:VEVENT
BEGIN:VEVENT
UID:ical-c0a902b3-3e00-4fd4-83d4-76a14bf085ba
DTSTART;VALUE=DATE:20230724
DTEND;VALUE=DATE:20230725
SUMMARY:PMAP 8101: (Session 15) Truth, beauty, and data revisited
DESCRIPTION:https://datavizs23.classes.andrewheiss.com/content/15-content.html
DTSTAMP:20230529T203523Z
END:VEVENT
BEGIN:VEVENT
UID:ical-db60d0e4-1612-442a-99d4-f8138b2008c0
DTSTART;VALUE=DATE:20230730
DTEND;VALUE=DATE:20230731
SUMMARY:PMAP 8101: Final project due
DESCRIPTION:https://datavizs23.classes.andrewheiss.com/assignment/final-project.html
DTSTAMP:20230529T203523Z
END:VEVENT
END:VCALENDAR
Loading

0 comments on commit cd97b2c

Please sign in to comment.