mirror of
https://github.com/SeedSigner/seedsigner.git
synced 2026-10-05 15:08:25 +00:00
Merge pull request #558 from dbast/logging
Setup Python logging + convert print statements to logger calls
This commit is contained in:
@@ -58,6 +58,7 @@ branch = true
|
|||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
testpaths = ["tests"]
|
testpaths = ["tests"]
|
||||||
|
addopts = "-p no:logging"
|
||||||
|
|
||||||
[tool.setuptools]
|
[tool.setuptools]
|
||||||
include-package-data = true
|
include-package-data = true
|
||||||
|
|||||||
Regular → Executable
+51
-2
@@ -1,4 +1,53 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
import sys
|
||||||
|
|
||||||
from seedsigner.controller import Controller
|
from seedsigner.controller import Controller
|
||||||
|
|
||||||
# Get the one and only Controller instance and start our main loop
|
logger = logging.getLogger(__name__)
|
||||||
Controller.get_instance().start()
|
|
||||||
|
DEFAULT_MODULE_LOG_LEVELS = {
|
||||||
|
"PIL": logging.WARNING,
|
||||||
|
# "seedsigner.gui.toast": logging.DEBUG, # example of more specific submodule logging config
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def main(sys_argv=None):
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument(
|
||||||
|
"-l",
|
||||||
|
"--loglevel",
|
||||||
|
choices=list((logging._nameToLevel.keys())),
|
||||||
|
default="INFO",
|
||||||
|
type=str,
|
||||||
|
help=(
|
||||||
|
"Set the log level (default: %(default)s), WARNING: changing the log level "
|
||||||
|
"to something more verbose than %(default)s may result in unwanted data "
|
||||||
|
"being written to stderr"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
args = parser.parse_args(sys_argv)
|
||||||
|
|
||||||
|
root_logger = logging.getLogger()
|
||||||
|
root_logger.setLevel(logging.getLevelName(args.loglevel))
|
||||||
|
console_handler = logging.StreamHandler(sys.stderr)
|
||||||
|
console_handler.setFormatter(
|
||||||
|
logging.Formatter("%(asctime)s %(levelname)8s [%(name)s %(funcName)s (%(lineno)d)]: %(message)s")
|
||||||
|
)
|
||||||
|
root_logger.addHandler(console_handler)
|
||||||
|
|
||||||
|
# Set log levels for specific modules
|
||||||
|
for module, level in DEFAULT_MODULE_LOG_LEVELS.items():
|
||||||
|
logging.getLogger(module).setLevel(level)
|
||||||
|
|
||||||
|
logger.info(f"Starting SeedSigner with: {args.__dict__}")
|
||||||
|
|
||||||
|
# Get the one and only Controller instance and start our main loop
|
||||||
|
Controller.get_instance().start()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main(sys.argv[1:])
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ class Controller(Singleton):
|
|||||||
Example:
|
Example:
|
||||||
class MyView(View)
|
class MyView(View)
|
||||||
def run(self, some_arg, other_arg):
|
def run(self, some_arg, other_arg):
|
||||||
print(other_arg)
|
logger.info(other_arg)
|
||||||
|
|
||||||
class OtherView(View):
|
class OtherView(View):
|
||||||
def run(self):
|
def run(self):
|
||||||
@@ -305,11 +305,11 @@ class Controller(Singleton):
|
|||||||
self.psbt_parser = None
|
self.psbt_parser = None
|
||||||
self.psbt_seed = None
|
self.psbt_seed = None
|
||||||
|
|
||||||
print(f"back_stack: {self.back_stack}")
|
logger.info(f"\nback_stack: {self.back_stack}")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Instantiate the View class and run it
|
# Instantiate the View class and run it
|
||||||
print(f"Executing {next_destination}")
|
logger.info(f"Executing {next_destination}")
|
||||||
next_destination = next_destination.run()
|
next_destination = next_destination.run()
|
||||||
|
|
||||||
except StopFlowBasedTest:
|
except StopFlowBasedTest:
|
||||||
@@ -337,7 +337,7 @@ class Controller(Singleton):
|
|||||||
# Remove the current View from history; it's forwarding us straight
|
# Remove the current View from history; it's forwarding us straight
|
||||||
# to the next View so it should be as if this View never happened.
|
# to the next View so it should be as if this View never happened.
|
||||||
current_view = self.back_stack.pop()
|
current_view = self.back_stack.pop()
|
||||||
print(f"Skipping current view: {current_view}")
|
logger.info(f"Skipping current view: {current_view}")
|
||||||
|
|
||||||
# Hang on to this reference...
|
# Hang on to this reference...
|
||||||
clear_history = next_destination.clear_history
|
clear_history = next_destination.clear_history
|
||||||
@@ -355,12 +355,10 @@ class Controller(Singleton):
|
|||||||
# Do not push a "new" destination if it is the same as the current one on
|
# Do not push a "new" destination if it is the same as the current one on
|
||||||
# the top of the stack.
|
# the top of the stack.
|
||||||
if len(self.back_stack) == 0 or self.back_stack[-1] != next_destination:
|
if len(self.back_stack) == 0 or self.back_stack[-1] != next_destination:
|
||||||
print(f"Appending next destination: {next_destination}")
|
logger.info(f"Appending next destination: {next_destination}")
|
||||||
self.back_stack.append(next_destination)
|
self.back_stack.append(next_destination)
|
||||||
else:
|
else:
|
||||||
print(f"NOT appending {next_destination}")
|
logger.info(f"NOT appending {next_destination}")
|
||||||
|
|
||||||
print("-" * 30)
|
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
from seedsigner.gui.renderer import Renderer
|
from seedsigner.gui.renderer import Renderer
|
||||||
@@ -371,7 +369,7 @@ class Controller(Singleton):
|
|||||||
self.toast_notification_thread.stop()
|
self.toast_notification_thread.stop()
|
||||||
|
|
||||||
# Clear the screen when exiting
|
# Clear the screen when exiting
|
||||||
print("Clearing screen, exiting")
|
logger.info("Clearing screen, exiting")
|
||||||
Renderer.get_instance().display_blank_screen()
|
Renderer.get_instance().display_blank_screen()
|
||||||
|
|
||||||
|
|
||||||
@@ -385,10 +383,10 @@ class Controller(Singleton):
|
|||||||
# block until the screensaver is done, at which point the toast can re-acquire
|
# block until the screensaver is done, at which point the toast can re-acquire
|
||||||
# the Renderer.lock and resume where it left off.
|
# the Renderer.lock and resume where it left off.
|
||||||
if self.toast_notification_thread and self.toast_notification_thread.is_alive():
|
if self.toast_notification_thread and self.toast_notification_thread.is_alive():
|
||||||
print(f"Controller: settings toggle_render_lock for {self.toast_notification_thread.__class__.__name__}")
|
logger.info(f"Controller: settings toggle_render_lock for {self.toast_notification_thread.__class__.__name__}")
|
||||||
self.toast_notification_thread.toggle_renderer_lock()
|
self.toast_notification_thread.toggle_renderer_lock()
|
||||||
|
|
||||||
print("Controller: Starting screensaver")
|
logger.info("Controller: Starting screensaver")
|
||||||
if not self.screensaver:
|
if not self.screensaver:
|
||||||
# Do a lazy/late import and instantiation to reduce Controller initial startup time
|
# Do a lazy/late import and instantiation to reduce Controller initial startup time
|
||||||
from seedsigner.views.screensaver import ScreensaverScreen
|
from seedsigner.views.screensaver import ScreensaverScreen
|
||||||
@@ -397,7 +395,7 @@ class Controller(Singleton):
|
|||||||
|
|
||||||
# Start the screensaver, but it will block until it can acquire the Renderer.lock.
|
# Start the screensaver, but it will block until it can acquire the Renderer.lock.
|
||||||
self.screensaver.start()
|
self.screensaver.start()
|
||||||
print("Controller: Screensaver started")
|
logger.info("Controller: Screensaver started")
|
||||||
|
|
||||||
|
|
||||||
def reset_screensaver_timeout(self):
|
def reset_screensaver_timeout(self):
|
||||||
@@ -416,16 +414,16 @@ class Controller(Singleton):
|
|||||||
"""
|
"""
|
||||||
if self.is_screensaver_running:
|
if self.is_screensaver_running:
|
||||||
# New toast notifications break out of the Screensaver
|
# New toast notifications break out of the Screensaver
|
||||||
print("Controller: stopping screensaver")
|
logger.info("Controller: stopping screensaver")
|
||||||
self.screensaver.stop()
|
self.screensaver.stop()
|
||||||
|
|
||||||
if self.toast_notification_thread and self.toast_notification_thread.is_alive():
|
if self.toast_notification_thread and self.toast_notification_thread.is_alive():
|
||||||
# Can only run one toast at a time
|
# Can only run one toast at a time
|
||||||
print(f"Controller: stopping {self.toast_notification_thread.__class__.__name__}")
|
logger.info(f"Controller: stopping {self.toast_notification_thread.__class__.__name__}")
|
||||||
self.toast_notification_thread.stop()
|
self.toast_notification_thread.stop()
|
||||||
|
|
||||||
self.toast_notification_thread = toast_manager_thread
|
self.toast_notification_thread = toast_manager_thread
|
||||||
print(f"Controller: starting {self.toast_notification_thread.__class__.__name__}")
|
logger.info(f"Controller: starting {self.toast_notification_thread.__class__.__name__}")
|
||||||
self.toast_notification_thread.start()
|
self.toast_notification_thread.start()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import logging
|
||||||
import math
|
import math
|
||||||
import os
|
import os
|
||||||
import pathlib
|
import pathlib
|
||||||
@@ -13,6 +14,8 @@ from seedsigner.models.settings import Settings
|
|||||||
from seedsigner.models.settings_definition import SettingsConstants
|
from seedsigner.models.settings_definition import SettingsConstants
|
||||||
from seedsigner.models.singleton import Singleton
|
from seedsigner.models.singleton import Singleton
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
# TODO: Remove all pixel hard coding
|
# TODO: Remove all pixel hard coding
|
||||||
class GUIConstants:
|
class GUIConstants:
|
||||||
@@ -1439,7 +1442,7 @@ def reflow_text_into_pages(text: str,
|
|||||||
lines = []
|
lines = []
|
||||||
for line_dict in reflowed_lines_dicts:
|
for line_dict in reflowed_lines_dicts:
|
||||||
lines.append(line_dict["text"])
|
lines.append(line_dict["text"])
|
||||||
print(f"""{line_dict["text_width"]:3}: {line_dict["text"]}""")
|
logging.info(f"""{line_dict["text_width"]:3}: {line_dict["text"]}""")
|
||||||
|
|
||||||
font = Fonts.get_font(font_name=font_name, size=font_size)
|
font = Fonts.get_font(font_name=font_name, size=font_size)
|
||||||
# Measure the font's height above baseline and how for below it certain characters
|
# Measure the font's height above baseline and how for below it certain characters
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import math
|
import math
|
||||||
|
import logging
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
@@ -16,6 +17,7 @@ from ..components import (Button, FontAwesomeIconConstants, Fonts, FormattedAddr
|
|||||||
from seedsigner.gui.keyboard import Keyboard, TextEntryDisplay
|
from seedsigner.gui.keyboard import Keyboard, TextEntryDisplay
|
||||||
from seedsigner.hardware.buttons import HardwareButtons, HardwareButtonsConstants
|
from seedsigner.hardware.buttons import HardwareButtons, HardwareButtonsConstants
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -1412,9 +1414,9 @@ class SeedAddressVerificationScreen(ButtonListScreen):
|
|||||||
|
|
||||||
def _run_callback(self):
|
def _run_callback(self):
|
||||||
# Exit the screen on success via a non-None value
|
# Exit the screen on success via a non-None value
|
||||||
print(f"verified_index: {self.verified_index.cur_count}")
|
logger.info(f"verified_index: {self.verified_index.cur_count}")
|
||||||
if self.verified_index.cur_count is not None:
|
if self.verified_index.cur_count is not None:
|
||||||
print("Screen callback returning success!")
|
logger.info("Screen callback returning success!")
|
||||||
self.threads[-1].stop()
|
self.threads[-1].stop()
|
||||||
while self.threads[-1].is_alive():
|
while self.threads[-1].is_alive():
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
|
|||||||
+15
-13
@@ -1,8 +1,10 @@
|
|||||||
|
import logging
|
||||||
import time
|
import time
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from seedsigner.gui.components import BaseComponent, GUIConstants, Icon, SeedSignerIconConstants, TextArea
|
from seedsigner.gui.components import BaseComponent, GUIConstants, Icon, SeedSignerIconConstants, TextArea
|
||||||
from seedsigner.models.threads import BaseThread
|
from seedsigner.models.threads import BaseThread
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -119,33 +121,33 @@ class BaseToastOverlayManagerThread(BaseThread):
|
|||||||
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
print(f"{self.__class__.__name__}: started")
|
logger.info(f"{self.__class__.__name__}: started")
|
||||||
start = time.time()
|
start = time.time()
|
||||||
while time.time() - start < self.activation_delay:
|
while time.time() - start < self.activation_delay:
|
||||||
if self.hw_inputs.has_any_input():
|
if self.hw_inputs.has_any_input():
|
||||||
# User has pressed a button, cancel the toast
|
# User has pressed a button, cancel the toast
|
||||||
print(f"{self.__class__.__name__}: Canceling toast due to user input")
|
logger.info(f"{self.__class__.__name__}: Canceling toast due to user input")
|
||||||
return
|
return
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Hold onto the Renderer lock so we're guaranteed to restore the original
|
# Hold onto the Renderer lock so we're guaranteed to restore the original
|
||||||
# screen before any other listener can get a screen write in.
|
# screen before any other listener can get a screen write in.
|
||||||
print(f"{self.__class__.__name__}: Acquiring lock")
|
logger.info(f"{self.__class__.__name__}: Acquiring lock")
|
||||||
self.renderer.lock.acquire()
|
self.renderer.lock.acquire()
|
||||||
print(f"{self.__class__.__name__}: Lock acquired")
|
logger.info(f"{self.__class__.__name__}: Lock acquired")
|
||||||
|
|
||||||
has_rendered = False
|
has_rendered = False
|
||||||
previous_screen_state = None
|
previous_screen_state = None
|
||||||
while self.keep_running and self.should_keep_running():
|
while self.keep_running and self.should_keep_running():
|
||||||
if self.hw_inputs.has_any_input():
|
if self.hw_inputs.has_any_input():
|
||||||
# User has pressed a button, hide the toast
|
# User has pressed a button, hide the toast
|
||||||
print(f"{self.__class__.__name__}: Exiting due to user input")
|
logger.info(f"{self.__class__.__name__}: Exiting due to user input")
|
||||||
break
|
break
|
||||||
|
|
||||||
if self._toggle_renderer_lock:
|
if self._toggle_renderer_lock:
|
||||||
# Controller has notified us that another process needs the lock
|
# Controller has notified us that another process needs the lock
|
||||||
print(f"{self.__class__.__name__}: Releasing lock")
|
logger.info(f"{self.__class__.__name__}: Releasing lock")
|
||||||
self._toggle_renderer_lock = False
|
self._toggle_renderer_lock = False
|
||||||
self.renderer.lock.release()
|
self.renderer.lock.release()
|
||||||
|
|
||||||
@@ -155,29 +157,29 @@ class BaseToastOverlayManagerThread(BaseThread):
|
|||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
# Block while waiting to reaquire the lock
|
# Block while waiting to reaquire the lock
|
||||||
print(f"{self.__class__.__name__}: Blocking to re-acquire lock")
|
logger.info(f"{self.__class__.__name__}: Blocking to re-acquire lock")
|
||||||
self.renderer.lock.acquire()
|
self.renderer.lock.acquire()
|
||||||
print(f"{self.__class__.__name__}: Lock re-acquired")
|
logger.info(f"{self.__class__.__name__}: Lock re-acquired")
|
||||||
|
|
||||||
if not has_rendered:
|
if not has_rendered:
|
||||||
previous_screen_state = self.renderer.canvas.copy()
|
previous_screen_state = self.renderer.canvas.copy()
|
||||||
print(f"{self.__class__.__name__}: Showing toast")
|
logger.info(f"{self.__class__.__name__}: Showing toast")
|
||||||
self.toast.render()
|
self.toast.render()
|
||||||
has_rendered = True
|
has_rendered = True
|
||||||
|
|
||||||
if time.time() - start > self.activation_delay + self.duration and has_rendered:
|
if time.time() - start > self.activation_delay + self.duration and has_rendered:
|
||||||
print(f"{self.__class__.__name__}: Hiding toast")
|
logger.info(f"{self.__class__.__name__}: Hiding toast")
|
||||||
break
|
break
|
||||||
|
|
||||||
# Free up cpu resources for main thread
|
# Free up cpu resources for main thread
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
print(f"{self.__class__.__name__}: exiting")
|
logger.info(f"{self.__class__.__name__}: exiting")
|
||||||
if has_rendered and self.renderer.lock.locked():
|
if has_rendered and self.renderer.lock.locked():
|
||||||
# As far as we know, we currently hold the Renderer.lock
|
# As far as we know, we currently hold the Renderer.lock
|
||||||
self.renderer.show_image(previous_screen_state)
|
self.renderer.show_image(previous_screen_state)
|
||||||
print(f"{self.__class__.__name__}: restored previous screen state")
|
logger.info(f"{self.__class__.__name__}: restored previous screen state")
|
||||||
|
|
||||||
# We're done, release the lock
|
# We're done, release the lock
|
||||||
self.renderer.lock.release()
|
self.renderer.lock.release()
|
||||||
@@ -223,7 +225,7 @@ class SDCardStateChangeToastManagerThread(BaseToastOverlayManagerThread):
|
|||||||
|
|
||||||
|
|
||||||
def instantiate_toast(self) -> ToastOverlay:
|
def instantiate_toast(self) -> ToastOverlay:
|
||||||
print("instantiating toast!")
|
logger.info("instantiating toast!")
|
||||||
return ToastOverlay(
|
return ToastOverlay(
|
||||||
icon_name=SeedSignerIconConstants.MICROSD,
|
icon_name=SeedSignerIconConstants.MICROSD,
|
||||||
label_text=self.message,
|
label_text=self.message,
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
|
import logging
|
||||||
from typing import List
|
from typing import List
|
||||||
import RPi.GPIO as GPIO
|
import RPi.GPIO as GPIO
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from seedsigner.models.singleton import Singleton
|
from seedsigner.models.singleton import Singleton
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class HardwareButtons(Singleton):
|
class HardwareButtons(Singleton):
|
||||||
if GPIO.RPI_INFO['P1_REVISION'] == 3: #This indicates that we have revision 3 GPIO
|
if GPIO.RPI_INFO['P1_REVISION'] == 3: #This indicates that we have revision 3 GPIO
|
||||||
print("Detected 40pin GPIO (Rasbperry Pi 2 and above)")
|
logger.info("Detected 40pin GPIO (Rasbperry Pi 2 and above)")
|
||||||
KEY_UP_PIN = 31
|
KEY_UP_PIN = 31
|
||||||
KEY_DOWN_PIN = 35
|
KEY_DOWN_PIN = 35
|
||||||
KEY_LEFT_PIN = 29
|
KEY_LEFT_PIN = 29
|
||||||
@@ -18,7 +22,7 @@ class HardwareButtons(Singleton):
|
|||||||
KEY3_PIN = 36
|
KEY3_PIN = 36
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print("Assuming 26 Pin GPIO (Raspberry P1 1)")
|
logger.info("Assuming 26 Pin GPIO (Raspberry P1 1)")
|
||||||
KEY_UP_PIN = 5
|
KEY_UP_PIN = 5
|
||||||
KEY_DOWN_PIN = 11
|
KEY_DOWN_PIN = 11
|
||||||
KEY_LEFT_PIN = 3
|
KEY_LEFT_PIN = 3
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
|
||||||
@@ -5,6 +6,7 @@ from seedsigner.models.singleton import Singleton
|
|||||||
from seedsigner.models.threads import BaseThread
|
from seedsigner.models.threads import BaseThread
|
||||||
from seedsigner.models.settings import Settings
|
from seedsigner.models.settings import Settings
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class MicroSD(Singleton, BaseThread):
|
class MicroSD(Singleton, BaseThread):
|
||||||
@@ -63,7 +65,7 @@ class MicroSD(Singleton, BaseThread):
|
|||||||
while self.keep_running:
|
while self.keep_running:
|
||||||
with open(self.FIFO_PATH) as fifo:
|
with open(self.FIFO_PATH) as fifo:
|
||||||
action = fifo.read()
|
action = fifo.read()
|
||||||
print(f"fifo message: {action}")
|
logger.info(f"fifo message: {action}")
|
||||||
|
|
||||||
Settings.handle_microsd_state_change(action=action)
|
Settings.handle_microsd_state_change(action=action)
|
||||||
Controller.get_instance().activate_toast(SDCardStateChangeToastManagerThread(action=action))
|
Controller.get_instance().activate_toast(SDCardStateChangeToastManagerThread(action=action))
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
# import the necessary packages
|
# import the necessary packages
|
||||||
|
import logging
|
||||||
from picamera.array import PiRGBArray
|
from picamera.array import PiRGBArray
|
||||||
from picamera import PiCamera
|
from picamera import PiCamera
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
# Modified from: https://github.com/jrosebr1/imutils
|
# Modified from: https://github.com/jrosebr1/imutils
|
||||||
class PiVideoStream:
|
class PiVideoStream:
|
||||||
@@ -41,7 +44,7 @@ class PiVideoStream:
|
|||||||
# if the thread indicator variable is set, stop the thread
|
# if the thread indicator variable is set, stop the thread
|
||||||
# and resource camera resources
|
# and resource camera resources
|
||||||
if self.should_stop:
|
if self.should_stop:
|
||||||
print("PiVideoStream: closing everything")
|
logger.info("PiVideoStream: closing everything")
|
||||||
self.stream.close()
|
self.stream.close()
|
||||||
self.rawCapture.close()
|
self.rawCapture.close()
|
||||||
self.camera.close()
|
self.camera.close()
|
||||||
|
|||||||
@@ -912,7 +912,7 @@ class SignMessageQrDecoder(BaseSingleFrameQrDecoder):
|
|||||||
|
|
||||||
# TODO: support formats other than ascii?
|
# TODO: support formats other than ascii?
|
||||||
if fmt != "ascii":
|
if fmt != "ascii":
|
||||||
print(f"Sign message: Unsupported format: {fmt}")
|
logger.info(f"Sign message: Unsupported format: {fmt}")
|
||||||
return DecodeQRStatus.INVALID
|
return DecodeQRStatus.INVALID
|
||||||
|
|
||||||
self.complete = True
|
self.complete = True
|
||||||
@@ -1083,7 +1083,7 @@ class GenericWalletQrDecoder(BaseSingleFrameQrDecoder):
|
|||||||
self.complete = True
|
self.complete = True
|
||||||
return DecodeQRStatus.COMPLETE
|
return DecodeQRStatus.COMPLETE
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(repr(e))
|
logger.info(repr(e), exc_info=True)
|
||||||
return DecodeQRStatus.INVALID
|
return DecodeQRStatus.INVALID
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import logging
|
||||||
from binascii import hexlify
|
from binascii import hexlify
|
||||||
from embit import psbt, script, ec, bip32
|
from embit import psbt, script, ec, bip32
|
||||||
from embit.descriptor import Descriptor
|
from embit.descriptor import Descriptor
|
||||||
@@ -9,6 +10,7 @@ from typing import List
|
|||||||
from seedsigner.models.seed import Seed
|
from seedsigner.models.seed import Seed
|
||||||
from seedsigner.models.settings import SettingsConstants
|
from seedsigner.models.settings import SettingsConstants
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class OPCODES:
|
class OPCODES:
|
||||||
OP_RETURN = 106
|
OP_RETURN = 106
|
||||||
@@ -68,11 +70,11 @@ class PSBTParser():
|
|||||||
|
|
||||||
def parse(self):
|
def parse(self):
|
||||||
if self.psbt is None:
|
if self.psbt is None:
|
||||||
print(f"self.psbt is None!!")
|
logger.info(f"self.psbt is None!!")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if not self.seed:
|
if not self.seed:
|
||||||
print("self.seed is None!")
|
logger.info("self.seed is None!")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self._set_root()
|
self._set_root()
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import logging
|
||||||
import unicodedata
|
import unicodedata
|
||||||
import hashlib
|
import hashlib
|
||||||
import hmac
|
import hmac
|
||||||
@@ -9,6 +10,8 @@ from typing import List
|
|||||||
|
|
||||||
from seedsigner.models.settings import SettingsConstants
|
from seedsigner.models.settings import SettingsConstants
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class InvalidSeedException(Exception):
|
class InvalidSeedException(Exception):
|
||||||
pass
|
pass
|
||||||
@@ -46,7 +49,7 @@ class Seed:
|
|||||||
try:
|
try:
|
||||||
self.seed_bytes = bip39.mnemonic_to_seed(self.mnemonic_str, password=self._passphrase, wordlist=self.wordlist)
|
self.seed_bytes = bip39.mnemonic_to_seed(self.mnemonic_str, password=self._passphrase, wordlist=self.wordlist)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(repr(e))
|
logger.info(repr(e), exc_info=True)
|
||||||
raise InvalidSeedException(repr(e))
|
raise InvalidSeedException(repr(e))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import logging
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
@@ -7,6 +8,8 @@ from typing import List
|
|||||||
from seedsigner.models.settings_definition import SettingsConstants, SettingsDefinition
|
from seedsigner.models.settings_definition import SettingsConstants, SettingsDefinition
|
||||||
from seedsigner.models.singleton import Singleton
|
from seedsigner.models.singleton import Singleton
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class InvalidSettingsQRData(Exception):
|
class InvalidSettingsQRData(Exception):
|
||||||
pass
|
pass
|
||||||
@@ -77,7 +80,7 @@ class Settings(Singleton):
|
|||||||
# Replace abbreviated name with full attr_name
|
# Replace abbreviated name with full attr_name
|
||||||
settings_entry = SettingsDefinition.get_settings_entry_by_abbreviated_name(abbreviated_name)
|
settings_entry = SettingsDefinition.get_settings_entry_by_abbreviated_name(abbreviated_name)
|
||||||
if not settings_entry:
|
if not settings_entry:
|
||||||
print(f"Ignoring unrecognized attribute: {abbreviated_name}")
|
logger.info(f"Ignoring unrecognized attribute: {abbreviated_name}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Validate value(s) against SettingsDefinition's valid options
|
# Validate value(s) against SettingsDefinition's valid options
|
||||||
@@ -162,9 +165,9 @@ class Settings(Singleton):
|
|||||||
if attr_name == SettingsConstants.SETTING__PERSISTENT_SETTINGS and value == SettingsConstants.OPTION__DISABLED:
|
if attr_name == SettingsConstants.SETTING__PERSISTENT_SETTINGS and value == SettingsConstants.OPTION__DISABLED:
|
||||||
try:
|
try:
|
||||||
os.remove(self.SETTINGS_FILENAME)
|
os.remove(self.SETTINGS_FILENAME)
|
||||||
print(f"Removed {self.SETTINGS_FILENAME}")
|
logger.info(f"Removed {self.SETTINGS_FILENAME}")
|
||||||
except:
|
except:
|
||||||
print(f"{self.SETTINGS_FILENAME} not found to be removed")
|
logger.info(f"{self.SETTINGS_FILENAME} not found to be removed")
|
||||||
|
|
||||||
self._data[attr_name] = value
|
self._data[attr_name] = value
|
||||||
self.save()
|
self.save()
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import logging
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from embit.descriptor import Descriptor
|
from embit.descriptor import Descriptor
|
||||||
@@ -9,6 +10,7 @@ from seedsigner.models.settings import SettingsConstants
|
|||||||
from seedsigner.views.settings_views import SettingsIngestSettingsQRView
|
from seedsigner.views.settings_views import SettingsIngestSettingsQRView
|
||||||
from seedsigner.views.view import BackStackView, ErrorView, MainMenuView, NotYetImplementedView, OptionDisabledView, View, Destination
|
from seedsigner.views.view import BackStackView, ErrorView, MainMenuView, NotYetImplementedView, OptionDisabledView, View, Destination
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class ScanView(View):
|
class ScanView(View):
|
||||||
@@ -111,14 +113,14 @@ class ScanView(View):
|
|||||||
p = re.compile(r'(\[[0-9,a-f,A-F]+?\/[0-9,\/,h,\']+?\][a-z,A-Z,0-9]*?)([\,,\)])')
|
p = re.compile(r'(\[[0-9,a-f,A-F]+?\/[0-9,\/,h,\']+?\][a-z,A-Z,0-9]*?)([\,,\)])')
|
||||||
descriptor_str = p.sub(r'\1/{0,1}/*\2', descriptor_str)
|
descriptor_str = p.sub(r'\1/{0,1}/*\2', descriptor_str)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(repr(e))
|
logger.info(repr(e), exc_info=True)
|
||||||
descriptor_str = orig_descriptor_str
|
descriptor_str = orig_descriptor_str
|
||||||
|
|
||||||
descriptor = Descriptor.from_string(descriptor_str)
|
descriptor = Descriptor.from_string(descriptor_str)
|
||||||
|
|
||||||
if not descriptor.is_basic_multisig:
|
if not descriptor.is_basic_multisig:
|
||||||
# TODO: Handle single-sig descriptors?
|
# TODO: Handle single-sig descriptors?
|
||||||
print(f"Received single sig descriptor: {descriptor}")
|
logger.info(f"Received single sig descriptor: {descriptor}")
|
||||||
return Destination(NotYetImplementedView)
|
return Destination(NotYetImplementedView)
|
||||||
|
|
||||||
self.controller.multisig_wallet_descriptor = descriptor
|
self.controller.multisig_wallet_descriptor = descriptor
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
import time
|
import time
|
||||||
@@ -9,6 +10,7 @@ from seedsigner.gui.screens.screen import BaseScreen
|
|||||||
from seedsigner.models.settings import Settings
|
from seedsigner.models.settings import Settings
|
||||||
from seedsigner.models.settings_definition import SettingsConstants
|
from seedsigner.models.settings_definition import SettingsConstants
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
# TODO: This early code is now outdated vis-a-vis Screen vs View distinctions
|
# TODO: This early code is now outdated vis-a-vis Screen vs View distinctions
|
||||||
@@ -178,7 +180,7 @@ class ScreensaverScreen(LogoScreen):
|
|||||||
|
|
||||||
except KeyboardInterrupt as e:
|
except KeyboardInterrupt as e:
|
||||||
# Exit triggered; close gracefully
|
# Exit triggered; close gracefully
|
||||||
print("Shutting down Screensaver")
|
logger.info("Shutting down Screensaver")
|
||||||
|
|
||||||
# Have to let the interrupt bubble up to exit the main app
|
# Have to let the interrupt bubble up to exit the main app
|
||||||
raise e
|
raise e
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import logging
|
||||||
import embit
|
import embit
|
||||||
import random
|
import random
|
||||||
import time
|
import time
|
||||||
@@ -25,7 +26,7 @@ from seedsigner.models.settings_definition import SettingsDefinition
|
|||||||
from seedsigner.models.threads import BaseThread, ThreadsafeCounter
|
from seedsigner.models.threads import BaseThread, ThreadsafeCounter
|
||||||
from seedsigner.views.view import NotYetImplementedView, OptionDisabledView, View, Destination, BackStackView, MainMenuView
|
from seedsigner.views.view import NotYetImplementedView, OptionDisabledView, View, Destination, BackStackView, MainMenuView
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class SeedsMenuView(View):
|
class SeedsMenuView(View):
|
||||||
@@ -1870,7 +1871,7 @@ class SeedAddressVerificationView(View):
|
|||||||
def run(self):
|
def run(self):
|
||||||
while self.keep_running:
|
while self.keep_running:
|
||||||
if self.threadsafe_counter.cur_count % 10 == 0:
|
if self.threadsafe_counter.cur_count % 10 == 0:
|
||||||
print(f"Incremented to {self.threadsafe_counter.cur_count}")
|
logger.info(f"Incremented to {self.threadsafe_counter.cur_count}")
|
||||||
|
|
||||||
i = self.threadsafe_counter.cur_count
|
i = self.threadsafe_counter.cur_count
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
import hashlib
|
import hashlib
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
|
||||||
@@ -21,6 +22,7 @@ from seedsigner.views.seed_views import SeedDiscardView, SeedFinalizeView, SeedM
|
|||||||
|
|
||||||
from .view import View, Destination, BackStackView
|
from .view import View, Destination, BackStackView
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class ToolsMenuView(View):
|
class ToolsMenuView(View):
|
||||||
@@ -143,7 +145,7 @@ class ToolsImageEntropyMnemonicLengthView(View):
|
|||||||
serial_hash = hashlib.sha256(serial_num)
|
serial_hash = hashlib.sha256(serial_num)
|
||||||
hash_bytes = serial_hash.digest()
|
hash_bytes = serial_hash.digest()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(repr(e))
|
logger.info(repr(e), exc_info=True)
|
||||||
hash_bytes = b'0'
|
hash_bytes = b'0'
|
||||||
|
|
||||||
# Build in modest entropy via millis since power on
|
# Build in modest entropy via millis since power on
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import logging
|
||||||
|
import sys
|
||||||
|
from unittest.mock import patch, call
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
sys.path.insert(0,'src')
|
||||||
|
from main import main
|
||||||
|
|
||||||
|
|
||||||
|
@patch("main.Controller")
|
||||||
|
def test_main__argparse__default(patched_controller):
|
||||||
|
main([])
|
||||||
|
assert logging.root.level == logging.INFO
|
||||||
|
assert logging.getLogger().getEffectiveLevel() == logging.INFO
|
||||||
|
patched_controller.assert_has_calls(
|
||||||
|
[call.get_instance(), call.get_instance().start()]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@patch("main.Controller")
|
||||||
|
def test_main__argparse__enable_debug_logging(patched_controller):
|
||||||
|
main(["--loglevel", "DEBUG"])
|
||||||
|
assert logging.root.level == logging.DEBUG
|
||||||
|
assert logging.getLogger().getEffectiveLevel() == logging.DEBUG
|
||||||
|
patched_controller.assert_has_calls(
|
||||||
|
[call.get_instance(), call.get_instance().start()]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_main__argparse__invalid_arg():
|
||||||
|
with pytest.raises(SystemExit):
|
||||||
|
main(["--invalid"])
|
||||||
|
|
||||||
|
|
||||||
|
@patch("main.Controller")
|
||||||
|
def test_main__logging__writes_to_stderr(patched_controller, capsys):
|
||||||
|
main([])
|
||||||
|
_, err = capsys.readouterr()
|
||||||
|
assert "Starting SeedSigner" in err and "INFO" in err
|
||||||
Reference in New Issue
Block a user