]> git.ipfire.org Git - pbs.git/blob - src/buildservice/messages.py
messages: Fix sending emails
[pbs.git] / src / buildservice / messages.py
1 #!/usr/bin/python
2
3 import logging
4 import smtplib
5 import subprocess
6 import tornado.locale
7
8 from email.mime.text import MIMEText
9
10 from . import base
11
12 class Messages(base.Object):
13 def add(self, to, subject, text, frm=None):
14 subject = "%s %s" % (self.pakfire.settings.get("email_subject_prefix"), subject)
15
16 # Get default sender from the settings.
17 if not frm:
18 frm = self.pakfire.settings.get("email_from")
19
20 self.db.execute("INSERT INTO user_messages(frm, to, subject, text)"
21 " VALUES(%s, %s, %s, %s)", frm, to, subject, text)
22
23 def get_all(self, limit=None):
24 query = "SELECT * FROM user_messages ORDER BY time_added ASC"
25 if limit:
26 query += " LIMIT %d" % limit
27
28 return self.db.query(query)
29
30 @property
31 def count(self):
32 ret = self.db.get("SELECT COUNT(*) as count FROM user_messages")
33
34 return ret.count
35
36 def delete(self, id):
37 self.db.execute("DELETE FROM user_messages WHERE id = %s", id)
38
39 def process_queue(self):
40 # Get 10 messages at a time and send them one after the other
41 while True:
42 messages = self.get_all(limit=10)
43
44 for message in messages:
45 self.send_msg(message)
46 else:
47 break
48
49 def send_to_all(self, recipients, subject, body, format=None):
50 """
51 Sends an email to all recipients and does the translation.
52 """
53 if not format:
54 format = {}
55
56 for recipient in recipients:
57 if not recipient:
58 logging.warning("Ignoring empty recipient.")
59 continue
60
61 # We try to get more information about the user from the database
62 # like the locale.
63 user = self.pakfire.users.get_by_email(recipient)
64 if user:
65 # Get locale that the user prefers.
66 locale = tornado.locale.get(user.locale)
67 else:
68 # Get the default locale.
69 locale = tornado.locale.get()
70
71 # Translate the message.
72 _subject = locale.translate(subject) % format
73 _body = locale.translate(body) % format
74
75 # If we know the real name of the user we add the realname to
76 # the recipient field.
77 if user:
78 recipient = "%s <%s>" % (user.realname, user.email)
79
80 # Add the message to the queue that it is sent.
81 self.add(recipient, _subject, _body)
82
83 def send_msg(self, msg):
84 if not msg.to:
85 logging.warning("Dropping message with empty recipient.")
86 return
87
88 logging.debug("Sending mail to %s: %s" % (msg.to, msg.subject))
89
90 # Preparing mail content.
91 mail = MIMEText(msg.text.encode("latin-1"))
92 mail["From"] = msg.frm.encode("latin-1")
93 mail["To"] = msg.to.encode("latin-1")
94 mail["Subject"] = msg.subject.encode("latin-1")
95 #mail["Content-type"] = "text/plain; charset=utf-8"
96
97 #smtp = smtplib.SMTP("localhost")
98 #smtp.sendmail(msg.frm, msg.to.split(", "), mail.as_string())
99 #smtp.quit()
100
101 # We use sendmail here to workaround problems with the mailserver
102 # communication.
103 # So, just call /usr/lib/sendmail, pipe the message in and see
104 # what sendmail tells us in return.
105 sendmail = ["/usr/lib/sendmail", "-t"]
106 p = subprocess.Popen(sendmail, bufsize=0, close_fds=True,
107 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
108
109 stdout, stderr = p.communicate(mail.as_string())
110
111 # Wait until sendmail has finished.
112 p.wait()
113
114 if p.returncode:
115 raise Exception, "Could not send mail: %s" % stderr
116
117 # If everything was okay, we can delete the message in the database.
118 self.delete(msg.id)