From e37f237286f97b44931430bbfdffae4b073cd0be Mon Sep 17 00:00:00 2001 From: Andrew Ruthven Date: Fri, 24 Jun 2011 15:35:21 +1200 Subject: [PATCH] Modify CalDAV, it works! --- find_todo.py | 110 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 74 insertions(+), 36 deletions(-) diff --git a/find_todo.py b/find_todo.py index 0433159..95c99dd 100755 --- a/find_todo.py +++ b/find_todo.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -# account_analysis.py -- Output all the credits and debits on an account +# find_todo.py -- Find transactions marked "To Do" and update CalDAV. # # Copyright (C) 2009, 2010 ParIT Worker Co-operative # This program is free software; you can redistribute it and/or @@ -19,47 +19,31 @@ # 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 # Boston, MA 02110-1301, USA gnu@gnu.org # -# @author Mark Jenkins, ParIT Worker Co-operative - -## @file -# @brief Output all the credits and debits on an account -# @author Mark Jenkins, ParIT Worker Co-operative -# @ingroup python_bindings_examples +# @author Andrew Ruthven +# based on account-anlysis.py by Mark Jenkins, ParIT Worker Co-operative +# # python imports from sys import argv, stdout -from datetime import date, timedelta +from datetime import date, timedelta, datetime from bisect import bisect_right from decimal import Decimal from math import log10 import re import csv +import caldav +from caldav.elements import dav, cdav +import yaml # gnucash imports from gnucash import Session, GncNumeric, Split # Invoke this script like the following example -# $ gnucash-env python account_analysis.py gnucash_file.gnucash \ -# 2010 1 monthly 12 \ -# debits-show credits-show Assets 'Test Account' -# -# That will do an analysis on the account 'Assets:Test Account' from -# gnucash_file.xac, all of the debits and all of the credits will be shown -# and summed on for 12 monthly periods starting from January (1st month) 2010 -# -# if you just want to see the credit and debit sums for each period, use -# the debits-noshow and credits-noshow argument -# -# The output goes to stdout and is in csv format. +# $ gnucash-env python find_todo.py \ +# Assets 'Test Account' # -# Account path arugments are space separated, so you need to quote parts of -# the account path with spaces in them -# -# available period types are monthly quarterly and yearly -# -# At the moment this script only supports GnuCash files of the sqllite3 type -# its an easy edit to switch to xml: etc... - +# That will find all transations in the account 'Assets:Test Account' and +# and update a CalDAV calendar, using the description, if the ZERO = Decimal(0) @@ -101,13 +85,30 @@ def main(): account_path = argv[2:] + # Principal url + url = "https://xxx:xxx@xxx.etc.gen.nz/caldav.php/gnucash/home" + client = caldav.DAVClient(url) + principal = caldav.Principal(client, url) + calendars = principal.calendars() + + if len(calendars) > 0: + calendar = calendars[0] + print "Using calendar", calendar + else: + print "No calendars found!" + exit + gnucash_session = Session(gnucash_file, is_new=False) root_account = gnucash_session.book.get_root_account() account_of_interest = account_from_path(root_account, account_path) - ical = """BEGIN:VCALENDAR + header = """BEGIN:VCALENDAR VERSION:2.0 -PRODID:-//Example Corp.//CalDAV Client//EN""" +PRODID:-//Gnucash//Find Todos//EN +""" + footer = "END:VCALENDAR" + + current_events = dict() # insert and add all splits in the periods of interest for split in account_of_interest.GetSplitList(): @@ -119,18 +120,55 @@ PRODID:-//Example Corp.//CalDAV Client//EN""" if (re.search('To Do', num, re.I)): split_amount = gnc_numeric_to_python_Decimal(split.GetAmount()) + if split_amount < ZERO: + type = "debit" + split_amount = abs(split_amount) + else: + type = "credit" + + day = trans_date.strftime("%Y%m%dZ"); - stamp = trans_date.strftime("%Y%m%dT%H%M%SZ"); - event = """BEGIN:VEVENT -UID:""" + trans.GetGUID().to_string() + """ + stamp = datetime.utcnow().strftime("%Y%m%dT%H%M%SZ"); + guid = trans.GetGUID().to_string() + "@gnucash" + current_events[guid] = 1 + summary = "%s - %s $%d" % (trans.GetDescription(), type, split_amount) + + ical = header + """BEGIN:VEVENT +UID:""" + guid + """ DTSTAMP:""" + stamp + """ DTSTART:""" + day + """ -SUMMARY:""" + trans.GetDescription() + """ - $%d -END:VEVENT""" % split_amount - print event +SUMMARY:""" + summary + """ +LOCATION:""" + account.name + """ +END:VEVENT +""" + footer + + try: + event = calendar.event(guid) + if summary != event.instance.vevent.summary.value or trans_date != event.instance.vevent.dtstart.value: + event.set_data(ical) + event.save() + print "Event", event, "updated" + else: + print "Event", event, "unchanged, skipping" + except caldav.lib.error.NotFoundError: + url = "/caldav.php/gnucash/home/" + guid + ".ics" + event = caldav.Event(client, url = url, data = ical, parent = calendar).save() + print "Event", event, "created" + + current_events[guid] = 1 + else: continue + # Go through the events on the server and remove anything that we've added + # previously that is now stale. + events = calendar.events() + for event in events: + event.load() + if not current_events.has_key(event.instance.vevent.uid.value): + if (re.search('@gnucash', event.instance.vevent.uid.value)): + print "Event", event, "deleted, %s" % event.instance.vevent.uid.value + event.delete() # no save needed, we're just reading.. gnucash_session.end() -- 2.30.2