-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbot.py
More file actions
181 lines (140 loc) · 7.2 KB
/
Copy pathbot.py
File metadata and controls
181 lines (140 loc) · 7.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
import pandas as pd
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
import re
import time
import schedule
import datetime
import discord
from discord.ext import commands
import math
from decouple import config
class Bot:
"""
docstring
"""
def __init__(self, notifications = True, email = '', password = ''):
self._classes = ''
self._notifications = notifications
self._email = email
self._password = password
#get the classes info from the csv file
def UpdateClasses(self):
classes = pd.read_csv("classes.csv")
classes_list = []
for index, row in classes.iterrows():
class_info = [row['Class name'], row['Week day'], row['Time'], row['Link']]
classes_list.append(class_info)
self._classes = classes_list
#enter your google meet class
def LoginClass(self, class_name, link, start_time):
#accept the microfone and camera permissions
#when the pop up shows up
profile = webdriver.FirefoxProfile()
profile.set_preference("permissions.default.microphone", 1)
profile.set_preference("permissions.default.camera", 1)
#logging gmail account
driver = webdriver.Firefox(profile)
driver.get("https://accounts.google.com/signin/v2/identifier?ltmpl=meet&continue=https%3A%2F%2Fmeet.google.com%3Fhs%3D193&&o_ref=https%3A%2F%2Fmeet.google.com%2Ftbj-djkw-soh&_ga=2.125951309.19111609.1604633728-1240995876.1604633728&flowName=GlifWebSignIn&flowEntry=ServiceLogin")
email_login = driver.find_element_by_id("identifierId")
email_login.send_keys(self._email)
login_button = driver.find_element_by_id("identifierNext")
login_button.click()
time.sleep(3)
password_login = driver.find_element_by_name("password")
password_login.send_keys(self._password)
password_button = driver.find_element_by_id("passwordNext")
password_button.click()
time.sleep(4)
#after logging in we will access the class' google meet link
driver.get(link)
time.sleep(4)
#disable microphone and camera
actions = ActionChains(driver)
actions.key_down(Keys.CONTROL).send_keys('E').key_up(Keys.CONTROL).key_down(Keys.CONTROL).send_keys('D').key_up(Keys.CONTROL).perform()
#join class
join_button = driver.find_element_by_xpath("/html/body/div[1]/c-wiz/div/div/div[6]/div[3]/div/div/div[2]/div/div[1]/div[2]/div/div[2]/div/div[1]/div[1]")
join_button.click()
self.CheckCurrentPeople(driver, class_name, start_time)
#check if you have any classes in the day
def CheckClasses(self):
for c in self._classes:
if c[1].lower() == 'sunday':
schedule.every().sunday.at(c[2]).do(self.LoginClass, c[0], c[3], c[2])
if c[1].lower() == 'monday':
schedule.every().monday.at(c[2]).do(self.LoginClass, c[0], c[3], c[2])
if c[1].lower() == 'tuesday':
schedule.every().tuesday.at(c[2]).do(self.LoginClass, c[0], c[3], c[2])
if c[1].lower() == 'wednesday':
schedule.every().wednesday.at(c[2]).do(self.LoginClass, c[0], c[3], c[2])
if c[1].lower() == 'thursday':
schedule.every().thursday.at(c[2]).do(self.LoginClass, c[0], c[3], c[2])
if c[1].lower() == 'friday':
schedule.every().friday.at(c[2]).do(self.LoginClass, c[0], c[3], c[2])
if c[1].lower() == 'saturday':
schedule.every().saturday.at(c[2]).do(self.LoginClass, c[0], c[3], c[2])
while True:
# Checks whether a scheduled task
# is pending to run or not
schedule.run_pending()
time.sleep(2)
#check every 5 seconds the amount people watching the class
def CheckCurrentPeople(self, driver, class_name, start_time):
try:
#wait at most 60 seconds to join the class
chat_button = WebDriverWait(driver, 60).until(EC.presence_of_element_located((By.XPATH, "/html/body/div[1]/c-wiz/div[1]/div/div[6]/div[3]/div[6]/div[3]/div/div[2]/div[1]")))
chat_button.click()
total = 1
while True:
time.sleep(5)
current_people = self.GetTotalPeople(driver)
if current_people > total:
total = current_people
if current_people <= math.ceil(total/3)+1:
##leave_class = driver.find_element_by_xpath('/html/body/div[1]/c-wiz/div[1]/div/div[6]/div[3]/div[9]/div[2]/div[2]')
##leave_class.click()
driver.quit()
self.NotifyDiscord(class_name, start_time, datetime.datetime.now())
#the professor didn't accept you in time
except TimeoutException:
print("Waiting to join the class...")
#aux function to return the amount of current people watching
def GetTotalPeople(self, driver):
total_people = driver.find_element_by_xpath("/html/body/div[1]/c-wiz/div[1]/div/div[6]/div[3]/div[3]/div/div[2]/div[2]/div[1]/div[1]/span/div/span[2]")
total_people = total_people.text
#get only the numbers
total_people_formatted = re.search("\d+", total_people)
total_people_formatted = total_people_formatted.group(0)
return int(total_people_formatted)
#send a message to your discord server when a class is over
def NotifyDiscord(self, class_name, start_time, end_time):
bot = commands.Bot(command_prefix='!')
bot.remove_command('help')
#search for a specific text channel on your discord server
def FindDiscordChannel():
for guild in bot.guilds:
for channel in guild.text_channels:
if channel.name == 'online-classes':
return channel.id
#add a help command
@bot.command()
async def help(ctx):
channel_id = FindDiscordChannel()
await ctx.send("You receive notifications when the class is over! Until then do something useful! :-)")
@bot.event
async def on_ready():
channel_id = FindDiscordChannel()
date = str(end_time.month) + '/' + str(end_time.day) + '/' + str(end_time.year)
time_ended = str(end_time.hour) + ':' + str(end_time.minute)
embed = discord.Embed(title="Class Notification", description="You received a notification!")
embed.add_field(name="Class name:", value=class_name, inline=False)
embed.add_field(name="Date:", value=date, inline=False)
embed.add_field(name="Start time:", value=start_time, inline=True)
embed.add_field(name="End time:", value=time_ended, inline=True)
await bot.get_channel(channel_id).send(embed=embed)
bot.run(config('BOT_TOKEN'))