1 """
2 email interface for mailing lists or private mail
3
4 @copyright: (c) 2011 hackmeeting U{http://sindominio.net/hackmeeting}
5 @author: Ruben Pollan
6 @organization: hackmeeting U{http://sindominio.net/hackmeeting}
7 @contact: meskio@sindominio.net
8 @license:
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the Do What The Fuck You Want To
11 Public License, Version 2, as published by Sam Hocevar. See
12 U{http://sam.zoy.org/projects/COPYING.WTFPL} for more details.
13 """
14
15 import poplib
16 import smtplib
17 import logging
18 from email.mime.text import MIMEText
19 from email.utils import parsedate
20 from time import mktime, sleep
21 from datetime import datetime
22
23 from emma.interface import Interface
24 from emma.sched import periodic
25 from emma.events import Event, trigger, subscribe
26
27 from message import Message
28
29
42
44 """
45 Fetch email
46
47 Will be run periodically fetching the email from a POP3 server.
48 """
49 if 'pop_user' in self.conf:
50 user = self.conf['pop_user']
51 passwd = self.conf['pop_pass']
52 elif 'user' in self.conf:
53 user = self.conf['user']
54 passwd = self.conf['pass']
55 else:
56 self.log(_("No user defined for pop"), logging.ERROR)
57 return
58
59 self.log(_("fetching email %(user)s@%(host)s")
60 % {'user': user, 'host': self.conf['pop_host']})
61 try:
62 if 'pop_ssl' in self.conf and self.conf['pop_ssl'] == "yes":
63 pop = poplib.POP3_SSL(self.conf['pop_host'])
64 else:
65 pop = poplib.POP3(self.conf['pop_host'])
66 pop.user(user)
67 pop.pass_(passwd)
68 except:
69 self.log(_(" error connecting by POP3"), logging.ERROR)
70 return
71
72 recv_event = Event(event='receive', interface='email', \
73 identifier=self.identifier)
74 cmd_event = Event(event='command', interface='email', \
75 identifier=self.identifier)
76 numMessages = len(pop.list()[1])
77 for i in range(numMessages):
78 message = Message(pop.retr(i + 1)[1])
79 trigger(recv_event, message)
80 for command in message.commands():
81 trigger(cmd_event, (command, message))
82 if self.conf['store'] == "yes":
83 self.store(message)
84 pop.dele(i + 1)
85
86 pop.quit()
87 self.log(_(" %s found") % numMessages)
88
90 msg['From'] = self.conf['smtp_address']
91 mime = MIMEText(msg['Body'])
92 mime['Subject'] = msg['Subject']
93 mime['To'] = msg['To']
94 self.send(msg['To'], mime.as_string())
95
96 - def send(self, to, msg):
97 if 'smtp_user' in self.conf:
98 user = self.conf['smtp_user']
99 passwd = self.conf['smtp_pass']
100 elif 'user' in self.conf:
101 user = self.conf['user']
102 passwd = self.conf['pass']
103 else:
104 self.log(_("No user defined for smtp"), logging.ERROR)
105 return
106
107 try:
108 if 'smtp_ssl' in self.conf and self.conf['smtp_ssl'] == "yes":
109 server = smtplib.SMTP_SSL(self.conf['smtp_host'])
110 else:
111 server = smtplib.SMTP(self.conf['smtp_host'])
112 if 'smtp_tls' in self.conf and self.conf['smtp_tls'] == "yes":
113 server.starttls()
114 server.login(user, passwd)
115 except:
116 self.log(_("Error sending email"), logging.ERROR)
117 return
118
119 fromaddr = self.conf['smtp_address']
120 server.sendmail(fromaddr, to, msg)
121 server.quit()
122
123 - def store(self, message):
124 """
125 Store message on the database
126
127 @type message: Message
128 @param message: message to be stored
129 """
130 dmsg = dict(message)
131 self.db.insert(dmsg)
132
134 old_version, version = Interface.update_db(self)
135 if not old_version or old_version == 0.1:
136 try:
137 res = self.db.find({}, ['_id', 'Date'])
138 except Exception:
139 self.log(_("db request error."))
140 res = []
141 for doc in res:
142 if not 'Date' in doc:
143 continue
144 date = doc['Date']
145 if type(date) != unicode:
146 continue
147 _id = doc['_id']
148
149 try:
150 timestamp = mktime(parsedate(date))
151 except TypeError:
152 self.log(_("time conversion error: %(id)s - %(date)s") %
153 {'id': _id, 'date': date})
154 continue
155 utcdate = datetime.fromtimestamp(timestamp)
156 try:
157 self.db.update({'_id': _id}, {"$set": {'Date': utcdate}})
158 except Exception:
159 self.log(_("db update error: %(id)s - %(date)s") %
160 {'id': _id, 'date': date})
161
162 return (old_version, version)
163