author Angelo Gladding
name Calendar
published 2025-08-15T22:11:06.712200-07:00
type entry
updated 2026-10-23T00:28:40.614068-07:00
url /calendar, /2025/08/16/mh
visibility public
Content
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | $def with () $code: events = web.tx.db.select( "resources", what=""" json_extract(resource, '$."in-reply-to"[0].name[0]') AS name, json_extract(resource, '$."in-reply-to"[0].url[0]') AS url, COALESCE( json_extract(resource, '$."in-reply-to"[0].start[0].datetime'), json_extract(resource, '$."in-reply-to"[0].start[0]') ) AS start, COALESCE( json_extract(resource, '$."in-reply-to"[0].end[0].datetime'), json_extract(resource, '$."in-reply-to"[0].end[0]') ) AS end """, where=""" json_extract(resource, '$.rsvp[0]') = 'yes' AND julianday(json_extract(resource, '$.published[0].datetime')) >= julianday('now', '-1 month') AND substr(start, 1, 10) >= date('now', 'start of month', '-1 month') AND substr(start, 1, 10) < date('now', 'start of month', '+3 months') """, order="start" ) events_by_day = collections.defaultdict(list) for event in events: events_by_day[str(event["start"])[:10]].append(event) days = web.tx.db.select( """( WITH RECURSIVE offsets(n) AS (VALUES (-1), (0), (1), (2)), numbers(n) AS ( SELECT 0 UNION ALL SELECT n + 1 FROM numbers WHERE n < 41 ), months(month) AS ( SELECT date('now', 'start of month', printf('%+d months', n)) FROM offsets ) SELECT substr(month, 1, 7) AS month, date( month, printf('-%d days', strftime('%w', month)), printf('+%d days', numbers.n) ) AS day FROM months CROSS JOIN numbers ) AS grid""", what="month, day", order="month, day" ) grids = collections.defaultdict(list) for day in days: grids[day["month"]].append(day["day"]) month_names = ( "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ) <div class="rsvp-calendars"> $for month in sorted(grids): <section> <h2>$(month_names[int(month[5:7]) - 1]) $(month[:4])</h2> <table class="rsvp-calendar"> <thead> <tr> $for weekday in ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"): <th scope="col">$weekday</th> </tr> </thead> <tbody> $for week_start in range(0, 42, 7): $if grids[month][week_start][:7] == month or grids[month][week_start + 6][:7] == month: <tr> $for day in grids[month][week_start:week_start + 7]: $if day[:7] == month: <td> <time datetime="$day">$(int(day[8:10]))</time> $for event in events_by_day.get(day, []): <a class="calendar-event" href="$(event['url'])"> <time datetime="$(event['start'])"> $(str(event["start"])[11:16]) </time> <span>$(event["name"])</span> </a> </td> $else: <td class="calendar-padding"></td> </tr> </tbody> </table> </section> </div> <style> .rsvp-calendars { display: grid; gap: 2rem; } .rsvp-calendar { width: 100%; table-layout: fixed; border-collapse: collapse; } .rsvp-calendar th, .rsvp-calendar td { border: 1px solid #8886; padding: .4rem; } .rsvp-calendar th { font-size: .8rem; } .rsvp-calendar td { height: 6rem; vertical-align: top; } .rsvp-calendar .calendar-padding { border: 0; background: transparent; } .calendar-event { display: block; margin-top: .4rem; padding: .35rem; border-radius: .25rem; background: #8882; font-size: .8rem; overflow-wrap: anywhere; } .calendar-event time, .calendar-event span { display: block; } </style> |