diff --git a/README.md b/README.md index aae4856..7eebbfb 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,10 @@ There is also few shortcuts to mark messages quickly: email.star() email.unstar() +You can send emails to multiple persons: + + g.send_mail("myfriend.com", subject, body, attachments) + ### Roadmap * Write tests * Better label support diff --git a/gmail/gmail.py b/gmail/gmail.py index 7fb09e1..a3d1554 100644 --- a/gmail/gmail.py +++ b/gmail/gmail.py @@ -1,17 +1,27 @@ import re import imaplib +import smtplib from mailbox import Mailbox from utf import encode as encode_utf7, decode as decode_utf7 from exceptions import * +# For SMTP +from email.mime.text import MIMEText +from email.mime.multipart import MIMEMultipart +from email.MIMEBase import MIMEBase +from email import Charset +from email.header import Header +from email.generator import Generator +from email import Encoders +from os.path import basename + class Gmail(): # GMail IMAP defaults GMAIL_IMAP_HOST = 'imap.gmail.com' GMAIL_IMAP_PORT = 993 # GMail SMTP defaults - # TODO: implement SMTP functions GMAIL_SMTP_HOST = "smtp.gmail.com" GMAIL_SMTP_PORT = 587 @@ -26,28 +36,12 @@ def __init__(self): self.mailboxes = {} self.current_mailbox = None - - # self.connect() - - def connect(self, raise_errors=True): - # try: - # self.imap = imaplib.IMAP4_SSL(self.GMAIL_IMAP_HOST, self.GMAIL_IMAP_PORT) - # except socket.error: - # if raise_errors: - # raise Exception('Connection failure.') - # self.imap = None - self.imap = imaplib.IMAP4_SSL(self.GMAIL_IMAP_HOST, self.GMAIL_IMAP_PORT) - - # self.smtp = smtplib.SMTP(self.server,self.port) + self.smtp = smtplib.SMTP(self.GMAIL_SMTP_HOST, self.GMAIL_SMTP_PORT) # self.smtp.set_debuglevel(self.debug) - # self.smtp.ehlo() - # self.smtp.starttls() - # self.smtp.ehlo() - - return self.imap - + self.smtp.ehlo() + self.smtp.starttls() def fetch_mailboxes(self): response, mailbox_list = self.imap.list() @@ -88,8 +82,6 @@ def delete_mailbox(self, mailbox_name): self.imap.delete(mailbox_name) del self.mailboxes[mailbox_name] - - def login(self, username, password): self.username = username self.password = password @@ -99,15 +91,14 @@ def login(self, username, password): try: imap_login = self.imap.login(self.username, self.password) - self.logged_in = (imap_login and imap_login[0] == 'OK') + smtp_login = self.smtp.login(self.username, self.password) + + self.logged_in = (imap_login and imap_login[0] == 'OK' and smtp_login) if self.logged_in: self.fetch_mailboxes() - except imaplib.IMAP4.error: + except: raise AuthenticationError - - # smtp_login(username, password) - return self.logged_in def authenticate(self, username, access_token): @@ -130,16 +121,15 @@ def authenticate(self, username, access_token): def logout(self): self.imap.logout() + self.smtp.close() self.logged_in = False - def label(self, label_name): return self.mailbox(label_name) def find(self, mailbox_name="[Gmail]/All Mail", **kwargs): box = self.mailbox(mailbox_name) return box.mail(**kwargs) - def copy(self, uid, to_mailbox, from_mailbox=None): if from_mailbox: @@ -157,7 +147,6 @@ def fetch_multiple_messages(self, messages): return messages - def labels(self, require_unicode=False): keys = self.mailboxes.keys() if require_unicode: @@ -184,3 +173,51 @@ def important(self): def mail_domain(self): return self.username.split('@')[-1] + + def noop(self): + return self.imap.noop() + + def add_files(self, message, attachment): + for filename in attachment: + try: + file_handle = open(filename, "rb") + except: + file_handle = None + + if file_handle == None: + continue + + content = file_handle.read() + attach_part = MIMEBase('application', 'octet-stream') + attach_part.set_payload(content) + Encoders.encode_base64(attach_part) + attach_part.add_header('Content-Disposition', + 'attachment; filename="%s"' % basename(filename)) + + message.attach(attach_part) + file_handle.close() + + def send_mail(self, recipient, subject, body, attachment): + recipient = recipient if type(recipient) is list else [recipient] + attachment = attachment if type(attachment) is list else [attachment] + + # For unicode message + message = MIMEMultipart('alternative') + message['Subject'] = "%s" % Header(subject, 'utf-8') + message['From'] = "%s" % (Header(self.username, 'utf-8')) + + recipient_string = "" + for name in recipient: + recipient_string = recipient_string + name + "," + # Cut the last comma + recipient_string = recipient_string[0: len(recipient_string) - 1] + + message['To'] = "%s" % (Header(recipient_string, 'utf-8')) + message.add_header('reply-to', "%s" % (Header(self.username, 'utf-8'))) + + # Attach text and attachment parts + text_part = MIMEText(body, 'plain', 'UTF-8') + message.attach(text_part) + self.add_files(message, attachment) + + self.smtp.sendmail(self.username, recipient, message.as_string())