#!/usr/bin/env python
# _*_ coding: latin1 -*_
# dzenscript -- prints out valuable system information
# Copyright (C) 2007 Róman Joost 
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# import pymetar
import os.path
import email.message
import time
import re
import math


DATEFORMAT = '%A, %d.%m.%Y %H:%M:%S'
# prints: 'private: (2) public: --'
MAILDIRS = {'private':"/home/user/Maildir",
            'public':"/home/user/AnotherMaildir"}
# monitor only specified inboxes ('' is the INBOX)
SHOWONLY = {'private':['INBOX.mailbox_a', '', 'INBOX.mailbox_b'],
            'public':['INBOX', 'INBOX.mailbox_a']}
# not used currently
FIELDS = {'Subject':[], 'From':[]}
WEATHERSTATION = 'EDDP' # Leipzig, Germany

#### code ####

def get_weather(station):
    rf = pymetar.ReportFetcher(station)
    rep = rf.FetchReport()
    report = pymetar.ReportParser().ParseReport(rep)
    return "%s: %s°C" %(report.getStationCity(),
                      report.getTemperatureCelsius())

def get_datetime():
    """prints datetime as str"""
    return time.strftime(DATEFORMAT, time.localtime())


def get_worldtime(offset):
    """Returns time from a different timezone to current time."""
    local = time.localtime()
    hour = math.fmod((local[3] + offset), 24)
    return "%i" %hour + time.strftime(":%M")


class BatteryState(object):
    """Returns the battery life."""
    remaining_capacity_regex = re.compile('remaining.capacity.\s+(\d+)')
    last_full_regex = re.compile('last.full.capacity.\s+(\d+)')
    charging_state_regex = re.compile('charging.state.\s+(\w+)')
    iconpath = "/home/roman/tools/dzen_bitmaps/battery.xbm"

    # XXX only one battery is currently supported
    def __init__(self, basedir="/proc/acpi/battery/BAT0"):
        self.basedir = basedir
        self.state = 0
        self.capacity = 1
        self.charging_state = ""
        self.parse_proc()

    def parse_proc(self):
        """parses the files in proc and indexes interesting values"""
        files = ['info', 'state']
        contents = ""
        for fname in files:
            f = open(os.path.join(self.basedir, fname))
            contents += f.read()
            f.close()

        capacity = self.last_full_regex.search(contents).groups()[0]
        state = self.remaining_capacity_regex.search(contents).groups()[0]
        charging_state = (self.charging_state_regex.
                          search(contents).groups()[0])
        self.state = int(state)
        self.capacity = int(capacity)
        self.charging_state = charging_state

    @property
    def percentage(self):
        """Returns the capacity information in percentage"""
        return (self.state * 100)/self.capacity

    def printout(self):
        if os.path.exists(self.iconpath):
            label = "^i(%s)" % self.iconpath
        else:
            label = "Battery:"
        return "%s %s%% (%s)" %(label, self.percentage,
                                self.charging_state)


class Biff(object):
    """Simple Biff object."""

    def __init__(self, id, basepath, show_only):
        self.id = id
        self.basepath = basepath
        # who only mailboxes in this list
        self.show_only = show_only
        self.result = []
        self.newmail = False

    def check_mail(self):
        """Checks mail in maildir and returns list of mailbox objects.
        """
        if not os.path.exists(self.basepath):
            return []

        result = []
        for appendix in self.show_only:
            result.append(self.count_mails(appendix))
        self.result = result
        return self.result

    def count_mails(self, appendix):
        """Counts the files in 'new' of fnames"""
        path = os.path.join(self.basepath, appendix, 'new')
        if os.path.isdir(path):
            return Mailbox(path, FIELDS)

    def get_mboxes_with_new_mail(self):
        """Returns mboxes with new mail."""
        result = []
        self.newmail = False
        for mbox in self.check_mail():
            if mbox.get_mailcount() > 0:
                self.newmail = True
                result.append(mbox)
        return result


    def printout(self):
        """Print a str which states mailbox and new mail amout."""
        new_mail = self.get_mboxes_with_new_mail()
        if not self.newmail:
            return " %s: --" % self.id

        result = " %s:" % self.id
        for mbox in new_mail:
            result += "%s(%s) " % (mbox.name, mbox.get_mailcount())
        return result

    def get_mail_strings(self):
        return " ".join([mbox.get_interesting_fields() for mbox in self.result])


class Mailbox(object):
    """Mailbox object which holds the amount of mails and interesting
       mail information.

       interesting_fields = {'Subject':[], 'From':[]}

       Supports only maildir style mboxes!
    """

    def __init__(self, mboxpath, interesting_fields):
        self.name = self.get_mbox_name(mboxpath)
        self.mboxpath = mboxpath
        self.mailcount = 0
        self.get_mailcount()
        self.fields = interesting_fields

    def get_mbox_name(self, mboxpath):
        """Uses the basename for mbox name."""
        parentdir = os.path.split(mboxpath)[0]
        return os.path.basename(parentdir)

    def get_mailcount(self):
        """Returns the amount of new mail in the mbox."""
        self.mailcount = len(os.listdir(self.mboxpath))
        return self.mailcount

    # XXX TODO
    def indexmail(self, path):
        """indexes mail."""
        if not os.path.exists(path):
            return

        fp = open(path)
        mail = email.message_from_file(fp)
        fp.close()

        for field in self.fields:
            value = mail.get(field)
            self.fields[field].append(value)

    def get_interesting_fields(self):
        """Returns values of interesting fields as string."""
        result = ""

        if self.get_mailcount() == 0:
            return result

        for key, val in self.fields.items():
            result += " ".join(val)

        return result


def main():
    """ main function """
    #battery = BatteryState()
    mailstatus = ""
    for id, maildirpath in MAILDIRS.items():
        biff = Biff(id, maildirpath, SHOWONLY[id])
        mailstatus += "%s" % biff.printout()
        printout = "%s | %s (AUS %s, CAN %s)" % (
                                        #battery.printout(),
                                        mailstatus,
                                        get_datetime(),
                                        get_worldtime(+10),
                                        get_worldtime(-7))
    print printout

if __name__ == "__main__":
    main()

