Skip to content

Instantly share code, notes, and snippets.

@chrisjurich
Created August 14, 2020 20:44
Show Gist options
  • Save chrisjurich/306d0adcb504c47b43d22addec624b38 to your computer and use it in GitHub Desktop.
Save chrisjurich/306d0adcb504c47b43d22addec624b38 to your computer and use it in GitHub Desktop.
import urllib.request
from html.parser import HTMLParser
from bs4 import BeautifulSoup
import re
import datetime
###################################################################################
####################### HELPER FUNCTIONS ##########################################
def get_date_from_href(href):
"""Helper method that gets date from a hypertext link. Assumes format of MM/DD/YYYY. Raises error if number of matches != 1"""
matches = re.findall('[0-9]{2}/[0-9]{2}/[0-9]{4}',href)
if len(matches) != 1:
raise Exception("number of matches is incorrect. Should be 1 but is {}".format(len(matches)))
return matches[0]
def get_time_from_text(text):
"""Helper method that gets the time from a html text. Assumes format of HH:MM [am|pm]- HH:MM [am|pm]"""
matches = re.findall('[0-9 ][0-9]\:[0-9]{2} [ap]m',text)
if len(matches) != 2:
raise Exception("number of matches is incorrect. Should be 2 but is {}".format(len(matches)))
start = float(matches[0].rsplit(' ',1)[0].replace(':','.')) +( 12. if matches[0].rsplit(' ',1)[1] == "pm" else 0.)
end = float(matches[1].rsplit(' ',1)[0].replace(':','.')) + (12. if matches[1].rsplit(' ',1)[1] == "pm" else 0.)
if start == 24: start = 12
return start,end
def get_spots_fromt_text(text):
"""Helper method that gets the number of total and available spots from the html text. Assumes a format of "XX of XX Available"""
matches = re.findall("[0-9]{1,}",text.rsplit('m',1)[-1])
if len(matches) != 2:
raise Exception("number of matches is incorrect. Should be 2 but is {}".format(len(matches)))
available = int(matches[0])
total = int(matches[1])
return available,total
###################################################################################
class TermColor:
black= "\u001b[30m"
red = "\u001b[31m"
green = "\u001b[32m"
yellow = "\u001b[33m"
blue = "\u001b[34m"
magenta = "\u001b[35m"
cyan = "\u001b[36m"
white = "\u001b[37m"
reset = "\u001b[0m"
class LiftTime:
"""Class representing a lift time"""
start_time=float()
end_time=float()
spots_remaining = int()
date=str()
fill_level=str()
def __str__(self):
if self.fill_level == "low":
color = TermColor.green
elif self.fill_level == "medium":
color = TermColor.yellow
elif self.fill_level == "high":
color = TermColor.red
return "{COLOR_START}{CURR} spots{RESET}".format(
COLOR_START=color,CURR=self.spots_remaining,RESET=TermColor.reset
)
class LiftCaldendar:
"""Class that holds the lift times and delays them"""
days = list()
times = tuple((9,10,11,12,13,14,15,16,17,18,19,20,21))
lift_holder = dict()
def display(self):
output = str()
preamble ="UNL City campus weight room avaiability\n\n"
header = " | ".join([" time "] + self.days)
divider = '-'*len(header)
body = []
for time in self.times:
line = " {TIME}:00 {MER}m".format(
TIME=str(time if time <= 12 else time -12),
MER='a' if time < 12 else 'p'
)
line += " "*(10-len(line))
for day in self.days:
if (day,time) not in self.lift_holder:
if day == self.days[0] and time <= datetime.datetime.now().hour:
line += "|" + " passed "
else:
line += "|" + " not opened "
else:
new_entry = str(self.lift_holder[(day,time)])
excess = 22 - len(new_entry)
line += "|" + ' '*int(excess*0.5) +new_entry +' '*int(excess*0.5)
body.append(divider)
body.append(line)
end = "\n\n Availablity as of {TIME}\n Subject to change".format(
TIME=datetime.datetime.now().date())
print("\n".join( [preamble,
header] + body +[end] ))
def build_lift_times():
contents = urllib.request.urlopen("https://shopcrec.unl.edu/wbwsc/webtrac.wsc/search.html?display=calendar&module=AR&keyword=strength&location=CREC&_ga=2.22302008.2083201124.1597015035-1723204169.1591553160").read().decode('utf-8')
parsed_html = BeautifulSoup(contents,"html.parser")
lift_times = []
for tt in parsed_html.find_all('a'):
if tt.get_text().find("Available") != -1 and tt.get_text().find("of ") != -1:
link = tt['href']
if len(link) > 8:
text = tt.get_text()
start, end = get_time_from_text(text)
date = get_date_from_href(tt['href'])
available, total = get_spots_fromt_text(tt.get_text())
LT = LiftTime()
LT.start_time = start
LT.end_time = end
LT.spots_remaining = available
LT.date = date
LT.fill_level = ["high","medium","low"][int(available/total) + 1]
lift_times.append(LT)
return lift_times
def build_lift_calendar(lift_times):
days = set()
lift_dict = dict()
for lift in lift_times:
days.add(lift.date)
lift_dict[(lift.date,lift.start_time)] = lift
LC = LiftCaldendar()
LC.days = sorted(list(days))
LC.lift_holder = lift_dict
return LC
if __name__ == "__main__":
lift_times = build_lift_times()
lift_calendar = build_lift_calendar(lift_times)
lift_calendar.display()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment