1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import screenlets
17 import dbus
18 import os
19 import sys
20 import stat
21 import gettext
22 import re
23 import urllib
24 gettext.textdomain('screenlets')
25 gettext.bindtextdomain('screenlets', screenlets.INSTALL_PREFIX + '/share/locale')
26 import gobject
27 import socket
28 import threading
29 try:
30 import poplib
31 except ImportError, err:
32 print " !!!Please install python poplib :", err
33 try:
34 import imaplib
35 except ImportError, err:
36 print " !!!Please install python imaplib :", err
37
38 try:
39 import gnomevfs
40 except ImportError, err:
41 print " !!!Please install python gnomevfs :", err
42
43
45 """This gets the unread mail number of kmail"""
46 kmail = commands.getoutput("dcop kmail default checkMail; sleep 5; echo ' ' | tr -d '\n'; dcop kmail KMailIface getFolder /Krealia/Inbox > /dev/null; dcop 'DCOPRef(kmail,FolderIface)' unreadMessages | tr -d '\n'; echo ' '")
47 if kmail.find("ERROR: Couldn't attach to DCOP server!") != -1:
48 return None
49 else:
50 return kmail
51
53 """This output the number of messages of gmail box"""
54 f = os.popen("wget --no-check-certificate -qO - https://%s:%s@mail.google.com/mail/feed/atom" % (urllib.pathname2url(login), urllib.pathname2url(password)))
55 a = f.read()
56 f.close()
57 match = re.search("<fullcount>([0-9]+)</fullcount>", a)
58 if match == None:
59 return None
60 else:
61 return match.group(1)
62
63
64
66 """This output the number of messages of mail box"""
67 try:
68 m = poplib.POP3_SSL(server)
69 except:
70 try:
71 m = poplib.POP3(server)
72 except:
73 return None
74
75 m.user(login)
76 m.pass_(passwd)
77 out = m.stat()
78 m.quit()
79 num = out[0]
80 return num
81
82
83 -def send_mail(smtp_server,fromaddr,toaddrs, subject,msg):
84 """Send mail via SMTP"""
85 import smtplib
86 server = smtplib.SMTP(smtp_server)
87 server.sendmail(fromaddr, toaddrs, subject + msg)
88 server.quit()
89
90
91
92
93
94 MSG_CONNECTION_FAILED = "Error while connecting to server."
95 MSG_FETCH_MAILS_FAILED = "Unable to retrieve mails from server."
96 MSG_AUTH_FAILED = """Error on login - invalid login data given? Some hosts
97 may block connections for a certain interval before allowing reconnects."""
98
99
105
106
112
114 """The backend class which performs checking for mail and offers access
115 to the current mail-backend. By subclassing this class you can add multiple
116 mail-backends to the MailCheckScreenlet (e.g. pop3, maildir, imap,
117 gmail, ...)."""
118
119
120 __gsignals__ = {
121 'check_finished' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,(gobject.TYPE_INT, gobject.TYPE_INT,))
122 }
123
125 gobject.GObject.__init__(self)
126
127 self.name = name
128 self.screenlet = screenlet
129 self.refreshing = False
130 self.unseen_count = 0
131 self.status = MailCheckStatus.IDLE
132 self.mailbox_status = MailboxStatus.UNKNOWN
133 self.error = ''
134 self.options = []
135 self.thread = None
136 self.mailcount = 0
137
139 """This handler should be overridden by subclasses to add new types
140 of checking mails in a backend. This handler has to set self.mailcount
141 to the number of mails found in the backend. The return value is
142 ignored, set self.error and self.status to return results."""
143
145 """Stop receiving mails from the backend. This should be overridden
146 by subclasses."""
147 self.thread = None
148
150 """Start receiving mails from the backend. Runs self.__execute as
151 a separate thread."""
152 self.thread = threading.Thread(target=self.__execute).start()
153
155 """Execute the thread and call the check-mail function."""
156
157 self.refreshing = True
158 self.check_mail()
159 self.emit('check_finished', self.status, self.mailbox_status)
160
161 self.refreshing = False
162
163
164
166 """A backend for retrieving the mailcount from an IMAP server."""
167
172
174
175 socket.setdefaulttimeout(30000)
176 print "IMAPBackend: Connecting to IMAP-server ... please wait."
177 self.status = MailCheckStatus.REFRESH
178 try:
179 self.server = imaplib.IMAP4_SSL(self.screenlet.imap_host)
180 except:
181 try:
182 self.server = imaplib.IMAP4(self.screenlet.imap_host)
183 except:
184 self.error = MSG_CONNECTION_FAILED
185 self.status = MailCheckStatus.ERROR
186 return False
187 user, passwd = self.screenlet.imap_account
188 try:
189 self.server.login(user, passwd)
190 except:
191 self.error = MSG_AUTH_FAILED
192 self.status = MailCheckStatus.ERROR
193 self.server.logout()
194 return False
195
196 self.server.select()
197 typ, data = self.server.search(None, 'UNSEEN')
198 if typ == 'OK':
199 self.unseen_count = len(data[0].split())
200 if self.unseen_count > 0:
201 typ, data = self.server.search(None, 'NEW')
202 if typ == 'OK':
203 if len(data[0].split()) > 0:
204 self.mailbox_status = MailboxStatus.NEW_MAIL
205 print "NEW_MAIL"
206 else:
207 self.mailbox_status = MailboxStatus.UNREAD_MAIL
208 print "UNREAD_MAIL"
209 else:
210 print "IMAP error (checking new count): " + typ
211 else:
212 self.mailbox_status = MailboxStatus.ALL_READ
213 self.status = MailCheckStatus.IDLE
214 else:
215 print "IMAP error (checking unseen count): " + typ
216 self.error = MSG_FETCH_MAILS_FAILED
217 self.status = MailCheckStatus.ERROR
218 self.mailbox_status = MailboxStatus.UNKNOWN
219 self.server.close()
220 self.server.logout()
221 return False
222
224 if self.server:
225 self.server.close()
226 self.server.logout()
227 self.thread.join()
228 self.thread = None
229
231 """
232 Class that retrieve the information from an Imap, Pop or mbox account
233
234 All the email-related operation lies in this few lines
235 """
236 import imaplib
237 import poplib
238 import mailbox
239 from sys import exc_info
240 from os import stat, utime, path, listdir
241
242
244 self.config=config
245 self.last_size=-1
246 self.size=-1
247 self.mbox_size = 0
248 self.mbox_mtime = 0
249
251 self.last_size=self.size
252
253 try:
254
255
256 if self.config['method']=='imap4':
257 s = self.imaplib.__dict__['IMAP4'+['','_SSL']
258 [self.config['ssl']]]\
259 (self.config['host'])
260 s.login(self.config['user_name'],self.config['user_password'])
261 s.select()
262 size = len(s.search(None, 'UNSEEN')[1][0].split())
263 s.logout()
264
265
266
267 elif self.config['method']=='pop3':
268 s = self.poplib.__dict__['POP3'+['','_SSL']
269 [self.config['ssl']]]\
270 (self.config['host'])
271 s.user(self.config['user_name'])
272 s.pass_(self.config['user_password'])
273 size = len(s.list()[1])
274
275
276
277
278
279
280
281
282 elif self.config['method'] == 'maildir':
283 mdir_path = getenv('MAILDIR', self.config['mailspool'])
284 mdir_new = self.path.join(self.path.expanduser(mdir_path), 'new')
285
286 size = len([f for f in self.listdir(mdir_new) if f[0] != '.'])
287
288
289
290 elif self.config['method'] == 'mbox':
291 mbox_path = getenv('MAIL',self.config['mailspool'])
292
293
294 s = self.stat(mbox_path)
295 if (s.st_size == self.mbox_size and
296 s.st_mtime == self.mbox_mtime):
297 size = self.last_size
298 else:
299 size = 0
300 for m in self.mailbox.PortableUnixMailbox(file(mbox_path)):
301 if m.get('status','N').find('N') != -1:
302 size += 1
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317 self.utime(mbox_path, (s.st_atime, s.st_mtime))
318
319
320
321 self.mbox_size = s.st_size
322 self.mbox_mtime = s.st_mtime
323
324
325
326 else:
327 raise RuntimeError('unknown access method `%s\'' %
328 self.config['method'])
329 except:
330
331
332 size = -1
333 print '='*80
334 print traceback.print_exception(*self.exc_info())
335 print '='*80
336 print self.config
337 print '='*80
338
339 self.size = size
340 return size
341
342
344 """A backend for retrieving the mailcount from a POP3 server."""
345
350
351
352
353
354
356
357 socket.setdefaulttimeout(30000)
358 print "POP3Backend: Connecting to POP3-server ... please wait."
359
360 try:
361 self.server = poplib.POP3_SSL(self.screenlet.pop3_server)
362 except:
363 try:
364 self.server = poplib.POP3(self.screenlet.pop3_server)
365 except:
366 self.error = MSG_CONNECTION_FAILED
367 self.status = MailCheckStatus.ERROR
368 return False
369
370 user, pw = self.screenlet.pop3_account
371
372 try:
373 self.server.user(user)
374 self.server.pass_(pw)
375 except:
376 self.error = MSG_AUTH_FAILED
377 self.status = MailCheckStatus.ERROR
378 self.server.quit()
379 return False
380
381 resp = self.server.list()
382 if resp[0].startswith('+OK'):
383 messages = resp[1]
384
385 msgnum = len(messages)
386 if msgnum > self.mailcount:
387 diff = msgnum - self.mailcount
388 self.mailcount = msgnum
389 self.mailbox_status = MailboxStatus.NEW_MAIL
390 self.status = MailCheckStatus.GOT_MAIL
391 print "GOT_MAIL"
392 elif msgnum <= self.mailcount:
393 print "set status to IDLE (POP3Backend.check_mail)"
394 self.mailbox_status = MailboxStatus.ALL_READ
395 self.mailcount = msgnum
396 self.status = MailCheckStatus.IDLE
397 print "IDLE"
398 else:
399 self.error = MSG_FETCH_MAILS_FAILED
400 self.status = MailCheckStatus.ERROR
401
402
403
404 self.server.quit()
405 return False
406
408 if self.server:
409 self.server.quit()
410 self.thread.join()
411 self.thread = None
412