initial import

This commit is contained in:
2022-09-30 10:02:47 +02:00
commit 16e60508ad
2 changed files with 273 additions and 0 deletions

View File

273
pywmcurrencies/pywmcurrencies.py Executable file
View File

@@ -0,0 +1,273 @@
#!/usr/bin/env python
"""
Simple dockapp to show up temperature for selected labels
"""
import argparse
import datetime
import os
import re
import sys
import time
import requests
import wmdocklib
from wmdocklib import helpers
from wmdocklib import pywmgeneral
import yaml
XDG_CONF_DIR = os.getenv('XDG_CONFIG_HOME', os.path.expanduser('~/.config'))
# expected bitmap contained font should be found in the same location as main
# program
BACKGROUND = '''\
/* XPM */
static char *mask_text[] = {
/* columns rows colors chars-per-pixel */
"64 64 4 1 ",
" c None",
". c black",
"X c #202020",
"O c gray78",
/* pixels */
" ",
" ",
" ............................................................ ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXO ",
" OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO ",
" ",
" "
};
'''
FONT = '''\
/* XPM */
static char *_x8_lcd_arrows[] = {
/* columns rows colors chars-per-pixel */
"192 16 4 1 ",
" c #202020",
". c #004941",
"X c #188A86",
"o c #20B2AE",
/* pixels */
" ... .X. o.o o.o .o. X...X oo. ..o ..o o.. ... ... ... ... ... ...X ooo ...X XoooX XoooX o...o XoooX XoooX XoooX XoooX XoooX ... ... ..oX ... Xo.. XoooX ",
". . . o . .o o. .X X. .XXXo o o o X. . X. . X . . X . o o . X . . . . . . . . o o o . o . o . o o o o . o . . o o o o o . . . . . X . . . . X . o o ",
". . . o . .X X. oXXXo o . . X. .XX . . X . .X . . X. .X X. . X . . . . . . . . X. o o . o . o . o o o o . o . . o o o o o . X . . X . .X . oXXXo . X. . o ",
" ... .X. ... o.o ooo .o. o.. ... o.. ..o XoooX XoooX ... XoooX ... .o. X...X ...X XoooX oooX XoooX ooooX XoooX ...X XoooX XoooX ... ... X... ... ...X ..oX ",
". . . o . . . oXXXo . o .X . o X o . . .X . . X. .X X. . X . . . . . . . .X . o o . o o . . o . o . o o o . o o o . o . . . . .X . oXXXo . X. . X . ",
". . . . . . .X X. oXXX. o o o X. . . . X . . X . o o . X . . X . . . . XX. o . o o . o o . . o . o . o o o . o o o . o . X . . X . . X . . . . X . . . ",
" ... .o. ... o.o .o. X...X oo.X ... ..o o.. ... ... .o. ... .oo X... ooo ...X XoooX XoooX ...X XoooX XoooX ...o XoooX XoooX ... .o. ..oX ... Xo.. .o. ",
" X X ",
" ooo ooo Xooo ooo Xooo XoooX XoooX oooX X...X .X. XoooX X...X X... oXo Xooo ooo Xooo ooo Xooo ooo XoXoX X...X X...X X...X X...X X...X XoooX .o. .o. .o. .o. ... ",
"o o o o o o o . o o o . o . o . o o . o . . o o o o . o o o o o o o o o o o o o o X . o . o o o o o o o o o o . o . X . .o o. .XXX. .X X. . . ",
"o XXo o o o o o . o o o . o . o . o o . o . . o o o o . o o o o o o o o o o o o o o . . o . o o o o o o Xo oX oX Xo . oX . X . . o . o X o o o . . ",
"X.o.X XoooX Xooo X... X...X XoooX Xooo X..oo XoooX .X. ...X Xooo X... X.X.X X...X X...X Xooo X...X Xooo ooo .X. X...X X...X X.X.X .ooo. .o.o. .o. .o. ... .o. ... ... ",
"o XXo o o o o o . o o o . o . o o o o . o . . o o o o . o o o o o o o o . o o o o o . o . o . o o o o o o o Xo oX . o . Xo . o X o . . . X . . . . . ",
"o o o o o o . o o o . o . o o o o . o . o o o o o . o o o o o o o o . o oo o o X o . o . o o Xo oX o o o o o . o . o . .XXX. . . . X . . . . . ",
" ooo X...X Xooo ooo Xooo XoooX X... ooo X...X .X. ooo X...X XoooX X. .X X...X ooo X... oooX X...X ooo .o. ooo XoX XoXoX X...X .X. XoooX .o. ... .o. ... ... ",
" "
};
'''
class SensorDockApp(wmdocklib.DockApp):
"""
Discover and display values for defined in config temperatures or other
readings using information found on /sys file system.
"""
background_color = '#202020'
def __init__(self, args=None):
super().__init__(args)
self.fonts = [wmdocklib.BitmapFonts(FONT, (6, 8))]
self.background = BACKGROUND
self.conf = {}
self.critical = 0
self.warning = 0
self._data = {}
self._read_config()
self._current_graph = ''
def run(self):
self.prepare_pixmaps()
self.open_xwindow()
try:
self.main_loop()
except KeyboardInterrupt:
pass
def main_loop(self):
count = 0
while True:
position = 1
if count == 0:
for currency in self.conf.get('currencies', [])[:7]:
value = self.get_rate_string(currency)
self._put_string(currency, value, position)
position += self.fonts[0].height + 1
count += 1
if count >= 10:
count = 0
self.redraw()
time.sleep(0.1)
def get_rate_string(self, currency):
self._get_rates()
previous, current = self._data[currency]
if len(str(int(current))) > 5:
return 'ERROR'
arrow = ']' # ↑
if current - previous < 0:
arrow = '[' # ↓
string = f'{current:.2f}{arrow}'
amount = 0
while len(string) < 5:
zeros = '0' * amount
string = f'{current:.2f}{zeros}{arrow}'
amount += 1
return string
def _get_rates(self):
now = datetime.datetime.now()
end_date = now.strftime("%Y-%m-%d")
# this is arbitrary number, since we have space for around 60, and
# there is no rating at holidays and weekends, so that makes around 20
# rates per month.
start_date = (now - datetime.timedelta(days=10)).strftime("%Y-%m-%d")
if (self._data.get('_last_update') and
(now - self._data['_last_update']).seconds < 7500):
# don't hammer npb service to often
return
for currency in self.conf.get('currencies'):
url = (f'http://api.nbp.pl/api/exchangerates/rates/a/{currency}/'
f'{start_date}/{end_date}/')
try:
response = requests.get(url)
except requests.ConnectionError:
return
if response.status_code != 200:
print(f'error requesting data for currency "{currency} on '
f'time range between {start_date} and {end_date}')
return
self._data['_last_update'] = now
result = response.json()
previous, current = [x['mid']
for x in result.get('rates', [])][-2:]
self._data[currency] = (previous, current)
def _switch_graph(self):
currencies = self.conf.get('currencies')
idx = currencies.index(self._current_graph)
try:
self._current_graph = currencies[idx + 1]
except IndexError:
self._current_graph = currencies[0]
def _read_config(self):
conf = os.path.join(XDG_CONF_DIR, 'pywmcurrencies.yaml')
if self.args.config:
conf = self.args.config
try:
with open(conf) as fobj:
self.conf = yaml.safe_load(fobj)
except OSError:
# TODO: add some logging?
pass
def _put_string(self, currency, value, position):
name = f'{currency[:3]:3}'.upper()
self.fonts[0].add_string(name, 1, position)
self.fonts[0].add_string(value, 28, position)
def _draw_graph_label(self):
name = self._current_graph.upper()
name = name[:4]
# ugly as hell 1 pixel border for the upper and left side of the label
helpers.copy_xpm_area(1, 65,
len(name) * self.fonts[0].width + 1, 1,
4, 51)
helpers.copy_xpm_area(1, 65,
1, self.fonts[0].height + 1,
4, 51)
self.fonts[0].add_string(name, 2, 49)
def main():
parser = argparse.ArgumentParser()
parser.add_argument('-c', '--config', help='Alternate config file')
args = parser.parse_args()
dockapp = SensorDockApp(args)
dockapp.run()
if __name__ == '__main__':
main()