├── .gitignore ├── README.md ├── Scraper.py └── taskbarNotifier.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | lib/ 17 | lib64/ 18 | parts/ 19 | sdist/ 20 | var/ 21 | *.egg-info/ 22 | .installed.cfg 23 | *.egg 24 | 25 | # PyInstaller 26 | # Usually these files are written by a python script from a template 27 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 28 | *.manifest 29 | *.spec 30 | 31 | # Installer logs 32 | pip-log.txt 33 | pip-delete-this-directory.txt 34 | 35 | # Unit test / coverage reports 36 | htmlcov/ 37 | .tox/ 38 | .coverage 39 | .cache 40 | nosetests.xml 41 | coverage.xml 42 | 43 | # Translations 44 | *.mo 45 | *.pot 46 | 47 | # Django stuff: 48 | *.log 49 | 50 | # Sphinx documentation 51 | docs/_build/ 52 | 53 | # PyBuilder 54 | target/ 55 | 56 | CaptchaParser.py -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ApprovalNotifier 2 | A desktop python application that notifies students when leave, outing requests have been approved. 3 | -------------------------------------------------------------------------------- /Scraper.py: -------------------------------------------------------------------------------- 1 | from taskbarNotifier import WindowsBalloonTip 2 | from BeautifulSoup import BeautifulSoup 3 | import mechanize 4 | from StringIO import StringIO 5 | from PIL import Image 6 | from CaptchaParser import CaptchaParser 7 | import cookielib 8 | import time, threading 9 | 10 | approval_array = [] 11 | def balloon_tip(title, msg): 12 | w=WindowsBalloonTip(title, msg) 13 | 14 | 15 | def Scanner(): 16 | br = mechanize.Browser() 17 | br.set_handle_redirect(True) 18 | br.set_handle_referer(True) 19 | cj = cookielib.CookieJar() 20 | br.set_cookiejar(cj) 21 | response = br.open('https://academics.vit.ac.in/student/stud_login.asp') 22 | html = response.read() 23 | soup = BeautifulSoup(html) 24 | im = soup.find('img', id='imgCaptcha') 25 | image_response = br.open_novisit(im['src']) 26 | img = Image.open(StringIO(image_response.read())) 27 | parser = CaptchaParser() 28 | captcha = parser.getCaptcha(img) 29 | br.select_form('stud_login') 30 | br.form['regno'] = '' 31 | br.form['passwd'] = '' 32 | br.form['vrfcd'] = str(captcha) 33 | br.submit() 34 | if(br.geturl() == "https://academics.vit.ac.in/student/home.asp"): 35 | print "-"*30 36 | print " "*12+"SUCCESS" 37 | print "-"*30 38 | br.open('https://academics.vit.ac.in/student/stud_home.asp') 39 | response1 = br.open('https://academics.vit.ac.in/student/student_outing_request.asp') 40 | html1 = response1.read() 41 | soup1 = BeautifulSoup(html1) 42 | trs = soup1.findAll('tr') 43 | index = 0 44 | for tr in trs: 45 | if(tr.text=="Sl.NoApply onApply ToLeave TypeFromToNo. of Hrs"): 46 | break 47 | index = index + 1 48 | outing_history = [] 49 | 50 | for tr in trs[index+1:]: 51 | tds = tr.findAll('td') 52 | outing_history.append({'sl_no': tds[0].text, 53 | 'apply_on': tds[1].text, 54 | 'apply_to': tds[2].text, 55 | 'leave_type': tds[3].text, 56 | 'from': tds[4].text, 57 | 'to': tds[5].text, 58 | 'no_of_hrs': tds[6].text, 59 | 'approved_by': tds[7].text, 60 | 'approved_on': tds[8].text, 61 | 'approval_status': tds[9].text}) 62 | if outing_history[0]['approval_status'] == '': 63 | if len(approval_array) != 0: 64 | if approval_array[len(approval_array)-1] == 'n': 65 | approval_array.append('a') 66 | if __name__ == '__main__': 67 | balloon_tip("NOTIFY", "APPROVED") 68 | return 69 | else: 70 | approval_array.append('a') 71 | 72 | 73 | 74 | 75 | 76 | else: 77 | approval_array.append('n') 78 | 79 | 80 | 81 | else: 82 | print"FAIL" 83 | print(time.ctime()) 84 | threading.Timer(10, Scanner).start() 85 | 86 | Scanner() 87 | 88 | -------------------------------------------------------------------------------- /taskbarNotifier.py: -------------------------------------------------------------------------------- 1 | from win32api import * 2 | from win32gui import * 3 | import win32con 4 | import sys, os 5 | import struct 6 | import time 7 | 8 | class WindowsBalloonTip: 9 | def __init__(self, title, msg): 10 | message_map = { 11 | win32con.WM_DESTROY: self.OnDestroy, 12 | } 13 | # Register the Window class. 14 | wc = WNDCLASS() 15 | hinst = wc.hInstance = GetModuleHandle(None) 16 | wc.lpszClassName = "PythonTaskbar" 17 | wc.lpfnWndProc = message_map # could also specify a wndproc. 18 | classAtom = RegisterClass(wc) 19 | # Create the Window. 20 | style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU 21 | self.hwnd = CreateWindow( classAtom, "Taskbar", style, \ 22 | 0, 0, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, \ 23 | 0, 0, hinst, None) 24 | UpdateWindow(self.hwnd) 25 | iconPathName = os.path.abspath(os.path.join( sys.path[0], "balloontip.ico" )) 26 | icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE 27 | try: 28 | hicon = LoadImage(hinst, iconPathName, \ 29 | win32con.IMAGE_ICON, 0, 0, icon_flags) 30 | except: 31 | hicon = LoadIcon(0, win32con.IDI_APPLICATION) 32 | flags = NIF_ICON | NIF_MESSAGE | NIF_TIP 33 | nid = (self.hwnd, 0, flags, win32con.WM_USER+20, hicon, "tooltip") 34 | Shell_NotifyIcon(NIM_ADD, nid) 35 | Shell_NotifyIcon(NIM_MODIFY, \ 36 | (self.hwnd, 0, NIF_INFO, win32con.WM_USER+20,\ 37 | hicon, "Balloon tooltip",msg,200,title)) 38 | # self.show_balloon(title, msg) 39 | time.sleep(10) 40 | DestroyWindow(self.hwnd) 41 | classAtom = UnregisterClass(classAtom, hinst) 42 | def OnDestroy(self, hwnd, msg, wparam, lparam): 43 | nid = (self.hwnd, 0) 44 | Shell_NotifyIcon(NIM_DELETE, nid) 45 | PostQuitMessage(0) # Terminate the app. 46 | 47 | 48 | --------------------------------------------------------------------------------