Skip to content

Commit 8b2eac2

Browse files
committed
update schedule to move the panel earlier
1 parent e7f3b76 commit 8b2eac2

4 files changed

Lines changed: 189 additions & 16 deletions

File tree

_data/osr_schedule.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,16 @@ days:
6161
tab_label: June 17
6262
heading: June 17, Wednesday
6363
entries:
64+
- session_id: ten-years-ossig
6465
- id: emergent-1
6566
title: Emergent Session 1
66-
start_time: "08:00"
67-
end_time: "09:00"
68-
gcal_start: "20260617T080000"
69-
gcal_end: "20260617T090000"
67+
start_time: "09:30"
68+
end_time: "10:30"
69+
gcal_start: "20260617T093000"
70+
gcal_end: "20260617T103000"
7071
page_url: /emergent/
7172
crowdcast_url: "https://www.crowdcast.io/c/osr-2026-emergent-1"
7273
feedback_url: "https://forms.gle/NbGEjLwgYTRkS11Q7"
73-
- session_id: ten-years-ossig
7474
- session_id: career-journeys
7575
- id: emergent-2
7676
title: Emergent Session 2

_data/osr_sessions.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,10 @@
7272
title: Ten years of OSSIG - historical perspectives on open science at OHBM
7373
day_label: June 17, 2026
7474
weekday: Wednesday
75-
start_time: "09:30"
76-
end_time: "10:30"
77-
gcal_start: "20260617T093000"
78-
gcal_end: "20260617T103000"
75+
start_time: "08:00"
76+
end_time: "09:00"
77+
gcal_start: "20260617T080000"
78+
gcal_end: "20260617T090000"
7979
crowdcast_url: "https://www.crowdcast.io/c/osr-2026-panel-10-years-ossig"
8080
feedback_url: "https://forms.gle/5zUiQCFY8gNhEVacA"
8181
description: >

downloads/OSRschedule.ics

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -157,27 +157,27 @@ LOCATION:OHBM Open Science Room
157157
URL:https://ohbm.github.io/osr2026/schedule/
158158
END:VEVENT
159159
BEGIN:VEVENT
160-
UID:osr2026-emergent-1@ohbm.github.io
160+
UID:osr2026-ten-years-ossig@ohbm.github.io
161161
DTSTAMP:20260514T000000Z
162162
DTSTART;TZID=Europe/Paris:20260617T080000
163163
DTEND;TZID=Europe/Paris:20260617T090000
164-
SUMMARY:Emergent Session 1
164+
SUMMARY:Panel 3: Ten years of OSSIG - historical perspectives on open scien
165+
ce at OHBM
165166
DESCRIPTION:OHBM Open Science Room 2026 session. Full schedule: https://ohb
166167
m.github.io/osr2026/schedule/
167168
LOCATION:OHBM Open Science Room
168-
URL:https://ohbm.github.io/osr2026/emergent/
169+
URL:https://ohbm.github.io/osr2026/panel/#ten-years-ossig
169170
END:VEVENT
170171
BEGIN:VEVENT
171-
UID:osr2026-ten-years-ossig@ohbm.github.io
172+
UID:osr2026-emergent-1@ohbm.github.io
172173
DTSTAMP:20260514T000000Z
173174
DTSTART;TZID=Europe/Paris:20260617T093000
174175
DTEND;TZID=Europe/Paris:20260617T103000
175-
SUMMARY:Panel 3: Ten years of OSSIG - historical perspectives on open scien
176-
ce at OHBM
176+
SUMMARY:Emergent Session 1
177177
DESCRIPTION:OHBM Open Science Room 2026 session. Full schedule: https://ohb
178178
m.github.io/osr2026/schedule/
179179
LOCATION:OHBM Open Science Room
180-
URL:https://ohbm.github.io/osr2026/panel/#ten-years-ossig
180+
URL:https://ohbm.github.io/osr2026/emergent/
181181
END:VEVENT
182182
BEGIN:VEVENT
183183
UID:osr2026-career-journeys@ohbm.github.io

