############################ # Apply against mailer 0.0.6 # ############################ diff --minimal -u a/README b/README --- a/README 2005-06-12 15:36:03.000000000 -0400 +++ b/README 2005-06-22 14:02:20.000000000 -0400 @@ -7,7 +7,7 @@ email account, either imap4, pop3 or local mbox. This should run on every python implementation >= 2.3.0, with adesklets >= 0.4.0. -This was tested on python 2.4.1 final, on a linux 2.6.11 glibc 2.3.4 +This was tested on python 2.4.1 final, on a linux 2.6.12 glibc 2.3.4 x86 machine. Just run the 'mailer.py' script from its final location on you disk @@ -16,6 +16,14 @@ Have a look at http://adesklets.sf.net/ for more details on this program. +What's new in version 0.0.7 +--------------------------- +Merged many changes suggested by dessaya, from the forums. mbox code +optimization tune up, mutt confusion fix, new configuration options +'click_anytime' that can make the program_on_click accessible regardless +of the account state, and 'window_never_shrink', that makes the window +only changes its size when more space is needed. Big thanks to him! + What's new in version 0.0.6 --------------------------- Add a relevant error trace output to the console every time the information @@ -54,4 +62,5 @@ your config.txt slightly. What was once a 'imap' boolean no longuer exists, but is not replaced with a more generic 'method' string. Other modifications are minor. + =========================== Common subdirectories: a/icons and b/icons diff --minimal -u a/mailer.py b/mailer.py --- a/mailer.py 2005-06-12 15:36:03.000000000 -0400 +++ b/mailer.py 2005-06-22 14:04:06.000000000 -0400 @@ -34,7 +34,7 @@ This desklets display in a simple form the number of new messages in a given imap, pop or mbox email account. -This was tested on python 2.4.1 final, on a linux 2.6.11 glibc 2.3.4 +This was tested on python 2.4.1 final, on a linux 2.6.12 glibc 2.3.4 x86 machine. Just run this script from its final location on you disk to start the desklet. @@ -65,11 +65,13 @@ MAIL from environment is used; this value is a fallback if MAIL is not defined. - the delay between checks (delay, in seconds: less than a minute will - be ignored) + be ignored for all methods but mbox) - whether you want to connect over an encrypted connection or not (only make sense with pop3 and imap4 servers) - the program (email client and alike) to launch when the applet is clicked on (program_on_click) + - whether program_on_click should be launchable when there is no + new email detected (click_anytime) - the program (sound notification and such) to launch when the number of new emails grown since last check (program_on_new - generate a PC speaker beep by default) @@ -103,6 +105,11 @@ - icon_width and icon_height are the dimensions on final icon on screen. It will always be scaled appropriatly, regardless of its initial size. + - 'window_never_shrink' is a boolean specifying that the window should + never shrink back in size when it could. It is usefull, for instance, I you + place desklets against the right or bottom side of your screen to avoid some + displacements. + - `backround_color' can be set to None to remove completely background effect - `background_gradient_cutpoint' is the x coordinate at which the background @@ -119,7 +126,7 @@ """ cfg_default = { 'method' : 'imap4', - 'host': 'voidvoid.org', + 'host': 'example.org', 'user_name': 'nobody', 'user_password': 'whoami', 'ssl': False, 'mailspool': '/dev/null', @@ -142,9 +149,11 @@ 'icons' : [ 'error.png', 'noemail.png', 'email.png' ], 'icon_width': 48, 'icon_height': 48, - 'delay':300, - 'program_on_click':None, - 'program_on_new':'beep.sh'} + 'window_never_shrink': False, + 'delay': 300, + 'program_on_click': None, + 'program_on_new': 'beep.sh', + 'click_anytime': False } def __init__(self,id,filename): adesklets.ConfigFile.__init__(self,id,filename) @@ -163,11 +172,14 @@ import poplib import mailbox from sys import exc_info + from os import stat, utime def __init__(self, config): self.config=config self.last_size=-1 self.size=-1 + self.mbox_size = 0 + self.mbox_mtime = 0 def __call__(self): self.last_size=self.size @@ -192,27 +204,59 @@ (self.config['host']) s.user(self.config['user_name']) s.pass_(self.config['user_password']) - size=len(s.list()[1]) + size = len(s.list()[1]) # Unix mbox # if self.config['method'] == 'mbox': - size=0 - for m in self.mailbox.PortableUnixMailbox( - file(getenv('MAIL',self.config['mailspool']))): - if m.get('status','N').find('N') != -1: - size += 1 + mbox_path = getenv('MAIL',self.config['mailspool']) + # Get mbox inode properties + # + s = self.stat(mbox_path) + if (s.st_size == self.mbox_size and + s.st_mtime == self.mbox_mtime): + # mbox has not changed on disk + # + size = self.last_size + else: + # mbox has changed + # + size = 0 + for m in self.mailbox.PortableUnixMailbox(file(mbox_path)): + if m.get('status','N').find('N') != -1: + size += 1 + + # Trick the system into thinking the mbox inode was not + # accessed since last modification. From 'manual.txt' + # of mutt 1.5.8: + # + # [ ... new mail is detected by comparing the last + # modification time to the last access time. + # Utilities like biff or frm or any other program + # which accesses the mailbox might cause Mutt to + # never detect new mail for that mailbox if they + # do not properly reset the access time. + # Backup tools are another common reason for updated + # access times. ] + # + self.utime(mbox_path, (s.st_atime, s.st_mtime)) + + # Remember size and time + # + self.mbox_size = s.st_size + self.mbox_mtime = s.st_mtime + except: # Exception handling: output a significant printout # - size= -1 + size = -1 print '='*80 print traceback.print_exception(*self.exc_info()) print '='*80 print self.config print '='*80 - self.size=size + self.size = size return size #------------------------------------------------------------------------------- @@ -272,7 +316,13 @@ self._execute(join(self.basedir, self.config['program_on_new'])) self.unblock() - return max(self.config['delay'],60) + + # Do not apply delay adjustment to mboxes + # + if self.config['method'] == 'mbox': + return self.config['delay'] + else: + return max(self.config['delay'],60) def menu_fire(self, delayed, menu_id, item): if item=='Configure': @@ -282,7 +332,7 @@ join(self.basedir,'config.txt')) def button_press(self, delayed, x, y, button): - if self.mailer.size>0: + if self.config['click_anytime'] or self.mailer.size>0: self._execute(self.config['program_on_click']) def background_grab(self,delayed): @@ -342,6 +392,13 @@ h=max(self.config['icon_height'],caption_dim[1]+message_dim[1]+ 2*self.config['text_padding']) + # Correct the size if needed + # + if self.config['window_never_shrink']: + adesklets.context_set_image(0) + w = max(adesklets.image_get_width(),w) + h = max(adesklets.image_get_height(),h) + # Set up a buffer accordingly # buffer = adesklets.create_image(w,h) @@ -401,7 +458,8 @@ text_y*2+self.config['text_padding']+ caption_dim[1],message) - # Resize window if usefull, and put everything back on foreground + # Resize window if useful, and put everything back on foreground + # adesklets.context_set_image(0) if w != adesklets.image_get_width() or h!= adesklets.image_get_height(): adesklets.window_resize(w,h)