diff --git a/nengo_gui/components/ace_editor.py b/nengo_gui/components/ace_editor.py index 53616d03..9ca0ed5f 100644 --- a/nengo_gui/components/ace_editor.py +++ b/nengo_gui/components/ace_editor.py @@ -1,10 +1,14 @@ import json +import logging import os from nengo_gui.components.editor import Editor import nengo_gui.exec_env +logger = logging.getLogger(__name__) + + class AceEditor(Editor): config_defaults = {} @@ -87,8 +91,8 @@ def message(self, msg): with open(self.page.filename, 'w') as f: f.write(self.current_code) except IOError: - print("Could not save %s; permission denied" % - self.page.filename) + logger.exception("Could not save %s; permission denied", + self.page.filename) self.page.net_graph.update_code(self.current_code) else: self.page.net_graph.update_code(self.current_code) diff --git a/nengo_gui/components/component.py b/nengo_gui/components/component.py index fb1d6ff3..fc6635d5 100644 --- a/nengo_gui/components/component.py +++ b/nengo_gui/components/component.py @@ -1,4 +1,8 @@ import json +import logging + + +logger = logging.getLogger(__name__) class Component(object): @@ -60,7 +64,7 @@ def message(self, msg): Any data sent by the client ove the WebSocket will be passed into this method. """ - print('unhandled message', msg) + logger.warning('unhandled message %s', msg) def finish(self): """Close this Component""" diff --git a/nengo_gui/components/netgraph.py b/nengo_gui/components/netgraph.py index 1985c2fa..da5156ca 100644 --- a/nengo_gui/components/netgraph.py +++ b/nengo_gui/components/netgraph.py @@ -1,12 +1,13 @@ -import time -import os -import traceback import collections +import json +import logging +import os import threading +import time +import traceback import nengo from nengo import spa -import json from nengo_gui.components.component import Component from nengo_gui.components.value import Value @@ -15,6 +16,10 @@ import nengo_gui.user_action import nengo_gui.layout + +logger = logging.getLogger(__name__) + + class NetGraph(Component): """Handles computations and communications for NetGraph on the JS side. @@ -281,8 +286,7 @@ def _reload(self, code=None): old_component.replace_with = obj obj.original_id = old_component.original_id except: - traceback.print_exc() - print('failed to recreate plot for %s' % obj) + logger.exception('failed to recreate plot for %s', obj) components.append(obj) components.sort(key=lambda x: x.component_order) @@ -398,7 +402,7 @@ def message(self, msg): try: info = json.loads(msg) except ValueError: - print('invalid message', repr(msg)) + logger.warning('invalid message %s', repr(msg)) return action = info.get('act', None) undo = info.get('undo', None) @@ -416,15 +420,14 @@ def message(self, msg): self.page.undo_stack.append([act]) del self.page.redo_stack[:] except: - print('error processing message', repr(msg)) - traceback.print_exc() + logger.exception('error processing message %s', repr(msg)) elif undo is not None: if undo == '1': self.undo() else: self.redo() else: - print('received message', msg) + logger.debug('received message %s', msg) def undo(self): if self.page.undo_stack: diff --git a/nengo_gui/components/sim_control.py b/nengo_gui/components/sim_control.py index b05a80c1..d9fdcc36 100644 --- a/nengo_gui/components/sim_control.py +++ b/nengo_gui/components/sim_control.py @@ -138,10 +138,6 @@ def smart_sleep(self, delay_time): else: self.smart_sleep_offset += delay_time - def config_settings(self, data): - for i in data: - print(i) - def update_client(self, client): now = time.time() # send off a ping now and then so we'll notice when connection closes diff --git a/nengo_gui/conftest.py b/nengo_gui/conftest.py index 01b0ff45..6150fd09 100644 --- a/nengo_gui/conftest.py +++ b/nengo_gui/conftest.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import os.path import socket import threading diff --git a/nengo_gui/gui.py b/nengo_gui/gui.py index 5245768f..198bf4f3 100644 --- a/nengo_gui/gui.py +++ b/nengo_gui/gui.py @@ -1,8 +1,7 @@ """Classes to instantiate and manage the life cycle of the nengo_gui backend.""" -from __future__ import print_function - +import logging import select import signal import sys @@ -13,6 +12,9 @@ from nengo_gui.guibackend import GuiServer +logger = logging.getLogger(__name__) + + class ServerShutdown(Exception): """Causes the server to shutdown when raised.""" pass @@ -70,25 +72,25 @@ class InteractiveGUI(BaseGUI): def start(self): protocol = 'https:' if self.server.settings.use_ssl else 'http:' - print("Starting nengo server at %s//%s:%d" % - (protocol, 'localhost', self.server.server_port)) + logger.info("Starting nengo server at %s//%s:%d", + protocol, 'localhost', self.server.server_port) if not sys.platform.startswith('win'): signal.signal(signal.SIGINT, self._confirm_shutdown) try: self.server.serve_forever(poll_interval=0.02) - print("No connections remaining to the nengo_gui server.") + logger.info("No connections remaining to the nengo_gui server.") except ServerShutdown: self.server.shutdown() finally: - print("Shutting down server...") + logger.info("Shutting down server...") self.server.wait_for_shutdown(0.05) n_zombie = sum(thread.is_alive() for thread, _ in self.server.requests) if n_zombie > 0: - print("%d zombie threads will close abruptly" % n_zombie) + logger.debug("%d zombie threads will close abruptly", n_zombie) def _confirm_shutdown(self, signum, frame): signal.signal(signal.SIGINT, self._immediate_shutdown) @@ -100,9 +102,9 @@ def _confirm_shutdown(self, signum, frame): if line[0].lower() == 'y': raise ServerShutdown() else: - print("Resuming...") + sys.stdout.write("Resuming...\n") else: - print("No confirmation received. Resuming...") + sys.stdout.write("No confirmation received. Resuming...\n") signal.signal(signal.SIGINT, self._confirm_shutdown) def _immediate_shutdown(self, signum, frame): diff --git a/nengo_gui/guibackend.py b/nengo_gui/guibackend.py index 707afb71..69188863 100644 --- a/nengo_gui/guibackend.py +++ b/nengo_gui/guibackend.py @@ -1,7 +1,5 @@ """Nengo GUI backend implementation.""" -from __future__ import print_function - import hashlib import json import logging @@ -252,7 +250,7 @@ def _handle_ws_msg(self, component, msg): component.message(msg.data) return True except: - logging.exception('Error processing: %s', repr(msg.data)) + logger.exception('Error processing: %s', repr(msg.data)) def _handle_config_msg(self, component, msg): cfg = json.loads(msg.data[7:]) @@ -295,7 +293,7 @@ def get_session(self): return session def log_message(self, format, *args): - logger.info(format, *args) + logger.debug(format, *args) class ModelContext(object): @@ -399,6 +397,6 @@ def remove_page(self, page): time.sleep(self.settings.auto_shutdown) earliest_shutdown = self._last_access + self.settings.auto_shutdown if earliest_shutdown < time.time() and len(self.pages) <= 0: - logging.info( + logger.info( "No connections remaining to the nengo_gui server.") self.shutdown() diff --git a/nengo_gui/ipython.py b/nengo_gui/ipython.py index e894b8d1..b0e5bc27 100644 --- a/nengo_gui/ipython.py +++ b/nengo_gui/ipython.py @@ -1,6 +1,5 @@ -from __future__ import print_function - import atexit +import logging import socket import threading import time @@ -18,8 +17,7 @@ import nengo_gui -class ConfigReuseWarning(UserWarning): - pass +logger = logging.getLogger(__name__) class IPythonViz(object): @@ -56,9 +54,9 @@ def start_server(cls, cfg, model): server = cls.servers.get(cfg, None) existent = server_thread is not None and server is not None if existent and server_thread.is_alive(): - warnings.warn(ConfigReuseWarning( + logger.warning( "Reusing config. Only the most recent visualization will " - "update the config.")) + "update the config.") for page in server.pages: page.save_config(force=True) page.filename_cfg = get_ipython().mktempfile() @@ -127,7 +125,7 @@ def _ipython_display_(self): '''.format(url=self.url, id=uuid.uuid4(), height=self.height))) else: - print("Server is not alive.") + logger.error("Server is not alive.") atexit.register(IPythonViz.shutdown_all, timeout=5) diff --git a/nengo_gui/layout.py b/nengo_gui/layout.py index f59a8e05..727dbb16 100644 --- a/nengo_gui/layout.py +++ b/nengo_gui/layout.py @@ -1,3 +1,5 @@ +import logging + from collections import OrderedDict import nengo @@ -5,6 +7,9 @@ from nengo_gui.grandalf.layouts import VertexViewer, SugiyamaLayout +logger = logging.getLogger(__name__) + + class Layout(object): """Generates layouts for nengo Networks""" def __init__(self, model): @@ -35,7 +40,7 @@ def find_parent(self, obj): if len(self.unexamined_networks) == 0: # there are no networks left we haven't looked into # this should not happen in a valid nengo.Network - print("could not find parent of", obj) + logger.error("could not find parent of %s", obj) return None # grab the next network we haven't looked into net = self.unexamined_networks.pop(0) @@ -120,7 +125,7 @@ def make_layout(self, network): if pre is None or post is None: # the connection does not go to a child of this network, # so ignore it. - print('error processing', c) + logger.error('error processing %s', c) else: edges[c] = Edge(vertices[pre], vertices[post], data=c) diff --git a/nengo_gui/main.py b/nengo_gui/main.py index 36c7ccf8..300125a2 100644 --- a/nengo_gui/main.py +++ b/nengo_gui/main.py @@ -1,6 +1,7 @@ import argparse import logging import os.path +import sys import threading import webbrowser @@ -10,9 +11,13 @@ from nengo_gui.password import gensalt, hashpw, prompt_pw +logger = logging.getLogger(__name__) + + def old_main(): - print("'nengo_gui' has been renamed to 'nengo'.") - print("Please run 'nengo' in the future to avoid this message!\n") + print("'nengo_gui' has been renamed to 'nengo'.", file=sys.stderr) + print("Please run 'nengo' in the future to avoid this message!\n", + file=sys.stderr) main() @@ -46,9 +51,9 @@ def main(): args = parser.parse_args() if args.debug: - logging.basicConfig(level=logging.DEBUG) + logging.basicConfig(format='%(message)s', level=logging.DEBUG) else: - logging.basicConfig() + logging.basicConfig(format='%(message)s', level=logging.INFO) if args.password: if args.password is True: diff --git a/nengo_gui/page.py b/nengo_gui/page.py index 46372269..9c1e2226 100644 --- a/nengo_gui/page.py +++ b/nengo_gui/page.py @@ -14,6 +14,9 @@ import nengo_gui.config +logger = logging.getLogger(__name__) + + class PageSettings(object): __slots__ = ['backend', 'editor_class', 'filename_cfg'] @@ -259,7 +262,7 @@ def load_config(self): except Exception: # FIXME #if self.gui.interactive: - logging.debug('error parsing config: %s', line) + logger.debug('error parsing config: %s', line) # make sure the required Components exist if '_viz_sim_control' not in self.locals: @@ -313,8 +316,8 @@ def save_config(self, lazy=False, force=False): with open(self.filename_cfg, 'w') as f: f.write(self.config.dumps(uids=self.default_labels)) except IOError: - print("Could not save %s; permission denied" % - self.filename_cfg) + logger.exception("Could not save %s; permission denied" % + self.filename_cfg) def modified_config(self): """Set a flag that the config file should be saved.""" @@ -407,7 +410,7 @@ def remove_uid(self, uid): del self.locals[uid] del self.default_labels[obj] else: - print('WARNING: remove_uid called on unknown uid: %s' % uid) + logger.warning('remove_uid called on unknown uid: %s', uid) def remove_component(self, component): """Remove a component from the layout.""" diff --git a/nengo_gui/password.py b/nengo_gui/password.py index 24f5f821..ecd6f763 100644 --- a/nengo_gui/password.py +++ b/nengo_gui/password.py @@ -1,13 +1,15 @@ """Password hashing functions replicating bcrypt API.""" -from __future__ import print_function - import binascii from getpass import getpass import hashlib +import logging import os +logger = logging.getLogger(__name__) + + def gensalt(size=16): return binascii.hexlify(os.urandom(size)) diff --git a/nengo_gui/tests/test_basic_functionality.py b/nengo_gui/tests/test_basic_functionality.py index ac3cfe82..cf751f1d 100644 --- a/nengo_gui/tests/test_basic_functionality.py +++ b/nengo_gui/tests/test_basic_functionality.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import os import time