From: Andrew Ruthven Date: Fri, 3 Jun 2011 11:12:02 +0000 (+1200) Subject: Generate vEvent, and remove unrequired code. X-Git-Url: http://git.etc.gen.nz/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a8a0120c5cdc9cb3de380d19303f59aadba7f52e;p=gnucash-tools.git Generate vEvent, and remove unrequired code. --- diff --git a/find_todo.py b/find_todo.py index 2270426..0433159 100755 --- a/find_todo.py +++ b/find_todo.py @@ -32,6 +32,7 @@ from datetime import date, timedelta from bisect import bisect_right from decimal import Decimal from math import log10 +import re import csv # gnucash imports @@ -60,18 +61,6 @@ from gnucash import Session, GncNumeric, Split # its an easy edit to switch to xml: etc... -# a dictionary with a period name as key, and number of months in that -# kind of period as the value -PERIODS = {"monthly": 1, - "quarterly": 3, - "yearly": 12 } - -NUM_MONTHS = 12 - -ONE_DAY = timedelta(days=1) - -DEBITS_SHOW, CREDITS_SHOW = ("debits-show", "credits-show") - ZERO = Decimal(0) def gnc_numeric_to_python_Decimal(numeric): @@ -94,47 +83,6 @@ def gnc_numeric_to_python_Decimal(numeric): return Decimal( (sign, digit_tuple, -exponent) ) -def next_period_start(start_year, start_month, period_type): - # add numbers of months for the period length - end_month = start_month + PERIODS[period_type] - # use integer division to find out if the new end month is in a different - # year, what year it is, and what the end month number should be changed - # to. - # Because this depends on modular arithmatic, we have to curvert the month - # values from 1-12 to 0-11 by subtracting 1 and putting it back after - # - # the really cool part is that this whole thing is implemented without - # any branching; if end_month > NUM_MONTHS - # - # A the super nice thing is that you can add all kinds of period lengths - # to PERIODS - end_year = start_year + ( (end_month-1) / NUM_MONTHS ) - end_month = ( (end_month-1) % NUM_MONTHS ) + 1 - - return end_year, end_month - - -def period_end(start_year, start_month, period_type): - if period_type not in PERIODS: - raise Exception("%s is not a valid period, should be %s" % ( - period_type, str(PERIODS.keys()) ) ) - - end_year, end_month = next_period_start(start_year, start_month, - period_type) - - # last step, the end date is day back from the start of the next period - # so we get a period end like - # 2010-03-31 for period starting 2010-01 instead of 2010-04-01 - return date(end_year, end_month, 1) - ONE_DAY - - -def generate_period_boundaries(start_year, start_month, period_type, periods): - for i in xrange(periods): - yield ( date(start_year, start_month, 1), - period_end(start_year, start_month, period_type) ) - start_year, start_month = next_period_start(start_year, start_month, - period_type) - def account_from_path(top_account, account_path, original_path=None): if original_path==None: original_path = account_path account, account_path = account_path[0], account_path[1:] @@ -149,108 +97,40 @@ def account_from_path(top_account, account_path, original_path=None): def main(): - (gnucash_file, start_year, start_month, period_type, periods, - debits_show, credits_show) = argv[1:8] - start_year, start_month, periods = [int(blah) - for blah in (start_year, start_month, - periods) ] - - debits_show = debits_show == DEBITS_SHOW - credits_show = credits_show == CREDITS_SHOW + (gnucash_file) = argv[1] - account_path = argv[8:] + account_path = argv[2:] 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) - # a list of all the periods of interest, for each period - # keep the start date, end date, a list to store debits and credits, - # and sums for tracking the sum of all debits and sum of all credits - period_list = [ - [start_date, end_date, - [], # debits - [], # credits - ZERO, # debits sum - ZERO, # credits sum - ] - for start_date, end_date in generate_period_boundaries( - start_year, start_month, period_type, periods) - ] - # a copy of the above list with just the period start dates - period_starts = [e[0] for e in period_list ] + ical = """BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//Example Corp.//CalDAV Client//EN""" # insert and add all splits in the periods of interest for split in account_of_interest.GetSplitList(): trans = split.parent trans_date = date.fromtimestamp(trans.GetDate()) - # use binary search to find the period that starts before or on - # the transaction date - period_index = bisect_right( period_starts, trans_date ) - 1 - - # ignore transactions with a date before the matching period start - # (after subtracting 1 above start_index would be -1) - # and after the last period_end - if period_index >= 0 and \ - trans_date <= period_list[len(period_list)-1][1]: - - # get the period bucket appropriate for the split in question - period = period_list[period_index] - - # more specifically, we'd expect the transaction date - # to be on or after the period start, and before or on the - # period end, assuming the binary search (bisect_right) - # assumptions from above are are right.. - # - # in other words, we assert our use of binary search - # and the filtered results from the above if provide all the - # protection we need - assert( trans_date>= period[0] and trans_date <= period[1] ) - - split_amount = gnc_numeric_to_python_Decimal(split.GetAmount()) - - # if the amount is negative, this is a credit - if split_amount < ZERO: - debit_credit_offset = 1 - # else a debit - else: - debit_credit_offset = 0 - - # store the debit or credit Split with its transaction, using the - # above offset to get in the right bucket - # - # if we wanted to be really cool we'd keep the transactions - period[2+debit_credit_offset].append( (trans, split) ) - - # add the debit or credit to the sum, using the above offset - # to get in the right bucket - period[4+debit_credit_offset] += split_amount - - csv_writer = csv.writer(stdout) - csv_writer.writerow( ('period start', 'period end', 'debits', 'credits') ) - - def generate_detail_rows(values): - return ( - ('', '', '', '', trans.GetDescription(), - gnc_numeric_to_python_Decimal(split.GetAmount())) - for trans, split in values ) + num = trans.GetNum() + if (re.search('To Do', num, re.I)): + split_amount = gnc_numeric_to_python_Decimal(split.GetAmount()) - for start_date, end_date, debits, credits, debit_sum, credit_sum in \ - period_list: - csv_writer.writerow( (start_date, end_date, debit_sum, credit_sum) ) + 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() + """ +DTSTAMP:""" + stamp + """ +DTSTART:""" + day + """ +SUMMARY:""" + trans.GetDescription() + """ - $%d +END:VEVENT""" % split_amount + print event + else: + continue - if debits_show and len(debits) > 0: - csv_writer.writerow( - ('DEBITS', '', '', '', 'description', 'value') ) - csv_writer.writerows( generate_detail_rows(debits) ) - csv_writer.writerow( () ) - if credits_show and len(credits) > 0: - csv_writer.writerow( - ('CREDITS', '', '', '', 'description', 'value') ) - csv_writer.writerows( generate_detail_rows(credits) ) - csv_writer.writerow( () ) # no save needed, we're just reading.. gnucash_session.end()