2018-10-17 20:56:59 -04:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
"""comment.py: Hog 4 comment macro interpreter and OSC bridge."""
|
|
|
|
|
|
|
|
__author__ = "Kevin Matz"
|
|
|
|
__copyright__ = "Copyright 2018, Company 235, LLC"
|
|
|
|
__credits__ = ["Kevin Matz"]
|
|
|
|
|
|
|
|
__license__ = "MIT"
|
2018-10-21 14:22:02 -04:00
|
|
|
__version__ = "3.9"
|
2018-10-17 20:56:59 -04:00
|
|
|
__maintainer__ = "Kevin Matz"
|
|
|
|
__email__ = "kevin@company235.com"
|
|
|
|
|
|
|
|
__status__ = "Prototype"
|
|
|
|
|
|
|
|
|
|
|
|
import configparser
|
2018-10-21 14:14:56 -04:00
|
|
|
import logging
|
2018-10-17 20:56:59 -04:00
|
|
|
import sys
|
|
|
|
|
2018-10-29 10:43:04 -04:00
|
|
|
from antlr4 import CommonTokenStream
|
|
|
|
from antlr4 import InputStream
|
|
|
|
from antlr4 import ParseTreeWalker
|
2018-10-29 01:21:19 -04:00
|
|
|
from antlr4.error.ErrorListener import ErrorListener
|
2018-10-17 20:56:59 -04:00
|
|
|
from pythonosc import udp_client
|
|
|
|
|
2019-11-17 13:27:08 -05:00
|
|
|
try:
|
|
|
|
# include reletive path imports when a module
|
|
|
|
from .CommentMacroLexer import CommentMacroLexer
|
|
|
|
from .CommentMacroParser import CommentMacroParser
|
|
|
|
from .OscCommentMacroListener import OscCommentMacroListener
|
|
|
|
except ImportError:
|
|
|
|
# include directly when called directly
|
|
|
|
from CommentMacroLexer import CommentMacroLexer
|
|
|
|
from CommentMacroParser import CommentMacroParser
|
|
|
|
from OscCommentMacroListener import OscCommentMacroListener
|
|
|
|
|
2018-10-17 20:56:59 -04:00
|
|
|
|
2018-10-29 01:21:19 -04:00
|
|
|
# define an error listener that raises SyntaxError exceptions
|
|
|
|
class SyntaxErrorListener(ErrorListener):
|
|
|
|
def syntaxError(self, recognizer, offendingSymbol, line, column, msg, e):
|
2018-10-29 10:42:29 -04:00
|
|
|
raise SyntaxError("line "+str(line)+":"+str(column)+" "+msg)
|
2018-10-29 01:21:19 -04:00
|
|
|
|
|
|
|
|
2018-10-21 14:14:56 -04:00
|
|
|
# setup logging
|
2018-10-28 18:27:25 -04:00
|
|
|
logger = logging.getLogger(__name__)
|
2018-10-21 14:14:56 -04:00
|
|
|
logger.setLevel(logging.DEBUG)
|
|
|
|
ch = logging.StreamHandler() # create console handler and
|
|
|
|
ch.setLevel(logging.INFO) # set console log level to INFO
|
|
|
|
logger.addHandler(ch) # add console log handler
|
|
|
|
|
2019-11-17 12:36:11 -05:00
|
|
|
# empty server dictionary
|
|
|
|
servers = {}
|
|
|
|
|
|
|
|
# open config file
|
2018-10-17 20:56:59 -04:00
|
|
|
config = configparser.ConfigParser(allow_no_value=True)
|
2019-11-17 12:36:11 -05:00
|
|
|
config.read('server.cfg')
|
|
|
|
|
|
|
|
# set up each hog device
|
2019-11-17 13:25:18 -05:00
|
|
|
for name in config.get('network', 'hogs').split(','):
|
2019-11-17 12:36:11 -05:00
|
|
|
try:
|
|
|
|
# move to config section
|
2019-11-17 13:25:18 -05:00
|
|
|
server = config[name.strip().strip('\"')]
|
2019-11-17 12:36:11 -05:00
|
|
|
# read settings
|
|
|
|
ip = 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
|
|
|
|
logger.info("Adding Hog device at net# " + str(net))
|
|
|
|
servers[net] = udp_client.SimpleUDPClient(ip, port)
|
|
|
|
except KeyError as e:
|
2019-11-17 13:26:31 -05:00
|
|
|
print('Error configuring net#', net, e)
|
2019-11-17 12:36:11 -05:00
|
|
|
continue
|
2018-10-17 20:56:59 -04:00
|
|
|
|
2019-11-17 13:04:54 -05:00
|
|
|
|
|
|
|
# clear temp variables off the stack
|
|
|
|
try:
|
|
|
|
del ip, port, net
|
|
|
|
del server, config
|
|
|
|
except NameError as e:
|
|
|
|
print('failed to release memory', e)
|
|
|
|
|
|
|
|
|
2019-11-17 13:05:13 -05:00
|
|
|
# init reusable walker and listener
|
2018-10-29 10:43:04 -04:00
|
|
|
walker = ParseTreeWalker()
|
2019-11-17 13:00:37 -05:00
|
|
|
listener = OscCommentMacroListener(servers)
|
2018-10-29 01:40:56 -04:00
|
|
|
|
2018-10-17 20:56:59 -04:00
|
|
|
|
2019-11-17 13:05:13 -05:00
|
|
|
# main handler for processing input
|
2018-10-17 20:56:59 -04:00
|
|
|
def comment(text):
|
2019-11-17 13:05:13 -05:00
|
|
|
# force upper case
|
2019-11-17 11:48:55 -05:00
|
|
|
text = text.upper()
|
2019-11-17 13:05:13 -05:00
|
|
|
# generate text stream
|
2018-10-29 10:43:04 -04:00
|
|
|
input_stream = InputStream(text)
|
2019-11-17 13:05:13 -05:00
|
|
|
# lex the text stream
|
2018-10-17 20:56:59 -04:00
|
|
|
lexer = CommentMacroLexer(input_stream)
|
2019-11-17 13:05:13 -05:00
|
|
|
# get token stream from lexer
|
2018-10-29 10:43:04 -04:00
|
|
|
stream = CommonTokenStream(lexer)
|
2019-11-17 13:05:13 -05:00
|
|
|
# parse the token steam
|
2018-10-17 20:56:59 -04:00
|
|
|
parser = CommentMacroParser(stream)
|
2019-11-17 13:05:13 -05:00
|
|
|
# attach an error handler to the parser
|
2018-10-29 10:42:29 -04:00
|
|
|
parser._listeners.append(SyntaxErrorListener())
|
2018-10-29 01:21:19 -04:00
|
|
|
try:
|
2019-11-17 13:05:13 -05:00
|
|
|
# get tree from parser
|
2018-10-29 01:21:19 -04:00
|
|
|
tree = parser.prog()
|
2019-11-17 13:05:13 -05:00
|
|
|
# walk the tree
|
2019-11-17 13:00:37 -05:00
|
|
|
walker.walk(listener, tree)
|
2018-10-29 01:21:19 -04:00
|
|
|
except SyntaxError as e:
|
2018-10-29 10:42:29 -04:00
|
|
|
logger.debug(e) # antlr internal listener prints the error
|
|
|
|
# # log it to the debug logger anyway
|
2018-10-17 20:56:59 -04:00
|
|
|
|
|
|
|
|
2019-11-17 13:05:13 -05:00
|
|
|
# handle user input if run directly
|
2018-10-17 20:56:59 -04:00
|
|
|
if __name__ == '__main__':
|
|
|
|
if len(sys.argv) > 1:
|
2019-11-17 13:05:13 -05:00
|
|
|
# look for macros passed as arguments
|
2018-10-21 14:14:56 -04:00
|
|
|
logger.debug("found macro at argv[1]")
|
2018-10-17 20:56:59 -04:00
|
|
|
comment(sys.argv[1])
|
|
|
|
else:
|
2019-11-17 13:05:13 -05:00
|
|
|
# for input history and line editing
|
|
|
|
import readline
|
|
|
|
# be an interactive shell
|
2018-10-17 20:56:59 -04:00
|
|
|
while True:
|
2019-11-17 13:05:13 -05:00
|
|
|
# get user input
|
2018-10-25 14:56:58 -04:00
|
|
|
try:
|
|
|
|
text = input("comment# ")
|
2018-10-28 17:12:12 -04:00
|
|
|
except (KeyboardInterrupt, EOFError):
|
2018-10-25 15:02:04 -04:00
|
|
|
text = 'exit'
|
|
|
|
print(text)
|
2019-11-17 13:05:13 -05:00
|
|
|
# catch exit keyword
|
2019-11-17 13:03:38 -05:00
|
|
|
if text.lower() == 'exit':
|
2018-10-25 18:16:48 -04:00
|
|
|
break
|
2019-11-17 13:05:13 -05:00
|
|
|
# exec user input
|
2019-11-17 13:03:04 -05:00
|
|
|
comment(text)
|