#!/usr/bin/env python
"""A simple GUI mail notifier that monitors one or more maildirs.

Copyright 2009 Charles Cazabon <http://pyropus.ca/>
Licensed under the GNU GPLv2 (only).
"""

import sys
import os.path
import subprocess

import getmailcore.utilities
from PyQt4 import QtGui, QtCore

POLL_FREQUENCY = 30 # seconds


class NotifierWindow(QtGui.QWidget):
    def __init__(self, maildirs, *args):
        QtGui.QWidget.__init__(self, *args)
        self.setWindowTitle('getmail notifier')
        # Data
        self.maildirs = maildirs[:]
        self.settings = QtCore.QSettings('Pyropus Technology', 
                                         'getmail-notifier')
        self.notifiers = {}
        self.seenmail = {}
        self.newcount = {}
        # Child widgets
        self.grid = QtGui.QGridLayout()
        for (row, maildir) in enumerate(self.maildirs):
            s = maildir[:-1]
            name = s.split('/')[-1]
            namelabel = QtGui.QLabel(name)
            self.grid.addWidget(namelabel, row, 0)
            statuslabel = QtGui.QLabel('')
            self.grid.addWidget(statuslabel, row, 1)
            self.notifiers[maildir] = statuslabel
            self.seenmail[maildir] = set()
            self.newcount[maildir] = 0
        
        self.timer = QtCore.QTimer(self)
        self.timer.setInterval(POLL_FREQUENCY * 1000)
        
        self.setLayout(self.grid)
        self.restoreWindowGeometry()
        
        self.connect(self.timer, QtCore.SIGNAL('timeout()'), self.checkMail)
        self.checkMail()
        self.timer.start()
    
    def restoreWindowGeometry(self):
        self.settings.beginGroup('window')
        size = self.settings.value('size').toSize()
        pos = self.settings.value('position').toPoint()
        self.settings.endGroup()
        if size.width() != -1:
            self.resize(size)
        self.move(pos)

    def closeEvent(self, event):
        self.timer.stop()
        size = QtCore.QVariant(self.size())
        pos = QtCore.QVariant(self.pos())
        self.settings.beginGroup('window')
        self.settings.setValue('size', size)
        self.settings.setValue('position', pos)
        self.settings.endGroup()
        self.settings.sync()
        QtGui.QWidget.closeEvent(self, event)
    
    def checkMail(self):
        gotnew = False
        for maildir in self.maildirs:
            seenmail = self.seenmail[maildir]
            statuslabel = self.notifiers[maildir]
            contents = set(os.listdir(os.path.join(maildir, 'new')))
            for item in list(seenmail):
                if item not in contents:
                    self.newcount[maildir] -= 1
                    seenmail.remove(item)
            for item in contents:
                if item not in seenmail:
                    gotnew = True
                    self.newcount[maildir] += 1
                    seenmail.add(item)
            if self.newcount[maildir]:
                statuslabel.setText('%d new messages' % self.newcount[maildir])
            else:
                statuslabel.setText('')
        if gotnew:
            self.notifyNew()
    
    def notifyNew(self):
        print 'Got new mail!'
        subprocess.call(['/usr/bin/beep'])


def main(maildirs):
    assert type(maildirs) == list and maildirs
    for maildir in maildirs:
        assert (type(maildir) == str 
                and getmailcore.utilities.is_maildir(maildir))
    app = QtGui.QApplication(sys.argv)
    window = NotifierWindow(maildirs)
    window.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    f = open(os.path.expanduser('~/.getmail/notifier-maildirs'), 'rb')
    maildirs = [os.path.expanduser(line.strip()) for line in f if line.strip()]
    main(maildirs)

