[boobank-indicator] Add a gtk appindicator for boobank
This commit is contained in:
parent
fa01fff348
commit
85dafe36b9
12 changed files with 283 additions and 0 deletions
7
contrib/boobank_indicator/CHANGELOG.md
Normal file
7
contrib/boobank_indicator/CHANGELOG.md
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
This file will only list released and supported versions, usually skipping over very minor updates.
|
||||||
|
|
||||||
|
0.0.1
|
||||||
|
=====
|
||||||
|
|
||||||
|
* Mar 26, 2015
|
||||||
|
* First release
|
||||||
4
contrib/boobank_indicator/MANIFEST.in
Normal file
4
contrib/boobank_indicator/MANIFEST.in
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
include boobank-indicator/data/indicator-boobank.png
|
||||||
|
include boobank-indicator/data/green_light.png
|
||||||
|
include boobank-indicator/data/red_light.png
|
||||||
|
exclude screenshot.png
|
||||||
64
contrib/boobank_indicator/README.md
Normal file
64
contrib/boobank_indicator/README.md
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
Weboob
|
||||||
|
==========
|
||||||
|
|
||||||
|
Weboob is a project which provides a core library, modules and applications
|
||||||
|
such as boobank.
|
||||||
|
|
||||||
|
Overview
|
||||||
|
--------
|
||||||
|
|
||||||
|
The core library defines capabilities: features common to various websites.
|
||||||
|
|
||||||
|
Each module interfaces with a website and implements one or many of these
|
||||||
|
capabilities. Modules can be configured (becoming a "backend"), which means
|
||||||
|
that the end-user can provide personal information to access the underlying
|
||||||
|
website, like a login and password.
|
||||||
|
|
||||||
|
Applications allow the end-user to work with many modules in parallel,
|
||||||
|
in a multi-threaded way.
|
||||||
|
|
||||||
|
The core library provides base classes which help developers write
|
||||||
|
modules and applications.
|
||||||
|
|
||||||
|
Weboob is written in Python and is distributed under the AGPLv3+ license.
|
||||||
|
|
||||||
|
For more information, please go to the official website at http://weboob.org/
|
||||||
|
|
||||||
|
|
||||||
|
##Installation
|
||||||
|
boobank_indicator is distributed as a python package. Do the following to install:
|
||||||
|
|
||||||
|
``` sh
|
||||||
|
sudo pip install boobank_indicator
|
||||||
|
OR
|
||||||
|
sudo easy_install boobank_indicator
|
||||||
|
OR
|
||||||
|
#Download Source and cd to it
|
||||||
|
sudo python setup.py install
|
||||||
|
```
|
||||||
|
|
||||||
|
After that, you can run `boobank_indicator` from anywhere and it will run. You can
|
||||||
|
now add it to your OS dependent session autostart method. In Ubuntu, you can
|
||||||
|
access it via:
|
||||||
|
|
||||||
|
1. System > Preferences > Sessions
|
||||||
|
(OR)
|
||||||
|
2. System > Preferences > Startup Applications
|
||||||
|
|
||||||
|
depending on your Ubuntu Version. Or put it in `~/.config/openbox/autostart`
|
||||||
|
|
||||||
|
###Dependencies
|
||||||
|
|
||||||
|
- weboob >= 1.0
|
||||||
|
- gir1.2-appindicator3 >= 0.1
|
||||||
|
- gir1.2-notify >= 0.7
|
||||||
|
|
||||||
|
###Troubleshooting
|
||||||
|
|
||||||
|
If the app indicator fails to show in Ubuntu versions, consider installing
|
||||||
|
python-appindicator with
|
||||||
|
|
||||||
|
`sudo apt-get install python-appindicator` weboob gir1.2-appindicator3 gir1.2-notify`
|
||||||
|
|
||||||
|
##Author Information
|
||||||
|
- Bezleputh (<bezleputh@gmail.com>)
|
||||||
0
contrib/boobank_indicator/__init__.py
Normal file
0
contrib/boobank_indicator/__init__.py
Normal file
0
contrib/boobank_indicator/boobank_indicator/__init__.py
Normal file
0
contrib/boobank_indicator/boobank_indicator/__init__.py
Normal file
188
contrib/boobank_indicator/boobank_indicator/boobank_indicator.py
Normal file
188
contrib/boobank_indicator/boobank_indicator/boobank_indicator.py
Normal file
|
|
@ -0,0 +1,188 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from threading import Thread
|
||||||
|
from signal import signal, SIGINT, SIG_DFL
|
||||||
|
from pkg_resources import resource_filename
|
||||||
|
|
||||||
|
from gi.repository import Gtk, GObject, Notify
|
||||||
|
from gi.repository import AppIndicator3 as appindicator
|
||||||
|
|
||||||
|
from weboob.core import Weboob, CallErrors
|
||||||
|
from weboob.capabilities.bank import CapBank
|
||||||
|
from weboob.capabilities import UserError
|
||||||
|
from weboob.tools.application.base import MoreResultsAvailable
|
||||||
|
from weboob.exceptions import BrowserUnavailable, BrowserIncorrectPassword, BrowserForbidden, BrowserSSLError
|
||||||
|
|
||||||
|
PING_FREQUENCY = 3600 # seconds
|
||||||
|
APPINDICATOR_ID = "boobank_indicator"
|
||||||
|
PATH = os.path.realpath(__file__)
|
||||||
|
|
||||||
|
|
||||||
|
def create_image_menu_item(label, image):
|
||||||
|
item = Gtk.ImageMenuItem()
|
||||||
|
img = Gtk.Image()
|
||||||
|
img.set_from_file(os.path.abspath(resource_filename('boobank_indicator.data', image)))
|
||||||
|
item.set_image(img)
|
||||||
|
item.set_label(label)
|
||||||
|
item.set_always_show_image(True)
|
||||||
|
return item
|
||||||
|
|
||||||
|
|
||||||
|
class BoobankTransactionsChecker(Thread):
|
||||||
|
def __init__(self, weboob, menu, account):
|
||||||
|
Thread.__init__(self)
|
||||||
|
self.weboob = weboob
|
||||||
|
self.menu = menu
|
||||||
|
self.account = account
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
account_history_menu = Gtk.Menu()
|
||||||
|
|
||||||
|
for tr in self.weboob.do('iter_history', self.account, backends=self.account.backend):
|
||||||
|
label = "%s - %s: %s%s" % (tr.date, tr.label, tr.amount, self.account.currency_text)
|
||||||
|
image = "green_light.png" if tr.amount > 0 else "red_light.png"
|
||||||
|
transaction_item = create_image_menu_item(label, image)
|
||||||
|
account_history_menu.append(transaction_item)
|
||||||
|
transaction_item.show()
|
||||||
|
|
||||||
|
self.menu.set_submenu(account_history_menu)
|
||||||
|
|
||||||
|
|
||||||
|
class BoobankChecker():
|
||||||
|
def __init__(self):
|
||||||
|
self.ind = appindicator.Indicator.new(APPINDICATOR_ID,
|
||||||
|
os.path.abspath(resource_filename('boobank_indicator.data',
|
||||||
|
'indicator-boobank.png')),
|
||||||
|
appindicator.IndicatorCategory.APPLICATION_STATUS)
|
||||||
|
|
||||||
|
self.menu = Gtk.Menu()
|
||||||
|
self.ind.set_menu(self.menu)
|
||||||
|
|
||||||
|
logging.basicConfig()
|
||||||
|
if 'weboob_path' in os.environ:
|
||||||
|
self.weboob = Weboob(os.environ['weboob_path'])
|
||||||
|
else:
|
||||||
|
self.weboob = Weboob()
|
||||||
|
|
||||||
|
self.weboob.load_backends(CapBank)
|
||||||
|
|
||||||
|
def clean_menu(self, menu):
|
||||||
|
for i in menu.get_children():
|
||||||
|
submenu = i.get_submenu()
|
||||||
|
if submenu:
|
||||||
|
self.clean_menu(i)
|
||||||
|
menu.remove(i)
|
||||||
|
|
||||||
|
def check_boobank(self):
|
||||||
|
self.ind.set_status(appindicator.IndicatorStatus.ACTIVE)
|
||||||
|
self.clean_menu(self.menu)
|
||||||
|
|
||||||
|
total = 0
|
||||||
|
currency = ''
|
||||||
|
threads = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
for account in self.weboob.do('iter_accounts'):
|
||||||
|
|
||||||
|
balance = account.balance
|
||||||
|
if account.coming:
|
||||||
|
balance += account.coming
|
||||||
|
|
||||||
|
total += balance
|
||||||
|
currency = account.currency_text
|
||||||
|
|
||||||
|
label = "%s: %s%s" % (account.label, balance, account.currency_text)
|
||||||
|
image = "green_light.png" if balance > 0 else "red_light.png"
|
||||||
|
account_item = create_image_menu_item(label, image)
|
||||||
|
thread = BoobankTransactionsChecker(self.weboob, account_item, account)
|
||||||
|
thread.start()
|
||||||
|
threads.append(thread)
|
||||||
|
|
||||||
|
except CallErrors as errors:
|
||||||
|
self.bcall_errors_handler(errors)
|
||||||
|
|
||||||
|
for thread in threads:
|
||||||
|
thread.join()
|
||||||
|
|
||||||
|
for thread in threads:
|
||||||
|
self.menu.append(thread.menu)
|
||||||
|
thread.menu.show()
|
||||||
|
|
||||||
|
if len(self.menu.get_children()) == 0:
|
||||||
|
Notify.Notification.new('<b>Boobank</b>',
|
||||||
|
'No Bank account found\n Please configure one by running boobank',
|
||||||
|
'notification-message-im').show()
|
||||||
|
|
||||||
|
sep = Gtk.SeparatorMenuItem()
|
||||||
|
self.menu.append(sep)
|
||||||
|
sep.show()
|
||||||
|
|
||||||
|
total_item = Gtk.MenuItem("%s: %s%s" % ("Total", total, currency))
|
||||||
|
self.menu.append(total_item)
|
||||||
|
total_item.show()
|
||||||
|
|
||||||
|
sep = Gtk.SeparatorMenuItem()
|
||||||
|
self.menu.append(sep)
|
||||||
|
sep.show()
|
||||||
|
|
||||||
|
btnQuit = Gtk.ImageMenuItem()
|
||||||
|
image = Gtk.Image()
|
||||||
|
image.set_from_stock(Gtk.STOCK_QUIT, Gtk.IconSize.BUTTON)
|
||||||
|
btnQuit.set_image(image)
|
||||||
|
btnQuit.set_label('Quit')
|
||||||
|
btnQuit.set_always_show_image(True)
|
||||||
|
btnQuit.connect("activate", self.quit)
|
||||||
|
self.menu.append(btnQuit)
|
||||||
|
btnQuit.show()
|
||||||
|
|
||||||
|
def quit(self, widget):
|
||||||
|
Gtk.main_quit()
|
||||||
|
|
||||||
|
def bcall_errors_handler(self, errors):
|
||||||
|
"""
|
||||||
|
Handler for the CallErrors exception.
|
||||||
|
"""
|
||||||
|
self.ind.set_status(appindicator.IndicatorStatus.ATTENTION)
|
||||||
|
for backend, error, backtrace in errors.errors:
|
||||||
|
notify = True
|
||||||
|
if isinstance(error, BrowserIncorrectPassword):
|
||||||
|
msg = 'invalid login/password.'
|
||||||
|
elif isinstance(error, BrowserSSLError):
|
||||||
|
msg = '/!\ SERVER CERTIFICATE IS INVALID /!\\'
|
||||||
|
elif isinstance(error, BrowserForbidden):
|
||||||
|
msg = unicode(error) or 'Forbidden'
|
||||||
|
elif isinstance(error, BrowserUnavailable):
|
||||||
|
msg = unicode(error)
|
||||||
|
if not msg:
|
||||||
|
msg = 'website is unavailable.'
|
||||||
|
elif isinstance(error, NotImplementedError):
|
||||||
|
notify = False
|
||||||
|
elif isinstance(error, UserError):
|
||||||
|
msg = unicode(error)
|
||||||
|
elif isinstance(error, MoreResultsAvailable):
|
||||||
|
notify = False
|
||||||
|
else:
|
||||||
|
msg = unicode(error)
|
||||||
|
|
||||||
|
if notify:
|
||||||
|
Notify.Notification.new('<b>Error Boobank: %s</b>' % backend.name,
|
||||||
|
msg,
|
||||||
|
'notification-message-im').show()
|
||||||
|
|
||||||
|
def main(self):
|
||||||
|
self.check_boobank()
|
||||||
|
GObject.timeout_add(PING_FREQUENCY * 1000, self.check_boobank)
|
||||||
|
Gtk.main()
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
signal(SIGINT, SIG_DFL)
|
||||||
|
GObject.threads_init()
|
||||||
|
Notify.init('boobank_indicator')
|
||||||
|
BoobankChecker().main()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
BIN
contrib/boobank_indicator/boobank_indicator/data/green_light.png
Normal file
BIN
contrib/boobank_indicator/boobank_indicator/data/green_light.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
BIN
contrib/boobank_indicator/boobank_indicator/data/red_light.png
Normal file
BIN
contrib/boobank_indicator/boobank_indicator/data/red_light.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 966 B |
BIN
contrib/boobank_indicator/screenshot.png
Normal file
BIN
contrib/boobank_indicator/screenshot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 72 KiB |
20
contrib/boobank_indicator/setup.py
Normal file
20
contrib/boobank_indicator/setup.py
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
from setuptools import setup
|
||||||
|
from setuptools import find_packages
|
||||||
|
|
||||||
|
setup(name='boobank_indicator',
|
||||||
|
version='0.0.1',
|
||||||
|
description='show your bank accounts in your System Tray',
|
||||||
|
long_description='boobank_indicator will show you bank accounts and associated transactions in your system tray. Your bank accounts should be configured in boobank',
|
||||||
|
keywords='weboob boobank tray icon',
|
||||||
|
url='http://weboob.org/',
|
||||||
|
license='GNU AGPL 3',
|
||||||
|
author='Bezleputh',
|
||||||
|
author_email='bezleputh@gmail.com',
|
||||||
|
packages=find_packages(),
|
||||||
|
package_data={
|
||||||
|
'boobank_indicator.data': ['indicator-boobank.png', 'green_light.png', 'red_light.png']
|
||||||
|
},
|
||||||
|
entry_points={
|
||||||
|
'console_scripts': ['boobank_indicator = boobank_indicator.boobank_indicator:main'],
|
||||||
|
},
|
||||||
|
zip_safe=False)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue