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://" + login + ":" + password + "@mail.google.com/mail/feed/atom")
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 m = poplib.POP3(server)
62 m.user(login)
63 m.pass_(passwd)
64 out = m.stat()
65 m.quit()
66 num = out[0]
67 return num
68
69
70 -def send_mail(smtp_server,fromaddr,toaddrs, subject,msg):
71 """Send mail via SMTP"""
72 import smtplib
73 server = smtplib.SMTP(smtp_server)
74 server.sendmail(fromaddr, toaddrs, subject + msg)
75 server.quit()
76
77
78
79
80
81 MSG_CONNECTION_FAILED = "Error while connecting to server."
82 MSG_FETCH_MAILS_FAILED = "Unable to retrieve mails from server."
83 MSG_AUTH_FAILED = """Error on login - invalid login data given? Some hosts
84 may block connections for a certain interval before allowing reconnects."""
85
86
92
93
99
101 """The backend class which performs checking for mail and offers access
102 to the current mail-backend. By subclassing this class you can add multiple
103 mail-backends to the MailCheckScreenlet (e.g. pop3, maildir, imap,
104 gmail, ...)."""
105
106
107 __gsignals__ = {
108 'check_finished' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,(gobject.TYPE_INT, gobject.TYPE_INT,))
109 }
110
123
125 """This handler should be overridden by subclasses to add new types
126 of checking mails in a backend. This handler has to set self.mailcount
127 to the number of mails found in the backend. The return value is
128 ignored, set self.error and self.status to return results."""
129
131 """Stop receiving mails from the backend. This should be overridden
132 by subclasses."""
133 self.thread = None
134
136 """Start receiving mails from the backend. Runs self.__execute as
137 a separate thread."""
138 self.thread = threading.Thread(target=self.__execute).start()
139
141 """Execute the thread and call the check-mail function."""
142
143 self.refreshing = True
144 self.check_mail()
145 self.emit('check_finished', self.status, self.mailbox_status)
146
147 self.refreshing = False
148
149
150
152 """A backend for retrieving the mailcount from an IMAP server."""
153
158
160
161 socket.setdefaulttimeout(30000)
162 print "IMAPBackend: Connecting to IMAP-server ... please wait."
163 self.status = MailCheckStatus.REFRESH
164 try:
165 self.server = imaplib.IMAP4(self.screenlet.imap_host)
166 except:
167 self.error = MSG_CONNECTION_FAILED
168 self.status = MailCheckStatus.ERROR
169 return False
170 user, passwd = self.screenlet.imap_account
171 try:
172 self.server.login(user, passwd)
173 except:
174 self.error = MSG_AUTH_FAILED
175 self.status = MailCheckStatus.ERROR
176 self.server.logout()
177 return False
178
179 self.server.select()
180 typ, data = self.server.search(None, 'UNSEEN')
181 if typ == 'OK':
182 self.unseen_count = len(data[0].split())
183 if self.unseen_count > 0:
184 typ, data = self.server.search(None, 'NEW')
185 if typ == 'OK':
186 if len(data[0].split()) > 0:
187 self.mailboxstatus = MailboxStatus.NEW_MAIL
188 print "NEW_MAIL"
189 else:
190 self.mailboxstatus = MailboxStatus.UNREAD_MAIL
191 print "UNREAD_MAIL"
192 else:
193 print "IMAP error (checking new count): " + typ
194 else:
195 self.mailboxstatus = MailboxStatus.ALL_READ
196 self.status = MailCheckStatus.IDLE
197 else:
198 print "IMAP error (checking unseen count): " + typ
199 self.error = MSG_FETCH_MAILS_FAILED
200 self.status = MailCheckStatus.ERROR
201 self.mailboxstatus = MailboxStatus.UNKNOWN
202 self.server.close()
203 self.server.logout()
204 return False
205
207 if self.server:
208 self.server.close()
209 self.server.logout()
210 self.thread.join()
211 self.thread = None
212
214 """
215 Class that retrieve the information from an Imap, Pop or mbox account
216
217 All the email-related operation lies in this few lines
218 """
219 import imaplib
220 import poplib
221 import mailbox
222 from sys import exc_info
223 from os import stat, utime, path, listdir
224
225
227 self.config=config
228 self.last_size=-1
229 self.size=-1
230 self.mbox_size = 0
231 self.mbox_mtime = 0
232
234 self.last_size=self.size
235
236 try:
237
238
239 if self.config['method']=='imap4':
240 s = self.imaplib.__dict__['IMAP4'+['','_SSL']
241 [self.config['ssl']]]\
242 (self.config['host'])
243 s.login(self.config['user_name'],self.config['user_password'])
244 s.select()
245 size = len(s.search(None, 'UNSEEN')[1][0].split())
246 s.logout()
247
248
249
250 elif self.config['method']=='pop3':
251 s = self.poplib.__dict__['POP3'+['','_SSL']
252 [self.config['ssl']]]\
253 (self.config['host'])
254 s.user(self.config['user_name'])
255 s.pass_(self.config['user_password'])
256 size = len(s.list()[1])
257
258
259
260
261
262
263
264
265 elif self.config['method'] == 'maildir':
266 mdir_path = getenv('MAILDIR', self.config['mailspool'])
267 mdir_new = self.path.join(self.path.expanduser(mdir_path), 'new')
268
269 size = len([f for f in self.listdir(mdir_new) if f[0] != '.'])
270
271
272
273 elif self.config['method'] == 'mbox':
274 mbox_path = getenv('MAIL',self.config['mailspool'])
275
276
277 s = self.stat(mbox_path)
278 if (s.st_size == self.mbox_size and
279 s.st_mtime == self.mbox_mtime):
280 size = self.last_size
281 else:
282 size = 0
283 for m in self.mailbox.PortableUnixMailbox(file(mbox_path)):
284 if m.get('status','N').find('N') != -1:
285 size += 1
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300 self.utime(mbox_path, (s.st_atime, s.st_mtime))
301
302
303
304 self.mbox_size = s.st_size
305 self.mbox_mtime = s.st_mtime
306
307
308
309 else:
310 raise RuntimeError('unknown access method `%s\'' %
311 self.config['method'])
312 except:
313
314
315 size = -1
316 print '='*80
317 print traceback.print_exception(*self.exc_info())
318 print '='*80
319 print self.config
320 print '='*80
321
322 self.size = size
323 return size
324
325
327 """A backend for retrieving the mailcount from a POP3 server."""
328
333
334
335
336
337
339
340 socket.setdefaulttimeout(30000)
341 print "POP3Backend: Connecting to POP3-server ... please wait."
342
343 try:
344 self.server = poplib.POP3(self.screenlet.pop3_server)
345 except:
346 self.error = MSG_CONNECTION_FAILED
347 self.status = MailCheckStatus.ERROR
348 return False
349
350 user, pw = self.screenlet.pop3_account
351
352 try:
353 self.server.user(user)
354 self.server.pass_(pw)
355 except:
356 self.error = MSG_AUTH_FAILED
357 self.status = MailCheckStatus.ERROR
358 self.server.quit()
359 return False
360
361 resp = self.server.list()
362 if resp[0].startswith('+OK'):
363 messages = resp[1]
364
365 msgnum = len(messages)
366 if msgnum > self.unseen_count:
367 diff = msgnum - self.mailcount
368 self.mailcount = msgnum
369 self.status = MailCheckStatus.GOT_MAIL
370 print "GOT_MAIL"
371 elif msgnum <= self.mailcount:
372 print "set status to IDLE (POP3Backend.check_mail)"
373 self.mailcount = msgnum
374 self.status = MailCheckStatus.IDLE
375 print "IDLE"
376 else:
377 self.error = MSG_FETCH_MAILS_FAILED
378 self.status = MailCheckStatus.ERROR
379
380
381
382 self.server.quit()
383 return False
384
386 if self.server:
387 self.server.quit()
388 self.thread.join()
389 self.thread = None
390