first commit

This commit is contained in:
Baasil Siddiqui 2023-05-29 12:43:24 +04:00
commit ea264a41e7
9 changed files with 491 additions and 0 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
*.log
__pycache__
*.png

36
config.py Normal file
View file

@ -0,0 +1,36 @@
import smtplib, ssl, options
import keyring as kr
from selenium.webdriver import Firefox
from selenium.webdriver.firefox.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# email config
# edit the following with your imap server configuration for your email account
PORT = 465 # For SSL
CONTEXT = ssl.create_default_context()
IMAP_SERVER = ""
SENDER_EMAIL = ""
MAILING_LIST = ["johndoe@gmail.com","johnsmith@gmail.com"] # replace with mail addresses you want to notify
# credentials
# add email and immi credentials in your keyring and edit this accordingly
# https://pypi.org/project/keyring/
CRED_MAIL = kr.get_credential("service", "username")
CRED_IMMI = kr.get_credential("","")
# webdriver config
options=Options()
options.add_argument('-headless')
options.binary_location = r'' # fill with firefox binary path
profile_path = r"" # fill with firefox profile path
SERVICE = Service(r"") # download and fill with geckodriver location
URL = 'https://online.immi.gov.au/lusc/login'
options.set_preference('profile', profile_path)
# general
ini_status = "Received" # replace with your current application status
ini_msg = 2 # replace with the current number of messages in your portal
ERROR_PNG_FILENAME = "error.png"

BIN
granted.wav Normal file

Binary file not shown.

52
msg.py Normal file
View file

@ -0,0 +1,52 @@
# emails
message_status = """\
From: baasil@riseup.net
To: {}
Subject: Your Australian student visa application status has changed to \"{}\"\n\n
https://online.immi.gov.au/lusc/login
This is an automated message sent from a python script made by Baasil."""
message_new = """\
From: baasil@riseup.net
To: {}
Subject: You have new message(s) in your australian visa application portal\n\n
{}\n
https://online.immi.gov.au/lusc/login
check portal to see full message, I won't do everything for you\n
This is an automated message sent from a python script made by Baasil."""
message_final = """\
From: baasil@riseup.net
To:{}
Subject: Your Australian visa has been {}\n\n
https://online.immi.gov.au/lusc/login
check portal for details\nthis message may have been sent in error\n
this is an automated message sent from a python script made by Baasil."""
error_message = """\
From: baasil@riseup.net
To: {}
Subject: visa_stat.py exited due to too many consecutive errors\n\n
https://online.immi.gov.au/lusc/login - check what's up here
this is an automated message"""
net_error_msg = """\
From: baasil@riseup.net
To: {}
Subject: visa_stat.py too many consecutive net errors\n\n
https://online.immi.gov.au/lusc/login - check what's up here
this is an automated message"""
error_in_messages = """\
From: baasil@riseup.net
To:{}
Subject: too many consecutive errors in fetching messages, from visa_stat.py\n\n
https://online.immi.gov.au/lusc/login - check what's up here
this is an automated message"""

170
oldver.py Normal file
View file

