From 4d1e980572b4dd92d8489f2cf7803fababac5e1f Mon Sep 17 00:00:00 2001 From: nesi-mkdocs-bot Date: Wed, 8 Apr 2026 15:06:02 +1200 Subject: [PATCH 1/2] changed office hours banner to use ical. replace ms embed with table. disable mkdocs2 warning --- .github/fetch_includes.sh | 3 +- .github/workflows/checks.yml | 2 +- .github/workflows/demo_deploy.yml | 3 +- .github/workflows/deploy.yml | 2 + .vscode/tasks.json | 4 +- .../Weekly_Online_Office_Hours.md | 8 ++- docs/assets/javascripts/general.js | 62 ++++++++++++------- docs/assets/javascripts/officeHours.js | 59 ++++++++++++++++++ .../stylesheets/office-hours-calendar.css | 12 ++++ mkdocs.yml | 1 + requirements.in | 6 +- requirements.txt | 21 ++++--- 12 files changed, 146 insertions(+), 37 deletions(-) create mode 100644 docs/assets/javascripts/officeHours.js create mode 100644 docs/assets/stylesheets/office-hours-calendar.css diff --git a/.github/fetch_includes.sh b/.github/fetch_includes.sh index 47be8e78d..4ed3fc9ad 100644 --- a/.github/fetch_includes.sh +++ b/.github/fetch_includes.sh @@ -5,7 +5,7 @@ MODULES_UPDATE_URL="https://raw.githubusercontent.com/nesi/modules-list/main/rss GLOSSARY_URL="https://raw.githubusercontent.com/nesi/nesi-wordlist/main/outputs/glossary.md" DICTIONARY_URL="https://raw.githubusercontent.com/nesi/nesi-wordlist/main/outputs/dictionary.txt" SNIPPETS_URL="https://raw.githubusercontent.com/nesi/nesi-wordlist/main/outputs/snippets.md" -ICAL_URL="https://calendar.google.com/calendar/ical/c_hen6rr02et39kat2hmuamidots@group.calendar.google.com/public/basic.ics" +ICAL_URL="https://outlook.office365.com/owa/calendar/3d4e3c7b28ca4549803470b109cba86a@reannz.co.nz/0830583db389420aaa843dc231af48d810099982634588501079/calendar.ics" mkdir -p docs/assets/glossary @@ -18,3 +18,4 @@ python3 .github/workflows/link_apps_pages.py wget -q -O overrides/partials/glossary.html "${GLOSSARY_URL}" wget -q -O docs/assets/glossary/dictionary.txt "${DICTIONARY_URL}" wget -q -O docs/assets/glossary/snippets.md "${SNIPPETS_URL}" + diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 82271590b..37df036f1 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -173,4 +173,4 @@ jobs: fetch-depth: 0 - run: pip3 install -r requirements.txt - run: ./checks/run_test_build.py - - run: python3 checks/run_aria_check.py + - run: export NO_MKDOCS_2_WARNING="1"; python3 checks/run_aria_check.py diff --git a/.github/workflows/demo_deploy.yml b/.github/workflows/demo_deploy.yml index 4c0a8e344..81fbfc9dd 100644 --- a/.github/workflows/demo_deploy.yml +++ b/.github/workflows/demo_deploy.yml @@ -1,7 +1,7 @@ name: Deploy PR branches on: pull_request: - branches-ignore: "assets-update" + branches-ignore: ["assets-update"] env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} TARGET_REPO: "mkdocs-demo-deploy" @@ -10,6 +10,7 @@ env: DEPLOY_URL: "https://callumwalley.github.io/mkdocs-demo-deploy" HEAD: ${{ github.event.pull_request.head.ref }} GH_REPO: ${{ github.repository }} + NO_MKDOCS_2_WARNING: "1" permissions: write-all jobs: demo-deploy: diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index bebe9d639..5c48f7adb 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -8,6 +8,8 @@ on: env: PYTHON_VERSION: 3.14.2 GH_TOKEN: ${{ github.token }} + NO_MKDOCS_2_WARNING: "1" + permissions: contents: write pull-requests: write diff --git a/.vscode/tasks.json b/.vscode/tasks.json index c725ad437..4a3a0202c 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -82,7 +82,7 @@ "reveal":"never", "showReuseMessage": false }, - "command": "./checks/run_test_build.py", + "command": "export NO_MKDOCS_2_WARNING=1 && ./checks/run_test_build.py", "problemMatcher": { "severity": "info", "pattern": { @@ -163,7 +163,7 @@ "reveal":"never", "showReuseMessage": false }, - "command": "mkdocs serve --dirty" + "command": "export NO_MKDOCS_2_WARNING=1 && mkdocs serve --dirty" }, ] } diff --git a/docs/Getting_Started/Weekly_Online_Office_Hours.md b/docs/Getting_Started/Weekly_Online_Office_Hours.md index 6576c9115..e79194190 100644 --- a/docs/Getting_Started/Weekly_Online_Office_Hours.md +++ b/docs/Getting_Started/Weekly_Online_Office_Hours.md @@ -19,9 +19,11 @@ description: | ## Office Hours Dates -Click on the links below to view the upcoming office hours: - - + +
+

