def send(self, subject, message, attach=[]): # Create message msg = MIMEMultipart() msg.set_unixfrom('author') msg['To'] = email.utils.formataddr(('Recipient', self.to_email)) msg['From'] = email.utils.formataddr(('Author', '*****@*****.**')) msg['Subject'] = subject msg.attach(MIMEText(message)) try: self.server.set_debuglevel(False) # identify ourselves, prompting server for supported features self.server.ehlo() # If we can encrypt this session, do it if self.server.has_extn('STARTTLS'): self.server.starttls() self.server.ehlo() # re-identify ourselves over TLS connection # Attach files, if we have anything for atta in attach: part = MIMEBase('application', "octet-stream") part.set_payload(open(atta, "rb").read()) Encoders.encode_base64(part) part.add_header( 'Content-Disposition', 'attachment; filename="%s"' % os.path.basename(atta)) msg.attach(part) self.server.login(self.username, self.password) self.server.sendmail('*****@*****.**', [self.to_email], msg.as_string()) finally: self.server.quit()
def _convert_to_mbox_msg(self, msg): file_ids = list(msg.objectIds('File')) encoding = "utf-8" # true only if we have attachments if file_ids: enc_msg = MIMEMultipart() txt = MIMEText(msg.body.encode(encoding)) enc_msg.attach(txt) else: enc_msg = Message() enc_msg.set_payload(msg.body.encode(encoding)) enc_msg['From'] = encode_header(msg.from_addr, encoding) enc_msg['To'] = encode_header(self.context.mailto, encoding) enc_msg['Subject'] = encode_header(msg.subject, encoding).replace("\n", " ").strip() enc_msg['Date'] = encode_header(str(msg.date), encoding) enc_msg['Message-id'] = encode_header(msg.message_id, encoding) if msg.references: enc_msg['References'] = encode_header(" ".join(msg.references), encoding) if msg.in_reply_to: enc_msg['In-reply-to'] = encode_header(msg.in_reply_to, encoding) ctime = str(msg.date) enc_msg.set_unixfrom("From %s %s" % (parseaddr(msg.from_addr)[1], ctime)) for file_id in file_ids: file = msg._getOb(file_id) data = file.data if not isinstance(data, basestring): data = str(data) content_type = file.getContentType() if content_type == 'message/rfc822': attachment = message_from_string(data) else: attachment = Message() attachment.add_header('Content-Disposition', 'attachment', filename=file.title) attachment.add_header('Content-Type', content_type) attachment.set_payload(data) enc_msg.attach(attachment) try: retval = enc_msg.as_string(unixfrom=True) except TypeError, e: raise
def parse_and_deliver(maildir, url, statedir): feedhandle = None headers = None # first check if we know about this feed already feeddb = dbm.open(os.path.join(statedir, "feeds"), "c") if feeddb.has_key(url): data = feeddb[url] data = cgi.parse_qs(data) response = open_url("HEAD", url) headers = None if response: headers = response.getheaders() ischanged = False try: for header in headers: if header[0] == "content-length": if header[1] != data["content-length"][0]: ischanged = True elif header[0] == "etag": if header[1] != data["etag"][0]: ischanged = True elif header[0] == "last-modified": if header[1] != data["last-modified"][0]: ischanged = True elif header[0] == "content-md5": if header[1] != data["content-md5"][0]: ischanged = True except: ischanged = True if ischanged: response = open_url("GET", url) if response != None: headers = response.getheaders() feedhandle = response else: sys.stderr.write("Failed to fetch feed: %s\n" % (url)) return else: return # don't need to do anything, nothings changed. else: response = open_url("GET", url) if response != None: headers = response.getheaders() feedhandle = response else: sys.stderr.write("Failed to fetch feed: %s\n" % (url)) return fp = feedparser.parse(feedhandle) db = dbm.open(os.path.join(statedir, "seen"), "c") for item in fp["items"]: # have we seen it before? # need to work out what the content is first... if item.has_key("content"): content = item["content"][0]["value"] else: if item.has_key("description"): content = item["description"] else: content = u"" md5sum = md5.md5(content.encode("utf-8")).hexdigest() # make sure content is unicode encoded if not isinstance(content, unicode): cd_res = chardet.detect(content) chrset = cd_res["encoding"] print "detected charset %s for item %s" % (chrset, item["link"]) content = content.decode(chrset) prevmessageid = None db_guid_key = None db_link_key = (url + u"|" + item["link"]).encode("utf-8") # check if there's a guid too - if that exists and we match the md5, # return if item.has_key("guid"): db_guid_key = (url + u"|" + item["guid"]).encode("utf-8") if db.has_key(db_guid_key): data = db[db_guid_key] data = cgi.parse_qs(data) if data["contentmd5"][0] == md5sum: continue if db.has_key(db_link_key): data = db[db_link_key] data = cgi.parse_qs(data) if data.has_key("message-id"): prevmessageid = data["message-id"][0] if data["contentmd5"][0] == md5sum: continue try: author = item["author"] except: author = url # create a basic email message msg = MIMEMultipart("alternative") messageid = ( "<" + datetime.datetime.now().strftime("%Y%m%d%H%M") + "." + "".join([random.choice(string.ascii_letters + string.digits) for a in range(0, 6)]) + "@" + socket.gethostname() + ">" ) msg.add_header("Message-ID", messageid) msg.set_unixfrom('"%s" <rss2maildir@localhost>' % (url)) msg.add_header("From", '"%s" <rss2maildir@localhost>' % (author.encode("utf-8"))) msg.add_header("To", '"%s" <rss2maildir@localhost>' % (url.encode("utf-8"))) if prevmessageid: msg.add_header("References", prevmessageid) createddate = datetime.datetime.now().strftime("%a, %e %b %Y %T -0000") try: createddate = datetime.datetime(*item["updated_parsed"][0:6]).strftime("%a, %e %b %Y %T -0000") except: pass msg.add_header("Date", createddate) msg.add_header("X-rss2maildir-rundate", datetime.datetime.now().strftime("%a, %e %b %Y %T -0000")) title = html.fromstring(item["title"]).text title = re.sub(u"<", u"<", title) title = re.sub(u">", u">", title) msg.add_header("Subject", str(Header(title.encode("utf-8"), "utf-8"))) msg.set_default_type("text/plain") htmlcontent = content.encode("utf-8") htmlcontent = "%s\n\n<p>Item URL: <a href='%s'>%s</a></p>" % (content, item["link"], item["link"]) htmlpart = MIMEText(htmlcontent.encode("utf-8"), "html", "utf-8") msg.attach(htmlpart) # start by working out the filename we should be writting to, we do # this following the normal maildir style rules fname = ( str(os.getpid()) + "." + socket.gethostname() + "." + "".join([random.choice(string.ascii_letters + string.digits) for a in range(0, 10)]) + "." + datetime.datetime.now().strftime("%s") ) fn = os.path.join(maildir, "tmp", fname) fh = open(fn, "w") fh.write(msg.as_string()) fh.close() # now move it in to the new directory newfn = os.path.join(maildir, "new", fname) os.link(fn, newfn) os.unlink(fn) # now add to the database about the item if prevmessageid: messageid = prevmessageid + " " + messageid if item.has_key("guid") and item["guid"] != item["link"]: data = urllib.urlencode((("message-id", messageid), ("created", createddate), ("contentmd5", md5sum))) db[db_guid_key] = data try: data = db[db_link_key] data = cgi.parse_qs(data) newdata = urllib.urlencode( (("message-id", messageid), ("created", data["created"][0]), ("contentmd5", data["contentmd5"][0])) ) db[db_link_key] = newdata except: db[db_link_key] = data else: data = urllib.urlencode((("message-id", messageid), ("created", createddate), ("contentmd5", md5sum))) db[db_link_key] = data if headers: data = [] for header in headers: if header[0] in ["content-md5", "etag", "last-modified", "content-length"]: data.append((header[0], header[1])) if len(data) > 0: data = urllib.urlencode(data) feeddb[url] = data db.close() feeddb.close()