@ -0,0 +1,170 @@
"""script to track my visa application status"""
from time import sleep
from random import randrange
from datetime import datetime
from os import _exit
import smtplib, ssl, threading, options
from selenium.webdriver import Firefox
from selenium.webdriver.firefox.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import keyring as kr
import simpleaudio as sa
from plyer import notification as toast
from msg import *
# email config
port = 465 # For SSL
context = ssl.create_default_context()
imap_server = "mail.riseup.net"
sender_email = "baasil@riseup.net"
receivers = ["baasil@riseup.net","baasilsiddiqui@gmail.com","siddiqui_m_j@yahoo.com"]
# credentials
cred_mail = kr.get_credential("riseup","sedentaryowl")
cred_immi = kr.get_credential("immi","sbaasil51@gmail.com")
# webdriver config
options=Options()
options.add_argument('-headless')
options.binary_location = r'/usr/sbin/firefox'
profile_path = r"/home/baasil/.mozilla/firefox/z93eslik.default-release"
service = Service(r"/home/baasil/dls/geckodriver")
url = 'https://online.immi.gov.au/lusc/login'
options.set_preference('profile', profile_path)
errors=0 # variable to track number of consecutive errors
def notifier(receiver_email, msg):
"""sends mail to receiver_email with msg message"""
global imap_server, port, context, sender_email, cred_mail
with smtplib.SMTP_SSL(imap_server, port, context=context) as server:
server.login(cred_mail.username, cred_mail.password)
server.sendmail(sender_email, receiver_email, msg)
def music(file):
sa.WaveObject.from_wave_file(file).play()
# main event loop
while True:
driver = Firefox(service=service, options=options)
driver.get(url)
print("------------------------------------------------------------------")
try:
driver.find_element(by=By.NAME, value="username").send_keys(cred_immi.username)
driver.find_element(by=By.NAME, value="password").send_keys(cred_immi.password)
driver.find_element(by=By.XPATH, value="/html/body/form/div/div[2]/button[2]").click() # login
sleep(2)
driver.find_element(by=By.NAME, value="continue").click()
details_element = WebDriverWait(driver, 25).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="defaultActionPanel_0_7"]'))) # view details
sleep(5)
try:
details_element.click()
except:
pass
status_line_element = WebDriverWait(driver, 25).until(EC.visibility_of_element_located((By.XPATH, '//*[@id="_0a1a0c1a0a0b1a0a1a0a"]/div/div/strong')))
status_line = status_line_element.text
trashy, status = status_line.split(": ")
print(datetime.now().strftime("%H:%M"), end=": ")
print(f"Application status: {status}")
try:
driver.find_element(by=By.ID, value="_0a1a0c1a0a0b0a1a0b0-body").click() # messages tab
sleep(5)
messages = driver.find_elements(by=By.XPATH, value="//table/tbody/tr") # list of messages
latest = ''
for i in messages:
if '06 feb' not in i.text.lower() and '25 jan' not in i.text.lower():
latest_element = i; latest = i.text; break
if 'acknowledge' not in i.text.lower():
latest_element = i; latest = i.text
errors=0
except:
driver.save_screenshot('/home/baasil/learnpy/visa_stat/error.png')
errors+=1
latest=''
messages=[]
driver.close()
# checking status
if status=="Received":
pass
elif status=="Finalised":
print("status change detected")
print(latest)
print("sending mails...")
if 'grant' in latest.lower() or 'accept' in latest.lower():
play = threading.Thread(target=music, args=('granted.wav',)); play.start()
toast.notify(title="your Australian visa has been granted", message='congratulations')
for r_mail in receivers:
notifier(r_mail, message_final.format(r_mail, 'granted'))
print("mails sent")
_exit(1)
elif 'reject' in latest.lower():
play = threading.Thread(target=music, args=('rejected.wav',)); play.start()
toast.notify(title="your Australian visa has been rejected")
for r_mail in receivers:
notifier(r_mail, message_final.format(r_mail, 'rejected'))
print("mails sent")
_exit(1)
else:
toast.notify(title=f"your Australian visa application status has changed to \"{status}\"")
for r_mail in receivers:
notifier(r_mail, message_status.format(r_mail, status))
print("mails sent")
if len(messages)==2:
_exit(1)
else:
print("status change detected")
print("sending mails...")
toast.notify(title=f"your Australian visa application status has changed to \"{status}\"")
for r_mail in receivers:
notifier(r_mail, message_status.format(r_mail, status))
print("mails sent")
if len(messages)==2:
_exit(1)
# checking messages
if len(messages)==2 and '2023' in latest:
print("no new messages")
elif len(messages)>2:
print("found new message")
print(latest)
print("sending mails...")
toast.notify(title="you have a new message in your Australian visa application portal", message=latest)
for r_mail in receivers:
notifier(r_mail, message_new.format(r_mail,latest))
print("mails sent")
_exit(1)
else:
print("can't find messages")
sleep(5*60)
continue
n = randrange(15,30)
sleep(n*60)
except KeyboardInterrupt:
try:
driver.close()
except:
pass
_exit(1)
except:
try:
driver.save_screenshot('/home/baasil/learnpy/visa_stat/error.png')
driver.close()
except KeyboardInterrupt:
_exit(1)
except:
pass
print("ERROR"); errors+=1
if errors>=5:
notifier(receivers[0], error_message.format(receivers[0]))
toast.notify(title="visa_stat.py",message="too many consecutive errors, exiting...")
print("too many consecutive errors, exiting...")
_exit(1)
else:
sleep(15*60)