Loading Calendar...

+
+ If you are unable to add an Office Hour session to your calendar through these links, please email us at [training@reannz.co.nz](mailto:training@reannz.co.nz) and we can send a diff --git a/docs/assets/javascripts/general.js b/docs/assets/javascripts/general.js index 914104b68..7c5e5eed7 100644 --- a/docs/assets/javascripts/general.js +++ b/docs/assets/javascripts/general.js @@ -36,26 +36,45 @@ async function showOfficeBanner() { .then(r => r.ok ? r.text() : ""); if (!text) { console.warn("failed to load calendar ") }; - const now = new Date(); - let allmatch = text.matchAll(/DTSTART:(\d+T\d+Z)/g); - // Extract all dates. - for (const t of allmatch) { - if (!t) continue; - let d = format8601(t[1]); - // if today - if (now.toDateString() == d.toDateString()) { - // if not finished. - if (now.getTime() < d.getTime() + 3600000) { - // if not started - if (now < d) { - addBanner(`

Weekly Online Office Hour on today, starting ${d.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}. Drop in for any queries.`, "calendar-banner"); - - } else { - addBanner(`

Weekly Online Office Hour on now. Join Zoom Meeting Now for any queries.

`, "calendar-banner"); + try { + const jcal = ICAL.parse(text); + const comp = new ICAL.Component(jcal); + const vevents = comp.getAllSubcomponents('vevent'); + for (const vevent of vevents) { + const dtstart = vevent.getFirstPropertyValue('dtstart'); + const date = dtstart.toJSDate(); + // if today + if (now.toDateString() == date.toDateString()) { + // if not finished. + if (now.getTime() < date.getTime() + 3600000) { + // if not started + if (now < date) { + addBanner(`

Weekly Online Office Hour on today, starting ${date.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}. Drop in for any queries.`, "calendar-banner"); + } else { + addBanner(`

Weekly Online Office Hour on now. Join Zoom Meeting Now for any queries.

`, "calendar-banner"); + } } + break; + } + } + } catch (error) { + console.warn("ICAL parsing failed, falling back to regex:", error); + // Fallback to regex + let allmatch = text.matchAll(/DTSTART;TZID=New Zealand Standard Time:(\d+T\d+)/g); + for (const t of allmatch) { + if (!t) continue; + let d = format8601(t[1]); + if (now.toDateString() == d.toDateString()) { + if (now.getTime() < d.getTime() + 3600000) { + if (now < d) { + addBanner(`

Weekly Online Office Hour on today, starting ${d.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}. Drop in for any queries.`, "calendar-banner"); + } else { + addBanner(`

Weekly Online Office Hour on now. Join Zoom Meeting Now for any queries.

`, "calendar-banner"); + } + } + break; } - break; } } } @@ -81,14 +100,15 @@ function format8601(str){ const dateStringFormatted = str.substring(0, 4) + '-' + str.substring(4, 6) + '-' + - str.substring(6, 8) + - str.substring(8, 9) + + str.substring(6, 8) + 'T' + str.substring(9, 11) + ':' + str.substring(11, 13) + ':' + - str.substring(13, 15) + - str.substring(15, 16); + str.substring(13, 15) + '+12:00'; return new Date(dateStringFormatted); } + +showOfficeBanner(); + // Remove me later // showOfficeBanner().then(() => { // if (!document.getElementById("calendar-banner")){ diff --git a/docs/assets/javascripts/officeHours.js b/docs/assets/javascripts/officeHours.js new file mode 100644 index 000000000..5b6cfee29 --- /dev/null +++ b/docs/assets/javascripts/officeHours.js @@ -0,0 +1,59 @@ +async function displayOfficeHoursCalendar() { + const calendarDiv = document.getElementById('office-hours-calendar'); + const calendarP = document.getElementById('office-hours-calendar-message'); + if (!calendarDiv) return; + + const text = await fetch("/assets/training_calendar.ics") + .then(r => r.ok ? r.text() : ""); + if (!text) { + calendarP.innerHTML = 'Failed to load calendar.'; + return; + } + + try { + const jcal = ICAL.parse(text); + const comp = new ICAL.Component(jcal); + const events = comp.getAllSubcomponents('vevent').map(vevent => { + const summary = vevent.getFirstPropertyValue('summary'); + const dtstart = vevent.getFirstPropertyValue('dtstart'); + const description = (vevent.getFirstPropertyValue('description') || '').replace(/\\n/g, '\n').replace(/\\,/g, ','); + const urlMatch = description.match(/(https?:\/\/[^\s]+)/); + const start = dtstart.toJSDate(); + return { + title: summary, + start, + description, + meetingLink: urlMatch ? urlMatch[1] : MEETING_LINK, + day: start.toLocaleDateString('en-US', { weekday: 'long' }), + date: start.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }), + time: start.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' }) + }; + }); + + // Sort events by date + events.sort((a, b) => a.start - b.start); + + // Create table + const tableWrap = document.createElement('div'); + tableWrap.className = 'md-typeset__table' + const table = document.createElement('table'); + let rows = ''; + events.forEach(event => { + rows += ` + + ${event.day}, ${event.date} + ${event.time} + Add to Calendar + + `; + }); + table.innerHTML = `${rows}`; + tableWrap.appendChild(table); + calendarDiv.appendChild(tableWrap); + calendarP.innerHTML = ''; + } catch (error) { + console.error('Error parsing ICS:', error); + calendarP.innerHTML = '

Error loading Calendar.

'; + } +} +window.addEventListener("load", displayOfficeHoursCalendar); diff --git a/docs/assets/stylesheets/office-hours-calendar.css b/docs/assets/stylesheets/office-hours-calendar.css new file mode 100644 index 000000000..312f2a736 --- /dev/null +++ b/docs/assets/stylesheets/office-hours-calendar.css @@ -0,0 +1,12 @@ +.md-button.md-button--addcal { + padding: 0.1em; + margin: auto; + font-size: medium; + padding: 0.5em; +} +.md-button.md-button--addcal > svg { + height: 24px; + margin: auto; + vertical-align: middle; +} + diff --git a/mkdocs.yml b/mkdocs.yml index 1040b3767..8b538a602 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -126,3 +126,4 @@ extra_javascript: - https://status.nesi.org.nz/embed/script.js - assets/javascripts/mathjax.js - https://unpkg.com/mathjax@3/es5/tex-mml-chtml.js + - https://cdn.jsdelivr.net/npm/ical.js@1.5.0/build/ical.min.js diff --git a/requirements.in b/requirements.in index 9bb9aa178..29768f8bf 100644 --- a/requirements.in +++ b/requirements.in @@ -1,5 +1,5 @@ # documentation generation -mkdocs +mkdocs < 2.0 # See https://fpgmaas.com/blog/collapse-of-mkdocs/ mkdocs-section-index mkdocs-bootstrap4 mkdocs-material @@ -18,6 +18,10 @@ mkdocs_quiz @ git+https://github.com/CallumWalley/mkdocs-quiz.git@fix-template-o # checkers neoteroi-mkdocs codespell + +# calendar fetching +requests +icalendar proselint linkcheckmd symspellpy diff --git a/requirements.txt b/requirements.txt index 119459964..c10704fad 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ # aiohappyeyeballs==2.6.1 # via aiohttp -aiohttp==3.13.3 +aiohttp==3.13.5 # via linkcheckmd aiosignal==1.4.0 # via aiohttp @@ -41,9 +41,9 @@ cffi==2.0.0 # via # cryptography # pynacl -charset-normalizer==3.4.6 +charset-normalizer==3.4.7 # via requests -click==8.3.1 +click==8.3.2 # via # mkdocs # neoteroi-mkdocs @@ -54,7 +54,7 @@ codespell==2.4.2 # via -r requirements.in colorama==0.4.6 # via mkdocs-material -cryptography==46.0.5 +cryptography==46.0.7 # via pyjwt editdistpy==0.2.0 # via symspellpy @@ -98,6 +98,8 @@ httpcore==1.0.9 # via httpx httpx==0.28.1 # via neoteroi-mkdocs +icalendar==7.0.3 + # via -r requirements.in idna==3.11 # via # anyio @@ -236,13 +238,13 @@ pydantic-core==2.41.5 # via pydantic pygithub==2.9.0 # via mkdocs-git-committers-plugin -pygments==2.19.2 +pygments==2.20.0 # via # mkdocs-material # rich pyjwt[crypto]==2.12.1 # via pygithub -pymdown-extensions==10.21 +pymdown-extensions==10.21.2 # via mkdocs-material pynacl==1.6.2 # via pygithub @@ -255,6 +257,7 @@ pyspelling==2.12.1 python-dateutil==2.9.0.post0 # via # ghp-import + # icalendar # mkdocs-macros-plugin pyyaml==6.0.3 # via @@ -273,8 +276,9 @@ pyyaml-env-tag==1.1 # properdocs questionary==2.1.1 # via mkdocs-quiz -requests==2.33.0 +requests==2.33.1 # via + # -r requirements.in # cachecontrol # mkdocs-macros-plugin # mkdocs-material @@ -310,12 +314,15 @@ typing-extensions==4.15.0 # aiosignal # anyio # beautifulsoup4 + # icalendar # pydantic # pydantic-core # pygithub # typing-inspection typing-inspection==0.4.2 # via pydantic +tzdata==2026.1 + # via icalendar urllib3==2.6.3 # via # pygithub From 57745545ef986f55dc2bb08410dc9a98c9fa40c3 Mon Sep 17 00:00:00 2001 From: nesi-mkdocs-bot Date: Wed, 8 Apr 2026 15:20:23 +1200 Subject: [PATCH 2/2] remove redundnat --- docs/assets/javascripts/general.js | 19 +------------------ mkdocs.yml | 2 +- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/docs/assets/javascripts/general.js b/docs/assets/javascripts/general.js index 7c5e5eed7..5b5dab9c2 100644 --- a/docs/assets/javascripts/general.js +++ b/docs/assets/javascripts/general.js @@ -1,4 +1,3 @@ -const CALENDAR_ID = "c_hen6rr02et39kat2hmuamidots@group.calendar.google.com"; const MEETING_LINK = "https://nesi.zoom.us/j/83987449505?pwd=TzlYTk9pdGJXZFZVSUxhUFUyeFYrUT09"; function changeVersion(app, version, warn = false) { @@ -59,23 +58,7 @@ async function showOfficeBanner() { } } } catch (error) { - console.warn("ICAL parsing failed, falling back to regex:", error); - // Fallback to regex - let allmatch = text.matchAll(/DTSTART;TZID=New Zealand Standard Time:(\d+T\d+)/g); - for (const t of allmatch) { - if (!t) continue; - let d = format8601(t[1]); - if (now.toDateString() == d.toDateString()) { - if (now.getTime() < d.getTime() + 3600000) { - if (now < d) { - addBanner(`

Weekly Online Office Hour on today, starting ${d.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}. Drop in for any queries.`, "calendar-banner"); - } else { - addBanner(`

Weekly Online Office Hour on now. Join Zoom Meeting Now for any queries.

`, "calendar-banner"); - } - } - break; - } - } + console.warn("ICAL parsing failed", error); } } diff --git a/mkdocs.yml b/mkdocs.yml index 8b538a602..0f7f98bb7 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -126,4 +126,4 @@ extra_javascript: - https://status.nesi.org.nz/embed/script.js - assets/javascripts/mathjax.js - https://unpkg.com/mathjax@3/es5/tex-mml-chtml.js - - https://cdn.jsdelivr.net/npm/ical.js@1.5.0/build/ical.min.js + - https://cdnjs.cloudflare.com/ajax/libs/ical.js/1.3.0/ical.min.js