kopia lustrzana https://github.com/collective/icalendar
Cli (#256)
* 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
rodzic
c880a5b262
commit
e86570b2da
|
@ -4,6 +4,9 @@ Changelog
|
|||
4.0.1 (unreleased)
|
||||
------------------
|
||||
|
||||
- Added rudimentary command line interface.
|
||||
[jfjlaros]
|
||||
|
||||
- Readme, setup and travis updates.
|
||||
[jdufresne, PabloCastellano]
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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>
|
||||
|
|
|
@ -10,5 +10,6 @@ Contents
|
|||
install
|
||||
usage
|
||||
api
|
||||
cli
|
||||
credits
|
||||
license
|
||||
|
|
1
setup.py
1
setup.py
|
@ -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
|
||||
},
|
||||
|
|
|
@ -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()
|
Ładowanie…
Reference in New Issue