diff --git a/bacon/OscListener.py b/bacon/OscListener.py index df99b20..9fd1ab9 100644 --- a/bacon/OscListener.py +++ b/bacon/OscListener.py @@ -1,5 +1,4 @@ -"""OscCommentMacroListener.py: Hog 4 comment macro antlr4 listener for OSC. -""" +"""OscCommentMacroListener.py: Hog 4 comment macro antlr4 listener for OSC.""" import logging @@ -12,7 +11,8 @@ from .hog4 import HogNet # https://raw.githubusercontent.com/jszheng/py3antlr4book/master/bin/pygrun # this is a python version of TestRig def beautify_lisp_string(in_string): - __author__ = 'jszheng' + """Prety output of a lisp string.""" +# __author__ = 'jszheng' indent_size = 2 add_indent = ' ' * indent_size out_string = in_string[0] # no indent for 1st ( @@ -31,27 +31,35 @@ def beautify_lisp_string(in_string): class OscCommentMacroListener(CommentMacroListener): + """antlr4 listener for comment macros.""" + def __init__(self): + """Initialize the listener.""" self.osc = None def exitWait(self, ctx: CommentMacroParser.WaitContext): - logging.info("Waiting " + str(ctx.number().value) + " seconds.") + """On exiting the WAIT macro.""" + logging.info("Waiting %d seconds.", ctx.number().value) sleep(ctx.number().value) def enterStatement(self, ctx: CommentMacroParser.StatementContext): + """On entering a statement.""" # print the lisp tree of this macro lisp_tree_str = ctx.toStringTree(recog=ctx.parser) logging.debug(beautify_lisp_string(lisp_tree_str)) def enterTarget(self, ctx: CommentMacroParser.TargetContext): + """On entering a target.""" ctx.targets = [] def exitTarget(self, ctx: CommentMacroParser.TargetContext): + """On exiting a target.""" ctx.targets = set(ctx.targets) if isinstance(ctx.parentCtx, CommentMacroParser.TargetContext): ctx.parentCtx.targets.extend(ctx.targets) # add to parent targets def exitNumber(self, ctx: CommentMacroParser.NumberContext): + """On exiting a number.""" try: ctx.value = int(ctx.getText()) except ValueError: @@ -60,6 +68,7 @@ class OscCommentMacroListener(CommentMacroListener): ctx.parentCtx.targets.append(ctx.value) def exitSpan(self, ctx: CommentMacroParser.SpanContext): + """On exiting a span.""" lower = min(ctx.n1.value, ctx.n2.value) upper = max(ctx.n1.value, ctx.n2.value) while lower <= upper: @@ -67,47 +76,49 @@ class OscCommentMacroListener(CommentMacroListener): lower += 1 def exitMasterGo(self, ctx: CommentMacroParser.MasterGoContext): + """On exiting a Go macro.""" if ctx.target() is None: logging.info("Main GO") self.osc.button_press(ctx.device(), "/hog/hardware/maingo") return for i in ctx.target().targets: if isinstance(i, int) is not True: - logging.warn("GO MASTER macro targets must be intigers. " - + str(i) + " is not an intigers.") + logging.error("GO MASTER macro targets must be intigers.") continue - if (i < 0): - logging.warn("Master "+str(i)+" is not greater than 0.") + if i < 0: + logging.error("Master %d is not greater than 0.", i) continue master = str(i) - logging.info("GO on master " + master) + logging.info("GO on master %s", master) self.osc.button_press(ctx.device(), "/hog/hardware/go/" + master) def exitMasterHalt(self, ctx: CommentMacroParser.MasterHaltContext): + """On exiting a Master Halt macro.""" if ctx.target() is None: logging.info("Main HALT") self.osc.button_press(ctx.device(), "/hog/hardware/mainhalt") return for i in ctx.target().targets: if isinstance(i, int) is not True: - logging.warn("GO MASTER macro targets must be intigers. " - + str(i) + " is not an intigers.") + logging.error("GO MASTER macro targets must be intigers.") continue - if (i < 0): - logging.warn("Master "+str(i)+" is not greater than 0.") + if i < 0: + logging.error("Master %d is not greater than 0.", i) continue master = str(i) - logging.info("HALT on master " + master) + logging.info("HALT on master %s", master) self.osc.button_press(ctx.device(), "/hog/hardware/pause/"+master) def exitMasterAssert(self, ctx: CommentMacroParser.MasterAssertContext): - if ctx.target()is not None: + """On exiting a Master Assert macro.""" + if ctx.target() is not None: logging.error("ERROR: limited to asserting current master only.") return logging.info("ASSERT on current master.") self.osc.button_press(ctx.device(), "/hog/hardware/assert") def exitMasterRelease(self, ctx: CommentMacroParser.MasterReleaseContext): + """On exiting a Master Release macro.""" if ctx.target() is not None: logging.error("ERROR: limited to releasing current master only.") return @@ -115,7 +126,8 @@ class OscCommentMacroListener(CommentMacroListener): self.osc.button_press(ctx.device(), "/hog/hardware/release") def exitMasterFade(self, ctx: CommentMacroParser.MasterFadeContext): - if ctx.target()is None: + """On exiting a Master Fade macro.""" + if ctx.target() is None: logging.error("ERROR: limited to fading specified masters only.") return level = ctx.number().value @@ -124,14 +136,13 @@ class OscCommentMacroListener(CommentMacroListener): return for i in ctx.target().targets: if isinstance(i, int) is not True: - logging.warn("FADE MASTER macro targets must be intigers. " - + str(i) + " is not an intigers.") + logging.error("FADE MASTER macro targets must be intigers.") continue - if (i < 0): - logging.warn("Master "+str(i)+" is not greater than 0.") + if i < 0: + logging.error("Master %d is not greater than 0.", i) continue master = str(i) - logging.info("Fade Master "+master+" to "+str(level)+"%") + logging.info("Fade Master %s to %d", master, level) level *= 255 / 100 # percent in Macro, 0>255 in OSC self.osc.send_message(ctx.device(), "/hog/hardware/fader/" + master, @@ -139,23 +150,26 @@ class OscCommentMacroListener(CommentMacroListener): def exitFadeGrandMaster(self, ctx: CommentMacroParser.FadeGrandMasterContext): + """On exiting a GM Fade Macro.""" level = ctx.number().value if (level < 0 or level > 100): logging.error("Level must be between 0 and 100.") return - logging.info("Fading Grand Master to " + str(level) + "%") + logging.info("Fading Grand Master to %d", level) level *= 255 / 100 # percent in Macro, 0>255 in OSC self.osc.send_message(ctx.device(), "/hog/hardware/fader/0", level) def exitMasterChoose(self, ctx: CommentMacroParser.MasterChooseContext): - if (ctx.number().value < 0): + """On exiting a Master Choose macro.""" + if ctx.number().value < 0: logging.error("Master must be greater than 0.") return master = str(ctx.number().value) - logging.info("Choose Master " + master) + logging.info("Choose Master %s", master) self.osc.button_press(ctx.device(), "/hog/hardware/choose/" + master) def exitReleaseAll(self, ctx: CommentMacroParser.ReleaseAllContext): + """On exiting a Release All Macro.""" logging.info("Release All") self.osc.send_message(ctx.device(), "/hog/hardware/pig", self.osc.buttonDOWN) @@ -164,60 +178,72 @@ class OscCommentMacroListener(CommentMacroListener): self.osc.buttonUP) def exitListGo(self, ctx: CommentMacroParser.ListGoContext): + """On exiting a List GO macro.""" for i in ctx.target().targets: - logging.info("Go on List " + str(i)) + logging.info("Go on List %d", i) self.osc.send_message(ctx.device(), "/hog/playback/go/0", i) def exitListGoto(self, ctx: CommentMacroParser.ListGotoContext): + """On exiting a GOTO macro.""" for i in ctx.target().targets: - list = str(i) + "." + str(ctx.number().value) - logging.info("Go on List " + str(list)) + cuelist = str(i) + "." + str(ctx.number().value) + logging.info("Go on List %s", cuelist) self.osc.send_message(ctx.device(), "/hog/playback/go/0", list) def exitListHalt(self, ctx: CommentMacroParser.ListHaltContext): + """On exiting a Halt macro.""" for i in ctx.target().targets: - logging.info("Halting List " + str(i)) + logging.info("Halting List %d", i) self.osc.send_message(ctx.device(), "/hog/playback/halt/0", i) def exitListRelese(self, ctx: CommentMacroParser.ListReleseContext): + """On exiting a Release macro.""" for i in ctx.target().targets: - logging.info("Releasing List " + str(i)) + logging.info("Releasing List %d", i) self.osc.send_message(ctx.device(), "/hog/playback/release/0", i) def exitSceneGo(self, ctx: CommentMacroParser.SceneGoContext): + """On exiting a Scene GO macro.""" for i in ctx.target().targets: - logging.info("Go on Scene " + str(i)) + logging.info("Go on Scene %d", i) self.osc.send_message(ctx.device(), "/hog/playback/go/1", i) def exitSceneHalt(self, ctx: CommentMacroParser.SceneHaltContext): + """On exiting a Scene Halt macro.""" for i in ctx.target().targets: - logging.info("Halt Scene " + str(i)) + logging.info("Halt Scene %d", i) self.osc.send_message(ctx.device(), "/hog/playback/halt/1", i) def exitSceneRelease(self, ctx: CommentMacroParser.SceneReleaseContext): + """On exiting a Scene Release macro.""" for i in ctx.target().targets: - logging.info("Release Scene " + str(i)) + logging.info("Release Scene %d", i) self.osc.send_message(ctx.device(), "/hog/playback/release/1", i) def exitMacroGo(self, ctx: CommentMacroParser.MacroGoContext): + """On exiting a Macro GO macro.""" for i in ctx.target().targets: - logging.info("Go on Macro " + str(i)) + logging.info("Go on Macro %d", i) self.osc.send_message(ctx.device(), "/hog/playback/go/2", i) def exitMacroHalt(self, ctx: CommentMacroParser.MacroHaltContext): + """On exiting a Macro Halt macro.""" for i in ctx.target().targets: - logging.info("Pause Macro " + str(i)) + logging.info("Pause Macro %d", i) self.osc.send_message(ctx.device(), "/hog/playback/halt/2", i) def exitMacroStop(self, ctx: CommentMacroParser.MacroStopContext): + """On exiting a Macro Stop macro.""" for i in ctx.target().targets: - logging.info("Stop Macro " + str(i)) + logging.info("Stop Macro %d", i) self.osc.send_message(ctx.device(), "/hog/playback/release/2", i) def exitPageNext(self, ctx: CommentMacroParser.PageNextContext): + """On exiting a Next Page macro.""" logging.info("Next Page") self.osc.button_press(ctx.device(), "/hog/hardware/nextpage") def exitPagePrev(self, ctx: CommentMacroParser.PagePrevContext): + """On exiting a Previous Page macro.""" logging.info("Prev Page") self.osc.button_press(ctx.device(), "/hog/hardware/backpage") diff --git a/bacon/__init__.py b/bacon/__init__.py index 471681a..51a23f9 100644 --- a/bacon/__init__.py +++ b/bacon/__init__.py @@ -1 +1,2 @@ +"""Main BaconScript module init.""" __all__ = ["script", "hog4", "OscListener"] diff --git a/bacon/commentmacro/__init__.py b/bacon/commentmacro/__init__.py index 3b6c1c4..52c2354 100644 --- a/bacon/commentmacro/__init__.py +++ b/bacon/commentmacro/__init__.py @@ -1 +1,2 @@ +"""Init for comment macro antlr4.""" __all__ = ["CommentMacroLexer", "CommentMacroListener", "CommentMacroParser"] diff --git a/bacon/hog4.py b/bacon/hog4.py index bc72663..c21d79b 100644 --- a/bacon/hog4.py +++ b/bacon/hog4.py @@ -1,43 +1,48 @@ +"""hog4.py: Class methods for Hog 4 representation.""" + import logging -from pythonosc import osc_message_builder from time import sleep +from pythonosc import osc_message_builder class HogNet: + """Class definition of a hognet participant.""" + # button state constants buttonDOWN = 1 buttonUP = 0 def __init__(self, servers): + """Init method.""" self.servers = servers def button_press(self, device, path, delay=0.05): + """Button presses are a pair of up/down OSC.""" self.send_message(device, path, self.buttonDOWN) sleep(delay) self.send_message(device, path, self.buttonUP) - # utility function to send simple messages with one argument def send_message(self, device, path, arg): + """Send a simple OSC message with one argument.""" msg = osc_message_builder.OscMessageBuilder(address=path) msg.add_arg(arg) self.send(device, msg.build()) - # send python-osc messages def send(self, device, msg): + """Send python-osc messages.""" if device is None: osc = list(self.servers.values())[0] # first configured server else: - if (device.nodeType().getText().lower() != 'h'): + if device.nodeType().getText().lower() != 'h': logging.error("ERROR: Only Hog type devices are supported.") return - else: - try: - osc = self.servers[device.number().value] - except KeyError: - logging.error("ERROR: Net# " + str(device.number().value) + - " not found.") - return + try: + osc = self.servers[device.number().value] + except KeyError: + logging.error("ERROR: Net# %d not found.", + device.number().value) + return try: osc.send(msg) - except Exception as e: - logging.error(e) + except OSError as exception: + logging.error(exception) diff --git a/bacon/script.py b/bacon/script.py index 235f91e..220b6a0 100644 --- a/bacon/script.py +++ b/bacon/script.py @@ -1,5 +1,4 @@ -"""comment.py: Hog 4 comment macro interpreter and OSC bridge. -""" +"""comment.py: Hog 4 comment macro interpreter and OSC bridge.""" import configparser import logging @@ -14,13 +13,15 @@ from .commentmacro.CommentMacroParser import CommentMacroParser from .OscListener import OscCommentMacroListener -# define an error listener that raises SyntaxError exceptions class SyntaxErrorListener(ErrorListener): + """An error listener that raises SyntaxError exceptions.""" + def syntaxError(self, recognizer, offendingSymbol, line, column, msg, e): raise SyntaxError("line "+str(line)+":"+str(column)+" "+msg) -def loadConfig(file='server.cfg'): +def load_config(file='server.cfg'): + """Load an ini style configuration file.""" # empty server dictionary servers = {} @@ -34,25 +35,25 @@ def loadConfig(file='server.cfg'): # move to config section server = config[name.strip().strip('\"')] # read settings - ip = server.get("ip", "10.0.0.100") + addr = server.get("ip", "10.0.0.100") port = server.getint("port", 7001) net = server.getint("net", 1) # osc clients are added to the dictionary with the net # as the key - logging.info("Adding Hog device at net# " + str(net)) - servers[net] = udp_client.SimpleUDPClient(ip, port) - except KeyError as e: - print('Error configuring net#', net, e) + logging.info("Adding Hog device at net# %d", str(net)) + servers[net] = udp_client.SimpleUDPClient(addr, port) + except KeyError as exception: + print('Error configuring net#', net, exception) continue return servers # init reusable walker and listener -walker = ParseTreeWalker() -listener = OscCommentMacroListener() +WALKER = ParseTreeWalker() +LISTENER = OscCommentMacroListener() -# main handler for processing input def comment(text): + """Process comment macro input.""" # force upper case text = text.upper() # generate text stream @@ -69,7 +70,7 @@ def comment(text): # get tree from parser tree = parser.prog() # walk the tree - walker.walk(listener, tree) - except SyntaxError as e: - logging.debug(e) # antlr internal listener prints the error -# # log it to the debug logging anyway + WALKER.walk(LISTENER, tree) + except SyntaxError as exception: + logging.debug(exception) # antlr internal listener prints the error +# # log it to the debug logging anyway diff --git a/bs.py b/bs.py index 02aebaa..8eb7c54 100755 --- a/bs.py +++ b/bs.py @@ -1,21 +1,20 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -"""Interactive BaconScript shell. -""" +"""Interactive BaconScript shell.""" import logging import sys -from bacon.script import comment, listener -from bacon.script import loadConfig as loadBsConfig +from bacon.script import comment, LISTENER +from bacon.script import load_config as loadBsConfig from bacon.hog4 import HogNet # setup logging -logger = logging.getLogger() -logger.setLevel(logging.DEBUG) +LOGGER = logging.getLogger() +LOGGER.setLevel(logging.DEBUG) -listener.osc = HogNet(loadBsConfig('server.cfg')) +LISTENER.osc = HogNet(loadBsConfig('server.cfg')) # handle user input if run directly if __name__ == '__main__': @@ -24,18 +23,16 @@ if __name__ == '__main__': logging.debug("found macro at argv[1]") comment(sys.argv[1]) else: - # for input history and line editing - import readline # be an interactive shell while True: # get user input try: - text = input("comment# ") + TEXT = input("comment# ") except (KeyboardInterrupt, EOFError): - text = 'exit' - print(text) + TEXT = 'exit' + print(TEXT) # catch exit keyword - if text.lower() == 'exit': + if TEXT.lower() == 'exit': break # exec user input - comment(text) + comment(TEXT) diff --git a/setup.py b/setup.py index 08826d3..11e6797 100755 --- a/setup.py +++ b/setup.py @@ -1,6 +1,8 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +"""Setup.py: Module install script.""" + from setuptools import setup, find_packages setup(name='baconscript', @@ -12,7 +14,7 @@ setup(name='baconscript', license='MIT', packages=find_packages(), install_requires=[ - 'antlr4-python3-runtime', - 'python-osc', + 'antlr4-python3-runtime', + 'python-osc', ], zip_safe=False)