* Added rudimentary command line interface.

* Added documentation on the CLI.

* Added example output.

* Removed _optional wrapper in favour of the built-in get() method.

* Added --version option.

* Removed default for 'attendee'.

* Looping over all vevents now.

* Updated changelog.
pull/261/head
Jeroen F.J. Laros 2018-02-09 01:37:52 +01:00 zatwierdzone przez Johannes Raggam
rodzic c880a5b262
commit e86570b2da
6 zmienionych plików z 153 dodań i 0 usunięć

Wyświetl plik

@ -4,6 +4,9 @@ Changelog
4.0.1 (unreleased)
------------------
- Added rudimentary command line interface.
[jfjlaros]
- Readme, setup and travis updates.
[jdufresne, PabloCastellano]

36
docs/cli.rst 100644
Wyświetl plik

@ -0,0 +1,36 @@
iCalendar utility
=================
To get more information about the command line interface, use the ``-h``
option::
$ icalendar -h
view
----
Use the ``view`` subcommand for a human readable summary of an event::
$ icalendar view myfile.ics
The output will look something like this::
Organiser: Secretary <secretary@company.com>
Attendees:
John Doe <j.doe@company.com>
Randy <boss@company.com>
Summary: Yearly evaluation.
When: Tue 14 Mar 2017 11:00-12:00
Location: Randy's office
Comment: Reminder.
Description:
Your yearly evaluation is scheduled for next Tuesday. Please be on time.
To use this in terminal based e-mail clients like mutt, add a new mime type (as
root)::
# cat << EOF > /usr/lib/mime/packages/icalendar
text/calendar; icalendar view '%s'; copiousoutput; description=iCalendar text; priority=2
EOF
# update-mime

Wyświetl plik

@ -15,6 +15,7 @@ icalendar contributors
- Erik Simmler <tgecho@gmail.com>
- George V. Reilly <george@reilly.org>
- Jannis Leidel <jannis@leidel.info>
- Jeroen F.J. Laros <jlaros@fixedpoint.nl>
- Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>
- Jordan Kiang <jordan@cozi.com>
- Klaus Klein <kleink+github@kleink.org>

Wyświetl plik

@ -10,5 +10,6 @@ Contents
install
usage
api
cli
credits
license

Wyświetl plik

@ -57,6 +57,7 @@ setuptools.setup(
zip_safe=False,
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
install_requires=install_requires,
entry_points = {'console_scripts': ['icalendar = icalendar.cli:main']},
extras_require={
'test': tests_require
},

Wyświetl plik

@ -0,0 +1,111 @@
# -*- 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()