| Home | Trees | Indices | Help |
|
|---|
|
|
1 # This application is released under the GNU General Public License
2 # v3 (or, at your option, any later version). You can find the full
3 # text of the license under http://www.gnu.org/licenses/gpl.txt.
4 # By using, editing and/or distributing this software you agree to
5 # the terms and conditions of this license.
6 # Thank you for using free software!
7
8 # mail module (c) Whise (Helder Fraga) 2008 <helder.fraga@hotmail.com>
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
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 #------CLASSES----------
78 #-----------------------
79
80 # error messages
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 # the current operational status of the mailcheck
92
93 # the mailcheck status
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
112 gobject.GObject.__init__(self)
113 # properties
114 self.name = name # name of backend
115 self.screenlet = screenlet # assigned MailCheckScreenlet
116 self.refreshing = False # not refreshing yet
117 self.unseen_count = 0 # number of unread messages on the server
118 self.status = MailCheckStatus.IDLE # status of the mailcheck backend
119 self.mailbox_status = MailboxStatus.UNKNOWN # status of the mailbox
120 self.error = '' # human-readable error message
121 self.options = [] # ???additonal ptions for backend
122 self.thread = None
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 # set status to REFRESH and call check_mail-handler to fetch mails
143 self.refreshing = True
144 self.check_mail()
145 self.emit('check_finished', self.status, self.mailbox_status)
146 # not refreshing anymore
147 self.refreshing = False
148
149
150 # IMAPBackend was contributed by Robert Gartler - thanks :)
152 """A backend for retrieving the mailcount from an IMAP server."""
153
158
160 # set default timeout for all socket connections to 30 secs
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 # IMAP4
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 # POP3
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 # Maildir
259 #
260 # This was reported to work with qmail, but it is untested with
261 # other mail servers -- for maximum portability, one could
262 # still rewrite next four lines using the mailbox Python module
263 # (in core libraries).
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 # Unix mbox
272 #
273 elif self.config['method'] == 'mbox':
274 mbox_path = getenv('MAIL',self.config['mailspool'])
275 # Get mbox inode properties
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 # mbox has not changed on disk
281 else:
282 size = 0 # mbox has changed
283 for m in self.mailbox.PortableUnixMailbox(file(mbox_path)):
284 if m.get('status','N').find('N') != -1:
285 size += 1
286
287 # Trick the system into thinking the mbox inode was not
288 # accessed since last modification. From 'manual.txt'
289 # of mutt 1.5.8:
290 #
291 # [ ... new mail is detected by comparing the last
292 # modification time to the last access time.
293 # Utilities like biff or frm or any other program
294 # which accesses the mailbox might cause Mutt to
295 # never detect new mail for that mailbox if they
296 # do not properly reset the access time.
297 # Backup tools are another common reason for updated
298 # access times. ]
299 #
300 self.utime(mbox_path, (s.st_atime, s.st_mtime))
301
302 # Remember size and time
303 #
304 self.mbox_size = s.st_size
305 self.mbox_mtime = s.st_mtime
306
307 # Uknown access method
308 #
309 else:
310 raise RuntimeError('unknown access method `%s\'' %
311 self.config['method'])
312 except:
313 # Exception handling: output a significant printout
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 # init additional attributes for this backend-type
334 # TODO: add POP3-specific options to the backend instead of having them
335 # defined in the screenlet by default (ideally they should be only shown
336 # when the POP3-backend is active
337
339 # set default timeout for all socket connections to 30 secs
340 socket.setdefaulttimeout(30000)
341 print "POP3Backend: Connecting to POP3-server ... please wait."
342 #self.screenlet.redraw_canvas()
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 # authenticate
350 user, pw = self.screenlet.pop3_account
351 #print "ACCOUNT IS %s/%s!!" % (o[0], o[1])
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 # get list with mails (response, list-of-mails)
361 resp = self.server.list()
362 if resp[0].startswith('+OK'):
363 messages = resp[1]
364 #print messages
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 #server.quit()
380 #return False
381 # close connection
382 self.server.quit()
383 return False
384
390
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0beta1 on Wed Jun 4 18:52:59 2008 | http://epydoc.sourceforge.net |