#!/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 <transparency@parit.ca>
# This program is free software; you can redistribute it and/or
# 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 <mark@parit.ca>
-
-## @file
-# @brief Output all the credits and debits on an account
-# @author Mark Jenkins, ParIT Worker Co-operative <mark@parit.ca>
-# @ingroup python_bindings_examples
+# @author Andrew Ruthven <andrew@etc.gen.nz>
+# based on account-anlysis.py by Mark Jenkins, ParIT Worker Co-operative
+# <mark@parit.ca>
# 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)
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():
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()