#! /usr/bin/env python
########################################################################
# COPYRIGHT_BEGIN
#
#           mical
#           Minimal iCalendar utilities
#
# Copyright (C) 2007, David Arnold
# 
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License, version 2, as
# published by the Free Software Foundation.
#
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# COPYRIGHT_END
########################################################################
# $ZeroXOne: mical/micshow,v 1.9 2007/06/04 17:13:05 d Exp $
########################################################################

import sys, os, vobject
from   optparse import OptionParser
from   dateutil.tz import tzlocal
from   mical import VERSION

PROGRAM = os.path.basename(sys.argv[0])

INTERVALS = {
    1: "",
    2: "second",
    3: "third",
    4: "fourth",
    5: "fifth",
    6: "sixth",
    7: "seventh",
    8: "eighth",
    9: "nineth",
    10: "tenth",
    11: "11th",
    12: "12th",
    13: "13th"
    }

########################################################################

def main():

    parser = OptionParser(description = "Write a user-friendly summary "
                          "representation of an iCalendar object to "
                          "the standard output device.\n\nThe iCalendar "
                          "object is read from the specified saved event, "
                          "or from the standard input device.",
                          usage="%prog [index]",
                          version=PROGRAM + "-" + VERSION)
    (options, args) = parser.parse_args()
    
    # Check for saved event name
    if len(args) == 1:
        path = "%s/.mical/%s" % (os.environ["HOME"], sys.argv[1])
        if not os.path.exists(path):
            path = sys.argv[1]
        try:
            f = open(path)
        except IOError:
            print "No such file or saved calendar item: %s" % sys.argv[1]
            sys.exit(1)
        vobj = vobject.readOne(f)
        f.close

    else:
        vobj = vobject.readOne(sys.stdin)

    # Print more-or-less nicely
    event = vobj.vevent

    # Action
    if hasattr(vobj, 'method'):
        method = vobj.method.value.capitalize()
        print "Meeting " + method
        print "--------" + ("-" * len(method))

    # Summary
    if hasattr(event, 'summary'):
        print "Summary\n\t" + event.summary.value + "\n"

    # Location
    if hasattr(event, 'location'):
        print "Location\n\t" + event.location.value + "\n"

    # Time
    if hasattr(event, 'dtstart'):
        start = event.dtstart.value
        local_start = start.astimezone(tzlocal())

        if hasattr(event, 'dtend'):
            end = event.dtend.value
            local_end = end.astimezone(tzlocal())

        elif hasattr(event, 'duration'):
            end = start + event.duration.value
            local_end = end.astimezone(tzlocal())

        s =  "Time\n"
        s += "\t"  + local_start.strftime("%l:%M %p").strip()
        s += " - " + local_end.strftime("%l:%M %p %Z").strip()
        print s

        #FIXME: repeat rule
        if hasattr(event, 'rrule'):
            rrules = {}
            for param in event.rrule.value.split(";"):
                k,v = param.split("=")
                rrules[k.upper()] = v.upper()

            if rrules.has_key('FREQ'):
                freq = rrules['FREQ'].lower()[:-2]
            else:
                freq = ""

            if rrules.has_key('INTERVAL'):
                interval_num = int(rrules['INTERVAL'])
                if interval_num < 14:
                    interval = INTERVALS[interval_num]
                elif interval_num % 10 == 1:
                    interval = str(interval_num) + "st"
                elif interval_num % 10 == 2:
                    interval = str(interval_num) + "nd"
                elif interval_num % 10 == 3:
                    interval = str(interval_num) + "rd"
                else:
                    interval = str(interval_num) + "th"
            else:
                interval = ""

            print "\tEvery %s%s%s" % (interval, interval and " ", freq)

            s = "\tStarting "
        else:
            s = "\t"
            
        s += local_start.strftime("%A, %d %B %Y") + "\n"
        print s

    # Attendees
    if event.contents.has_key('attendee'):
        print "Attendees"
        for attendee in event.contents['attendee']:
            email = attendee.value.split(':')[1]
            s = "\t"
            if attendee.params.has_key('CN'):
                s += attendee.params['CN'][0] + " <" + email + ">"
            else:
                s += email

            if attendee.params.has_key('ROLE'):
                s += " ("
                for role in attendee.params['ROLE']:
                    if role == 'REQ-PARTICIPANT':
                        s += "Required"
                    elif role == 'OPT-PARTICIPANT':
                        s += "Optional"
                    elif role == 'NON-PARTICIPANT':
                        s += "Informational copy"
                    else:
                        s += role.capitalize()  # CHAIR + other
                s += ")"

            if attendee.params.has_key('PARTSTAT'):
                s += ": "
                for status in attendee.params['PARTSTAT']:
                    s += status.capitalize().replace("-", " ") + " "

            print s
            
        if hasattr(event, 'organizer'):
            organizer = event.organizer
            email = organizer.value.split(":")[1]
            s = "\n\t"
            if organizer.params.has_key('CN'):
                for cn in organizer.params['CN']:
                    s += cn + " "
                s += "<" + email + ">"
            else:
                s += email

            s += " (Organizer)"
            print s
            
        print
                
            
    # Description
    if hasattr(event, 'description'):
        desc = event.description.value
        # Remove Outlook-specific description prefix if present
        outlook_nonsense = desc.find("*~*~*~*~*~*~*~*~*~*")
        if outlook_nonsense > 0:
            desc = desc[outlook_nonsense+19:].strip()

        if len(desc) > 0:
            desc = desc.encode("utf-8", 'replace')
            desc = desc.replace('\r', '')

            desc = reduce(lambda line, word: '%s%s%s' % (line, ' \n'[(len(line) - line.rfind('\n') - 1 + len(word.split('\n', 1)[0]) >= 60)], word), desc.split(' '))
            
            desc = desc.replace("\n", "\n\t")
            print "Description\n\t" + desc

    
if __name__ == "__main__":
    main()


########################################################################
