ya3

ya3 -- yet another appointment application
Log | Files | Refs

commit eff971abce607538c41bff6cc2e4a53e0cb69361
parent f08a8e52b210a84561e602658019b6bbe0d8bc7a
Author: Matthias Balk <matthias.balk@fotopuzzle.de>
Date:   Mon, 17 Sep 2018 17:40:01 +0200

ya3 takes command as first parameter

Diffstat:
MREADME.rst | 6++----
Acommands.py | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dcreate-appointment.py | 66------------------------------------------------------------------
Mya3 | 56++++++++++++++++++++------------------------------------
4 files changed, 114 insertions(+), 106 deletions(-)

diff --git a/README.rst b/README.rst @@ -33,11 +33,9 @@ Edit configuration in config.py to fit your needs. Usage ~~~~~ -$ create-appointment.py - -$ ya3 <vcal file> +$ ya3 <command> Example ~~~~~~~ You may want to write something like this to your shell's rc file: -ya3 $HOME/.ya3/calendars/* | sort +ya3 print | sort diff --git a/commands.py b/commands.py @@ -0,0 +1,92 @@ +import os +import re +import time +import uuid +from collections import OrderedDict +from datetime import datetime + +import vobject +from dateutil.parser import parse +from dateutil.tz import gettz + +import config + + +def _localtime2utc(datetimestr): + local = parse('%s %s' % (datetimestr, time.tzname[0])) + return local - local.utcoffset() + + +def _get_input(key): + if key in config.DEFAULTS: + i = input('%s: [%s] ' % (key, config.DEFAULTS[key])) + return i if i.strip() is not '' else config.DEFAULTS[key] + return input('%s: ' % key) + + +def _event2file(event): + filename = '%s-%s.ics' % (event['DTSTART'].strftime('%Y-%m-%d'), + re.sub(r'\s+', '-', event['SUMMARY'].lower())) + f = open(os.path.join(config.CAL_DIR, filename), 'w') + f.write('BEGIN:VCALENDAR\nVERSION:2.0\n') + f.write('PRODID://ya3//yet another appointment application//\n') + + def item2str(key, value): + if isinstance(value, datetime): + return '%s:%s\n' % (key, value.strftime('%Y%m%dT%H%M%SZ')) + return '%s:%s\n' % (key, value) + + for key in event: + f.write(item2str(key, event[key])) + + f.write('END:VCALENDAR\n') + f.close() + + +def create_event(): + event = OrderedDict([ + ('BEGIN', 'VEVENT'), + ('DTSTART', None), + ('DTEND', None), + ('LOCATION', None), + ('SUMMARY', None), + ('UID', str(uuid.uuid4())), + ('END', 'VEVENT'), + ]) + + for key in ['DTSTART', 'DTEND', 'LOCATION', 'SUMMARY']: + event[key] = _get_input(key) + if re.match('DT', key): + event[key] = _localtime2utc(event[key]) + + _event2file(event) + + +def _conv2local(dt): + if not isinstance(dt, datetime): + return datetime(dt.year, dt.month, dt.day, tzinfo=gettz()) + if dt.tzinfo is None: + return datetime(dt.year, dt.month, dt.day, + dt.hour, dt.minute, dt.second, + tzinfo=gettz()) + return dt.astimezone(gettz()) + + +def print_events(icsfilename): + + f = open(icsfilename) + for event in vobject.readComponents(f): + start = _conv2local(event.vevent.dtstart.value) + end = _conv2local(event.vevent.dtend.value) + + try: + location = " (" + event.vevent.location.value + ")" + except AttributeError: + location = "" + + if start >= datetime.now(gettz()) - config.MAX_AGE and \ + start < datetime.now(gettz()) + config.MAX_AHEAD: + print('%s - %s %s%s' % (start.strftime('%Y-%m-%d %H:%M'), + end.strftime('%H:%M'), + event.vevent.summary.value, + location)) diff --git a/create-appointment.py b/create-appointment.py @@ -1,66 +0,0 @@ -#!/usr/bin/env python3 - -import os -import re -import time -import uuid -from collections import OrderedDict -from datetime import datetime - -from dateutil.parser import parse - -import config - - -def localtime2utc(datetimestr): - local = parse('%s %s' % (datetimestr, time.tzname[0])) - return local - local.utcoffset() - - -def get_input(key): - if key in config.DEFAULTS: - i = input('%s: [%s] ' % (key, config.DEFAULTS[key])) - return i if i.strip() is not '' else config.DEFAULTS[key] - return input('%s: ' % key) - - -def create_event(): - event = OrderedDict([ - ('BEGIN', 'VEVENT'), - ('DTSTART', None), - ('DTEND', None), - ('LOCATION', None), - ('SUMMARY', None), - ('UID', str(uuid.uuid4())), - ('END', 'VEVENT'), - ]) - - for key in ['DTSTART', 'DTEND', 'LOCATION', 'SUMMARY']: - event[key] = get_input(key) - if re.match('DT', key): - event[key] = localtime2utc(event[key]) - - return event - - -def event2file(event): - filename = '%s-%s.ics' % (event['DTSTART'].strftime('%Y-%m-%d'), - re.sub(r'\s+', '-', event['SUMMARY'].lower())) - f = open(os.path.join(config.CAL_DIR, filename), 'w') - f.write('BEGIN:VCALENDAR\nVERSION:2.0\n') - f.write('PRODID://ya3//yet another appointment application//\n') - - def item2str(key, value): - if isinstance(value, datetime): - return '%s:%s\n' % (key, value.strftime('%Y%m%dT%H%M%SZ')) - return '%s:%s\n' % (key, value) - - for key in event: - f.write(item2str(key, event[key])) - - f.write('END:VCALENDAR\n') - f.close() - - -event = create_event() -event2file(event) diff --git a/ya3 b/ya3 @@ -1,44 +1,28 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """ya3 -- yet another appointment application""" -import sys -from datetime import datetime +import glob +import os.path +from optparse import OptionParser +import commands import config -import vobject -from dateutil.tz import gettz -def conv2local(dt): - if not isinstance(dt, datetime): - return datetime(dt.year, dt.month, dt.day, tzinfo=gettz()) - if dt.tzinfo is None: - return datetime(dt.year, dt.month, dt.day, - dt.hour, dt.minute, dt.second, - tzinfo=gettz()) - return dt.astimezone(gettz()) +usage = """%prog <command> + commands: create, print""" +parser = OptionParser(usage=usage) +(options, args) = parser.parse_args() +if len(args) != 1: + parser.print_help() +else: + command = args[0] -def print_events(icsfilename): - """foo""" - - f = open(icsfilename) - for event in vobject.readComponents(f): - start = conv2local(event.vevent.dtstart.value) - end = conv2local(event.vevent.dtend.value) - - try: - location = " (" + event.vevent.location.value + ")" - except AttributeError: - location = "" - - if start >= datetime.now(gettz()) - config.MAX_AGE and \ - start < datetime.now(gettz()) + config.MAX_AHEAD: - print('%s - %s %s%s' % (start.strftime('%Y-%m-%d %H:%M'), - end.strftime('%H:%M'), - event.vevent.summary.value, - location)) - - -for filename in sys.argv[1:]: - print_events(filename) + if command == 'create': + commands.create_event() + elif command == 'print': + for filename in glob.glob(os.path.join(config.CAL_DIR, '*.ics')): + commands.print_events(filename) + else: + parser.print_help()