#! /usr/bin/env python3 # -*- coding: utf-8 -*- """ Copyright 2020, Nils Hilbricht, Germany ( https://www.hilbricht.net ) The Non-Session-Manager by Jonathan Moore Liles : 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 . """ #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,dataClientHook=nothing, parameterNsmOSCUrl=URL) thread = threading.Thread(target=run_receivingServer, args=()) thread.daemon = True # Daemonize thread thread.start() # Start the execution NSMCmd().cmdloop()