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