Browse Source

switched to oop approach

pull/18/head
theycallmemac 3 years ago
parent
commit
313844c09b
10 changed files with 364 additions and 110 deletions
  1. +0
    -1
      .travis.yml
  2. +3
    -3
      scripts/dcurooms
  3. +0
    -1
      scripts/index.py
  4. +39
    -0
      scripts/lab_booking.py
  5. +69
    -0
      scripts/lookup.py
  6. +122
    -0
      scripts/main.py
  7. +82
    -0
      scripts/now.py
  8. +49
    -0
      scripts/room_booking.py
  9. +0
    -18
      tests/test_builder.py
  10. +0
    -87
      tests/test_search_dict.py

+ 0
- 1
.travis.yml View File

@@ -10,7 +10,6 @@ install:
script:
- python tests/test_available_now.py
- python tests/test_lookup.py
- python tests/test_search_dict.py

notifications:
email: false

+ 3
- 3
scripts/dcurooms View File

@@ -1,6 +1,6 @@
import index
import main

__version__ = '1.0.0'
__version__ = '2.0.0'
__author__ = 'theycallmemac'

index.main()
main.main()

+ 0
- 1
scripts/index.py View File

@@ -21,7 +21,6 @@ __version__ = '1.0.0'
__copyright__ = 'Copyright (c) 2017 theycallmemac'
__license__ = 'GPL-3.0'


