-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathappscript.js
174 lines (160 loc) · 5.46 KB
/
appscript.js
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
// https://github.com/cca/people-api
let url = "https://portal.cca.edu/search/people/_search"
, http_options = {
method: 'post',
followRedirects: true,
muteHttpExceptions: true,
contentType: 'application/json',
headers: {
accept: 'application/json'
}
}
, pm_pattern = /(senior )?(program|project) manager/i
, pgram = / Program/i
, fields = ["Name","Email","Role","Program(s) or Department"];
function pm(p) {
// find useful data in person record for program managers
let position = p.positions.filter(pos => pos.match(pm_pattern))[0]
let program = null
// parse out the academic program, positions look like this
// "Project Manager, Humanities & Sciences, Academic Affairs"
// Handle "Senior Project Manager for Department" exception:
if (position.match(" for ")) {
let pos_prog = position.split(" for ")
position = pos_prog[0]
program = pos_prog[1].split(", ")[0]
} else {
program = position.split(', ')[1]
position = position.match(pm_pattern)[0]
}
// some people don't have emails? but everyone has a username
return [p.full_name, p.username + '@cca.edu', position, program ]
}
function sm(p) {
// find useful data in person record for studio managers
// program is hidden in first position somewhere in a wildly inconsistent manner
// but if we can strip out "Studio Manager" and "Studio Operations" then program
// is _usually_ the only thing left
let program = p.positions[0].replace(', Studio Operations', '').replace('Studio Manager', '')
.replace('Studio Operations Manager', '').replace(/^, /, '').replace(/^ -/, '').trim()
return [ p.full_name, p.username + '@cca.edu', 'Studio Manager', program ]
}
function chair(p) {
// find useful data in person record for program chair, co-chair
// chairs tend to have multiple positions, they look like this:
// "Assistant Chair, Illustration Program"
// let's hope no one ever has a chair _and_ asst. chair role
// create a list of all programs, set gives free deduplication
let position, programs = new Set()
p.positions.forEach(pos => {
if (pos.toLowerCase().match("chair")) {
position = pos.split(", ")[0]
program = pos.split(", ")[1]
// trim " Program" off the end of string
program = program.replace(pgram, '')
programs.add(program)
}
})
return [ p.full_name, p.username + '@cca.edu', position, Array.from(programs).join('; ') ]
}
let staff_query = {
"query": {
"simple_query_string": {
// search term
"query": "manager",
"fields": [
"full_name^5",
"positions^5",
"get_staff_departments",
"username",
],
"default_operator": "AND",
}
},
// other filters are Faculty and Student
"post_filter": {"term": {"usertype_filter": "Staff"}},
"size": 60,
"sort": [{"_score": "desc"}, {"get_last_name_filter": "asc"}],
}
, faculty_query = {
"query": {
"simple_query_string": {
// search term
"query": "chair",
"fields": [
"full_name^5",
"get_faculty_programs",
"positions^5",
"username",
],
"default_operator": "AND",
}
},
"post_filter": {"term": {"usertype_filter": "Faculty"}},
"size": 60,
"sort": [{"_score": "desc"}, {"get_last_name_filter": "asc"}],
};
/**
* Fetch data from Portal about faculty & staff
*
* @return [People] array of people arrays with ["name", "email", "role", "program"] data
*/
function getPeopleData() {
let staff = getStaffData()
let faculty = getFacultyData()
let all = staff.concat(faculty)
addPeopleToSheet(all)
}
function getStaffData() {
http_options.payload = JSON.stringify(staff_query)
let response = UrlFetchApp.fetch(url, http_options)
let text = response.getContentText()
let status = response.getResponseCode()
if (status != 200) {
return Logger.log(`Error fetching data from Portal. HTTP ${status}\n${text}`);
}
let data = JSON.parse(text)
let staff = []
data.hits.hits.forEach(d => {
let person = d._source
if (person.staff_primary_department.toLowerCase() === 'studio operations') {
staff.push(sm(person))
} else if (person.positions.some(p => p.match(pm_pattern))) {
staff.push(pm(person))
}
})
return staff
}
function getFacultyData() {
http_options.payload = JSON.stringify(faculty_query)
let response = UrlFetchApp.fetch(url, http_options)
let text = response.getContentText()
let status = response.getResponseCode()
if (status != 200) {
return Logger.log(`Error fetching data from Portal. HTTP ${status}\n${text}`);
}
let data = JSON.parse(text)
let faculty = data.hits.hits.filter(d => d._source.positions.some(p => p.toLowerCase().match("chair")))
.map(d => chair(d._source))
return faculty
}
/**
* Clears worksheet and inserts people rows
*
* @param {array} Array of people rows
*
* @return undefined (no return value)
*/
function addPeopleToSheet(people) {
let sheet = SpreadsheetApp.getActiveSheet()
// clear existing data
sheet.clear()
// header row
sheet.appendRow(fields)
// update whole range at once instead of iterating with sheet.appendRow()
sheet.getRange(2, 1, people.length, people[0].length).setValues(people)
}
function onOpen() {
let ss = SpreadsheetApp.getActiveSpreadsheet()
ss.addMenu("Refresh Data", [{name: "Update spreadsheet from Portal", functionName: "getPeopleData"}])
}