pygtk-imap-chk/Window.py

170 lines
5.8 KiB
Python
Executable File

import re
import gtk
import gobject
import imaplib
import math
from datetime import datetime, timedelta
from subprocess import *
class Window(object):
def __init__(self, title, conf):
self.conf = conf
self.count = 0
self.connection = None
if not 'width' in self.conf:
self.conf['width'] = 32
if not 'height' in self.conf:
self.conf['height'] = 32
if not 'mailbox' in self.conf:
self.conf['mailbox'] = 'Inbox'
if not 'updaterate' in self.conf:
self.conf['updaterate'] = 5000
if not 'fgcolor' in self.conf:
self.conf['fgcolor'] = (0.0, 0.0, 0.0)
if not 'bgcolor' in self.conf:
self.conf['bgcolor'] = (1.0, 0.5, 0.0)
if not 'bgcolor2' in self.conf:
self.conf['bgcolor2'] = (1.0, 1.0, 1.0)
if not 'flash_rate' in self.conf:
self.conf['flash_rate'] = 3000
if not 'font_size' in self.conf:
self.conf['font_size'] = 18
if not 'mouse' in self.conf:
self.conf['mouse'] = {}
if not 'left' in self.conf['mouse']:
self.conf['mouse']['left'] = ''
if not 'middle' in self.conf['mouse']:
self.conf['mouse']['middle'] = 'reconnect'
if not 'right' in self.conf['mouse']:
self.conf['mouse']['right'] = 'exit'
if not 'always_on_top' in self.conf:
self.conf['always_on_top'] = True
if not 'sticky' in self.conf:
self.conf['sticky'] = True
self.font_sz = int(1024 * self.conf['font_size'])
self.fgcolor = ''.join(map(lambda x: '%02x' % int(0xFF * x),
self.conf['fgcolor']))
self.window = gtk.Window()
self.window.set_title(title)
self.window.set_decorated(False)
if self.conf['sticky']:
self.window.stick()
if self.conf['always_on_top']:
self.window.set_keep_above(True)
self.window.connect('destroy', self.destroy_event)
self.label = gtk.Label('-')
self.viewport = gtk.Viewport()
self.viewport.set_shadow_type(gtk.SHADOW_OUT)
self.viewport.add(self.label)
self.viewport.connect('button-release-event', self.button_release)
self.viewport.set_events(gtk.gdk.BUTTON_RELEASE_MASK)
self.viewport.modify_bg(gtk.STATE_NORMAL,
gtk.gdk.Color(*map(lambda x: int(65535 * x),
self.conf['bgcolor'])))
self.window.add(self.viewport)
self.connect()
self.window.show_all()
if 'x' in self.conf and 'y' in self.conf:
self.window.move(self.conf['x'], self.conf['y'])
self.window.resize(self.conf['width'], self.conf['height'])
def run(self):
gtk.main()
def connect(self):
try:
self.connection = imaplib.IMAP4_SSL(
self.conf['server'], self.conf['port'])
self.connection.login(self.conf['user'], self.conf['password'])
self.update()
gobject.timeout_add(self.conf['updaterate'], self.update)
except:
self.connection = None
def disconnect(self):
if self.connection is not None:
self.connection = None
def update_conf(self):
w, h = self.window.get_size()
self.conf['width'] = w
self.conf['height'] = h
x, y = self.window.get_position()
self.conf['x'] = x
self.conf['y'] = y
def update(self):
if self.connection is not None:
try:
self.connection.select(self.conf['mailbox'])
msgs = self.connection.search(None, 'UnSeen')[1][0].split()
old_count = self.count
self.count = len(msgs)
if (self.conf['flash_rate'] > 0
and old_count == 0
and self.count > 0):
self.flash_start_dt = datetime.now()
gobject.timeout_add(100, self.do_flash)
except:
self.connection = None
self.update_count()
return self.connection is not None
def update_count(self):
if self.connection is None:
self.label.set_text('-')
else:
self.label.set_markup(
('<span font_weight="bold" foreground="#%s" '
'font_size="%d">%d</span>'
% (self.fgcolor, self.font_sz, self.count)))
def do_flash(self):
if self.count > 0:
delta = datetime.now() - self.flash_start_dt
delta_msec = delta.seconds * 1000 + delta.microseconds / 1000
period = delta_msec / float(self.conf['flash_rate'])
mix = (1.0 - math.cos(math.pi * 2 * period)) / 2.0
else:
mix = 0
linear_combination = lambda (x, y): x + (y - x) * mix
bg1 = self.conf['bgcolor']
bg2 = self.conf['bgcolor2']
flash_bgcolor = map(linear_combination, zip(bg1, bg2))
self.viewport.modify_bg(gtk.STATE_NORMAL,
gtk.gdk.Color(*map(lambda x: int(65535 * x), flash_bgcolor)))
return self.count > 0
def destroy_event(self):
self.disconnect()
self.update_conf()
gtk.main_quit()
return False
def button_release(self, widget, event):
try:
btn_name = {1: 'left', 2: 'middle', 3: 'right'}[event.button]
action = self.conf['mouse'][btn_name]
m = re.match(r'\s*cmd:\s*(.*)', action)
if m is not None:
cmd = m.group(1)
Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
elif action == 'reconnect':
self.disconnect()
self.connect()
elif action == 'exit':
self.destroy_event()
except KeyError:
return False
return True