root / mailer / mailer.py

Revision 143:1d4505cef74f, 3.9 kB (checked in by Tarek Ziad?? <tarek@…>, 11 months ago)

fixed mail headers

Line 
1#!/usr/bin/python
2# -*- coding: UTF-8 -*-
3#
4# Copyright (c) 2007 Tarek Ziadé
5#
6# Authors:
7#   Tarek Ziadé <tarek@ziade.org>
8#
9# This program is free software; you can redistribute it and/or
10# modify it under the terms of the GNU General Public License
11# as published by the Free Software Foundation; either version 2
12# of the License, or (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program; if not, write to the Free Software
21# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22from datetime import datetime
23import os
24import sys
25import smtplib
26import logging
27from threading import Thread
28import time
29from base64 import b64decode
30from email.MIMEText import MIMEText
31
32from model import mailed_data, mail_data
33import settings
34
35class MailWorker(Thread):
36    """reads the SQLDB to do the jobs"""
37
38    def __init__(self):
39        Thread.__init__(self)
40        self.is_working = False
41        self.running = False
42
43    def _get_mails(self):
44        """returns lines of mail_data """
45        return mail_data.select().execute().fetchall()
46
47    def _get_message(self, mail):
48        """returns a Mime"""
49        data = b64decode(mail.data)
50        # some sgbd are in unicode
51        if isinstance(data, unicode):
52            data = data.decode('utf8')
53        msg = MIMEText(data)
54        msg['From'] = mail.sender
55        msg['To'] = mail.recipients
56        msg['Subject'] = mail.subject
57        msg.set_charset('utf-8')
58        msg['Date'] = mail.date.strftime('%c')
59        return msg
60
61    def _send_mail(self, mail):
62        """sends the mail"""
63        server = smtplib.SMTP(settings.SMTP_SERVER)
64        msg = self._get_message(mail)
65        try:
66            server.sendmail(msg['From'], msg['To'], msg.as_string())
67        finally:
68            server.quit()
69        logging.debug('mailer:message sent to %s' % msg['To'])
70
71    def _store_mail(self, mail, error=None):
72        """stores the mail"""
73        if error is not None:
74            error = str(error)
75        ins = mailed_data.insert()
76        ins.execute(subject=mail.subject, sender=mail.sender,
77                    original_id=mail.id, recipients=mail.recipients,
78                    error=error, data=mail.data, date=datetime.now(),
79                    status='processed')
80
81        # removes from original table
82        mail_data.delete().execute(id=mail.id)
83
84    def run(self):
85        """called threaded"""
86        self.running = True
87        logging.debug('mailer:launched')
88
89        while self.running:
90            # index
91            self.is_working = True
92            try:
93                # get mails to send
94                mails = self._get_mails()
95                for mail in mails:
96                    try:
97                        # send then
98                        self._send_mail(mail)
99                    except Exception, e:
100                        logging.debug('mailer:failed to send mail')
101                        self._store_mail(mail, e)
102                    else:
103                        self._store_mail(mail)
104            finally:
105                self.is_working = False
106                time.sleep(.1)
107
108        logging.debug('mailer:stopped')
109
110worker = None
111
112def start_server():
113    """starts the worker"""
114    global worker
115    worker = MailWorker()
116    worker.start()
117
118def stop_server():
119    """stops the worker"""
120    global worker
121    if worker is not None:
122        worker.running = False
123        worker.join()
124        worker = None
125
126def is_working():
127    """tells if the worker works"""
128    return worker.is_working
129
130# will make sure the thread stops when the process quits
131from atexit import register
132register(stop_server)
Note: See TracBrowser for help on using the browser.