#!/usr/bin/python3 # -*- coding: utf-8 -*- # -*- mode: Python -*- ''' LJ Laser Server v0.8.1 Plugins Handler. ''' from OSC3 import OSCServer, OSCClient, OSCMessage from websocket_server import WebsocketServer from libs3 import gstt import os import subprocess import sys from socket import * def Init(wserver): global WSserver WSserver = wserver def sendWSall(message): #if gstt.debug >0: #print("WS sending %s" % (message)) WSserver.send_message_to_all(message) # What is plugin's OSC port ? def Port(name): data = gstt.plugins.get(name) return data.get("OSC") def Ping(name): sendWSall("/"+ name + "/start 0") return OSCsend(name,"/ping",1) #return True # How to start the plugin ? def Command(name): data = gstt.plugins.get(name) return data.get("command") # Get all plugin current state def Data(name): return gstt.plugins.get(name) def Kill(name): #data = Data(name) print("Killing", name, "...") OSCsend(name,"/quit") ''' if data["process"] != None: print name, "plugin is owned by LJ." print "Killing plugin", name OSCsend(name,"/quit") #data["process"].terminate() sendWSall("/status Killing "+ name +".") else: print "Killing asked but plugin is not owned by LJ" sendWSall("/status Not own plugin") ''' def Restart(name): Kill(name) Start(name) # See LJ.conf data def Start(name): # get Plugin configuration. command = Command(name) sendWSall("/status Starting "+name+"...") # Get LJ path #ljpath = r'%s' % os.getcwd().replace('\\','/') print("") print("LJ is starting plugin :", name) # Construct the command with absolute path. PluginPath = command.split(" ") # Launch as a subprocess print("launch :", PluginPath[0], gstt.ljpath + "/" + PluginPath[1]) # without argument if len(PluginPath) < 3: PluginProcess = subprocess.Popen( [PluginPath[0], gstt.ljpath + "/" + PluginPath[1] ], env=os.environ) # with 1 argument else: PluginProcess = subprocess.Popen( [PluginPath[0], gstt.ljpath + "/" + PluginPath[1] + " " + PluginPath[2]], env=os.environ) #PluginProcess = os.execv([PluginPath[0], ljpath + "/" + PluginPath[1]]) if gstt.debug >0: print("LJ path :", ljpath) print("New process pid for ", name, ":", PluginProcess.pid) ''' # Maybe it's not fully started data = Data(name) if command != "" and "pid" not in data : sendWSall("/status Starting "+name+"...") # Get LJ path ljpath = r'%s' % os.getcwd().replace('\\','/') print "" print "LJ is starting plugin :", name # Construct the command with absolute path. PluginPath = command.split(" ") # Launch as a subprocess PluginProcess = subprocess.Popen([PluginPath[0], ljpath + "/" + PluginPath[1]]) if gstt.debug >0: print "LJ path :", ljpath print "New process pid for ", name, ":", PluginProcess.pid data = Data(name) data["pid"] = PluginProcess.pid data["process"] = PluginProcess # Process can be terminated with : # PluginProcess.terminate() ''' def OSCsend(name, oscaddress, oscargs =''): #print "OSCsend in plugins got for", name, ": oscaddress", oscaddress, "oscargs :", oscargs PluginPort = Port(name) #sendWSall("/status Checking "+ name + "...") osclientplugin = OSCClient() osclientplugin.connect((gstt.LjayServerIP, PluginPort)) oscmsg = OSCMessage() oscmsg.setAddress(oscaddress) oscmsg.append(oscargs) try: if gstt.debug > 0: print("Plugins manager : OSCsending", oscmsg,"to plugin", name, "at", gstt.LjayServerIP, ":", PluginPort) osclientplugin.sendto(oscmsg, (gstt.LjayServerIP, PluginPort)) oscmsg.clearData() if gstt.debug >0: print(oscaddress, oscargs, "was sent to",name) return True except: if gstt.debug > 0: print('OSCSend : Connection to plugin IP', gstt.LjayServerIP ,':', PluginPort,'refused : died ?') #sendWSall("/status No plugin.") #sendWSall("/status " + name + " is offline") #sendWSall("/" + name + "/start 0") #PluginStart(name) return False def sendbroadcast(): if gstt.debug > 0: print("Sending broadcast") cs = socket(AF_INET, SOCK_DGRAM) cs.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) cs.setsockopt(SOL_SOCKET, SO_BROADCAST, 1) cs.sendto("LJ 0.8".encode(), ("255.255.255.255", 54545)) # for each plugin will automatically add /pluginame before oscpath to send like /aurora/scim 1, if oscpath = "/scim 1" def SendAll(oscpath): print("Sending to all plugins...") for plugin in list(gstt.plugins.keys()): if gstt.debug > 0: print("sending /"+plugin+oscpath,"to", plugin) print("sending /"+plugin+oscpath[0],"to", plugin) #sendWSall("/"+ plugin + "/start 0") Send(plugin, ["/"+plugin+oscpath[0], oscpath[1]]) # Send a command to given plugin. Will also start it if command contain /start 1 def Send(name, oscpath): print("OSC is sending to", name,":", oscpath) #if oscpath.find(name) != -1: if oscpath[0].find(name) != -1: print("pinging..", name) # Plugin is online ? if Ping(name): # Light up the plugin button #sendWSall("/" + name + "/start 1") #sendWSall("/status " + name + " online") if gstt.debug > 0: print('') print("Plugins manager got", oscpath, "for plugin", name, "currently online.") # If start 0, try to kill plugin if oscpath[0].find("start") != -1 and oscpath[1] == "0": if gstt.debug >0: print("start 0, so killing", name, "...") Kill(name) # Send osc command elif len(oscpath) == 1: OSCsend(name, oscpath[0], oscargs='noargs') elif len(oscpath) == 2: OSCsend(name, oscpath[0], oscargs=oscpath[1]) elif len(oscpath) == 3: OSCsend(name, oscpath[0], oscargs=(oscpath[1], oscpath[2])) elif name == "trckr": #print("To trckr", name, oscpath, len(oscpath)) OSCsend(name, oscpath[0], oscpath[1:]) elif name == "aurora": #print("To Aurora", oscpath) #OSCsend(name, oscpath[:-2], oscpath[-1] ) print("To Aurora", oscpath, len(oscpath)) OSCsend(name, oscpath[0], oscpath[1:]) return True # Plugin not online.. else: if gstt.debug >0: print("Plugin manager send says plugin " + name + " is offline.") #sendWSall("/redstatus Plugin " + name + " offline") #sendWSall("/"+ name + "/start 0") # Try to Start it if /start 1 if oscpath[0].find("start") != -1 and oscpath[1] == "1": if gstt.debug >0: print("Plugin Manager Trying to start", name, "...") Start(name) return False