M numberstation/otpurl.py => numberstation/otpurl.py +14 -1
@@ 46,7 46,9 @@ class OTPUrl:
def get_token(self):
if self.type == 'totp':
totp = pyotp.TOTP(self.secret, interval=self.period, digits=self.digits, digest=self.digest)
- return totp.now(), totp.interval - datetime.now().timestamp() % totp.interval
+ base_timestamp = totp.interval * int(datetime.now().timestamp() / totp.interval)
+ valid_until = datetime.fromtimestamp(base_timestamp + totp.interval)
+ return totp.now(), valid_until
elif self.type == 'hotp':
hotp = pyotp.HOTP(self.secret, digits=self.digits, digest=self.digest, initial_count=self.initial_count)
return hotp.at(0), None
@@ 54,6 56,17 @@ class OTPUrl:
sys.stderr.write("Unknown key format '{}'\n".format(self.type))
return None, None
+ def get_validity(self):
+ """Returns floating value in the range 0.0-1.0
+ described how long generated code will be valid
+ relative to update period
+ """
+ if self.type == 'totp':
+ secs_left = self.period - datetime.now().timestamp() % self.period
+ return 1.0 * secs_left / self.period
+ else:
+ return None
+
def get_url(self):
properties = {
'secret': self.secret,
M numberstation/window.py => numberstation/window.py +11 -13
@@ 1,4 1,5 @@
from base64 import b32decode
+from datetime import datetime
from collections import namedtuple
import keyring
@@ 128,7 129,7 @@ class NumberstationWindow:
self.save_keyring()
def update_code_label(self, label, progressbar, token):
- code, validity = token.get_token()
+ code, valid_until = token.get_token()
if code is None:
return
user_code = code
@@ 144,23 145,20 @@ class NumberstationWindow:
else:
label.set_label(user_code)
label.paste_code = paste_code
- if validity:
- progressbar.validity = int(validity)
+ if valid_until:
+ progressbar.valid_until = valid_until
else:
if progressbar:
- progressbar.validity = None
+ progressbar.valid_until = None
def update_codes(self):
GLib.timeout_add(1000, self.update_codes)
for timer in self.timers:
- if timer.validity is None:
+ if timer.valid_until is None:
continue
- timer.validity -= 1
- if timer.validity < 1:
- timer.validity = int(timer.period)
+ if timer.valid_until < datetime.now():
self.update_code_label(timer.display, timer, timer.token)
-
- timer.set_fraction(1.0 / timer.period * timer.validity)
+ timer.set_fraction(timer.token.get_validity())
def on_long_press(self, gesture, x, y, *args):
eb = gesture.eb
@@ 249,12 247,12 @@ class NumberstationWindow:
timer.token = token
timer.display = code
- if not hasattr(timer, 'validity'):
+ if not hasattr(timer, 'valid_until'):
continue
- if timer.validity is not None:
+ if timer.valid_until is not None:
timer.show()
timer.set_no_show_all(False)
- timer.set_fraction(1.0 / token.period * timer.validity)
+ timer.set_fraction(token.get_validity())
else:
timer.hide()
timer.set_no_show_all(True)