Skip to content

Commit

Permalink
[fc] Repository: icalendar
Browse files Browse the repository at this point in the history
Branch: refs/heads/master
Date: 2018-02-09T01:37:52+01:00
Author: Jeroen F.J. Laros (jfjlaros) <J.F.J.Laros@lumc.nl>
Commit: collective/icalendar@e86570b

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.

Files changed:
A docs/cli.rst
A src/icalendar/cli.py
M CHANGES.rst
M docs/credits.rst
M docs/index.rst
M setup.py
  • Loading branch information
thet committed Feb 9, 2018
1 parent 5c2b4c1 commit b2e9d1b
Showing 1 changed file with 226 additions and 11 deletions.
237 changes: 226 additions & 11 deletions last_commit.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,243 @@ Repository: icalendar


Branch: refs/heads/master
Date: 2018-02-08T22:48:02+01:00
Author: Johannes Raggam (thet) <thetetet@gmail.com>
Commit: https://github.com/collective/icalendar/commit/c880a5b2620fa07fd415681616a08ceb9d46c5e8
Date: 2018-02-09T01:37:52+01:00
Author: Jeroen F.J. Laros (jfjlaros) <J.F.J.Laros@lumc.nl>
Commit: https://github.com/collective/icalendar/commit/e86570b2da80bcdfeab61c923089fcd15cf28ded

changelog for last 3 PR merges
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.

Files changed:
A docs/cli.rst
A src/icalendar/cli.py
M CHANGES.rst
M docs/credits.rst
M docs/index.rst
M setup.py

diff --git a/CHANGES.rst b/CHANGES.rst
index 14fa813..ea167c6 100644
index ea167c6..1bff14e 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -4,7 +4,8 @@ Changelog
@@ -4,6 +4,9 @@ Changelog
4.0.1 (unreleased)
------------------

-- Nothing changed yet.
+- Readme, setup and travis updates.
+ [jdufresne, PabloCastellano]

+- Added rudimentary command line interface.
+ [jfjlaros]
+
- Readme, setup and travis updates.
[jdufresne, PabloCastellano]

4.0.0 (2017-11-08)
diff --git a/docs/cli.rst b/docs/cli.rst
new file mode 100644
index 0000000..f86b7f9
--- /dev/null
+++ b/docs/cli.rst
@@ -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
diff --git a/docs/credits.rst b/docs/credits.rst
index 834a730..bf39a7a 100644
--- a/docs/credits.rst
+++ b/docs/credits.rst
@@ -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>
diff --git a/docs/index.rst b/docs/index.rst
index 10a7296..5a7e8ae 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -10,5 +10,6 @@ Contents
install
usage
api
+ cli
credits
license
diff --git a/setup.py b/setup.py
index 50ac92f..f28096f 100644
--- a/setup.py
+++ b/setup.py
@@ -57,6 +57,7 @@
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
},
diff --git a/src/icalendar/cli.py b/src/icalendar/cli.py
new file mode 100644
index 0000000..5d7b72f
--- /dev/null
+++ b/src/icalendar/cli.py
@@ -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()


0 comments on commit b2e9d1b

Please sign in to comment.