Browse Source

use jsonify rather than dumps

master
wes 8 years ago
parent
commit
163cd32f3b
  1. 47
      src/mcmaster/classes.py
  2. 358
      src/mcmaster/classes2.py
  3. 50
      src/mcmaster/errors2.log
  4. 2172
      src/mcmaster/errors3.log
  5. BIN
      src/mcmaster/requests3.pcap
  6. 12
      src/mcmaster/sylla.py
  7. 117
      src/mcmaster/sylla2.py
  8. 0
      src/mcmaster/texbooks.csv
  9. 0
      src/mcmaster/textbooks.csv
  10. 1
      src/mcmaster/wtf.xml
  11. 18
      src/website.py

47
src/mcmaster/classes.py

@ -1,7 +1,7 @@
#! /usr/bin/python2
#! /usr/bin/python3
from sys import argv
from itertools import chain, islice, izip as zip
from itertools import chain, islice
from re import search, sub
from functools import total_ordering
@ -11,6 +11,7 @@ from collections import MutableMapping
import datetime as dt
import lxml.html as lxh
import requests
import logging
import sys
import copy
@ -19,7 +20,7 @@ spring_summer = "2175"
winter = "2171"
# threading stuff
import Queue as q
import queue as q
import threading as thd
baseurl = "https://applicants.mcmaster.ca/psp/prepprd/EMPLOYEE/PSFT_LS/c/COMMUNITY_ACCESS.CLASS_SEARCH.GBL"
@ -31,6 +32,11 @@ custom_headers = {
"Content-Type" : "application/x-www-form-urlencoded; charset=UTF-8",
}
get_headers = {
"User-Agent" : "Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0",
"Content-Type" : "text/html; charset=UTF-8",
}
courseCodes1 = "ICAJAX=1&ICNAVTYPEDROPDOWN=1&ICType=Panel&ICElementNum=0&ICStateNum={0}&ICAction=CLASS_SRCH_WRK2_SSR_PB_SUBJ_SRCH%240&ICXPos=0&ICYPos=0&ResponsetoDiffFrame=-1&TargetFrameName=None&FacetPath=None&ICFocus=&ICSaveWarningFilter=0&ICChanged=-1&ICResubmit=0&ICSID=5tq9x%2Fjt42mf62Sh5z%2BrjxT0gT15kiIyQ2cecCSmRB4%3D&ICActionPrompt=false&ICFind=&ICAddCount=&ICAPPCLSDATA=&CLASS_SRCH_WRK2_STRM$45$={1}"
courseCodes2 = "ICAJAX=1&ICNAVTYPEDROPDOWN=1&ICType=Panel&ICElementNum=0&ICStateNum={0}&ICAction=SSR_CLSRCH_WRK2_SSR_ALPHANUM_{1}&ICXPos=0&ICYPos=0&ResponsetoDiffFrame=-1&TargetFrameName=None&FacetPath=None&ICFocus=&ICSaveWarningFilter=0&ICChanged=-1&ICResubmit=0&ICSID=vIUgl6ZXw045S07EPbQw4RDzv7NmKCDdJFdT4CTRQNM%3D&ICActionPrompt=false&ICFind=&ICAddCount=&ICAPPCLSDATA=&CLASS_SRCH_WRK2_STRM$45$={2}"
@ -140,7 +146,7 @@ class Section(dict):
assert len(self._day) == 2
day = self._day
else:
day = [day[n:n+2] for n in xrange(0, len(day)-1, 2)]
day = [day[n:n+2] for n in range(0, len(day)-1, 2)]
self._date = (day, timeparse(start), timeparse(end))
@ -213,7 +219,7 @@ def parseColumns(subject, html):
if span.xpath("@id") and
search(r"DERIVED_CLSRCH_DESCR", span.xpath("@id")[0]))
return zip(classNames, classInfo)
return list(zip(classNames, classInfo))
def getCodes(html):
parsed = lxh.fromstring(html)
@ -231,7 +237,7 @@ class MosReq(object):
# Let the server set some cookies before doing the searching
cookies = {}
for key, val in s.cookies.iteritems():
for key, val in list(s.cookies.items()):
cookies[key] = val
self.cookies = cookies
self.statenum = False
@ -239,17 +245,20 @@ class MosReq(object):
def getlist(self, subject):
sys.stderr.write("Getting %s\n" % subject.decode("UTF-8"))
first_req = requests.get(searchurl, cookies=self.cookies).content
first_req = requests.get(searchurl, cookies=self.cookies, headers=get_headers)
# for some reason Mosaic wants us to request it twice, ??????????????????
self.statenum = getStateNum(first_req)
self.statenum = getStateNum(first_req.content)
first_req = requests.post(searchurl,
data=payload.format(self.statenum, subject, self.semester),
cookies=self.cookies,
allow_redirects=False,
headers=custom_headers).content
headers=custom_headers)
print("HEADERS")
print(first_req.request.headers)
# we make a first request to get the ICStateNum in case it thinks there are too many results
try:
self.statenum = getStateNum(first_req)
self.statenum = getStateNum(first_req.content)
except IndexError:
pass
if b"Your search will return over" in first_req:
@ -263,11 +272,13 @@ class MosReq(object):
return first_req
def classes(self, subject):
print("Trying to get classes")
print(subject)
return list(parseColumns(subject, self.getlist(subject)))
def getCodes(self, letter):
sys.stderr.write("Getting letter " + letter + "\n")
first_req = requests.get(searchurl, cookies=self.cookies).content
sys.stderr.write("Getting letter %s\n" % letter)
first_req = requests.get(searchurl, cookies=self.cookies, headers=get_headers).content
self.statenum = getStateNum(first_req)
self.statenum = getStateNum(requests.post(searchurl,
@ -284,9 +295,9 @@ class MosReq(object):
def codes(self):
if not self.codes_:
self.codes_ = list(chain.from_iterable(
map((lambda l:
list(map((lambda l:
self.getCodes(chr(l))),
xrange(65, 91))))
list(range(65, 91))))))
return self.codes_
def request(codes, lists, semester):
@ -295,8 +306,8 @@ def request(codes, lists, semester):
code = codes.get()
try:
lists.put(requester.classes(code))
except exception:
print(exception)
except Exception as e:
print(e)
codes.task_done()
return
codes.task_done()
@ -321,7 +332,7 @@ class CourseInfo(object):
lists = q.Queue()
threads = []
thread = None
for i in xrange(self.threadcount):
for i in range(self.threadcount):
thread = thd.Thread(group=None, target=request, args=(qcodes, lists, self.semester))
threads.append(thread)
thread.start()
@ -357,4 +368,4 @@ def allCourses():
if __name__ == "__main__":
for course in allCourses():
sys.stdout.write("%s, %s, %s, %s\n" % (course.title, course.code, course.dept, list(chain.from_iterable(course.books))))
print course.sections
print((course.sections))

358
src/mcmaster/classes2.py

@ -0,0 +1,358 @@
#! /usr/bin/python2
from sys import argv
from itertools import chain, islice
from re import search, sub
from functools import total_ordering
from sylla2 import textbookInfo
from collections import MutableMapping
import datetime as dt
import lxml.html as lxh
import requests
import logging
import sys
import copy
fall = "2169"
spring_summer = "2175"
winter = "2171"
# threading stuff
import Queue as q
import threading as thd
baseurl = "https://applicants.mcmaster.ca/psp/prepprd/EMPLOYEE/PSFT_LS/c/COMMUNITY_ACCESS.CLASS_SEARCH.GBL"
searchurl = "https://csprd.mcmaster.ca/psc/prcsprd/EMPLOYEE/PSFT_LS/c/COMMUNITY_ACCESS.CLASS_SEARCH.GBL"
custom_headers = {
"User-Agent" : "Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0",
"Content-Type" : "application/x-www-form-urlencoded; charset=UTF-8",
}
courseCodes1 = "ICAJAX=1&ICNAVTYPEDROPDOWN=1&ICType=Panel&ICElementNum=0&ICStateNum={0}&ICAction=CLASS_SRCH_WRK2_SSR_PB_SUBJ_SRCH%240&ICXPos=0&ICYPos=0&ResponsetoDiffFrame=-1&TargetFrameName=None&FacetPath=None&ICFocus=&ICSaveWarningFilter=0&ICChanged=-1&ICResubmit=0&ICSID=5tq9x%2Fjt42mf62Sh5z%2BrjxT0gT15kiIyQ2cecCSmRB4%3D&ICActionPrompt=false&ICFind=&ICAddCount=&ICAPPCLSDATA=&CLASS_SRCH_WRK2_STRM$45$={1}"
courseCodes2 = "ICAJAX=1&ICNAVTYPEDROPDOWN=1&ICType=Panel&ICElementNum=0&ICStateNum={0}&ICAction=SSR_CLSRCH_WRK2_SSR_ALPHANUM_{1}&ICXPos=0&ICYPos=0&ResponsetoDiffFrame=-1&TargetFrameName=None&FacetPath=None&ICFocus=&ICSaveWarningFilter=0&ICChanged=-1&ICResubmit=0&ICSID=vIUgl6ZXw045S07EPbQw4RDzv7NmKCDdJFdT4CTRQNM%3D&ICActionPrompt=false&ICFind=&ICAddCount=&ICAPPCLSDATA=&CLASS_SRCH_WRK2_STRM$45$={2}"
payload2 = "ICAJAX=1&ICNAVTYPEDROPDOWN=1&ICType=Panel&ICElementNum=0&ICStateNum={0}&ICAction=%23ICSave&ICXPos=0&ICYPos=0&ResponsetoDiffFrame=-1&TargetFrameName=None&FacetPath=None&ICFocus=&ICSaveWarningFilter=0&ICChanged=-1&ICResubmit=0&ICSID=aWx3w6lJ6d2wZui6hwRVSEnzsPgCA3afYJEFBLLkxe4%3D&ICActionPrompt=false&ICFind=&ICAddCount=&ICAPPCLSDATA=&CLASS_SRCH_WRK2_STRM$45$={1}"
payload = "ICAJAX=1&ICNAVTYPEDROPDOWN=1&ICType=Panel&ICElementNum=0&ICStateNum={0}&ICAction=CLASS_SRCH_WRK2_SSR_PB_CLASS_SRCH&ICXPos=0&ICYPos=0&ResponsetoDiffFrame=-1&TargetFrameName=None&FacetPath=None&ICFocus=&ICSaveWarningFilter=0&ICChanged=-1&ICResubmit=0&ICSID=aWx3w6lJ6d2wZui6hwRVSEnzsPgCA3afYJEFBLLkxe4%3D&ICActionPrompt=false&ICFind=&ICAddCount=&ICAPPCLSDATA=&SSR_CLSRCH_WRK_SUBJECT$75$$0={1}&CLASS_SRCH_WRK2_STRM$45$={2}"
year = dt.date.today().year
month = dt.date.today().month
days = {
"Mo" : 0,
"Tu" : 1,
"We" : 2,
"Th" : 3,
"Fr" : 4,
"Sa" : 5,
"Su" : 6
}
day_descs = {
"Mo" : "Monday Mon Mo",
"Tu" : "Tuesday Tues Tu Tue",
"We" : "Wednesday Wed We",
"Th" : "Thursday Th Thurs",
"Fr" : "Friday Fr Fri",
"Sa" : "Saturday Sat Sa",
"Su" : "Sunday Su Sun",
"T" : "TBA"
}
def timeparse(time):
"""
Parse the time into numbers
"""
if len(time) == 7:
hour = int(time[0:2])
minutes = int(time[3:5])
half = time[5:7]
else:
hour = int(time[0])
minutes = int(time[2:4])
half = time[4:6]
if half == "PM":
if hour < 12:
hour = hour + 12
return (str(hour), str(minutes), half)
class Class(object):
def __init__(self, dept, title, sections):
self.title = title.encode("UTF-8")
self.sections = sections
self.dept = dept
def __repr__(self):
return repr((self.title, self.sections))
def __iter__(self):
return iter((self.title, sec) for sec in self.sections)
def hasCode(self):
splitted = self.title.strip().split(" ")
return ((len(splitted) >= 2) and
(splitted[0].upper() == splitted[0]) and
(splitted[1].upper() == splitted[1]))
@property
def code(self):
if self.hasCode():
return self.title.strip().split(" ")[1].strip()
return False
@property
def books(self):
if self.dept and self.code:
return textbookInfo(self.dept, self.code, withPrices=True)
return False
@total_ordering
class Section(dict):
def __init__(self, time, loc, prof, sem):
self.time = time.encode("UTF-8")
self.loc = loc.encode("UTF-8")
self.prof = prof.encode("UTF-8")
self._sem = sem.encode("UTF-8")
self._date = False
self._day = False
@property
def sem(self):
if self._sem == fall:
return "Fall"
elif self._sem == winter:
return "Winter"
else:
return "Spring/Summer"
@property
def date(self):
if self.time != "TBA":
day, start, _, end = self.time.split()
if self._day:
assert len(self._day) == 2
day = self._day
else:
day = [day[n:n+2] for n in range(0, len(day)-1, 2)]
self._date = (day, timeparse(start), timeparse(end))
return self._date
return self.time
@property
def day(self):
return self.date[0]
@property
def start(self):
return self.date[1][0] + self.date[1][1]
def __repr__(self):
return ("""
Time = %s, Location = %s, Instructor = %s, Semester Running = %s
""" % (self.date, self.loc, self.prof, self.sem))
def __gt__(self, x):
if isinstance(self.day, list):
raise NotImplementedError
if (self.date == "TBA" or
x.date == "TBA"):
return False
return ((days[self.day] > days[x.day]) or
((self.day == x.day) and
(self.start > x.start)))
def __eq__(self, x):
return (x.date == self.date and
x.prof == self.prof and
x.loc == self.loc and
x.sem == self.sem)
def getStateNum(html):
"""
Get the state num from Mosaic
This is unique to each requester
"""
parsed = lxh.fromstring(html)
return parsed.xpath(".//input[@name=\"ICStateNum\"]")[0].value
def parseSection(section):
cols = section.xpath(".//td")
assert len(cols) == 4
time, loc, prof, sem = [col.text_content().encode("UTF-8").strip() for col in cols]
classinfo = Section(time, loc, prof, sem)
return classinfo
def getSectionInfo(table):
trs = table.xpath(".//tr")
for tr in trs:
if tr.xpath("@id") and search(r"SSR_CLSRCH", tr.xpath("@id")[0]):
yield parseSection(tr)
def parseColumns(subject, html):
parsed = lxh.fromstring(html)
classInfo = (list(getSectionInfo(table)) for table in
islice((table for table in parsed.xpath(".//table")
if table.xpath("@id") and
search(r"ICField[0-9]+\$scroll", table.xpath("@id")[0])), 1, sys.maxsize))
classNames = ((subject, span.text_content().strip()) for span in parsed.xpath(".//span")
if span.xpath("@id") and
search(r"DERIVED_CLSRCH_DESCR", span.xpath("@id")[0]))
return list(zip(classNames, classInfo))
def getCodes(html):
parsed = lxh.fromstring(html)
return (code.text_content().encode("UTF-8") for code in
parsed.xpath("//span")
if code.xpath("@id") and
search(r"SSR_CLSRCH_SUBJ_SUBJECT\$[0-9]+", code.xpath("@id")[0]))
class MosReq(object):
def __init__(self, semester):
self.semester = semester
s = requests.Session()
resp = s.get(baseurl, allow_redirects=True, headers=custom_headers).content
# Let the server set some cookies before doing the searching
cookies = {}
for key, val in s.cookies.items():
cookies[key] = val
self.cookies = cookies
self.statenum = False
self.codes_ = []
def getlist(self, subject):
sys.stderr.write("Getting %s\n" % subject.decode("UTF-8"))
first_req = requests.get(searchurl, cookies=self.cookies)
# for some reason Mosaic wants us to request it twice, ??????????????????
self.statenum = getStateNum(first_req.content)
first_req = requests.post(searchurl,
data=payload.format(self.statenum, subject, self.semester),
cookies=self.cookies,
allow_redirects=False,
headers=custom_headers)
print("HEADERS")
print(first_req.request.headers)
# we make a first request to get the ICStateNum in case it thinks there are too many results
try:
self.statenum = getStateNum(first_req.content)
except IndexError:
pass
if b"Your search will return over" in first_req:
return requests.post(searchurl,
data=payload2.format(self.statenum, self.semester),
cookies=self.cookies,
allow_redirects=False,
headers=custom_headers).content
else:
return first_req
def classes(self, subject):
return list(parseColumns(subject, self.getlist(subject)))
def getCodes(self, letter):
sys.stderr.write("Getting letter " + letter + "\n")
first_req = requests.get(searchurl, cookies=self.cookies).content
self.statenum = getStateNum(first_req)
self.statenum = getStateNum(requests.post(searchurl,
data=courseCodes1.format(self.statenum, self.semester),
cookies=self.cookies,
headers=custom_headers).content)
return getCodes(requests.post(searchurl,
data=courseCodes2.format(self.statenum, letter, self.semester),
cookies=self.cookies,
allow_redirects=False,
headers=custom_headers).content)
@property
def codes(self):
if not self.codes_:
self.codes_ = list(chain.from_iterable(
list(map((lambda l:
self.getCodes(chr(l))),
range(65, 91)))))
return self.codes_
def request(codes, lists, semester):
requester = MosReq(semester)
while not codes.empty():
code = codes.get()
lists.put(requester.classes(code))
codes.task_done()
class CourseInfo(object):
def __init__(self, threadcount, semester):
self._codes = False
self.threadcount = threadcount
self.semester = semester
@property
def codes(self):
if not self._codes:
req = MosReq(self.semester)
self._codes = req.codes
return self._codes
def classes(self):
qcodes = q.Queue()
for code in self.codes:
qcodes.put(code)
lists = q.Queue()
threads = []
thread = None
for i in range(self.threadcount):
thread = thd.Thread(group=None, target=request, args=(qcodes, lists, self.semester))
threads.append(thread)
thread.start()
qcodes.join()
for t in threads:
t.join()
sections = []
while not lists.empty():
sections.append(lists.get())
for cl in chain.from_iterable(sections):
new_sections = []
for sec in cl[1]:
print(sec)
if len(sec.day) > 1:
for day in sec.day:
new_sections.append(copy.deepcopy(sec))
new_sections[-1]._day = day
else:
sec._day = sec.day[0]
new_sections.append(sec)
yield Class(cl[0][0], sub("\xa0+", "", cl[0][1]), sorted(new_sections))
def getCourses(semester, threadcount=10):
return CourseInfo(threadcount, semester).classes()
def allCourses():
return chain.from_iterable(
(getCourses(sem, threadcount=25)
for sem in (fall, winter, spring_summer)))
if __name__ == "__main__":
for course in allCourses():
sys.stdout.write("%s, %s, %s, %s\n" % (course.title, course.code, course.dept, list(chain.from_iterable(course.books) if course.books else [])))
print(course.sections)

50
src/mcmaster/errors2.log

@ -0,0 +1,50 @@
HEADERS
{'Content-Length': '417', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=xduoMvTAUgA7lPvyWdZde0Bl7Byb_2J1!-1839177281; PS_TOKEN=qQAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABRFKduLPmKmYqWIluxqMZGQ1zdhnWkAAAAFAFNkYXRhXXicHYlLDkBAEAVrEEsHcAfiM4ilyLAiEqznIK7mcJ7pRdWr9AMkcWSM/EaEyzdmNjynPMsrN051kTp2ZXaoFrXnYMI2VNT0FGItNgxht5R0chn+P3ssYzAfZUENsw==; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femployee%2fempl%2frefresh=list: %3ftab%3dmcm_tab_app_signin|%3frp%3dmcm_tab_app_signin|%3ftab%3dmcm_tab_app_signin_grad|%3frp%3dmcm_tab_app_signin_grad|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; PS_LOGINLIST=https://csprd.mcmaster.ca/prcsprd https://applicants.mcmaster.ca/prepprd; csprd-8000-PORTAL-PSJSESSIONID=TQB9Y7xGbS1LTKr8MFWz2rlv59g1BnP8!531660376; PS_TOKENEXPIRE=27_Nov_2016_23:51:03_GMT; SignOnDefault=MCM_SCC_GUEST; NSC_qh-dtqseqjb=ffffffffaf122a9d45525d5f4f58455e445a4a422970; ps_theme=node:EMPL portal:EMPLOYEE theme_id:MCM_GUEST_THEME css:MCM_PT_BRAND_CLASSIC_FLUID css_f:PT_BRAND_FLUID_TEMPLATE accessibility:A macroset:MCM_MYMAC_THEME formfactor:3 piamode:2; https%3a%2f%2fcsprd.mcmaster.ca%2fpsp%2fprcsprd%2femployee%2fhrms%2frefresh=list: %3ftab%3ddefault|%3frp%3ddefault|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; NSC_qh-fqqsebqqmjdbout=ffffffffaf122b9d45525d5f4f58455e445a4a422970', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
HEADERS
{'Content-Length': '417', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=BOuoMvUPHqPy0LjXeW8EBpO7BlbM-MKl!-1839177281; PS_TOKEN=qgAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABR+G9/wkfk8H4KY3xx0dTtEoQj4bGoAAAAFAFNkYXRhXnicHYlNDkAwGESfEksHcAeN+l2LYFVpgnUP4moOZ9JvMW/efC9Q5CbLxM+QrvaseCKXuIoHD5vsptw4pVWQ7fJIYGHoaHFMNEqn7JhT77GMok1/q32Sj9od/GVIDbA=; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femployee%2fempl%2frefresh=list: %3ftab%3dmcm_tab_app_signin|%3frp%3dmcm_tab_app_signin|%3ftab%3dmcm_tab_app_signin_grad|%3frp%3dmcm_tab_app_signin_grad|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; PS_LOGINLIST=https://csprd.mcmaster.ca/prcsprd https://applicants.mcmaster.ca/prepprd; csprd-8000-PORTAL-PSJSESSIONID=4MpRY7xGyQtLtLZwQYGyXrV1fdcHjX5m!-1080248884; PS_TOKENEXPIRE=27_Nov_2016_23:51:03_GMT; SignOnDefault=MCM_SCC_GUEST; NSC_qh-dtqseqjb=ffffffffaf122a9e45525d5f4f58455e445a4a422970; ps_theme=node:EMPL portal:EMPLOYEE theme_id:MCM_GUEST_THEME css:MCM_PT_BRAND_CLASSIC_FLUID css_f:PT_BRAND_FLUID_TEMPLATE accessibility:A macroset:MCM_MYMAC_THEME formfactor:3 piamode:2; https%3a%2f%2fcsprd.mcmaster.ca%2fpsp%2fprcsprd%2femployee%2fhrms%2frefresh=list: %3ftab%3ddefault|%3frp%3ddefault|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; NSC_qh-fqqsebqqmjdbout=ffffffffaf122b9d45525d5f4f58455e445a4a422970', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
HEADERS
{'Content-Length': '421', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=pI-oMvS9Ibt75xltbVqBUWjlnCJGoKDc!1679552918; PS_TOKEN=qwAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABSJfBd8pFfkOh5f2FAvW/R9aC3TMGsAAAAFAFNkYXRhX3icHYnLCYAwFATHDx4twB4Mxr9HEfUUCahnC7E1i3PJg7ezw75AmsRRJH4x4QrHguPhFBdx52aVXWQrhzT3sk3+4JlpayosPaXSKmuG0BsMnWjCbhiZtDX6CX5loQ27; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femployee%2fempl%2frefresh=list: %3ftab%3dmcm_tab_app_signin|%3frp%3dmcm_tab_app_signin|%3ftab%3dmcm_tab_app_signin_grad|%3frp%3dmcm_tab_app_signin_grad|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; PS_LOGINLIST=https://csprd.mcmaster.ca/prcsprd https://applicants.mcmaster.ca/prepprd; csprd-8000-PORTAL-PSJSESSIONID=1pQvY7xG7S59yPhLGcLcBdvtDppTnBl7!297042307; PS_TOKENEXPIRE=27_Nov_2016_23:51:03_GMT; SignOnDefault=MCM_SCC_GUEST; NSC_qh-dtqseqjb=ffffffffaf122a9f45525d5f4f58455e445a4a422970; ps_theme=node:EMPL portal:EMPLOYEE theme_id:MCM_GUEST_THEME css:MCM_PT_BRAND_CLASSIC_FLUID css_f:PT_BRAND_FLUID_TEMPLATE accessibility:A macroset:MCM_MYMAC_THEME formfactor:3 piamode:2; https%3a%2f%2fcsprd.mcmaster.ca%2fpsp%2fprcsprd%2femployee%2fhrms%2frefresh=list: %3ftab%3ddefault|%3frp%3ddefault|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; NSC_qh-fqqsebqqmjdbout=ffffffffaf122b9c45525d5f4f58455e445a4a422970', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
HEADERS
{'Content-Length': '417', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=jV2oMvScU3Ws7kM6WGcit63w2-bZLD1d!1679552918; PS_TOKEN=rQAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABSEs++BTGGPtSKM/EQIIoWVaIt6Qm0AAAAFAFNkYXRhYXicHYq5DYAwEASHR4QUQA9YPOZJkWWIQEhA7EJojeJY+YKdm7t9gTxLk0T8UuJUO46dwCU6cePBy24KzyEtT9kqD5ws2I6GlpFa2So7prj3GAbRxL/Rdcaq18v5AWWaDbY=; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femployee%2fempl%2frefresh=list: %3ftab%3dmcm_tab_app_signin|%3frp%3dmcm_tab_app_signin|%3ftab%3dmcm_tab_app_signin_grad|%3frp%3dmcm_tab_app_signin_grad|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; PS_LOGINLIST=https://csprd.mcmaster.ca/prcsprd https://applicants.mcmaster.ca/prepprd; csprd-8000-PORTAL-PSJSESSIONID=TJgVY7xGRD9zHB3vhLdnfTLCLpy230pH!-1080248884; PS_TOKENEXPIRE=27_Nov_2016_23:51:02_GMT; SignOnDefault=MCM_SCC_GUEST; NSC_qh-dtqseqjb=ffffffffaf122a9e45525d5f4f58455e445a4a422970; ps_theme=node:EMPL portal:EMPLOYEE theme_id:MCM_GUEST_THEME css:MCM_PT_BRAND_CLASSIC_FLUID css_f:PT_BRAND_FLUID_TEMPLATE accessibility:A macroset:MCM_MYMAC_THEME formfactor:3 piamode:2; https%3a%2f%2fcsprd.mcmaster.ca%2fpsp%2fprcsprd%2femployee%2fhrms%2frefresh=list: %3ftab%3ddefault|%3frp%3ddefault|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; NSC_qh-fqqsebqqmjdbout=ffffffffaf122b9c45525d5f4f58455e445a4a422970', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
HEADERS
{'Content-Length': '417', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=hoeoMvSJRaBLJZ2VDW48XWM5SypNEgTf!-1839177281; PS_TOKEN=qwAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABTDtIThLzRoGTByZlNKVU2PPpb6GmsAAAAFAFNkYXRhX3icHYpLDkBAEAXLEEsHcAdiZnzWIlgRCdZzEFdzOM90J6+60u8BstQkifga4pQbExuBU5zElZtZdpHP7NLikC3ywMFI62iw9FRKq3QM8fbUdGId/3/+Ta+18AFkxw2j; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femployee%2fempl%2frefresh=list: %3ftab%3dmcm_tab_app_signin|%3frp%3dmcm_tab_app_signin|%3ftab%3dmcm_tab_app_signin_grad|%3frp%3dmcm_tab_app_signin_grad|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; PS_LOGINLIST=https://csprd.mcmaster.ca/prcsprd https://applicants.mcmaster.ca/prepprd; csprd-8000-PORTAL-PSJSESSIONID=FfK8Y7xGlm0n5hD839tGFHNnZWMyHx9w!-675472577; PS_TOKENEXPIRE=27_Nov_2016_23:51:03_GMT; SignOnDefault=MCM_SCC_GUEST; NSC_qh-dtqseqjb=ffffffffaf122a9845525d5f4f58455e445a4a422970; ps_theme=node:EMPL portal:EMPLOYEE theme_id:MCM_GUEST_THEME css:MCM_PT_BRAND_CLASSIC_FLUID css_f:PT_BRAND_FLUID_TEMPLATE accessibility:A macroset:MCM_MYMAC_THEME formfactor:3 piamode:2; https%3a%2f%2fcsprd.mcmaster.ca%2fpsp%2fprcsprd%2femployee%2fhrms%2frefresh=list: %3ftab%3ddefault|%3frp%3ddefault|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; NSC_qh-fqqsebqqmjdbout=ffffffffaf122b9d45525d5f4f58455e445a4a422970', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
HEADERS
{'Content-Length': '421', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=QQWoMvVfAvglhWPIjZUDw95oEOEv1EhY!-1839177281; PS_TOKEN=qgAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABTl9T9nndclvjWPRHx4ZuAf6kvLJWoAAAAFAFNkYXRhXnicHYlNDkAwGERfSywdwB00foq1SFkRCdY9iKs5nEm/SebNy/cCeWaNET9LumpnYSdyiYu48RBkN0XgkJanbJVHTmZ8R0PLSK1u1R1T2j2OQXTp7+QTXssr/GVJDbE=; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femployee%2fempl%2frefresh=list: %3ftab%3dmcm_tab_app_signin|%3frp%3dmcm_tab_app_signin|%3ftab%3dmcm_tab_app_signin_grad|%3frp%3dmcm_tab_app_signin_grad|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; PS_LOGINLIST=https://csprd.mcmaster.ca/prcsprd https://applicants.mcmaster.ca/prepprd; csprd-8000-PORTAL-PSJSESSIONID=mZNvY7xGdZ6VGqYc4r2lYLnnLknXdQ40!-1851985177; PS_TOKENEXPIRE=27_Nov_2016_23:51:03_GMT; SignOnDefault=MCM_SCC_GUEST; NSC_qh-dtqseqjb=ffffffffaf122a9a45525d5f4f58455e445a4a422970; ps_theme=node:EMPL portal:EMPLOYEE theme_id:MCM_GUEST_THEME css:MCM_PT_BRAND_CLASSIC_FLUID css_f:PT_BRAND_FLUID_TEMPLATE accessibility:A macroset:MCM_MYMAC_THEME formfactor:3 piamode:2; https%3a%2f%2fcsprd.mcmaster.ca%2fpsp%2fprcsprd%2femployee%2fhrms%2frefresh=list: %3ftab%3ddefault|%3frp%3ddefault|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; NSC_qh-fqqsebqqmjdbout=ffffffffaf122b9d45525d5f4f58455e445a4a422970', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
HEADERS
{'Content-Length': '419', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=_omoMvSQwLtwMWWynzPs-6hVel8NRvKU!-1839177281; PS_TOKEN=qwAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABSx+qh8pW4t7OK6WrrPKzvXfzSoK2sAAAAFAFNkYXRhX3icHYlLDkBAFARrEEsHcAcTY3xiKYLViARrB3E1h9OZl3RXV94LZGlijPglxCsDM4GHU5zFjZtFdpEv7NLikK3yh4OJtqHG0VOpnbphiNtj6UQb/5aWUekVDz9ljA24; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femployee%2fempl%2frefresh=list: %3ftab%3dmcm_tab_app_signin|%3frp%3dmcm_tab_app_signin|%3ftab%3dmcm_tab_app_signin_grad|%3frp%3dmcm_tab_app_signin_grad|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; PS_LOGINLIST=https://csprd.mcmaster.ca/prcsprd https://applicants.mcmaster.ca/prepprd; csprd-8000-PORTAL-PSJSESSIONID=Cq2cY7xGdnctTZwD3PpF2Y9jpwCvnp08!-1344051968; PS_TOKENEXPIRE=27_Nov_2016_23:51:03_GMT; SignOnDefault=MCM_SCC_GUEST; NSC_qh-dtqseqjb=ffffffffaf122a9b45525d5f4f58455e445a4a422970; ps_theme=node:EMPL portal:EMPLOYEE theme_id:MCM_GUEST_THEME css:MCM_PT_BRAND_CLASSIC_FLUID css_f:PT_BRAND_FLUID_TEMPLATE accessibility:A macroset:MCM_MYMAC_THEME formfactor:3 piamode:2; https%3a%2f%2fcsprd.mcmaster.ca%2fpsp%2fprcsprd%2femployee%2fhrms%2frefresh=list: %3ftab%3ddefault|%3frp%3ddefault|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; NSC_qh-fqqsebqqmjdbout=ffffffffaf122b9d45525d5f4f58455e445a4a422970', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
HEADERS
{'Content-Length': '419', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=gceoMvTxE85prx6BpYYAnZTiatNw1_RI!1679552918; PS_TOKEN=qwAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABSbiEEKOKJeKHPsaJaPfR8vaJkkM2sAAAAFAFNkYXRhX3icHYlLDkBAEAXLJ5YO4A4mxjeWMhlWRIK1g7iaw3mmk37V1e8B0iSOIvGNCVOsOFZuDtGJCxdedpJ5Nmm+y2b5zc5EW1Nh6SmVVlkzhLvB0Ikm9H+O+vVaCx9lRA2w; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femployee%2fempl%2frefresh=list: %3ftab%3dmcm_tab_app_signin|%3frp%3dmcm_tab_app_signin|%3ftab%3dmcm_tab_app_signin_grad|%3frp%3dmcm_tab_app_signin_grad|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; PS_LOGINLIST=https://csprd.mcmaster.ca/prcsprd https://applicants.mcmaster.ca/prepprd; csprd-8000-PORTAL-PSJSESSIONID=29PQY7xGg9rWjWqkQGxJHCQgzQHFvRNc!-1851985177; PS_TOKENEXPIRE=27_Nov_2016_23:51:03_GMT; SignOnDefault=MCM_SCC_GUEST; NSC_qh-dtqseqjb=ffffffffaf122a9a45525d5f4f58455e445a4a422970; ps_theme=node:EMPL portal:EMPLOYEE theme_id:MCM_GUEST_THEME css:MCM_PT_BRAND_CLASSIC_FLUID css_f:PT_BRAND_FLUID_TEMPLATE accessibility:A macroset:MCM_MYMAC_THEME formfactor:3 piamode:2; https%3a%2f%2fcsprd.mcmaster.ca%2fpsp%2fprcsprd%2femployee%2fhrms%2frefresh=list: %3ftab%3ddefault|%3frp%3ddefault|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; NSC_qh-fqqsebqqmjdbout=ffffffffaf122b9c45525d5f4f58455e445a4a422970', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
HEADERS
{'Content-Length': '420', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=gCmoMvWIaXees8rdh9lNpisMOaQTe-5e!-1839177281; PS_TOKEN=rAAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABRj9LO046eWZkTNPbuNg1rEAbN1vGwAAAAFAFNkYXRhYHicHYpLDkBAEAVrEEsHcAcTnxnWIliNSLCeg7iaw3mZXrzq6n4vUOSZMeKXkaYOLAQil7iIOw+r7KZcOaTVKdvkkZMZ19PSMdIoO2XPlPYBixdt+luc6HTxavADZSQNrg==; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femployee%2fempl%2frefresh=list: %3ftab%3dmcm_tab_app_signin|%3frp%3dmcm_tab_app_signin|%3ftab%3dmcm_tab_app_signin_grad|%3frp%3dmcm_tab_app_signin_grad|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; PS_LOGINLIST=https://csprd.mcmaster.ca/prcsprd https://applicants.mcmaster.ca/prepprd; csprd-8000-PORTAL-PSJSESSIONID=0fHwY7xGQZZNwCmQ26yDYFTGyFRNz7tF!-1080248884; PS_TOKENEXPIRE=27_Nov_2016_23:51:03_GMT; SignOnDefault=MCM_SCC_GUEST; NSC_qh-dtqseqjb=ffffffffaf122a9e45525d5f4f58455e445a4a422970; ps_theme=node:EMPL portal:EMPLOYEE theme_id:MCM_GUEST_THEME css:MCM_PT_BRAND_CLASSIC_FLUID css_f:PT_BRAND_FLUID_TEMPLATE accessibility:A macroset:MCM_MYMAC_THEME formfactor:3 piamode:2; https%3a%2f%2fcsprd.mcmaster.ca%2fpsp%2fprcsprd%2femployee%2fhrms%2frefresh=list: %3ftab%3ddefault|%3frp%3ddefault|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; NSC_qh-fqqsebqqmjdbout=ffffffffaf122b9d45525d5f4f58455e445a4a422970', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
HEADERS
HEADERS{'Content-Length': '417', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=3XeoMvS0I0AKjt9hNR0h_Q2PCkOPSBBm!1679552918; PS_TOKEN=qwAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABRDtHDfWEeGAgRMXPyCiu/HBPzg/msAAAAFAFNkYXRhX3icHYpLDkBAFARrEEsHcAcT4zNsRbAiEqwdxNUcTpu36OpKvwdI4sgY8Y0Il6+MrNwc4iguXEyyk3Rik2a7bJbf7Aw0FSUOT6F0yoou9BpLK9qwW/4/r83TwwdlQQ23; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femployee%2fempl%2frefresh=list: %3ftab%3dmcm_tab_app_signin|%3frp%3dmcm_tab_app_signin|%3ftab%3dmcm_tab_app_signin_grad|%3frp%3dmcm_tab_app_signin_grad|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; PS_LOGINLIST=https://csprd.mcmaster.ca/prcsprd https://applicants.mcmaster.ca/prepprd; csprd-8000-PORTAL-PSJSESSIONID=BhddY7xGwRSt5TJWBVghBCGjlF1qQJrP!-1851985177; PS_TOKENEXPIRE=27_Nov_2016_23:51:02_GMT; SignOnDefault=MCM_SCC_GUEST; NSC_qh-dtqseqjb=ffffffffaf122a9a45525d5f4f58455e445a4a422970; ps_theme=node:EMPL portal:EMPLOYEE theme_id:MCM_GUEST_THEME css:MCM_PT_BRAND_CLASSIC_FLUID css_f:PT_BRAND_FLUID_TEMPLATE accessibility:A macroset:MCM_MYMAC_THEME formfactor:3 piamode:2; https%3a%2f%2fcsprd.mcmaster.ca%2fpsp%2fprcsprd%2femployee%2fhrms%2frefresh=list: %3ftab%3ddefault|%3frp%3ddefault|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; NSC_qh-fqqsebqqmjdbout=ffffffffaf122b9c45525d5f4f58455e445a4a422970', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
{'Content-Length': '421', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=8YqoMvT2-wgensT2w3mjTLx9pq8bkKy0!-1839177281; PS_TOKEN=rAAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABSWnSi7Ra5yxsbhpo/RDNRZubdtkmwAAAAFAFNkYXRhYHicHYpLDkBAEAVrEEsHcAfiMz5bkWFFJFjPQVzN4TzTnbx6le4HSOLIGPGNCJNvzGx4TnEWV26c7CJ17NLskC1yz8GEbaio6SmUtbJhCL2lpBPLcP+7ZdT2+uADZZsNuw==; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femployee%2fempl%2frefresh=list: %3ftab%3dmcm_tab_app_signin|%3frp%3dmcm_tab_app_signin|%3ftab%3dmcm_tab_app_signin_grad|%3frp%3dmcm_tab_app_signin_grad|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; PS_LOGINLIST=https://csprd.mcmaster.ca/prcsprd https://applicants.mcmaster.ca/prepprd; csprd-8000-PORTAL-PSJSESSIONID=0cL7Y7xGnLvvQm2jbBz2wSdQNsp2ZrbG!297042307; PS_TOKENEXPIRE=27_Nov_2016_23:51:03_GMT; SignOnDefault=MCM_SCC_GUEST; NSC_qh-dtqseqjb=ffffffffaf122a9f45525d5f4f58455e445a4a422970; ps_theme=node:EMPL portal:EMPLOYEE theme_id:MCM_GUEST_THEME css:MCM_PT_BRAND_CLASSIC_FLUID css_f:PT_BRAND_FLUID_TEMPLATE accessibility:A macroset:MCM_MYMAC_THEME formfactor:3 piamode:2; https%3a%2f%2fcsprd.mcmaster.ca%2fpsp%2fprcsprd%2femployee%2fhrms%2frefresh=list: %3ftab%3ddefault|%3frp%3ddefault|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; NSC_qh-fqqsebqqmjdbout=ffffffffaf122b9d45525d5f4f58455e445a4a422970', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
HEADERS
{'Content-Length': '420', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=4SGoMvWvMuwQfAEVstSjqs6EEje5G_bD!1679552918; PS_TOKEN=qwAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABQ9RowUj9KFjDdjF4lHANVZ4kQxhGsAAAAFAFNkYXRhX3icHYpNDkAwGERfEUsHcAeNqp+1CFYVCdY9iKs5nEm/xbx5me8FijwzRvwy0tWBhUDkEhdx52GV3ZQrh7Q6ZZs8cjLTd7Q4RhqlU3ZMqXssg2jTbun147R6NX5lMg2u; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femployee%2fempl%2frefresh=list: %3ftab%3dmcm_tab_app_signin|%3frp%3dmcm_tab_app_signin|%3ftab%3dmcm_tab_app_signin_grad|%3frp%3dmcm_tab_app_signin_grad|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; PS_LOGINLIST=https://csprd.mcmaster.ca/prcsprd https://applicants.mcmaster.ca/prepprd; csprd-8000-PORTAL-PSJSESSIONID=pBJlY7xG6hhjMLLPcDzTmq0f8YHJ5Tqp!-1851985177; PS_TOKENEXPIRE=27_Nov_2016_23:51:03_GMT; SignOnDefault=MCM_SCC_GUEST; NSC_qh-dtqseqjb=ffffffffaf122a9a45525d5f4f58455e445a4a422970; ps_theme=node:EMPL portal:EMPLOYEE theme_id:MCM_GUEST_THEME css:MCM_PT_BRAND_CLASSIC_FLUID css_f:PT_BRAND_FLUID_TEMPLATE accessibility:A macroset:MCM_MYMAC_THEME formfactor:3 piamode:2; https%3a%2f%2fcsprd.mcmaster.ca%2fpsp%2fprcsprd%2femployee%2fhrms%2frefresh=list: %3ftab%3ddefault|%3frp%3ddefault|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; NSC_qh-fqqsebqqmjdbout=ffffffffaf122b9c45525d5f4f58455e445a4a422970', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
HEADERS
{'Content-Length': '417', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=3DOoMvW4Svql1cvvIsMyS0Qp6VSQPqDe!-1839177281; PS_TOKEN=rAAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABSABEDPRcVjlM5XzKI1YIBxKI6JFmwAAAAFAFNkYXRhYHicHYpLDkBAEAVrEEsHcAcT4ze2IliNSLB2EFdzOC/Ti1dd3e8FsjQxRvwS4pSBmcDDKc7ixs0iu8gXdmlxyFb5w8FE11DjGKiUTtng495i6UUb/5ZRF6+ek/MDZYENsw==; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femployee%2fempl%2frefresh=list: %3ftab%3dmcm_tab_app_signin|%3frp%3dmcm_tab_app_signin|%3ftab%3dmcm_tab_app_signin_grad|%3frp%3dmcm_tab_app_signin_grad|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; PS_LOGINLIST=https://csprd.mcmaster.ca/prcsprd https://applicants.mcmaster.ca/prepprd; csprd-8000-PORTAL-PSJSESSIONID=PlsxY7xHz9QWS1x2BfdWVqWjmKB2GJQX!297042307; PS_TOKENEXPIRE=27_Nov_2016_23:51:03_GMT; SignOnDefault=MCM_SCC_GUEST; NSC_qh-dtqseqjb=ffffffffaf122a9f45525d5f4f58455e445a4a422970; ps_theme=node:EMPL portal:EMPLOYEE theme_id:MCM_GUEST_THEME css:MCM_PT_BRAND_CLASSIC_FLUID css_f:PT_BRAND_FLUID_TEMPLATE accessibility:A macroset:MCM_MYMAC_THEME formfactor:3 piamode:2; https%3a%2f%2fcsprd.mcmaster.ca%2fpsp%2fprcsprd%2femployee%2fhrms%2frefresh=list: %3ftab%3ddefault|%3frp%3ddefault|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; NSC_qh-fqqsebqqmjdbout=ffffffffaf122b9d45525d5f4f58455e445a4a422970', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
HEADERS
{'Content-Length': '422', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=wyqoMvWWYIdoyv_pTEdtWBQBxwKw9Iby!1679552918; PS_TOKEN=qwAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABRKfxHYuCPVPwlU0rlic94pvJ13h2sAAAAFAFNkYXRhX3icHYlLDkBAFATLJ5YO4A4mjEEsRbAik2A9B3E1h9OZTl7Xq/QL5FmaJOKXElMdLBwELnERdx5W2U2xckpLL9vkAc+MszS0DNTqVm0Z499h6EUTd8Mkc7pRxg9low25; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femployee%2fempl%2frefresh=list: %3ftab%3dmcm_tab_app_signin|%3frp%3dmcm_tab_app_signin|%3ftab%3dmcm_tab_app_signin_grad|%3frp%3dmcm_tab_app_signin_grad|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; PS_LOGINLIST=https://csprd.mcmaster.ca/prcsprd https://applicants.mcmaster.ca/prepprd; csprd-8000-PORTAL-PSJSESSIONID=bB1MY7xGnNXqyhzyDb6M0ypCg310SvJZ!-675472577; PS_TOKENEXPIRE=27_Nov_2016_23:51:03_GMT; SignOnDefault=MCM_SCC_GUEST; NSC_qh-dtqseqjb=ffffffffaf122a9845525d5f4f58455e445a4a422970; ps_theme=node:EMPL portal:EMPLOYEE theme_id:MCM_GUEST_THEME css:MCM_PT_BRAND_CLASSIC_FLUID css_f:PT_BRAND_FLUID_TEMPLATE accessibility:A macroset:MCM_MYMAC_THEME formfactor:3 piamode:2; https%3a%2f%2fcsprd.mcmaster.ca%2fpsp%2fprcsprd%2femployee%2fhrms%2frefresh=list: %3ftab%3ddefault|%3frp%3ddefault|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; NSC_qh-fqqsebqqmjdbout=ffffffffaf122b9c45525d5f4f58455e445a4a422970', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
HEADERS
{'Content-Length': '420', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=uneoMvTqjh7TWpenIofy6ckoE-o_AOCl!1679552918; PS_TOKEN=rAAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABSLxDKrAQnoDTukMVG+LDouZRlMoWwAAAAFAFNkYXRhYHicHYpLDkBAEAVrEEsHcAcT4zPWIliNSLCeg7iaw3mZXrzq6tcvUOSZMeKXkaYOLAQil7iIOw+r7KZcOaTVKdvkkZOZoaPF4WmUTtkxpb3HMoo29VYfXt2gm4cfZXMNtw==; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femployee%2fempl%2frefresh=list: %3ftab%3dmcm_tab_app_signin|%3frp%3dmcm_tab_app_signin|%3ftab%3dmcm_tab_app_signin_grad|%3frp%3dmcm_tab_app_signin_grad|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; PS_LOGINLIST=https://csprd.mcmaster.ca/prcsprd https://applicants.mcmaster.ca/prepprd; csprd-8000-PORTAL-PSJSESSIONID=RnYkY7xG2ppJhDZh62ys5KR9hKynG0xM!297042307; PS_TOKENEXPIRE=27_Nov_2016_23:51:03_GMT; SignOnDefault=MCM_SCC_GUEST; NSC_qh-dtqseqjb=ffffffffaf122a9f45525d5f4f58455e445a4a422970; ps_theme=node:EMPL portal:EMPLOYEE theme_id:MCM_GUEST_THEME css:MCM_PT_BRAND_CLASSIC_FLUID css_f:PT_BRAND_FLUID_TEMPLATE accessibility:A macroset:MCM_MYMAC_THEME formfactor:3 piamode:2; https%3a%2f%2fcsprd.mcmaster.ca%2fpsp%2fprcsprd%2femployee%2fhrms%2frefresh=list: %3ftab%3ddefault|%3frp%3ddefault|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; NSC_qh-fqqsebqqmjdbout=ffffffffaf122b9c45525d5f4f58455e445a4a422970', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
HEADERS
{'Content-Length': '421', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=UtWoMvWZC5Vy2ATqPc1he_e5_fE_8J07!-1839177281; PS_TOKEN=qwAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABQKe6x0IQngm7QjAaGw6iNX3qL86GsAAAAFAFNkYXRhX3icHYlLDkBAFARrEEsHcAcT428pgtWIBGsHcTWH05m36Orq9wJJHBkjfhHhcs+M5+EUZ3HjZpFdpAu7NDtkq/zhYKKpKHF0FEqnrOhDr7G0og1/q9XRMGof4Adleg26; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femployee%2fempl%2frefresh=list: %3ftab%3dmcm_tab_app_signin|%3frp%3dmcm_tab_app_signin|%3ftab%3dmcm_tab_app_signin_grad|%3frp%3dmcm_tab_app_signin_grad|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; PS_LOGINLIST=https://csprd.mcmaster.ca/prcsprd https://applicants.mcmaster.ca/prepprd; csprd-8000-PORTAL-PSJSESSIONID=pHXyY7xGggytCgKhPnBGrQngdKn4qGrH!531660376; PS_TOKENEXPIRE=27_Nov_2016_23:51:03_GMT; SignOnDefault=MCM_SCC_GUEST; NSC_qh-dtqseqjb=ffffffffaf122a9d45525d5f4f58455e445a4a422970; ps_theme=node:EMPL portal:EMPLOYEE theme_id:MCM_GUEST_THEME css:MCM_PT_BRAND_CLASSIC_FLUID css_f:PT_BRAND_FLUID_TEMPLATE accessibility:A macroset:MCM_MYMAC_THEME formfactor:3 piamode:2; https%3a%2f%2fcsprd.mcmaster.ca%2fpsp%2fprcsprd%2femployee%2fhrms%2frefresh=list: %3ftab%3ddefault|%3frp%3ddefault|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; NSC_qh-fqqsebqqmjdbout=ffffffffaf122b9d45525d5f4f58455e445a4a422970', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
HEADERS
{'Content-Length': '421', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=heCoMvXvm18xDJecdbtltSUtmQOFTuxC!-1839177281; PS_TOKEN=qgAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABQsFcmHlYRGjE7GWPUaojnid3QsE2oAAAAFAFNkYXRhXnicHYlLDkAwAESfTywdwB001K9bacqKSLB2EFdzOJPOYt68zAvkWZok4pcSU214Nh5O0YsrN0F2UQR2aXnIFvnDwUxvaWgZqdWt2jLF3WEYRBN/g5M5bSvjB2V+DbI=; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femployee%2fempl%2frefresh=list: %3ftab%3dmcm_tab_app_signin|%3frp%3dmcm_tab_app_signin|%3ftab%3dmcm_tab_app_signin_grad|%3frp%3dmcm_tab_app_signin_grad|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; PS_LOGINLIST=https://csprd.mcmaster.ca/prcsprd https://applicants.mcmaster.ca/prepprd; csprd-8000-PORTAL-PSJSESSIONID=ytLNY7xHZds8wv4XzH7YyVJQ9dQgMY1M!297042307; PS_TOKENEXPIRE=27_Nov_2016_23:51:04_GMT; SignOnDefault=MCM_SCC_GUEST; NSC_qh-dtqseqjb=ffffffffaf122a9f45525d5f4f58455e445a4a422970; ps_theme=node:EMPL portal:EMPLOYEE theme_id:MCM_GUEST_THEME css:MCM_PT_BRAND_CLASSIC_FLUID css_f:PT_BRAND_FLUID_TEMPLATE accessibility:A macroset:MCM_MYMAC_THEME formfactor:3 piamode:2; https%3a%2f%2fcsprd.mcmaster.ca%2fpsp%2fprcsprd%2femployee%2fhrms%2frefresh=list: %3ftab%3ddefault|%3frp%3ddefault|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; NSC_qh-fqqsebqqmjdbout=ffffffffaf122b9d45525d5f4f58455e445a4a422970', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
HEADERS
{'Content-Length': '420', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=PiOoMvX6ULIMy5pdEo-GE64kHLrYkTYv!1679552918; PS_TOKEN=qwAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABS8curVc9Vwlkhg7XcswvKHbXV0E2sAAAAFAFNkYXRhX3icHYpLDkBAEAVrEEsHcAcT4xtLEaxGJFg7iKs5nGd68aqr+z1AEkfGiG9EmNwz4bk5xElcuZhlJ+nMJs122SK/2RlpKkocHYXSKSv6sNdYWtGGv9X9bzkGJR9lKw2z; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femployee%2fempl%2frefresh=list: %3ftab%3dmcm_tab_app_signin|%3frp%3dmcm_tab_app_signin|%3ftab%3dmcm_tab_app_signin_grad|%3frp%3dmcm_tab_app_signin_grad|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; PS_LOGINLIST=https://csprd.mcmaster.ca/prcsprd https://applicants.mcmaster.ca/prepprd; csprd-8000-PORTAL-PSJSESSIONID=TxmzY7xHXLR6PLmKLQh29McdXkz1Gn6s!-1344051968; PS_TOKENEXPIRE=27_Nov_2016_23:51:04_GMT; SignOnDefault=MCM_SCC_GUEST; NSC_qh-dtqseqjb=ffffffffaf122a9b45525d5f4f58455e445a4a422970; ps_theme=node:EMPL portal:EMPLOYEE theme_id:MCM_GUEST_THEME css:MCM_PT_BRAND_CLASSIC_FLUID css_f:PT_BRAND_FLUID_TEMPLATE accessibility:A macroset:MCM_MYMAC_THEME formfactor:3 piamode:2; https%3a%2f%2fcsprd.mcmaster.ca%2fpsp%2fprcsprd%2femployee%2fhrms%2frefresh=list: %3ftab%3ddefault|%3frp%3ddefault|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; NSC_qh-fqqsebqqmjdbout=ffffffffaf122b9c45525d5f4f58455e445a4a422970', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
HEADERS
{'Content-Length': '417', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=M66oMvXALSSBCkHVm10rmVhf23yBAAcA!-1839177281; PS_TOKEN=rAAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABSpw7fcCqgCK/lgv+nVx0KN5K6rRmwAAAAFAFNkYXRhYHicHYrLCYAwEAXHDx4twB4MGqM5i6gnJaCeU4itWZyPLOybHd6+QFnkWSZ+OWmag4WDyCUu4s7DKrupVk5pHWSbPBKYcZaOnolW2SstPt0DhlE0qTfaTo3Tp4cfZSUNsw==; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femployee%2fempl%2frefresh=list: %3ftab%3dmcm_tab_app_signin|%3frp%3dmcm_tab_app_signin|%3ftab%3dmcm_tab_app_signin_grad|%3frp%3dmcm_tab_app_signin_grad|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; PS_LOGINLIST=https://csprd.mcmaster.ca/prcsprd https://applicants.mcmaster.ca/prepprd; csprd-8000-PORTAL-PSJSESSIONID=p16CY7xHJmDJk1wHdp0D1mZXfycG2ywq!-1080248884; PS_TOKENEXPIRE=27_Nov_2016_23:51:03_GMT; SignOnDefault=MCM_SCC_GUEST; NSC_qh-dtqseqjb=ffffffffaf122a9e45525d5f4f58455e445a4a422970; ps_theme=node:EMPL portal:EMPLOYEE theme_id:MCM_GUEST_THEME css:MCM_PT_BRAND_CLASSIC_FLUID css_f:PT_BRAND_FLUID_TEMPLATE accessibility:A macroset:MCM_MYMAC_THEME formfactor:3 piamode:2; https%3a%2f%2fcsprd.mcmaster.ca%2fpsp%2fprcsprd%2femployee%2fhrms%2frefresh=list: %3ftab%3ddefault|%3frp%3ddefault|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; NSC_qh-fqqsebqqmjdbout=ffffffffaf122b9d45525d5f4f58455e445a4a422970', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
HEADERS
{'Content-Length': '421', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=BYmoMvXRMDuzDOMAb4P2iVhHeMP7GpKB!-1839177281; PS_TOKEN=qgAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABRUi8sAfMgDStjEKeHLUNZpoTISaWoAAAAFAFNkYXRhXnicHYlJDkBAAARrEEcP8AcT+3IUwYlIcJ6H+JrHadOHrq70A0RhYIz4BvikGxMbjlOcxJWbWXYRz+zS5JAtcsfBSF2SU9CSqQt1Sed3haURrf//neup6BngA2ViDbo=; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femployee%2fempl%2frefresh=list: %3ftab%3dmcm_tab_app_signin|%3frp%3dmcm_tab_app_signin|%3ftab%3dmcm_tab_app_signin_grad|%3frp%3dmcm_tab_app_signin_grad|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; PS_LOGINLIST=https://csprd.mcmaster.ca/prcsprd https://applicants.mcmaster.ca/prepprd; csprd-8000-PORTAL-PSJSESSIONID=cSJrY7xHcBkQznTyqQy0c41wlp9QDVHn!-675472577; PS_TOKENEXPIRE=27_Nov_2016_23:51:03_GMT; SignOnDefault=MCM_SCC_GUEST; NSC_qh-dtqseqjb=ffffffffaf122a9845525d5f4f58455e445a4a422970; ps_theme=node:EMPL portal:EMPLOYEE theme_id:MCM_GUEST_THEME css:MCM_PT_BRAND_CLASSIC_FLUID css_f:PT_BRAND_FLUID_TEMPLATE accessibility:A macroset:MCM_MYMAC_THEME formfactor:3 piamode:2; https%3a%2f%2fcsprd.mcmaster.ca%2fpsp%2fprcsprd%2femployee%2fhrms%2frefresh=list: %3ftab%3ddefault|%3frp%3ddefault|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; NSC_qh-fqqsebqqmjdbout=ffffffffaf122b9d45525d5f4f58455e445a4a422970', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
HEADERS
{'Content-Length': '422', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=OMioMvYQ4SFm-QcU8PEcNwa1sMyGgl5j!-1839177281; PS_TOKEN=qwAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABStyPfVuQPDDbFZj7C2hw3a53BiKmsAAAAFAFNkYXRhX3icHYlLDkBAFATLJ5YO4A4mZvyXMsGKSLB2EFdzOJ15i65X3S+QJnEUiV9MuGLDs/Fwil5cuZllF9nMLs0P2SJ/OJhoHBWWjlJplY4+/DWGVjRhN+pHBm2dWn5lrQ2/; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femployee%2fempl%2frefresh=list: %3ftab%3dmcm_tab_app_signin|%3frp%3dmcm_tab_app_signin|%3ftab%3dmcm_tab_app_signin_grad|%3frp%3dmcm_tab_app_signin_grad|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; PS_LOGINLIST=https://csprd.mcmaster.ca/prcsprd https://applicants.mcmaster.ca/prepprd; csprd-8000-PORTAL-PSJSESSIONID=qBhJY7xHWNQvrKvMPyVcSl1tGy2p7hJR!-1344051968; PS_TOKENEXPIRE=27_Nov_2016_23:51:04_GMT; SignOnDefault=MCM_SCC_GUEST; NSC_qh-dtqseqjb=ffffffffaf122a9b45525d5f4f58455e445a4a422970; ps_theme=node:EMPL portal:EMPLOYEE theme_id:MCM_GUEST_THEME css:MCM_PT_BRAND_CLASSIC_FLUID css_f:PT_BRAND_FLUID_TEMPLATE accessibility:A macroset:MCM_MYMAC_THEME formfactor:3 piamode:2; https%3a%2f%2fcsprd.mcmaster.ca%2fpsp%2fprcsprd%2femployee%2fhrms%2frefresh=list: %3ftab%3ddefault|%3frp%3ddefault|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; NSC_qh-fqqsebqqmjdbout=ffffffffaf122b9d45525d5f4f58455e445a4a422970', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
HEADERS
{'Content-Length': '421', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=aWqoMvV1vf0XNk5PxfHjA5CX1ajSl6E8!1679552918; PS_TOKEN=qgAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABS95BJZ+bsocqIKMKQ6+uKGkLYBfmoAAAAFAFNkYXRhXnicHYlLDkAwAERfEUsHcAeNX5WlCFZEgrWDuJrDmXQW8+ZlXiCJI2PELyIk35jYeDjFSVy5mWUX6cwuzQ7ZIn84GGlrSio6CnWlrvFhN1icaMNvGejlXnTwA2XxDcU=; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femployee%2fempl%2frefresh=list: %3ftab%3dmcm_tab_app_signin|%3frp%3dmcm_tab_app_signin|%3ftab%3dmcm_tab_app_signin_grad|%3frp%3dmcm_tab_app_signin_grad|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; PS_LOGINLIST=https://csprd.mcmaster.ca/prcsprd https://applicants.mcmaster.ca/prepprd; csprd-8000-PORTAL-PSJSESSIONID=qlJYY7xGGBYy53ZQND4nDc1Nn1dv6CXD!-1344051968; PS_TOKENEXPIRE=27_Nov_2016_23:51:03_GMT; SignOnDefault=MCM_SCC_GUEST; NSC_qh-dtqseqjb=ffffffffaf122a9b45525d5f4f58455e445a4a422970; ps_theme=node:EMPL portal:EMPLOYEE theme_id:MCM_GUEST_THEME css:MCM_PT_BRAND_CLASSIC_FLUID css_f:PT_BRAND_FLUID_TEMPLATE accessibility:A macroset:MCM_MYMAC_THEME formfactor:3 piamode:2; https%3a%2f%2fcsprd.mcmaster.ca%2fpsp%2fprcsprd%2femployee%2fhrms%2frefresh=list: %3ftab%3ddefault|%3frp%3ddefault|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; NSC_qh-fqqsebqqmjdbout=ffffffffaf122b9c45525d5f4f58455e445a4a422970', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
HEADERS
{'Content-Length': '421', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=8Y2oMvXk9U32aTOvEL7lcCuyBMNkhGgJ!1679552918; PS_TOKEN=qgAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABQr24cbH8H2oFG7MscDE4WN0fi3EWoAAAAFAFNkYXRhXnicHYlLDkBAFARrEEsHcAfC+C9FhhWRYO0gruZw2rxFV1e/B4jCwBjxDfCXrkys3BziJC5cONlJ7NikyS6b5Tc7I7WloKQlU5ZKS+d7RU4j5v7/d8ug1dLDB2VpDbc=; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femployee%2fempl%2frefresh=list: %3ftab%3dmcm_tab_app_signin|%3frp%3dmcm_tab_app_signin|%3ftab%3dmcm_tab_app_signin_grad|%3frp%3dmcm_tab_app_signin_grad|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; PS_LOGINLIST=https://csprd.mcmaster.ca/prcsprd https://applicants.mcmaster.ca/prepprd; csprd-8000-PORTAL-PSJSESSIONID=DqJTY7xH1n0pb3fRP2yGgnmGQbQ5Jl84!-1080248884; PS_TOKENEXPIRE=27_Nov_2016_23:51:04_GMT; SignOnDefault=MCM_SCC_GUEST; NSC_qh-dtqseqjb=ffffffffaf122a9e45525d5f4f58455e445a4a422970; ps_theme=node:EMPL portal:EMPLOYEE theme_id:MCM_GUEST_THEME css:MCM_PT_BRAND_CLASSIC_FLUID css_f:PT_BRAND_FLUID_TEMPLATE accessibility:A macroset:MCM_MYMAC_THEME formfactor:3 piamode:2; https%3a%2f%2fcsprd.mcmaster.ca%2fpsp%2fprcsprd%2femployee%2fhrms%2frefresh=list: %3ftab%3ddefault|%3frp%3ddefault|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; NSC_qh-fqqsebqqmjdbout=ffffffffaf122b9c45525d5f4f58455e445a4a422970', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
HEADERS
{'Content-Length': '421', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=bxGoMvYBXtTwRPnwqwrLLRIauwH7jWbt!1679552918; PS_TOKEN=qwAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABSNBSrOPEVZNFl5HJwQuZvjx90qlGsAAAAFAFNkYXRhX3icHYpLDkBAFARrEEsHcAcT45tZimBFJFg7iKs5nDZv0dWV1w+QxJEx4hsRLl8ZWbk5xFFcuJhkJ+nEJs122Sy/2RloKkocHYXSKSv60GssrWjD32rhxX/t4QNlbQ21; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femployee%2fempl%2frefresh=list: %3ftab%3dmcm_tab_app_signin|%3frp%3dmcm_tab_app_signin|%3ftab%3dmcm_tab_app_signin_grad|%3frp%3dmcm_tab_app_signin_grad|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; PS_LOGINLIST=https://csprd.mcmaster.ca/prcsprd https://applicants.mcmaster.ca/prepprd; csprd-8000-PORTAL-PSJSESSIONID=ky4xY7xHhX2bjBbrngg9sTJdMh0H1GvF!-675472577; PS_TOKENEXPIRE=27_Nov_2016_23:51:04_GMT; SignOnDefault=MCM_SCC_GUEST; NSC_qh-dtqseqjb=ffffffffaf122a9845525d5f4f58455e445a4a422970; ps_theme=node:EMPL portal:EMPLOYEE theme_id:MCM_GUEST_THEME css:MCM_PT_BRAND_CLASSIC_FLUID css_f:PT_BRAND_FLUID_TEMPLATE accessibility:A macroset:MCM_MYMAC_THEME formfactor:3 piamode:2; https%3a%2f%2fcsprd.mcmaster.ca%2fpsp%2fprcsprd%2femployee%2fhrms%2frefresh=list: %3ftab%3ddefault|%3frp%3ddefault|%3ftab%3dremoteunifieddashboard|%3frp%3dremoteunifieddashboard; NSC_qh-fqqsebqqmjdbout=ffffffffaf122b9c45525d5f4f58455e445a4a422970', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
HEADERS
{'Content-Length': '421', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0', 'Connection': 'keep-alive', 'Cookie': 'PS_DEVICEFEATURES=new:1; epprd-8000-PORTAL-PSJSESSIONID=QzKoMvWjImoy2rcwi9bm9XHf0-YdNF_l!1679552918; PS_TOKEN=qQAAAAQDAgEBAAAAvAIAAAAAAAAsAAAABABTaGRyAk4Aewg4AC4AMQAwABQKh/Kkz1qgnd394kPa2EuiFKjaYmkAAAAFAFNkYXRhXXicJYlLDkBAEAXLJ5YO4A4E47eVybAik2DtIK7mcF5GL6pepR8gTeIokt+YcMWGZePmkK28cuFUJ5ljV+ZetahvPDNdS03DQCk2YssYtqGil6vw/2mYxBE+ZQINrg==; ExpirePage=https://applicants.mcmaster.ca/psp/prepprd/; https%3a%2f%2fapplicants.mcmaster.ca%2fpsp%2fprepprd%2femplo

2172
src/mcmaster/errors3.log

File diff suppressed because it is too large

BIN
src/mcmaster/requests3.pcap

Binary file not shown.

12
src/mcmaster/sylla.py

@ -1,7 +1,7 @@
#! /usr/bin/python2
#! /usr/bin/python3
from sys import argv
from itertools import chain, islice, izip_longest, izip as zip
from itertools import chain, islice, zip_longest
from re import search, sub
from functools import total_ordering
from re import sub
@ -34,7 +34,7 @@ class Book(object):
def grouper(n, iterable, fillvalue=None):
"grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
return zip_longest(fillvalue=fillvalue, *args)
searchUrl = "https://campusstore.mcmaster.ca/cgi-mcm/ws/txsub.pl?wsDEPTG1=%s&wsDEPTDESC1=&wsCOURSEG1=%s&crit_cnt=1"
@ -70,7 +70,7 @@ def books(dept, code, withPrices):
pricelist = prices(parsed)
for div in parsed.xpath(".//div"):
if (div.attrib.has_key("id") and
if ("id" in div.attrib and
"prodDesc" in div.attrib["id"]):
textbook = div.text_content()
@ -96,8 +96,8 @@ def prices(html):
]
try:
amts, stats = zip(*list(reversed(list(grouper(2, ps)))))
return map(Price, amts, stats)
amts, stats = list(zip(*list(reversed(list(grouper(2, ps))))))
return list(map(Price, amts, stats))
except ValueError:
return []

117
src/mcmaster/sylla2.py

@ -0,0 +1,117 @@
#! /usr/bin/python2
from sys import argv
from itertools import chain, islice, izip_longest, izip as zip
from re import search, sub
from functools import total_ordering
from re import sub
import datetime as dt
import lxml.html as lxh
import requests
# Purpose of this module is to download and parse syllabi from various departments
# In order to be corellated with individual courses
class Price(object):
def __init__(self, amnt, status):
self.dollars = float(amnt[1:])
self.status = status
def __repr__(self):
return "$%s %s" % (repr(self.dollars), self.status)
class Book(object):
def __init__(self, title, price):
self.title = title
self.price = price
def __repr__(self):
return '["%s", "%s"]' % (self.title, repr(self.price))
def grouper(n, iterable, fillvalue=None):
"grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
searchUrl = "https://campusstore.mcmaster.ca/cgi-mcm/ws/txsub.pl?wsDEPTG1=%s&wsDEPTDESC1=&wsCOURSEG1=%s&crit_cnt=1"
def normalize(word):
if len(word) > 1:
return ("%s%s" %
(word[0].upper(),
"".join(word[1:]).lower()))
return word
def parseAuthor(author):
split = author.split(" ")
if len(split) <= 1:
return author
lastname = split[0]
firstname = split[1]
return "%s %s" % (firstname, lastname)
def normwords(phrase):
words = phrase.split(" ")
return " ".join(map(normalize, words))
def books(dept, code, withPrices):
"""
Snatch me up a book title or three
"""
req = searchUrl % (dept, code)
html = requests.get(req).text
parsed = lxh.fromstring(html)
pricelist = prices(parsed)
for div in parsed.xpath(".//div"):
if (div.attrib.has_key("id") and
"prodDesc" in div.attrib["id"]):
textbook = div.text_content()
author = sub(r',', '',
"".join(
(div.getparent()
.xpath(".//span[@class='inline']")
[0].text_content()
.split(":")[1:])).strip())
price = pricelist.pop()
if withPrices:
yield (normwords(textbook), normwords(author), repr(price))
else:
yield (normwords(textbook), normwords(author))
def prices(html):
"""
Get the prices from a search result page
"""
ps = [
p.getparent().text_content().split()[0]
for p in html.xpath("//p/input[@type='checkbox']")
]
try:
amts, stats = zip(*list(reversed(list(grouper(2, ps)))))
return map(Price, amts, stats)
except ValueError:
return []
def textbookInfo(dept, code, withPrices=False):
"""
Return all the textbooks for a course
"""
return list(books(dept, code, withPrices))
def humanities():
"""
Download humanities syllabi
"""
return []
# Example, getting the course info for Personality Theory (PSYCH = Department, 2B03 = Course code)
# print list(courseInfo("PSYCH", "2B03"))

0
src/mcmaster/texbooks.csv

0
src/mcmaster/textbooks.csv

1
src/mcmaster/wtf.xml

File diff suppressed because one or more lines are too long

18
src/website.py

@ -1,7 +1,7 @@
#! /usr/bin/python3
from functools import partial
from flask import Blueprint, abort, Flask, render_template, flash, request, send_from_directory
from flask import Blueprint, abort, Flask, render_template, flash, request, send_from_directory, jsonify
from flask_bootstrap import Bootstrap
from flask_appconfig import AppConfig
@ -13,7 +13,7 @@ from syslog import syslog
from archive import searchIA
from urllib.parse import quote, unquote
from json import dumps, loads
from json import loads
from werkzeug.contrib.cache import MemcachedCache
cache = MemcachedCache(['127.0.0.1:11211'])
@ -24,15 +24,15 @@ def predict(fieldtype, term):
print(fieldtype)
print(term)
if not term:
return "[]"
return jsonify([])
else:
try:
cs = completers[fieldtype](term.lower())
except KeyError:
return "[]"
return jsonify([])
if cs:
return cs
return "[]"
return jsonify([])
def predictor(fieldtype):
def inner(request):
@ -106,14 +106,14 @@ def ClassSearch(configfile=None):
try:
params = loads(unquote(dict(request.args.items())["data"]))
except KeyError:
return dumps("false")
return jsonify("false")
print(params)
author = params["author"]
title = params["title"]
if ("No Textbooks" in title or
"No Adoption" in title):
return dumps("false")
return jsonify("false")
# Cache the result of the open library search
openlib = cacheit("openlib"+title+author, lambda : bookUrls(title, author))
@ -125,9 +125,9 @@ def ClassSearch(configfile=None):
if not (any(openlib) or any(iarchive)):
# We literally could not find ANYTHING
return dumps("false")
return jsonify("false")
return dumps({
return jsonify({
"iarchive" : iarchive,
"openlib" : openlib
})

Loading…
Cancel
Save