Mercurial > lbo > hg > stex
changeset 2:61952d5a8718
Add very simplistic initial graphic client
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Thu, 28 Feb 2019 18:19:21 +0100 |
parents | f867f7c3c2db |
children | 38725950fe15 |
files | client/client.py |
diffstat | 1 files changed, 219 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/client.py Thu Feb 28 18:19:21 2019 +0100 @@ -0,0 +1,219 @@ +#!/usr/bin/env python3 + +import arguments +import os +import os.path as path +import sys + +import PyQt5.QtWidgets as wid +import PyQt5.QtCore as core + +from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas +from matplotlib.figure import Figure + +class Creds: + user = '' + password = '' + addr = '' + +class ClientConfigDialog(wid.QDialog): + addr = None + user = None + password = None + defaults = False + + def __init__(self, parent, defaults=False): + super().__init__(parent) + self.defaults = defaults + + def show_dialog(self): + vbox = wid.QVBoxLayout(self) + + self.addr = wid.QLineEdit() + self.addr.readOnly = False + self.addr.setText(self.load_default('addr')) + self.user = wid.QLineEdit() + self.user.readOnly = False + self.user.setText(self.load_default('user')) + self.password = wid.QLineEdit() + self.password.readOnly = False + self.password.setText(self.load_default('password')) + self.password.setEchoMode(wid.QLineEdit.Password) + + if self.defaults and self.addr.text() and self.user.text() and self.password.text(): + self.finished.emit(1) + self.accepted.emit() + return + + hbox_addr = wid.QHBoxLayout() + hbox_addr.addWidget(wid.QLabel('Address of server: ')) + hbox_addr.addWidget(self.addr) + + hbox_user = wid.QHBoxLayout() + hbox_user.addWidget(wid.QLabel('Username: ')) + hbox_user.addWidget(self.user) + + hbox_password = wid.QHBoxLayout() + hbox_password.addWidget(wid.QLabel('Password: ')) + hbox_password.addWidget(self.password) + + ok = wid.QPushButton('OK') + ok.clicked.connect(self.ok_clicked) + ok.clicked.connect(super().done) + vbox.addLayout(hbox_addr) + vbox.addLayout(hbox_user) + vbox.addLayout(hbox_password) + vbox.addWidget(ok) + + self.setVisible(True) + + + default_addr_file = '.config/stex/' + + def load_default(self, id): + try: + home = os.environ.get('HOME') + if not home: + home = path.join('/home/', os.environ.get('USER')) + with open(path.join(home, self.default_addr_file, id), 'r') as f: + return f.readline() + except Exception as e: + sys.stderr.write("Couldn't read file: {}\n".format(e)) + return '' + + def save_default(self, id, val): + try: + home = os.environ.get('HOME') + if not home: + home = path.join('/home/', os.environ.get('USER')) + da = path.join(home, self.default_addr_file, id) + os.makedirs(path.dirname(da), exist_ok=True) + f = open(da, 'w' if os.access(da, os.F_OK) else 'x') + f.write(val) + except Exception as e: + sys.stderr.write("Couldn't write file: {}\n".format(e)) + return + + def ok_clicked(self): + self.save_default('addr', self.addr.text()) + self.save_default('user', self.user.text()) + self.save_default('password', self.password.text()) + + def creds(self): + creds = Creds() + creds.user = self.user.text() + creds.password = self.password.text() + creds.addr = self.addr.text() + return creds + +class StockGraph(FigureCanvas): + fig = None + axes = None + sym = '' + + MAX_LEN = 500 + XAXIS = [i for i in range(0, MAX_LEN)] + history = [0 for i in range(0, MAX_LEN)] + + def __init__(self, sym, dim): + self.sym = sym + self.fig = Figure(figsize=(dim or (200,100))) + self.axes = self.fig.add_subplot(111) + self.axes.grid(True) + self.axes.set_xlim(0, self.MAX_LEN) + + super().__init__(self.fig) + super().setSizePolicy(wid.QSizePolicy.Expanding, wid.QSizePolicy.Expanding) + super().updateGeometry() + + def update_stock(self, value): + self.history.append(value) + self.history[0:] = self.history[1:] + self.plot() + + def plot(self): + self.axes.set_title(self.sym) + self.axes.plot(self.XAXIS, self.history) + self.draw() + +class StockWidget(wid.QWidget): + graph = None + + def __init__(self, graph): + super().__init__() + self.graph = graph + + mainvbox = wid.QVBoxLayout(self) + mainvbox.addWidget(self.graph) + mainvbox.addLayout(self.init_buttonbox()) + self.update(5000) + self.show() + + def init_buttonbox(self): + buy = wid.QPushButton(' BUY ') + sell = wid.QPushButton(' SELL ') + self.current_state = wid.QLineEdit() + self.current_state.setReadOnly(True) + self.current_state.setAlignment(core.Qt.AlignCenter) + + hbox = wid.QHBoxLayout() + hbox.addWidget(buy) + hbox.addWidget(sell) + hbox.addWidget(self.current_state) + return hbox + + def update(self, val): + self.graph.update_stock(val) + self.current_state.setText('{} pc / {} ø/pc / {} ø'.format('?', val/100, val/100)) + +class Client(arguments.BaseArguments, wid.QWidget): + _doc = """ + Usage: + stex [options] + + Options + --defaults Use cached defaults if available. + """ + + creds = Creds() + + def __init__(self): + super(wid.QWidget, self).__init__() + super(arguments.BaseArguments, self).__init__(doc=self._doc) + + ccd = ClientConfigDialog(self, defaults=self.defaults) + ccd.accepted.connect(lambda: self.set_creds(ccd.creds())) + ccd.accepted.connect(self.start_main_window) + ccd.show_dialog() + + def set_creds(self, creds): + self.creds = creds + + def start_main_window(self): + mainvbox = wid.QVBoxLayout(self) + + hbox1 = wid.QHBoxLayout() + sg1 = StockWidget(StockGraph('ABCD', None)) + sg2 = StockWidget(StockGraph('EFGH', None)) + hbox1.addWidget(sg1) + hbox1.addWidget(sg2) + + hbox2 = wid.QHBoxLayout() + sg3 = StockWidget(StockGraph('ABCD', None)) + sg4 = StockWidget(StockGraph('ABCD', None)) + hbox2.addWidget(sg3) + hbox2.addWidget(sg4) + + mainvbox.addLayout(hbox1) + mainvbox.addLayout(hbox2) + + self.show() + + +def main(): + app = wid.QApplication(sys.argv) + client = Client() + sys.exit(app.exec_()) + +if __name__ == '__main__': + main()