[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