def setup_options():
parser = OptionParser(
description='Displays info and books room around DCU.',


+ 39
- 0
scripts/lab_booking.py View File

@@ -0,0 +1,39 @@
import sys
import smtplib
class LabBooking(object):
arguments = []
email= ""
password = ""
name = ""
society = ""

def __init__(self, email, password, name, society, arguments):
self.arguments = arguments
self.email = email
self.password = password
self.name = name
self.society = society

def draft(self):
FROM = self.email
TO = ['james.mcdermott89@gmail.com']
SUBJECT = 'Lab Booking'
BODY = "Just wondering if you could book " + self.arguments[0] + " on the " + \
self.arguments[1] + " from " + self.arguments[2][:2] + ":" + \
self.arguments[2][2:] + " to " + self.arguments[3][:2] + ":" + \
self.arguments[3][2:] + " for " + self.society + ".\n\nThank you,\n" + self.name + "."
message = """From: %s\nTo: %s\nSubject: %s\n\n%s""" % (FROM, ", ".join(TO), SUBJECT, BODY)
return (FROM, TO), message

def send(self, FROM, TO, message):
try:
server = smtplib.SMTP("smtp.gmail.com", 587)
server.ehlo()
server.starttls()
server.login(self.email, self.password)
server.sendmail(FROM, TO, message)
server.close()
print("Your email has been sent.")
except BaseException:
print("Email failed to send.")


+ 69
- 0
scripts/lookup.py View File

@@ -0,0 +1,69 @@
import sys
from mechanicalsoup import StatefulBrowser
from http.cookiejar import LWPCookieJar
from requests import get
from bs4 import BeautifulSoup
__author__ = "theycallmemac"
__version__ = '2.0.0'
__copyright__ = 'Copyright (c) 2018 theycallmemac'
__license__ = 'GPL-3.0'

class LookUp(object):
week = ""
day = ""
hour = ""

def __init__(self, week, day, hour):
self.week = week
self.day = day
self.hour = hour

def check_args(self):
if int(self.week) not in range(1, 53) or int(self.day) not in range(1, 7):
print("Incorrect parameters passed.")
sys.exit()
else:
pass

def check_time(self, times):
if self.hour not in times:
print("Outside scheduled timetables. Please try again at 08:00.")
sys.exit()
for k, v in times.items():
if k == self.hour:
self.hour = v
break
else:
pass

def building_option(self, lst):
for room in lst:
status = LookUp.build_timetable(self, room)
print(room + ": " + status)

def room_option(self, room):
status = LookUp.build_timetable(self, room)
print(room + ": " + status)

def build_timetable(self, room):
browser = StatefulBrowser()
cookie_jar = LWPCookieJar()
browser.set_cookiejar(cookie_jar)
browser.user_agent = [
("User-Agent",
"""Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/58.0.3029.110
Safari/537.36""")]
url = "https://www.dcu.ie/timetables/feed.php?room=GLA." + room + "&week1=" + self.week + "&hour=" + str(self.hour) + "&day=" + self.day + "&template=location"
browser.open(url)
result = LookUp.check_room(self, url)
return result

def check_room(self, url):
html = get(url)
soup = BeautifulSoup(html.text, "lxml")
tr = soup.select('tr')
return str(tr[12].getText().strip()) + " -> " + \
str(tr[14].getText().strip())


+ 122
- 0
scripts/main.py View File

@@ -0,0 +1,122 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# import libraries
import sys
import datetime
from optparse import OptionParser
from lab_booking import LabBooking
from room_booking import RoomBooking
from lookup import LookUp
from now import Now

__author__ = "theycallmemac"
__version__ = '1.0.0'
__copyright__ = 'Copyright (c) 2018 theycallmemac'
__license__ = 'GPL-3.0'

def setup_options():
parser = OptionParser(
description='Displays info and books room around DCU.',
prog='dcurooms', version='%prog ' + __version__,
usage='%prog [option]')
parser.add_option(
"-l", "--lookup", action="store_true",
help="returns information given a specific room, week, day and hour")
parser.add_option(
"-b", "--book", action="store_true",
help="books a room by providing the room, D/M/YYYY, start, and end")
parser.add_option(
"-a", "--available", action="store_true",
help="returns only the rooms/labs that are free in a building")
parser.add_option(
"-n", "--now", action="store_true",
help="show the status of each room/lab as it is currently")
# building options which can be passed
parser.add_option(
"-L", "--computing", action="store_true",
help="displays the status of the labs in the School of Computing")
parser.add_option(
"-C", "--grattan", action="store_true",
help="displays the status of rooms in the Henry Grattan building")

return parser

def get_data():
times, c, g, details = {'0800': '1', '0830': '2', '0900': '3', '0930': '4', '1000': '5', '1030': '6', '1100': '7', '1130': '8', '1200': '9', '1230': '10', '1300': '11', '1330': '12', '1400': '13','1430': '14', '1500': '15', '1530': '16', '1600': '17', '1630': '18', '1700': '19', '1730': '20', '1800': '21', '1830': '22', '1900': '23', '1930': '24', '2000': '25', '2030': '26', '2100': '27', '2130': '28', '2200': '29', '2230': '30'}, ['LG25', 'LG26', 'LG27', 'L101', 'L114', 'L125', 'L128'], ['CG01', 'CG02', 'CG03', 'CG04', 'CG05', 'CG06', 'CG11', 'CG12', 'CG20', 'CG68', 'C166'], sys.argv[2:]
return times, c, g, details

def required():
parser = setup_options()
(options, arguments) = parser.parse_args()
times, c, g, details = get_data()
return parser, (options, arguments), (c, g), (times, details)

def get_lab_credentials():
email = input("Your gmail: ")
password = input("Your gmail password: ")
your_name = input("Your name: ")
society = input("Society name: ")
return email, password, your_name, society

def get_room_credentials():
name = input("Your name: ")
email = input("Your email: ")
number = input("Your number: ")
society = input("Society name: ")
return email, number, name, society

def get_lst(c, g, options):
if options.computing: lst = c
elif options.grattan: lst = g
return lst

def get_current_time(date):
day = date.weekday()
hour = date.hour
minute = date.minute
year, week_no, weekday = date.isocalendar()
start = 36
if week_no >= start:
offset = -start
else:
offset = 52 - start
week = week_no + offset - 1
return str(week), str(day + 1), str(hour), str(minute)

def main():
parser, (options, arguments), rooms, info = required()
if options.book and info[1][0][0] == "L":
email, password, your_name, society = get_lab_credentials()
lab = LabBooking(email, password, your_name, society, info[1])
emails, message = lab.draft()
print(message)
result = lab.send(emails[0], emails[1], message)
elif options.book and info[1][0][0] == "C":
email, number, name, society = get_room_credentials()
room = RoomBooking(email, number, name, society, info[1])
form = room.fill()
result = room.submit(form)
if options.lookup and (options.grattan or options.computing):
lst = get_lst(rooms[0], rooms[1], options)
week, day, hour = info[1]
look = LookUp(week, day, hour)
look.check_args()
look.check_time(info[0])
look.building_option(lst)
elif options.lookup:
room, week, day, hour = info[1]
look = LookUp(week, day, hour)
look.check_args()
look.check_time(info[0])
look.room_option(room)
if options.now:
week, day, hour, minute = get_current_time(datetime.datetime.now())
now = Now(week, day, hour, minute)
now.round_it()
now.check_args()
now.check_time(info[0])
lst = get_lst(rooms[0], rooms[1], options)
now.building_option(lst, options)
if __name__ == "__main__":
main()

+ 82
- 0
scripts/now.py View File

@@ -0,0 +1,82 @@
import sys
from mechanicalsoup import StatefulBrowser
from http.cookiejar import LWPCookieJar
from requests import get
from bs4 import BeautifulSoup

__author__ = "theycallmemac"
__version__ = '2.0.0'
__copyright__ = 'Copyright (c) 2018 theycallmemac'
__license__ = 'GPL-3.0'

class Now(object):
week = ""
day = ""
hour = ""
minute = ""

def __init__(self, week, day, hour, minute):
self.week = week
self.day = day
self.hour = hour
self.minute = minute

def check_args(self):
if int(self.week) not in range(1, 53) or int(self.day) not in range(1, 7):
print("Incorrect parameters passed.")
sys.exit()
else:
pass

def round_it(self):
if int(self.hour) < 8 or int(self.hour) >= 23:
print("Outside scheduled timetables. Try again at 08:00.")
sys.exit()
if int(self.minute) >= 30:
self.minute = '30'
else:
self.minute = '00'

def check_time(self, times):
if self.hour not in times:
print("Outside scheduled timetables. Please try again at 08:00.")
for k, v in times.items():
if k == self.hour + self.minute:
self.hour = v
break
else:
pass

def get_status(self, options, room, status):
if options.available:
if len(status) <= 9:
print(room + ": " + status)
else:
print(room + ": " + status)

def building_option(self, lst, options):
for room in lst:
status = Now.build_timetable(self, room)
Now.get_status(self, options, room, status)

def build_timetable(self, room):
browser = StatefulBrowser()
cookie_jar = LWPCookieJar()
browser.set_cookiejar(cookie_jar)
browser.user_agent = [
("User-Agent",
"""Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/58.0.3029.110
Safari/537.36""")]
url = "https://www.dcu.ie/timetables/feed.php?room=GLA." + room + "&week1=" + self.week + "&hour=" + self.hour + "&day=" + self.day + "&template=location"
browser.open(url)
result = Now.check_room(self, url)
return result

def check_room(self, url):
html = get(url)
soup = BeautifulSoup(html.text, "lxml")
tr = soup.select('tr')
return str(tr[12].getText().strip()) + " -> " + str(tr[14].getText().strip())


+ 49
- 0
scripts/room_booking.py View File

@@ -0,0 +1,49 @@
import sys
from mechanicalsoup import StatefulBrowser
from http.cookiejar import LWPCookieJar
from requests import get

__author__ = "theycallmemac"
__version__ = '1.0.0'
__copyright__ = 'Copyright (c) 2017 theycallmemac'
__license__ = 'GPL-3.0'

class RoomBooking(object):
arguments = []
email= ""
number = ""
name = ""
society = ""

def __init__(self, email, number, name, society, arguments):
self.arguments = arguments
self.email = email
self.number = number
self.name = name
self.society = society

def fill(self):
browser = StatefulBrowser()
cookie_jar = LWPCookieJar()
browser.set_cookiejar(cookie_jar)
room, date, start, end = self.arguments[0], self.arguments[1].split("/"), self.arguments[2][:2] + ":" + self.arguments[2][2:], self.arguments[3][:2] + ":" + self.arguments[3][2:]
day, month, year = date[0], date[1], date[2]
browser.open("http://www.dcu.ie/registry/booking.shtml")
browser.select_form(nr=2)
browser["submitted[name_of_club_society]"] = self.society
browser["submitted[name_of_person_making_booking]"] = self.name
browser["submitted[contact_telephone_number]"] = self.number
browser["submitted[date_room_required][day]"] = day
browser["submitted[date_room_required][month]"] = month
browser["submitted[date_room_required][year]"] = year
browser["submitted[room_capacity]"] = "18"
browser["submitted[description_of_event]"] = "Meeting"
browser["submitted[hours_requiredfrom_to]"] = start + " - " + end
browser["submitted[building_room_reference]"] = room
browser["submitted[email_address]"] = self.email
return browser

def submit(self, form):
request = form.request
response = form.submit_selected()
return "Form submitted successfully."

+ 0
- 18
tests/test_builder.py View File

@@ -1,18 +0,0 @@

import unittest
import sys
import requests
sys.path.append('.')
from scripts.builders import build_timetable
class BuildTimetableTestCase(unittest.TestCase):
def test_return_val(self):
val = build_timetable("CG04", "24", "14", "4")
self.assertEqual(type(val), tuple)

def test_url_builder(self):
tt, url = build_timetable("LG26", "4", "10", "1")
info = requests.get(url)
self.assertTrue('200', info.status_code)

if __name__ == '__main__':
unittest.main()

+ 0
- 87
tests/test_search_dict.py View File

@@ -1,87 +0,0 @@
import unittest
import sys
import requests
sys.path.append('.')
from scripts.checks import search_dictionary
from scripts.builders import build_timetable
class SearchDictTestCase(unittest.TestCase):

def test_not_in_dict_search(self):
test_input_one = '0700'
times = {
'0800': '1',
'0830': '2',
'0900': '3',
'0930': '4',
'1000': '5',
'1030': '6',
'1100': '7',
'1130': '8',
'1200': '9',
'1230': '10',
'1300': '11',
'1330': '12',
'1400': '13',
'1430': '14',
'1500': '15',
'1530': '16',
'1600': '17',
'1630': '18',
'1700': '19',
'1730': '20',
'1800': '21',
'1830': '22',
'1900': '23',
'1930': '24',
'2000': '25',
'2030': '26',
'2100': '27',
'2130': '28',
'2200': '29',
'2230': '30'}
try:
not_in_dict_result = search_dictionary(times, test_input_one)

except SystemExit:
pass

def test_in_dict_search(self):
test_input_two = '1600'
times = {
'0800': '1',
'0830': '2',
'0900': '3',
'0930': '4',
'1000': '5',
'1030': '6',
'1100': '7',
'1130': '8',
'1200': '9',
'1230': '10',
'1300': '11',
'1330': '12',
'1400': '13',
'1430': '14',
'1500': '15',
'1530': '16',
'1600': '17',
'1630': '18',
'1700': '19',
'1730': '20',
'1800': '21',
'1830': '22',
'1900': '23',
'1930': '24',
'2000': '25',
'2030': '26',
'2100': '27',
'2130': '28',
'2200': '29',
'2230': '30'}
in_dict_result = search_dictionary(times, test_input_two)
self.assertTrue(int(in_dict_result) in range(1,31))


if __name__ == '__main__':
unittest.main()

Loading…
Cancel
Save