2013-12-17 14:41:30 +00:00
|
|
|
# Part of accounting-api project:
|
|
|
|
# https://gitorious.org/conservancy/accounting-api
|
|
|
|
# License: AGPLv3-or-later
|
|
|
|
|
2013-12-16 06:33:56 +00:00
|
|
|
import sys
|
|
|
|
import logging
|
|
|
|
import threading
|
2013-12-17 10:12:40 +00:00
|
|
|
import pkg_resources
|
2013-12-16 06:33:56 +00:00
|
|
|
|
2013-12-17 10:12:40 +00:00
|
|
|
from functools import wraps
|
2013-12-16 06:33:56 +00:00
|
|
|
from datetime import datetime
|
|
|
|
|
|
|
|
from gi.repository import Gtk
|
|
|
|
from gi.repository import GLib
|
|
|
|
from gi.repository import GObject
|
|
|
|
|
|
|
|
from accounting.client import Client
|
|
|
|
|
|
|
|
_log = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
2013-12-17 10:12:40 +00:00
|
|
|
def indicate_activity(func_or_str):
|
|
|
|
description = None
|
2013-12-16 06:33:56 +00:00
|
|
|
|
2013-12-17 10:12:40 +00:00
|
|
|
def decorator(func):
|
|
|
|
@wraps(func)
|
|
|
|
def wrapper(self, *args, **kw):
|
2013-12-17 13:11:59 +00:00
|
|
|
self.activity_description.set_text(description)
|
2013-12-17 10:12:40 +00:00
|
|
|
self.activity_indicator.show()
|
|
|
|
self.activity_indicator.start()
|
2013-12-17 05:00:21 +00:00
|
|
|
|
2013-12-17 10:12:40 +00:00
|
|
|
return func(self, *args, **kw)
|
2013-12-16 06:33:56 +00:00
|
|
|
|
2013-12-17 10:12:40 +00:00
|
|
|
return wrapper
|
2013-12-16 06:33:56 +00:00
|
|
|
|
2013-12-17 10:12:40 +00:00
|
|
|
if callable(func_or_str):
|
|
|
|
description = 'Working'
|
|
|
|
return decorator(func_or_str)
|
|
|
|
else:
|
|
|
|
description = func_or_str
|
|
|
|
return decorator
|
2013-12-17 05:00:21 +00:00
|
|
|
|
|
|
|
|
2013-12-17 10:12:40 +00:00
|
|
|
def indicate_activity_done(func):
|
|
|
|
@wraps(func)
|
|
|
|
def wrapper(self, *args, **kw):
|
2013-12-17 13:11:59 +00:00
|
|
|
self.activity_description.set_text('')
|
2013-12-17 10:12:40 +00:00
|
|
|
self.activity_indicator.stop()
|
|
|
|
self.activity_indicator.hide()
|
2013-12-17 05:00:21 +00:00
|
|
|
|
2013-12-17 10:12:40 +00:00
|
|
|
return func(self, *args, **kw)
|
2013-12-17 05:00:21 +00:00
|
|
|
|
2013-12-17 10:12:40 +00:00
|
|
|
return wrapper
|
2013-12-17 05:00:21 +00:00
|
|
|
|
|
|
|
|
2013-12-17 10:12:40 +00:00
|
|
|
class AccountingApplication:
|
|
|
|
def __init__(self):
|
|
|
|
#Gtk.Window.__init__(self, title='Accounting Client')
|
2013-12-16 06:33:56 +00:00
|
|
|
|
2013-12-17 10:12:40 +00:00
|
|
|
self.client = Client()
|
2013-12-17 05:00:21 +00:00
|
|
|
|
2013-12-17 10:12:40 +00:00
|
|
|
self.load_ui(pkg_resources.resource_filename(
|
|
|
|
'accounting', 'res/client-ui.glade'))
|
2013-12-17 05:00:21 +00:00
|
|
|
|
2013-12-17 10:12:40 +00:00
|
|
|
self.about_dialog.set_transient_for(self.accounting_window)
|
2013-12-17 05:00:21 +00:00
|
|
|
|
2013-12-17 10:12:40 +00:00
|
|
|
self.accounting_window.connect('delete-event', Gtk.main_quit)
|
|
|
|
self.accounting_window.set_border_width(0)
|
|
|
|
self.accounting_window.set_default_geometry(640, 360)
|
2013-12-17 05:00:21 +00:00
|
|
|
|
2013-12-17 10:12:40 +00:00
|
|
|
self.accounting_window.show_all()
|
|
|
|
self.transaction_detail.hide()
|
2013-12-17 05:00:21 +00:00
|
|
|
|
2013-12-17 10:12:40 +00:00
|
|
|
def load_ui(self, path):
|
|
|
|
_log.debug('Loading UI...')
|
|
|
|
builder = Gtk.Builder()
|
|
|
|
builder.add_from_file(path)
|
|
|
|
builder.connect_signals(self)
|
2013-12-16 06:33:56 +00:00
|
|
|
|
2013-12-17 10:12:40 +00:00
|
|
|
for element in builder.get_objects():
|
|
|
|
try:
|
|
|
|
setattr(self, Gtk.Buildable.get_name(element), element)
|
|
|
|
_log.debug('Loaded %s', Gtk.Buildable.get_name(element))
|
|
|
|
except TypeError as exc:
|
|
|
|
_log.error('%s could not be loaded: %s', element, exc)
|
2013-12-17 05:00:21 +00:00
|
|
|
|
2013-12-17 10:12:40 +00:00
|
|
|
_log.debug('UI loaded')
|
2013-12-17 05:00:21 +00:00
|
|
|
|
2013-12-17 10:12:40 +00:00
|
|
|
def on_transaction_view_cursor_changed(self, widget):
|
2013-12-17 05:00:21 +00:00
|
|
|
selection = self.transaction_view.get_selection()
|
|
|
|
selection.set_mode(Gtk.SelectionMode.SINGLE)
|
|
|
|
xact_store, xact_iter = selection.get_selected()
|
|
|
|
|
|
|
|
xact_id = xact_store.get_value(xact_iter, 0)
|
|
|
|
_log.debug('selection: %s', xact_id)
|
|
|
|
|
|
|
|
for transaction in self.transaction_data:
|
|
|
|
if transaction.id == xact_id:
|
2013-12-17 10:12:40 +00:00
|
|
|
self.transaction_header.set_text(transaction.payee)
|
2013-12-17 05:00:21 +00:00
|
|
|
|
|
|
|
self.posting_store.clear()
|
|
|
|
|
|
|
|
for posting in transaction.postings:
|
|
|
|
self.posting_store.append([
|
|
|
|
posting.account,
|
|
|
|
str(posting.amount.amount),
|
|
|
|
posting.amount.symbol
|
|
|
|
])
|
2013-12-16 06:33:56 +00:00
|
|
|
|
2013-12-17 10:12:40 +00:00
|
|
|
self.transaction_detail.show()
|
2013-12-17 05:00:21 +00:00
|
|
|
break
|
2013-12-16 06:33:56 +00:00
|
|
|
|
2013-12-17 10:12:40 +00:00
|
|
|
def on_show_about_activate(self, widget):
|
|
|
|
_log.debug('Showing About')
|
|
|
|
self.about_dialog.show_all()
|
|
|
|
|
|
|
|
def on_about_dialog_response(self, widget, response_type):
|
|
|
|
_log.debug('Closing About')
|
|
|
|
if response_type == Gtk.ResponseType.CANCEL:
|
|
|
|
self.about_dialog.hide()
|
|
|
|
else:
|
|
|
|
_log.error('Unexpected response_type: %d', response_type)
|
|
|
|
|
|
|
|
@indicate_activity('Refreshing Transactions')
|
|
|
|
def on_transaction_refresh_activate(self, widget):
|
2013-12-16 06:33:56 +00:00
|
|
|
def load_transactions():
|
|
|
|
transactions = self.client.get_register()
|
|
|
|
GLib.idle_add(self.on_transactions_loaded, transactions)
|
|
|
|
|
|
|
|
threading.Thread(target=load_transactions).start()
|
|
|
|
|
2013-12-17 10:12:40 +00:00
|
|
|
@indicate_activity_done
|
2013-12-16 06:33:56 +00:00
|
|
|
def on_transactions_loaded(self, transactions):
|
|
|
|
_log.debug('transactions: %s', transactions)
|
|
|
|
|
2013-12-17 05:00:21 +00:00
|
|
|
self.transaction_data = transactions
|
2013-12-16 06:33:56 +00:00
|
|
|
self.transaction_store.clear()
|
|
|
|
|
|
|
|
for transaction in transactions:
|
|
|
|
self.transaction_store.append([
|
2013-12-17 05:00:21 +00:00
|
|
|
transaction.id,
|
2013-12-16 06:33:56 +00:00
|
|
|
transaction.date.strftime('%Y-%m-%d'),
|
|
|
|
transaction.payee
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
def main(argv=None):
|
|
|
|
logging.basicConfig(level=logging.DEBUG)
|
|
|
|
|
|
|
|
GObject.threads_init()
|
|
|
|
|
2013-12-17 10:12:40 +00:00
|
|
|
accounting = AccountingApplication()
|
2013-12-16 06:33:56 +00:00
|
|
|
|
|
|
|
Gtk.main()
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
sys.exit(main())
|