This is done manually since they generally don't update that often, and there's no easy API for accessing the info. However, scraping things like this, especially the constantly-redesigning Gunn website, is unreliable so these probably won't work in the future.
npm run update-staff
You might want to update the last updated date in js/languages/en.js in
staff-disclaimer
.
One of the nice things about UGWA graduating this year is that I do not have to worry about the state of UGWA's club system. Due to clubs being virtual, there's a lot of quirkiness involved to support club videos and Zoom links. The code that handles it likely will not work in future years.
-
Follow the instructions in js/get-clubs-links.js.
-
npm run update-clubs
This uses your Google Calendar API key. You can enable the Google Drive API using the directions in js/get-clubs-gdrive-thumbnails.js.
You might want to update the last updated date in js/languages/en.js in
clubs-disclaimer
.
You can ignore this section. Some of these require top level await
; if
your console doesn't support it, wrap the code in
;(async () => {
// ...
})()
Go to the chartered club
list,
select all, copy, and paste into data:text/html;charset=UTF-8,<body contenteditable>
(open that URL in your browser). Run the following JavaScript in the console,
and copypaste the output into json/clubs.json.
r = {}
for (var s of document.querySelectorAll('table tr')) {
var boop = s.querySelectorAll('td')
var i = boop.length === 9
r[boop[1].textContent] = {
desc: boop[2].textContent,
donation:
(boop[3].textContent.slice(0, 1).toLowerCase() === 'n' ||
boop[3].textContent === '0' ||
boop[3].textContent.slice(0, 2) === '$0'
? undefined
: boop[3].textContent) || undefined,
day: boop[4 - i].textContent,
time: boop[5 - i].textContent,
room: boop[6 - i].textContent,
president: boop[7 - i].textContent,
teacher: boop[8 - i].textContent,
email: boop[9 - i].textContent
}
}
delete r['Club Name']
JSON.stringify(r, null, '\t')
Go to the staff directory on the Gunn website, run the following JavaScript in the console, and copypaste the output into json/staff.json.
pages = +$('.fsLastPageLink').attr('data-page')
r = {}
insertEmail = (_, domain, email) =>
`${[...email].reverse().join('')}@${[...domain].reverse().join('')}`
setTimeoute = f => f()
for (let i = 1; i <= pages; i++) {
const html = $(
$.parseHTML(
await fetch(
'https://gunn.pausd.org/fs/elements/11437?const_page=' + i
).then(r => r.text()),
document,
true
)
)
Object.assign(
r,
Object.fromEntries(
Array.from(html.find('.fsConstituentItem'), teach => [
teach.querySelector('.fsConstituentProfileLink').textContent.trim(),
{
jobTitle: teach.querySelector('.fsTitles').textContent.trim(),
email: eval(
teach
.querySelector('.fsEmail > div > script')
.innerHTML.replace('setTimeout', 'setTimeoute')
.replace('FS.util.', 'return ')
)
}
])
)
)
}
JSON.stringify(r, null, '\t')
r = {}
document.querySelectorAll('tbody tr').forEach(tr => {
const [name, position, department, email, phone] = Array.from(
tr.children
).map(td => td.textContent.trim())
r[name] = {
jobTitle: position,
department: department,
phone: phone,
email: email
}
})
JSON.stringify(r)
Club list v1 (where sela
is an alias of
document.querySelectorAll
)
for (var s of sela('table tr')) {
var boop = s.querySelectorAll('td')
var i = boop.length === 9
r[boop[1].textContent] = {
desc: boop[2].textContent,
day: boop[4 - i].textContent,
time: boop[5 - i].textContent,
room: boop[6 - i].textContent,
president: boop[7 - i].textContent,
teacher: boop[8 - i].textContent,
email: boop[9 - i].textContent
}
}
var r = {}
jQuery('.views-table.cols-6 tbody tr').each(function () {
var c = jQuery(this).children()
r[
c
.eq(0)
.find('a')
.html()
.trim()
] = {
jobTitle: c
.eq(1)
.html()
.trim(),
department: c
.eq(2)
.find('a')
.html()
? c
.eq(2)
.find('a')
.html()
.trim()
: null,
phone: c
.eq(3)
.html()
.trim(),
email: c
.eq(4)
.html()
.trim(),
webpage: c.eq(5).find('a').length
? c
.eq(5)
.find('a')
.attr('href')
: null
}
})
JSON.stringify(r)