Browse Source

python session stuff, first working version

tags/0.120.1
Torben Hohn 16 years ago
parent
commit
b9c8be9558
4 changed files with 172 additions and 30 deletions
  1. +61
    -21
      python/libjack.py
  2. +69
    -0
      python/sessionload.py
  3. +22
    -2
      python/sessionsave.py
  4. +20
    -7
      python/state.py

+ 61
- 21
python/libjack.py View File

@@ -1,6 +1,7 @@

from ctypes import *
import string
from Queue import Queue

class jack_client_t(Structure):
pass
@@ -49,7 +50,7 @@ rename_client.argtypes = [ client_p, c_char_p, c_char_p ]
rename_client.restype = c_int

class jack_session_command_t( Structure ):
_fields_ = [ ("uuid", 16*c_char ), ("client_name", 33*c_char), ("command", 256*c_char ) ]
_fields_ = [ ("uuid", 16*c_char ), ("clientname", 33*c_char), ("command", 256*c_char ) ]

session_notify = libjack.jack_session_notify
session_notify.argtypes = [ client_p, c_uint, c_char_p ]
@@ -113,8 +114,12 @@ class Port( object ):
self.name = name
self.portname = name.split(':')[1]
self.port_p = port_by_name( self.client, name )
self.conns = self.get_live_connections()

def get_connections( self ):
return self.conns

def get_live_connections( self ):
conns = port_get_all_connections( self.client, self.port_p )
if not conns:
return []
@@ -125,7 +130,6 @@ class Port( object ):
retval.append( conns[i] )
i+=1
jack_free(conns)

return retval

@@ -161,13 +165,17 @@ class Client( object ):
else:
return ""

def set_commandline( self, cmdline ):
self.commandline = cmdline

def add_port( self, portname ):
self.ports.append( Port( self.client, portname ) )

def rename( self, newname ):
rename_client( self.client, self.name, self.newname )
rename_client( self.client, self.name, newname )
self.ports = []
ports = get_ports( self.client, self.newname+":.*", None, 0 )
ports = get_ports( self.client, newname+":.*", None, 0 )
self.name = newname

i=0
while(ports[i]):
@@ -182,14 +190,6 @@ class JackGraph( object ):
def __init__( self, client, ports, uuids=[] ):
self.client = client
self.clients = {}
self.uuid_to_name = {}
self.name_to_uuid = {}
for uid in uuids:
name = get_client_name_by_uuid( self.client, uid )
if name:
self.uuid_to_name[uid] = name
self.name_to_uuid[name] = uid
jack_free( name )

i=0
while(ports[i]):
@@ -203,26 +203,55 @@ class JackGraph( object ):
def get_client( self, name ):
return self.clients[name]

def get_client_by_uuid( self, uuid ):
return self.clients[self.uuid_to_name[uuid]]
def get_port_list( self ):
retval = []
for c in self.clients.values():
for p in c.ports:
retval.append( p.name )
return retval



def check_client_name( self, client ):
if not client.name in self.clients.keys():
if not client.name in self.reserved_names:
return

oldname = client.name
cname_split = client.name.split('-')
if len(cname_split) == 0:
if len(cname_split) == 1:
cname_prefix = cname_split[0]
else:
cname_prefix = string.join( name_split[:-1], '-' )
cname_prefix = string.join( cname_split[:-1], '-' )

num = 1
while ("%s-%d"%(cname_prefix,num)) in self.clients.keys():
while ("%s-%d"%(cname_prefix,num)) in (self.clients.keys()+self.reserved_names):
num+=1

# XXX: this might still fail due to race.
# also needs to lock
client.rename( "%s-%d"%(cname_prefix,num ) )
newname = "%s-%d"%(cname_prefix,num )

client.rename( newname )
del self.clients[oldname]
self.clients[newname] = client


def remove_client( self, name ):
del self.clients[name]
for c in self.clients.values():
for p in c.ports:
for conn in p.get_connections():
if conn.startswith(name+":"):
p.conns.remove( conn )

def remove_client_only( self, name ):
del self.clients[name]

def ensure_clientnames( self, names ):
self.reserved_names = names
for c in self.clients.values():
self.check_client_name( c )


class NotifyReply(object):
def __init__( self, uuid, clientname, commandline ):
@@ -262,11 +291,22 @@ class JackClient(object):
commands = session_notify( self.client, JackSessionSave, path )
i=0
retval = []
while( commands[i].uuid[0] != 0 ):
retval.append( NotifyReply( commands[i].uuid, commands[i].clientname, commands[i].commandline ) )
while( commands[i].uuid != "" ):
retval.append( NotifyReply( commands[i].uuid, commands[i].clientname, commands[i].command ) )
i+=1
jack_free( commands )

