Music production session manager https://www.laborejo.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

216 lines
8.0 KiB

#! /usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Copyright 2020, Nils Hilbricht, Germany ( https://www.hilbricht.net )
The Non-Session-Manager by Jonathan Moore Liles <male@tuxfamily.org>: http://non.tuxfamily.org/nsm/
With help from code fragments from https://github.com/attwad/python-osc ( DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE v2 )
API documentation: http://non.tuxfamily.org/nsm/API.html
This file is part of the Laborejo Software Suite ( https://www.laborejo.org ),
more specifically its template base application.
The Template Base Application is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
#Standard Library
import logging
import threading
from time import sleep
import cmd
from pprint import pprint
import sys
from nsmservercontrol import NsmServerControl
class NSMCmd(cmd.Cmd):
intro = "Welcome to the NSM commandline tester. Type help or ? to list commands.\nThere is no prompt, just type.\n"
prompt = ""
file = None #?
lastClientId = None
def _clientId(self, arg):
if arg:
NSMCmd.lastClientId = arg
return arg
elif NSMCmd.lastClientId:
return NSMCmd.lastClientId
else:
return arg
def do_announce(self, arg):
"""Announce ourselves as GUI. This is sent automatically at program start,
but nsmd only remembers the last GUI that announces. Calling announce takes back control"""
nsmServerControl.gui_announce()
def do_ping(self, arg):
"""Ping the server"""
nsmServerControl.ping()
def do_broadcast(self, arg):
"""Send a message too all clients in the current session, except ourselves"""
args = arg.split()
path = args[0]
arguments = args[1:]
nsmServerControl.broadcast(path, arguments)
def do_listSessions(self, arg):
"""Request a list of projects, or sessions, from the server."""
nsmServerControl.list()
print ("Now call 'status'")
#This won't work because when we get back control from list the data is not here yet.
#print(nsmServerControl.internalState["sessions"])
def do_saveSessions(self, arg):
"""Save currently open session"""
nsmServerControl.save()
def do_closeSession(self, arg):
"""Close currently open session"""
nsmServerControl.close()
def do_abortSession(self, arg):
"""Close without saving!"""
nsmServerControl.abort()
def do_liftLockedSession(self, arg):
"""Remove the .lock file from a session. Use with caution. Intended for crash recovery.
Does nothing if not locked."""
nsmServerControl.forceLiftLock(arg)
def do_quitServer(self, arg):
"""Gracefully shut down the server, which will save. Then exit to OS."""
#nsmServerControl.quit() #We don't need that. Called by @atexit
quit()
def do_addClient(self, arg):
"""Add one client to current session. Executable must be in $PATH"""
nsmServerControl.clientAdd(arg)
def do_openSession(self, arg):
"""Open an existing session with a name as shown by the list command"""
nsmServerControl.open(arg)
def do_newSession(self, arg):
"""Saves the current session and creates a new session."""
nsmServerControl.new(arg)
def do_duplicateSession(self, arg):
"""Saves the current session, closes it and opens a copy of it with the given name."""
nsmServerControl.duplicate(arg)
def do_copySession(self, arg):
"""Copy a session with our internal methods. Does not use nsm duplicate and can operate
at any time at any session, locked or not."""
nsmSessionName, newName = arg.split()
nsmServerControl.copySession(nsmSessionName, newName)
def do_hideClient(self, arg):
"""Instruct a client to hide its GUI. Will do nothing if client does not support it"""
arg = self._clientId(arg)
nsmServerControl.clientHide(arg)
def do_showClient(self, arg):
"""Instruct a client to show its GUI again. Will do nothing if client does not support it"""
arg = self._clientId(arg)
nsmServerControl.clientShow(arg)
def do_removeClient(self, arg):
"""Remove a stopped client from a running session"""
arg = self._clientId(arg)
nsmServerControl.clientRemove(arg)
def do_stopClient(self, arg):
"""Stop a client in a running session"""
arg = self._clientId(arg)
nsmServerControl.clientStop(arg)
def do_resumeClient(self, arg):
"""Resume a previously stopped client"""
arg = self._clientId(arg)
nsmServerControl.clientResume(arg)
def do_saveClient(self, arg):
"""instruct a specific client to save"""
arg = self._clientId(arg)
nsmServerControl.clientSave(arg)
def do_allClientsShow(self, arg):
"""Call clientShow for all clients"""
nsmServerControl.allClientsShow()
def do_allClientsHide(self, arg):
"""Call clientHide for all clients"""
nsmServerControl.allClientsHide()
def do_deleteSession(self, arg):
"""Delete a session directory. This is a destructive operation without undo"""
nsmServerControl.deleteSession(arg)
def do_renameSession(self, arg):
"""Rename a non-open session. Arguments: nsmSessionName (from listSessions) newName"""
nsmSessionName, newName = arg.split()
nsmServerControl.renameSession(nsmSessionName, newName)
#Internal, not requests for nsm
def do_status(self, arg):
"""show internal status. Does not query nsm for any updates or live data.
Therefore can be out of date, e.g. after program start there are no listed
sessions. call listSessions first."""
pprint(nsmServerControl.internalState)
def do_loggingInfo(self, arg):
"""Set logging level to very verbose"""
logging.basicConfig(level=logging.INFO)
def do_loggingWarning(self, arg):
"""Set logging level to warnings and errors"""
logging.basicConfig(level=logging.WARNING)
def do_loggingError(self, arg):
"""Set logging level to only errors"""
logging.basicConfig(level=logging.ERROR)
#def default(self, arg):
# nsmServerControl.send(arg)
def run_receivingServer():
"""Run forever
http://sebastiandahlgren.se/2014/06/27/running-a-method-as-a-background-thread-in-python/
"""
while True:
nsmServerControl.process()
sleep(0.001)
def nothing(*args):
pass
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO) #development
try:
URL = sys.argv[1]
print ("Start with URL", sys.argv[1])
except:
URL = None
nsmServerControl = NsmServerControl(useCallbacks=True,sessionOpenReadyHook=nothing,sessionOpenLoadingHook=nothing,sessionClosedHook=nothing,clientStatusHook=nothing,singleInstanceActivateWindowHook=nothing, dataClientNamesHook=nothing, dataClientDescriptionHook=nothing, parameterNsmOSCUrl=URL)
thread = threading.Thread(target=run_receivingServer, args=())
thread.daemon = True # Daemonize thread
thread.start() # Start the execution
NSMCmd().cmdloop()