Varia's website https://varia.zone
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
3.1 KiB

# -*- coding: utf-8 -*-
"""iCalendar utility"""
from __future__ import unicode_literals
import argparse
import sys
from datetime import datetime
from . import Calendar, __version__
_template = """Organiser: {organiser}
Attendees:
{attendees}
Summary: {summary}
When: {time_from}-{time_to}
Location: {location}
Comment: {comment}
Description:
{description}
"""
def _format_name(address):
"""Retrieve the e-mail and optionally the name from an address.
:arg vCalAddress address: An address object.
:returns str: The name and optionally the e-mail address.
"""
if not address:
return ''
email = address.title().split(':')[1]
if 'cn' in address.params:
return '{} <{}>'.format(address.params['cn'], email)
return email
def _format_attendees(attendees):
"""Format the list of attendees.
:arg any attendees: Either a list, a string or a vCalAddress object.
:returns str: Formatted list of attendees.
"""
if type(attendees) == list:
return '\n '.join(map(_format_name, attendees))
return _format_name(attendees)
def view(input_handle, output_handle):
"""Make a human readable summary of an iCalendar file.
:arg stream handle: Open readable handle to an iCalendar file.
:returns str: Human readable summary.
"""
cal = Calendar.from_ical(input_handle.read())
for event in cal.walk('vevent'):
output_handle.write(_template.format(
organiser=_format_name(event.get('organizer', '')),
attendees=_format_attendees(event.get('attendee')),
summary=event.get('summary', ''),
time_from=datetime.strftime(
event.get('dtstart').dt, '%a %d %b %Y %H:%M'),
time_to=datetime.strftime(event.get('dtend').dt, '%H:%M'),
location=event.get('location', ''),
comment=event.get('comment', ''),
description=event.get('description', '')).encode('utf-8'))
def main():
"""Main entry point."""
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
description=__doc__)
parser.add_argument(
'-v', '--version', action='version',
version='{} version {}'.format(parser.prog, __version__))
# This seems a bit of an overkill now, but we will probably add more
# functionality later, e.g., iCalendar to JSON / YAML and vice versa.
subparsers = parser.add_subparsers(dest='subcommand')
subparser = subparsers.add_parser(
'view', description=view.__doc__.split('\n\n')[0])
subparser.add_argument(
'input_handle', metavar='INPUT', type=argparse.FileType('r'),
help='iCalendar file')
subparser.add_argument(
'-o', dest='output_handle', metavar='OUTPUT',
type=argparse.FileType('w'), default=sys.stdout,
help='output file (default=<stdout>)')
subparser.set_defaults(func=view)
args = parser.parse_args()
try:
args.func(**{k: v for k, v in vars(args).items()
if k not in ('func', 'subcommand')})
except ValueError as error:
parser.error(error)
if __name__ == '__main__':
main()