server.ehlo() server.starttls() server.login("*****@*****.**",phrase); class_insert = "Hey! These classes are open:\n\n"; is_open = False; file_path = os.path.dirname(os.path.realpath("CourseCRNs.txt"))+"\CourseCRNs.txt"; def sendMessage(class_message): msg = "\r\n".join([ "From: [email protected]", "To: [email protected]", "Open Classes", class_message]); server.sendmail("*****@*****.**", "*****@*****.**", msg); timetable = Timetable(); f = open(file_path,"r") crn_list = []; for line in f: crn_list.append(int(line)); f.close(); for i in range(len(crn_list)): curClass = timetable.crn_lookup(str(crn_list[i]),term_year=201801,open_only=True) if curClass != None: is_open = True; class_insert += str(curClass)+" "+curClass.instructor+"\n"; sendMessage(class_insert); class_insert = "Hey! These classes are open:\n\n";
class TestTimetableLookups(TestCase): def setUp(self): self.timetable = Timetable() def test_refined_lookup_raises_value_error(self): with self.assertRaises(ValueError): self.timetable.refined_lookup(crn_code='17') with self.assertRaises(ValueError): self.timetable.refined_lookup(class_number='100') with self.assertRaises(ValueError): self.timetable.refined_lookup(class_number='1000') @patch('pyvt.Timetable._make_request') @patch('pyvt.Timetable._parse_table') def test_refined_lookup_full_request(self, mock_parse, mock_request): mock_parse.return_value = [] mock_request.return_value = '<html></html>' request = { 'crn_code': '17583', 'subject_code': 'STAT', 'class_number': '4705', 'cle_code': 'AR%' } self.timetable.refined_lookup(**request) called_request = { 'crn': '17583', 'subj_code': 'STAT', 'CRSE_NUMBER': '4705', 'CORE_CODE': 'AR%', 'open_only': 'on', 'TERMYEAR': '201701' } called_request.update(self.timetable.base_request) mock_request.assert_called_once() @patch('pyvt.Timetable._make_request') @patch('pyvt.Timetable._parse_table') def test_refined_lookup_return_values(self, mock_parse, mock_request): mock_parse.return_value = [] mock_request.return_value = '' self.assertIsNone(self.timetable.refined_lookup(crn_code='17583')) mock_parse.return_value = None self.assertIsNone(self.timetable.refined_lookup(crn_code='17583')) mock_parse.return_value = [Section(), Section()] self.assertEqual(2, len(self.timetable.refined_lookup('17583'))) @patch('pyvt.Timetable.refined_lookup') def test_crn_lookup_call_args(self, mock_lookup): self.timetable.crn_lookup('17583', None, False) args = {'crn_code': '17583', 'open_only': False, 'term_year': None} mock_lookup.assert_called_once_with(**args) @patch('pyvt.Timetable.refined_lookup') def test_crn_lookup_return_values(self, mock_lookup): mock_lookup.return_value = None self.assertIsNone(self.timetable.crn_lookup('17583')) mock_lookup.return_value = [Section()] self.assertTrue(isinstance(self.timetable.crn_lookup('17583'), Section)) @patch('pyvt.Timetable.refined_lookup') def test_class_lookup_args(self, mock_lookup): self.timetable.class_lookup('STAT', '4705', None, False) mock_lookup.assert_called_once_with(subject_code='STAT', class_number='4705', term_year=None, open_only=False) @patch('pyvt.Timetable.refined_lookup') def test_cle_lookup_args(self, mock_lookup): self.timetable.cle_lookup('AR01', None, False) mock_lookup.assert_called_once_with(cle_code='AR01', term_year=None, open_only=False) @patch('pyvt.Timetable.refined_lookup') def test_subject_lookup_args(self, mock_lookup): self.timetable.subject_lookup('STAT', None, False) mock_lookup.assert_called_once_with(subject_code='STAT', term_year=None, open_only=False)
def setUp(self): self.timetable = Timetable()
class TestTimetableHelpers(TestCase): def setUp(self): self.timetable = Timetable() @patch('pyvt.Timetable._parse_row') def test_parse_table_single_entry(self, mock_row): with open('./tests/test_data/test_crn_request_table.html', 'r') as file: bs = BeautifulSoup(file.read(), 'html.parser') self.timetable._parse_table(bs) self.assertEqual(2, mock_row.call_count) @patch('pyvt.Timetable._parse_row') def test_parse_table_no_results(self, mock_row): with open('./tests/test_data/test_table_no_results.html', 'r') as file: table = BeautifulSoup(file.read(), 'html.parser') self.assertIsNone(self.timetable._parse_table(table)) mock_row.assert_not_called() @patch('pyvt.Timetable._parse_row') def test_parse_table_multiple_results(self, mock_row): with open('./tests/test_data/test_class_lookup_multiple_results.html', 'r') as file: html = BeautifulSoup(file.read(), 'html.parser') self.timetable._parse_table(html) self.assertEqual(6, mock_row.call_count) def test_parse_row_simple(self): with open('./tests/test_data/test_row.html', 'r') as file: row = BeautifulSoup(file.read(), 'html.parser') data = self.timetable._parse_row(row) c = Section(crn='17583', code='STAT 4705', name='Statistics for Engr', lecture_type='L', credits='3', capacity='60', instructor='GR Terrell', days='T R', start_time='9:30AM', end_time='10:45AM', location='WMS 220', exam_type='09T') self.assertEqual(c, data) @patch('requests.post') def test_make_request_bad_status(self, mock_post): mock_post.return_value.status_code = 400 with self.assertRaises(TimetableError): self.timetable._make_request({'dummy': 'data'}) self.assertEqual(2, self.timetable.sleep_time) @patch('requests.post') def test_make_request_simple(self, mock_post): mock_post.return_value.content = '<html></html>' mock_post.return_value.status_code = 200 self.assertTrue( isinstance(self.timetable._make_request({'dummy': 'data'}), BeautifulSoup)) @patch('pyvt.datetime') def test_default_term_year(self, mock_date): mock_date.today.return_value.year = 2017 mock_date.today.return_value.month = 1 self.assertEqual('201701', self.timetable._default_term_year) @patch('pyvt.datetime') def test_default_term_year_in_between_terms(self, mock_date): mock_date.today.return_value.year = 2017 mock_date.today.return_value.month = 3 self.assertEqual('201701', self.timetable._default_term_year) @patch('requests.post') def test_timetable_error_growth(self, mock_post): mock_post.return_value.status_code = 404 for i in range(10): try: self.timetable._make_request({'dummy': 'data'}) except TimetableError: continue self.assertEqual(1024, self.timetable.sleep_time) @patch('requests.post') def test_timetable_error_thrown_message(self, mock_post): mock_post.return_value.status_code = 404 try: self.timetable._make_request({'dummy': 'data'}) except TimetableError as e: self.assertEqual( 'The VT Timetable is down or the request was bad. Status Code was: 404', str(e))
from pyvt import Timetable import json #Note: This code requires the installation of pyvt, using pip install py-vt. #This produces a json file with all courses offered this semester #It is not set up for use directly in the website, only for supplemental use by admins at the start of each semester timetable = Timetable() courseCodes = ["ACIS","AFST","AHRM","AINS","ALCE","ALS","AOE","APS","APSC","ARBC","ARCH","ART","AS","ASPT","AT","BC","BCHM","BIOL","BIT","BMES","BMSP","BMVS","BSE","BTDM","CEE","CEM","CHE","CHEM","CHN","CINE","CLA","CMDA","CNST","COMM","COS","CRIM","CS","CSES","DASC","ECE","ECON","EDCI","EDCO","EDCT","EDEL","EDEP","EDHE","EDIT","EDP","EDRE","EDTE","ENGE","ENGL","ENGR","ENSC","ENT","ESM","FA","FIN","FIW","FL","FR","FREC","FST","GBCB","GEOG","GEOS","GER","GIA","GR","GRAD","HD","HEB","HIST","HNFE","HORT","HTM","HUM","IDS","IS","ISC","ISE","ITAL","ITDS","JPN","JUD","LAHS","LAR","LAT","LDRS","MACR","MATH","ME","MGT","MINE","MKTG","MN","MS","MSE","MTRG","MUS","NANO","NEUR","NR","NSEG","PAPA","PHIL","PHS","PHYS","PORT","PPWS","PSCI","PSVP","PSYC","REAL","RLCL","RUS","SBIO","SOC","SPAN","SPIA","STAT","STL","STS","SYSB","TA","TBMH","UAP","UH","UNIV","VM","WGS"] #Note: C21S, CONS, FCS, FMD, PM, RED, RTM have no sections sectionList = [] for code in courseCodes: #print(str(code)) sections = timetable.subject_lookup(code, open_only=False) for section in sections: sectionDict = {} sectionDict["crn"] = section.crn sectionDict["code"] = section.code sectionDict["name"] = section.name sectionDict["instructor"] = section.instructor sectionList.append(sectionDict) with open("timetable.json", 'w') as outfile: json.dump(sectionList, outfile) outfile.close #print(str(sectionList)) #print(str(sectionList[1]["name"])) ''' [{'crn':'1223', 'name':'blah'},{crn:'122222', 'name':'bleh'}] '''
printf('Course detected: ' + parts[0] + ' ' + parts[1] + ' ' + parts[2] + ' ' + parts[3] + ' ' + parts[4] + ' ' + parts[5].title()) section = Section(str(parts[0]), parts[1], parts[2], parts[3], parts[4], parts[5]) sections.append(section) if VERBOSE or MORE_VERBOSE: printf(currTime() + ' Listening for ' + str(section)) if DEBUG: printf('\nSections Listening To:') for section in sections: printf(section) printf('') timetable = Timetable() # Allow loop if listening to classes if (len(sections) > 0): printf(currTime() + ' Initiated alerter') output_file = open(output_file_name, 'w') while (True): open_section = False for section in sections: available_sections = None # Lookup section by crn if available and valid if len(getattr(section, 'crn_code')) == 5: try: available_sections = timetable.crn_lookup(