BIN
rejected.wav Normal file

Binary file not shown.

32
requirements.txt Normal file
View file

@ -0,0 +1,32 @@
async-generator==1.10
attrs==22.2.0
certifi==2022.12.7
cffi==1.15.1
chainmap==1.0.3
combomethod==1.0.12
cryptography==40.0.1
exceptiongroup==1.1.1
h11==0.14.0
idna==3.4
importlib-metadata==6.1.0
jaraco.classes==3.2.3
jeepney==0.8.0
keyring==23.13.1
more-itertools==9.1.0
nulltype==2.3.1
options==1.4.10
outcome==1.2.0
plyer==2.1.0
pycparser==2.21
PySocks==1.7.1
SecretStorage==3.3.3
selenium==4.8.3
simpleaudio==1.0.4
six==1.12.0
sniffio==1.3.0
sortedcontainers==2.4.0
trio==0.22.0
trio-websocket==0.10.2
urllib3==1.26.15
wsproto==1.2.0
zipp==3.15.0

23
utils.py Normal file
View file

@ -0,0 +1,23 @@
import simpleaudio as sa
from datetime import datetime
from config import *
def notifier(receivers_list, msg, *format_args):
"""sends mail to receivers_list with msg message formated with rmail and *format_args"""
for rmail in receivers_list:
with smtplib.SMTP_SSL(IMAP_SERVER, PORT, context=CONTEXT) as server:
server.login(CRED_MAIL.username, CRED_MAIL.password)
server.sendmail(SENDER_EMAIL, rmail, msg.format(rmail, *format_args))
def music(file):
"""plays music from wav file"""
sa.WaveObject.from_wave_file(file).play()
def parse_date(full_message):
"""parses date from message title"""
full_message_lines = full_message.split("\n")
date_line = full_message_lines[-1]
date_list = date_line.split(" ")
date_string = date_list[0]+' '+date_list[1]+' '+date_list[2]
return datetime.strptime(date_string, '%d %b %Y')

175
visa_stat.py Normal file
View file

