mobatime cmd line util
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
timebot/timebot/gui.py

189 lines
6.8 KiB

import datetime
import logging
from typing import Tuple
from PySide6 import QtGui
from PySide6.QtCore import QTimer, QObject, Signal, QThread, Qt, QRunnable, Slot, QThreadPool
from PySide6.QtWidgets import QWidget, QVBoxLayout, QPushButton, QLabel, QMessageBox, QLineEdit, \
QHBoxLayout, QCheckBox, QDialogButtonBox, QFormLayout, QDialog, QMainWindow
4 years ago
from timebot.timebot import TimeBot, TimebotObtainPasswordError
4 years ago
from pytimeparse.timeparse import timeparse
from timebot.ui.timebot import Ui_MainWindow
package_logger = logging.getLogger(__name__)
4 years ago
class MyPasswordDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Timebot Password")
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
self.buttonBox.accepted.connect(self.accept)
self.buttonBox.rejected.connect(self.reject)
self.first = QLineEdit(self)
self.first.setEchoMode(QLineEdit.Password)
self.second = QCheckBox(self)
self.layout = QFormLayout()
self.layout.addRow("Enter your password:", self.first)
self.layout.addRow("Cache password:", self.second)
self.layout.addWidget(self.buttonBox)
self.setLayout(self.layout)
def get_password(self) -> Tuple[bool, str, bool]:
if self.exec():
return True, self.first.text(), self.second.isChecked()
return False, "", False
class HoursPresentLabelArea(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.text_box_hours_present_label = QLabel()
self.text_box_hours_present_label.setText("Hours present:")
self.text_box_hours_present = QLabel()
self.text_box_hours_present.setStyleSheet("background : #E0E0E0")
self.text_box_hours_present.setAlignment(Qt.AlignCenter)
layout = QHBoxLayout()
layout.addWidget(self.text_box_hours_present_label)
layout.addWidget(self.text_box_hours_present)
self.setLayout(layout)
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self, timebot: TimeBot, refresh_interval="1m"):
super(MainWindow, self).__init__()
"""Load the precompiled ui"""
self.setupUi(self)
4 years ago
self.timebot = timebot
self.timebot.mobatime_api.ask_for_password = False
self.present = None
self.hours_present = datetime.timedelta(microseconds=0)
self.threadpool = QThreadPool()
self.refreshStatusButton.clicked.connect(self.update_status)
self.smartPunchButton.clicked.connect(self.smart_punch)
4 years ago
self.status_timer_time = timeparse(refresh_interval) * 1000
self.status_timer = QTimer()
self.status_timer.timeout.connect(self.update_status)
self.status_timer.start(self.status_timer_time)
self.main_window_timer_time = 1000 # msec -> 1s
self.main_window_timer = QTimer()
self.main_window_timer.timeout.connect(self.update_main_window)
self.main_window_timer.start(self.main_window_timer_time)
4 years ago
self.error_msg = QMessageBox()
self.error_msg.setWindowTitle("Timebot ERROR")
self.error_msg.setIcon(QMessageBox.Critical)
4 years ago
self.error_msg.finished.connect(self.error_msg_finished)
self.update_status_running = False
self.update_status()
def update_main_window(self):
self.update_hours_present()
4 years ago
def update_status(self):
if self.update_status_running:
return
status_worker = TimebotApiWorker(self.timebot)
status_worker.signals.error.connect(lambda exp, *args: self.error_msg_show(str(exp)))
status_worker.signals.obtain_password.connect(lambda *args: self.get_password(self.update_status))
status_worker.signals.finished.connect(self.update_status_finished)
status_worker.signals.result.connect(self.display_status)
self.threadpool.start(status_worker)
4 years ago
self.update_status_started()
def display_status(self, data):
self.present = data[0]
self.update_hours_present(override=data[1])
self.statusLabel.setText(data[2])
def smart_punch(self):
try:
self.timebot.smart_punch()
self.update_status()
except Exception as e:
self.error_msg_show(str(e))
def get_password(self, callback: callable = None):
if self.timebot.mobatime_api.password is not None:
return
self.status_timer.stop()
ok, password, keep = MyPasswordDialog(self).get_password()
if ok:
self.timebot.mobatime_api.password = password
try:
_ = self.timebot.mobatime_api.session
except Exception as e:
self.error_msg_show(str(e))
if not keep:
self.timebot.mobatime_api.password = None
4 years ago
if callback is not None:
callback()
self.status_timer.start(self.status_timer_time)
4 years ago
def error_msg_show(self, error_text: str):
self.error_msg.setText(error_text)
self.status_timer.stop()
self.error_msg.exec_()
def error_msg_finished(self):
self.status_timer.start(self.status_timer_time)
4 years ago
def update_status_started(self):
self.refreshStatusButton.setEnabled(False)
self.refreshStatusButton.setText("Refreshing...")
self.update_status_running = True
def update_status_finished(self):
self.refreshStatusButton.setEnabled(True)
self.refreshStatusButton.setText("Refresh Status")
self.update_status_running = False
4 years ago
4 years ago
def update_hours_present(self, override: datetime.timedelta = None):
if override is not None:
self.hours_present: datetime.timedelta = override
elif self.hours_present > datetime.timedelta(seconds=self.main_window_timer_time / 100)\
and self.present is True:
self.hours_present = self.hours_present + datetime.timedelta(seconds=1)
4 years ago
hp = self.hours_present - datetime.timedelta(microseconds=self.hours_present.microseconds)
self.label_3.setText(str(hp))
4 years ago
class TimebotApiWorkerSignals(QObject):
error = Signal(object)
obtain_password = Signal()
result = Signal(object)
finished = Signal()
4 years ago
class TimebotApiWorker(QRunnable):
def __init__(self, timebot: TimeBot):
super(TimebotApiWorker, self).__init__()
4 years ago
self.timebot = timebot
self.signals = TimebotApiWorkerSignals()
4 years ago
@Slot()
def run(self):
4 years ago
try:
self.signals.result.emit((self.timebot.present, self.timebot.get_hours_present(), self.timebot.status()))
4 years ago
except TimebotObtainPasswordError:
self.signals.obtain_password.emit()
4 years ago
except Exception as e:
self.signals.error.emit(e)
finally:
self.signals.finished.emit()