scripts/generate_osr_ics.rb

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
#!/usr/bin/env ruby
2+
# frozen_string_literal: true
3+
4+
require "date"
5+
require "fileutils"
6+
require "yaml"
7+
8+
ROOT = File.expand_path("..", __dir__)
9+
YEAR = 2026
10+
TIMEZONE = "Europe/Paris"
11+
OUTPUT_PATH = File.join(ROOT, "downloads", "OSRschedule.ics")
12+
SCHEDULE_PATH = File.join(ROOT, "_data", "osr_schedule.yml")
13+
SESSIONS_PATH = File.join(ROOT, "_data", "osr_sessions.yml")
14+
CONFIG_PATH = File.join(ROOT, "_config.yml")
15+
DTSTAMP = "20260514T000000Z"
16+
17+
def read_yaml(path)
18+
YAML.safe_load(File.read(path), aliases: true)
19+
end
20+
21+
def config_url(config)
22+
site_url = config.fetch("url")
23+
baseurl = config.fetch("baseurl", "")
24+
"#{site_url}#{baseurl}"
25+
end
26+
27+
def event_title(event)
28+
case event["category"]
29+
when "panel"
30+
"Panel #{event.fetch("number")}: #{event.fetch("title")}"
31+
when "tabletalk"
32+
"Table Talk #{event.fetch("number")}: #{event.fetch("title")}"
33+
else
34+
event.fetch("title")
35+
end
36+
end
37+
38+
def local_datetime(day_id, time_text)
39+
month, day = day_id.split("-").map(&:to_i)
40+
hour, minute = time_text.split(":").map(&:to_i)
41+
raise ArgumentError, "Invalid day id: #{day_id.inspect}" unless month && day
42+
raise ArgumentError, "Invalid time: #{time_text.inspect}" unless hour && minute
43+
44+
DateTime.new(YEAR, month, day, hour, minute, 0)
45+
end
46+
47+
def ics_datetime(datetime)
48+
datetime.strftime("%Y%m%dT%H%M%S")
49+
end
50+
51+
def gcal_datetime(datetime)
52+
datetime.strftime("%Y%m%dT%H%M%S")
53+
end
54+
55+
def escape_text(value)
56+
value.to_s
57+
.gsub("\\", "\\\\\\")
58+
.gsub("\n", "\\n")
59+
.gsub(";", "\\;")
60+
.gsub(",", "\\,")
61+
end
62+
63+
def fold_line(line)
64+
bytes = line.b
65+
return line if bytes.bytesize <= 75
66+
67+
folded = bytes.byteslice(0, 75)
68+
bytes = bytes.byteslice(75..)&.dup || +""
69+
70+
until bytes.empty?
71+
chunk = bytes.byteslice(0, 74)
72+
folded << "\r\n " << chunk
73+
bytes = bytes.byteslice(74..)&.dup || +""
74+
end
75+
folded
76+
end
77+
78+
def property(name, value)
79+
fold_line("#{name}:#{value}")
80+
end
81+
82+
def event_url(site_base, event)
83+
path = event.fetch("page_url")
84+
85+
if path.include?("://")
86+
path
87+
elsif event["anchor"]
88+
"#{site_base}#{path}##{event.fetch("anchor")}"
89+
else
90+
"#{site_base}#{path}"
91+
end
92+
end
93+
94+
schedule = read_yaml(SCHEDULE_PATH)
95+
sessions = read_yaml(SESSIONS_PATH).each_with_object({}) do |session, index|
96+
index[session.fetch("id")] = session
97+
end
98+
site_base = config_url(read_yaml(CONFIG_PATH))
99+
100+
lines = [
101+
"BEGIN:VCALENDAR",
102+
"VERSION:2.0",
103+
"PRODID:-//OHBM//OSR 2026//EN",
104+
"CALSCALE:GREGORIAN",
105+
"METHOD:PUBLISH",
106+
property("X-WR-CALNAME", escape_text("OHBM Open Science Room 2026")),
107+
property("X-WR-TIMEZONE", TIMEZONE),
108+
"BEGIN:VTIMEZONE",
109+
"TZID:Europe/Paris",
110+
"BEGIN:DAYLIGHT",
111+
"TZOFFSETFROM:+0100",
112+
"TZOFFSETTO:+0200",
113+
"TZNAME:CEST",
114+
"DTSTART:19700329T020000",
115+
"RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU",
116+
"END:DAYLIGHT",
117+
"BEGIN:STANDARD",
118+
"TZOFFSETFROM:+0200",
119+
"TZOFFSETTO:+0100",
120+
"TZNAME:CET",
121+
"DTSTART:19701025T030000",
122+
"RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU",
123+
"END:STANDARD",
124+
"END:VTIMEZONE"
125+
]
126+
127+
schedule.fetch("days").each do |day|
128+
day.fetch("entries").each do |entry|
129+
event = if entry["session_id"]
130+
sessions.fetch(entry.fetch("session_id")) do
131+
raise KeyError, "No session found for #{entry.fetch("session_id").inspect}"
132+
end
133+
else
134+
entry
135+
end
136+
137+
start_at = local_datetime(day.fetch("id"), event.fetch("start_time"))
138+
end_at = local_datetime(day.fetch("id"), event.fetch("end_time"))
139+
raise ArgumentError, "Event ends before it starts: #{event.fetch("id")}" unless end_at > start_at
140+
if event["gcal_start"] && event["gcal_start"] != gcal_datetime(start_at)
141+
raise ArgumentError, "gcal_start does not match schedule time for #{event.fetch("id")}"
142+
end
143+
if event["gcal_end"] && event["gcal_end"] != gcal_datetime(end_at)
144+
raise ArgumentError, "gcal_end does not match schedule time for #{event.fetch("id")}"
145+
end
146+
147+
uid = "osr2026-#{event.fetch("id")}@ohbm.github.io"
148+
url = event_url(site_base, event)
149+
description = "OHBM Open Science Room 2026 session. Full schedule: #{site_base}/schedule/"
150+
151+
lines.concat(
152+
[
153+
"BEGIN:VEVENT",
154+
property("UID", uid),
155+
property("DTSTAMP", DTSTAMP),
156+
property("DTSTART;TZID=#{TIMEZONE}", ics_datetime(start_at)),
157+
property("DTEND;TZID=#{TIMEZONE}", ics_datetime(end_at)),
158+
property("SUMMARY", escape_text(event_title(event))),
159+
property("DESCRIPTION", escape_text(description)),
160+
property("LOCATION", escape_text("OHBM Open Science Room")),
161+
property("URL", url),
162+
"END:VEVENT"
163+
]
164+
)
165+
end
166+
end
167+
168+
lines << "END:VCALENDAR"
169+
170+
FileUtils.mkdir_p(File.dirname(OUTPUT_PATH))
171+
File.write(OUTPUT_PATH, "#{lines.join("\r\n")}\r\n")
172+
173+
puts "Wrote #{OUTPUT_PATH}"

0 commit comments

Comments
 (0)