@ -0,0 +1,175 @@
"""script to track my visa application status"""
from time import sleep
from random import randrange
from os import _exit
import threading
from plyer import notification as toast
from msg import *
from utils import *
con_errors = 0 # variable to track number of consecutive errors
msg_errors = 0 # variable to track number of consecutive errors in fetching messages
net_errors = 0 # variable to track number of consecutive connection errors
# main event loop
while True:
print("------------------------------------------------------------------")
try:
try:
driver = Firefox(service=SERVICE, options=options)
driver.get(URL)
net_errors=0
except:
net_errors+=1
print("net error")
if net_errors>=5:
notifier(MAILING_LIST[0:1], net_error_msg)
toast.notify(title="visa_stat.py",message="too many consecutive net errors")
net_errors = 0
sleep(15*60)
continue
driver.find_element(by=By.NAME, value="username").send_keys(CRED_IMMI.username)
driver.find_element(by=By.NAME, value="password").send_keys(CRED_IMMI.password)
driver.find_element(by=By.XPATH, \
value="/html/body/form/div/div[2]/button[2]").click() # login
sleep(2)
driver.find_element(by=By.NAME, value="continue").click()
details_element = WebDriverWait(driver, 25).until(EC.element_to_be_clickable\
((By.XPATH, '//*[@id="defaultActionPanel_0_7"]')))
sleep(5)
try:
details_element.click()
except:
pass
status_line_element = WebDriverWait(driver, 25).until(EC.visibility_of_element_located\
((By.XPATH, '//*[@id="_0a1a0c1a0a0b1a0a1a0a"]/div/div/strong')))
status_line = status_line_element.text
trashy, status = status_line.split(": ")
print(datetime.now().strftime("%H:%M"), end=": ")
print(f"Application status: {status}")
try:
msg_tab = driver.find_element(by=By.ID, value="_0a1a0c1a0a0b0a1a0b0-body")
while_timeout = False # variable to deteremine if while loop timed out
timeout_while = 0
while not driver.find_elements(by=By.XPATH, value='//*[@id="_0a1a0c1a0a0b1a0c0a0b"]/div/div[1]'):
trashy = msg_tab.text
timeout_while+=1
if timeout_while>=7:
msg_err = True
while_timeout = True
break
msg_tab.click()
sleep(10)
if not while_timeout:
messages = driver.find_elements(by=By.XPATH, \
value="//table/tbody/tr") # list of messages
messages_string_list = []
for i in messages:
messages_string_list.append(i.text)
ordered_message_list = sorted(messages_string_list, key=parse_date)
new_message_list = ordered_message_list[ini_msg:]
new_messages_string = "\n\n".join(new_message_list)
msg_errors = 0
msg_err = False
except:
msg_err = True
finally:
if msg_err:
driver.save_screenshot(ERROR_PNG_FILENAME)
msg_errors+=1
new_messages_string = ""
messages=[]
if msg_errors>=5:
notifier(MAILING_LIST[0:1], error_in_messages)
msg_errors = 0
driver.close()
# checking status
if status==ini_status:
pass
elif status=="Finalised":
print("status change detected")
print(new_messages_string)
print("sending mails...", end="")
if 'grant' in new_messages_string.lower():
play = threading.Thread(target=music, args=('granted.wav',))
play.start()
toast.notify(title="your Australian visa has been granted", \
message='congratulations')
notifier(MAILING_LIST, message_final, 'granted')
print("mails sent")
_exit(0)
elif 'reject' in new_messages_string.lower():
play = threading.Thread(target=music, args=('rejected.wav',))
play.start()
toast.notify(title="your Australian visa has been rejected")
notifier(MAILING_LIST, message_final, 'rejected')
print("mails sent")
_exit(0)
else:
toast.notify(title=f"your Australian visa application status has changed to \"{status}\"")
notifier(MAILING_LIST, message_status, status)
print("mails sent")
ini_status = status
else:
print("status change detected")
print("sending mails...", end="")
toast.notify(title=f"your Australian visa application status has changed to \"{status}\"")
notifier(MAILING_LIST, message_status, status)
print("mails sent")
ini_status = status
# checking messages
if len(messages)==ini_msg:
print("no new messages")
elif len(messages)>ini_msg:
print("found new message(s)")
print(new_messages_string)
print("sending mails...", end="")
toast.notify(title="you have new message(s) in your Australian visa application portal", \
message=new_messages_string)
notifier(MAILING_LIST, message_new, new_messages_string)
print("mails sent")
ini_msg = len(messages)
if status=="Finalised":
_exit(0)
else:
print("can't find messages")
sleep(5*60)
continue
n = randrange(15,30)
sleep(n*60)
except KeyboardInterrupt:
try:
driver.close()
except:
pass
_exit(1)
except:
try:
driver.save_screenshot(ERROR_PNG_FILENAME)
driver.close()
except KeyboardInterrupt:
_exit(1)
except:
pass
print("ERROR")
con_errors+=1
if con_errors>=5:
notifier(MAILING_LIST[0:1], error_message)
toast.notify(title="visa_stat.py",message="too many consecutive errors, exiting...")
print("too many consecutive errors, exiting...")
_exit(1)
else:
sleep(15*60)