return retval

def connect( self, a, b ):
portA_p = port_by_name( self.client, a )
if( port_flags( portA_p ) & JackPortIsOutput ):
connect( self.client, a, b )
else:
connect( self.client, b, a )






+ 69
- 0
python/sessionload.py View File

@@ -0,0 +1,69 @@


import libjack
import state
import subprocess

SESSION_PATH="/home/torbenh/jackSessions/"
implicit_clients = ["system"]
infra_clients = ["system"]

sd = state.SessionDom( SESSION_PATH+"session.xml" )

cl=libjack.JackClient("bla5")
g=cl.get_graph()

print sd.get_client_names()

g.ensure_clientnames( sd.get_client_names() )

# get graph again... renaming isnt prefect yet.
g=cl.get_graph()
# build up list of port connections

conns = []
for p in sd.get_port_names():
for c in sd.get_connections_for_port( p ):
conns.append( (p,c) )
print conns

# now fire up the processes
children = []
for cname in sd.get_client_names():
cmd = sd.get_commandline_for_client( cname )
children.append( subprocess.Popen( cmd, shell=True ) )

avail_ports = g.get_port_list()
# wait for ports to appear, and connect em.

while len(conns) > 0:
p = cl.port_queue.get()
print p[0],p[1]
pname = libjack.port_name(p[0])
for c1 in conns:
if c1[0]==pname:
if c1[1] in avail_ports:
cl.connect( pname, c1[1] )

conns.remove( c1 )
if (c1[1],c1[0]) in conns:
conns.remove( (c1[1],c1[0]) )

break

if c1[1]==pname:
if c1[0] in avail_ports:
cl.connect( pname, c1[0] )

conns.remove( c1 )
if (c1[1],c1[0]) in conns:
conns.remove( (c1[1],c1[0]) )
break

avail_ports.append( pname )

print "session restored... exiting"
cl.close()


+ 22
- 2
python/sessionsave.py View File

@@ -2,14 +2,34 @@
import libjack
import state

SESSION_PATH="/home/torbenh/jackSessions/"
implicit_clients = ["system"]
infra_clients = ["system"]

c=libjack.JackClient("bla")
g=c.get_graph()
cl=libjack.JackClient("bla")
notify = cl.session_save( SESSION_PATH )
g=cl.get_graph()

for n in notify:
c = g.get_client( n.clientname )
c.set_commandline( n.commandline )

for c in g.clients.values():
if c.get_commandline() == "":
if not c.name in infra_clients:
g.remove_client( c.name )
elif c.name in implicit_clients:
g.remove_client_only( c.name )

sd = state.SessionDom()

for i in g.clients.values():
sd.add_client(i)

f = file( SESSION_PATH+"session.xml", "w" )
f.write( sd.get_xml() )
f.close()

print sd.get_xml()

cl.close()

+ 20
- 7
python/state.py View File

@@ -1,12 +1,12 @@

from xml.dom.minidom import getDOMImplementation, parseString, Element
from xml.dom.minidom import getDOMImplementation, parse, Element

impl = getDOMImplementation()

class SessionDom( object ):
def __init__( self, filename=None ):
if filename:
self.dom = parseString( filename )
self.dom = parse( filename )
else:
self.dom = impl.createDocument(None,"jacksession",None)
@@ -31,24 +31,37 @@ class SessionDom( object ):
self.dom.documentElement.appendChild( cl_elem )

def get_xml(self):
return self.dom.toxml()
return self.dom.toprettyxml()

def get_client_names(self):
retval = []
doc = self.dom.documentElement
for c in doc.getElementsByTagName( "jackclient" ):
yield c.getAttribute( "jackname" ).value
retval.append( c.getAttribute( "jackname" ) )

return retval

def get_port_names(self):
retval = []
doc = self.dom.documentElement
for c in doc.getElementsByTagName( "port" ):
yield c.getAttribute( "name" ).value
retval.append( c.getAttribute( "name" ) )
return retval

def get_connections_for_port( self, portname ):
retval = []
doc = self.dom.documentElement
for c in doc.getElementsByTagName( "port" ):
if c.getAttribute( "name" ).value == portname:
if c.getAttribute( "name" ) == portname:
for i in c.getElementsByTagName( "conn" ):
yield i.getAttribute( "dst" ).value
retval.append( i.getAttribute( "dst" ) )
return retval

def get_commandline_for_client( self, name ):
doc = self.dom.documentElement
for c in doc.getElementsByTagName( "jackclient" ):
if c.getAttribute( "jackname" ) == name:
return c.getAttribute( "cmdline" )




Loading…
Cancel
Save