Hello everyone! New update for the code is here!! Sorry for the late update but I have been trying to fox bugs and errors. Sadly I am stuck!
In this tutorial I will explain how you can send yourself emails when your hive power is full!
Or you can also send me an email at [email protected] to enroll in the program. Currently its not running, but when it does I will make a post! Furthermore the email will currently show up in your SPAM folder.
How it works
The program works by using the multiprocessing python library to run multiple processes at once. For each user there is a process created as seen in the code below
python
import updater_mod
import multiprocessing
import time
import schedule
import smtplib, ssl
#100%_hivepower_0%
# object armoredbanana
def user_1():
user1 = updater_mod.Hive_power_tracker(username = "armoredbanana", email_address = "", treshold = 0, resend_time = 360) # treshold when hive power is 100%, resends email when full after 6 hours
# object trostparadox
def user_2():
user2 = updater_mod.Hive_power_tracker(username = "trostparadox", email_address = "", treshold = 216, resend_time = 120) # treshold when hive power is 97%, resends email when full after 2 hours
# object bhanutejap
def user_3():
user3 = updater_mod.Hive_power_tracker(username = "bhanutejap", email_address = "", treshold = 0, resend_time = 1440) # treshold when hive power is 100%, resends email when full after 24 hours
process_1 = multiprocessing.Process(target=user_1)
process_2 = multiprocessing.Process(target=user_2)
process_3 = multiprocessing.Process(target=user_3)
process_1.start()
process_2.start()
process_3.start()
This code initiates the object of the following code:
from selenium import webdriver
from selenium.webdriver.firefox.service import Service
from selenium.webdriver.firefox.options import Options as FirefoxOptions
from selenium.webdriver.common.by import By
import time
import schedule
import smtplib, ssl
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import sys
class Hive_power_tracker:
def __init__(self, username, email_address, treshold, resend_time):
# getting drivers / webscraping working
options = FirefoxOptions()
options.add_argument("--headless")
self.driver = webdriver.Firefox(executable_path = r'/home/hivepowertracker/HivePowerTracker/Program/geckodriver', options=options) #this is the path where my geckodriver exists
# getting data paramaters accessible for the whole class
self.username = username
self.email_address = email_address
self.treshold = treshold
self.resend_time = resend_time
self.vote_value_percentage = ''
self.time_to_100 = ''
self.effective_hive_power = ''
self.hive_power = ''
self.total_minute_value = 0
# getting user data
# self.get_user_data()
self.email()
#print(self)
# gets user data
def get_user_data(self):
hivestats_url = 'https://hivestats.io/@' + self.username
self.driver.get(hivestats_url)
time.sleep(10)
self.vote_value_percentage = self.driver.find_element(By.XPATH,'/html/body/div/div/div[1]/div/div[2]/section[1]/div[2]/div/div/span[1]/span[2]')
self.time_to_100 = self.driver.find_element(By.XPATH,'/html/body/div/div/div[1]/div/div[2]/section[3]/div[2]/table/tbody/tr[8]/td[2]')
self.effective_hive_power = self.driver.find_element(By.XPATH, '/html/body/div/div/div[1]/div/div[2]/section[3]/div[2]/table/tbody/tr[1]/td[2]/span')
self.hive_power = self.driver.find_element(By.XPATH, '/html/body/div/div/div[1]/div/div[2]/section[3]/div[2]/table/tbody/tr[2]/td[2]/span')
return 0
# prints out user data
def __repr__(self):
print("---------------","\nUser:", self.username, "\nVote Power:", self.vote_value_percentage.text, "\nTime untill full:", self.time_to_100.text, "\nEffective HP:", self.effective_hive_power.text, "\nActual HP:", self.hive_power.text, "\nFull Hive Power in: ", self.total_minute_value, " minutes")
#return "User: % s Vote Power: % s Time untill full: % s Effective HP: % s Actual HP: % s" % (self.username, self.vote_value_percentage, self.time_to_100, self.effective_hive_power, self.hive_power)
return "---------------"
# gets the number of minutes left for the user to have full hive power again
def get_time(self):
string = str(self.time_to_100.text)
temp = string.replace(" ", "")
self.total_minute_value = 0
if (temp.find("Full") == 0):
self.total_minute_value = 0
# Getting the number of minutes remaining based on the day value
if (temp.find("day") != -1):
day_index = temp.find("day")
day_value = int(temp[day_index-1])
minute_day_value = day_value * 1440
self.total_minute_value += minute_day_value
# Getting the number of minutes remaining based on the hour value
if (temp.find("hour") != -1):
hour_index = temp.find("hour")
if (temp[hour_index-2].isdigit()):
hour_value = int(temp[hour_index-2] + temp[hour_index-1])
minute_hour_value = hour_value * 60
self.total_minute_value += minute_hour_value
elif (temp[hour_index-1].isdigit()):
hour_value = int(temp[hour_index-1])
minute_hour_value = hour_value * 60
self.total_minute_value += minute_hour_value
# Getting the number of minutes remaining based on the minute value
if (temp.find("minute") != -1):
minute_index = temp.find("minute")
if (temp[minute_index-2].isdigit()):
minute_value = int(temp[minute_index-2] + temp[minute_index-1])
self.total_minute_value += minute_value
elif (temp[minute_index-1].isdigit()):
minute_value = int(temp[minute_index-1])
self.total_minute_value += minute_value
return self.total_minute_value
def email(self):
# email things
port = 465 # For SSL
smtp_server = "smtp.gmail.com"
sender_email = "[email protected]" # Enter your address
password = "100%_hivepower_0%"
subject = self.username + " YOUR HIVE POWER IS FULL"
body = "Hello there: " + self.username + "\n\nYour hive power is full"
message = MIMEMultipart()
message['From'] = sender_email
message['To'] = self.email_address
message['Subject'] = subject
message.attach(MIMEText(body, 'plain'))
text = message.as_string()
print("Getting User Data for: ", self.username)
self.get_user_data()
check_back_time = self.get_time()-self.treshold
schedule.every(check_back_time).minutes.do(self.email)
while 1:
if check_back_time <= self.treshold:
# Create a secure SSL context
context = ssl.create_default_context()
# create server variable
with smtplib.SMTP_SSL("smtp.gmail.com", port, context=context) as server:
# log in to email
server.login(sender_email, password)
# send email
server.sendmail(sender_email, self.email_address, text)
print("Sent email")
time.sleep(self.resend_time*60)
schedule.run_pending()
time.sleep(5)
As you can see in the initialization of the class, the send_email() function is started. This will check the users hive power and depending on its % it will send an email or check back in some time.
The code blow send the email:
server.sendmail(sender_email, self.email_address, text)
Running the program through the terminal works amazing, but when I try to make it a service in systemd on linux, it fails.
error
File "/home/hivepowertracker/HivePowerTracker/Program/updater_mod.py", line 20, in __init__
Apr 08 16:15:45 hivepowertracker python3[22956]: self.driver = webdriver.Firefox(executable_path = r'/home/hivepowertracker/HivePowerTracker/Program/geckodriver', options=options) #this is the path where my geckodriver exists
Apr 08 16:15:45 hivepowertracker python3[22956]: File "/home/hivepowertracker/.local/lib/python3.8/site-packages/selenium/webdriver/firefox/webdriver.py", line 172, in __init__
Apr 08 16:15:45 hivepowertracker python3[22956]: self.service = Service(
Apr 08 16:15:45 hivepowertracker python3[22956]: File "/home/hivepowertracker/.local/lib/python3.8/site-packages/selenium/webdriver/firefox/service.py", line 49, in __init__
Apr 08 16:15:45 hivepowertracker python3[22956]: log_file = open(log_path, "a+") if log_path else None
Apr 08 16:15:45 hivepowertracker python3[22956]: PermissionError: [Errno 13] Permission denied: 'geckodriver.log'
Apr 08 16:15:45 hivepowertracker systemd[1]: hive_tracker.service: Succeeded.
As you can see my permissions are for some reason not lining up. I have tried many different ways to solve this issue, but so far none have worked.
I will write an update if I figure it out!
Thanks for reading and thank you @trostparadox for the class!