Created
August 14, 2020 20:44
-
-
Save chrisjurich/306d0adcb504c47b43d22addec624b38 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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