jack1 codebase
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.

278 lines
8.9KB

  1. #!/usr/bin/env python
  2. import libjack
  3. import state
  4. import subprocess
  5. from optparse import OptionParser
  6. from ConfigParser import SafeConfigParser
  7. import os
  8. try:
  9. import dbus.service
  10. import gobject
  11. have_dbus = True
  12. except:
  13. have_dbus = False
  14. SESSION_PATH=os.path.join(os.getenv("HOME"), "jackSessions")
  15. defaults = { "jackclientname": "sessionmanager", "sessiondir": "~/jackSessions" }
  16. class SessionManager( object ):
  17. def __init__( self ):
  18. self.config = SafeConfigParser( defaults )
  19. self.config.read( os.path.expanduser( "~/.jacksessionrc" ) )
  20. self.jackname = self.config.get( "DEFAULT", "jackclientname" )
  21. self.cl = libjack.JackClient( self.jackname )
  22. if self.config.has_section( "infra" ):
  23. self.infra_clients = {}
  24. for inf in self.config.items( "infra" ):
  25. self.infra_clients[inf[0]] = inf[1]
  26. else:
  27. self.infra_clients = { "a2j": "a2jmidid" }
  28. self.implicit_clients = [ "system" ]
  29. self.sessiondir = os.path.expanduser( self.config.get( "DEFAULT", "sessiondir" ) ) + "/"
  30. if not os.path.exists( self.sessiondir ):
  31. print "Sessiondir %s does not exist. Creating it..."%self.sessiondir
  32. os.mkdir( self.sessiondir )
  33. def list_projects( self ):
  34. files = os.listdir( self.sessiondir )
  35. files = filter( lambda x: os.path.isdir( os.path.join( self.sessiondir, x ) ), files )
  36. return files
  37. def load_session( self, name ):
  38. if not os.path.exists( self.sessiondir+name+"/session.xml" ):
  39. print "Session %s does not exist"%name
  40. return -1
  41. sd = state.SessionDom( self.sessiondir+name+"/session.xml" )
  42. g=self.cl.get_graph()
  43. children = []
  44. for ic in sd.get_infra_clients():
  45. if not ic[0] in g.clients.keys():
  46. children.append( subprocess.Popen( ic[1], shell=True ) )
  47. print sd.get_client_names()
  48. if opt.renames:
  49. g.ensure_clientnames( sd.get_reg_client_names() )
  50. # get graph again... renaming isnt prefect yet.
  51. g=self.cl.get_graph()
  52. # fixup names, doing this unconditionally, because
  53. # a client rename might have failed.
  54. sd.fixup_client_names( g )
  55. # now we have mangled all the names, lets reserve them.
  56. for (uuid, clientname) in sd.get_uuid_client_pairs():
  57. print "reserving name %s"%clientname
  58. g.reserve_name( uuid, clientname )
  59. # build up list of port connections
  60. conns = []
  61. for p in sd.get_port_names():
  62. for c in sd.get_connections_for_port( p ):
  63. conns.append( (p,c) )
  64. print conns
  65. # now fire up the processes
  66. for cname in sd.get_reg_client_names():
  67. cmd = sd.get_commandline_for_client( cname )
  68. children.append( subprocess.Popen( cmd, shell=True ) )
  69. avail_ports = g.get_port_list()
  70. # wait for ports to appear, and connect em.
  71. while len(conns) > 0:
  72. p = self.cl.port_queue.get()
  73. print p[0],p[1]
  74. pname = libjack.port_name(p[0])
  75. for c1 in conns:
  76. if c1[0]==pname:
  77. if c1[1] in avail_ports:
  78. self.cl.connect( pname, c1[1] )
  79. conns.remove( c1 )
  80. if (c1[1],c1[0]) in conns:
  81. conns.remove( (c1[1],c1[0]) )
  82. break
  83. if c1[1]==pname:
  84. if c1[0] in avail_ports:
  85. self.cl.connect( pname, c1[0] )
  86. conns.remove( c1 )
  87. if (c1[1],c1[0]) in conns:
  88. conns.remove( (c1[1],c1[0]) )
  89. break
  90. avail_ports.append( pname )
  91. print "session restored..."
  92. return 0
  93. def quit_session( self, name ):
  94. self.save_session( name, True )
  95. def save_session( self, name, quit=False ):
  96. if os.path.exists( self.sessiondir+name ):
  97. print "session %s already exists"%name
  98. return -1
  99. os.mkdir( self.sessiondir+name )
  100. g=self.cl.get_graph()
  101. if quit:
  102. notify = self.cl.session_save_and_quit( self.sessiondir+name+"/" )
  103. else:
  104. notify = self.cl.session_save( self.sessiondir+name+"/" )
  105. for n in notify:
  106. c = g.get_client( n.clientname )
  107. c.set_commandline( n.commandline )
  108. c.set_uuid( n.uuid )
  109. sd = state.SessionDom()
  110. for c in g.clients.values():
  111. if c.get_commandline() == "":
  112. if not c.name in self.infra_clients.keys()+self.implicit_clients:
  113. g.remove_client( c.name )
  114. elif c.name in self.implicit_clients:
  115. g.remove_client_only( c.name )
  116. else:
  117. c.set_infra( self.infra_clients[c.name] )
  118. for i in g.clients.values():
  119. sd.add_client(i)
  120. f = file( self.sessiondir+name+"/session.xml", "w" )
  121. f.write( sd.get_xml() )
  122. f.close()
  123. print sd.get_xml()
  124. return 0
  125. def exit( self ):
  126. self.cl.close()
  127. if have_dbus:
  128. class DbusSM( dbus.service.Object ):
  129. def __init__( self, sm ):
  130. self.sm = sm
  131. dbus.service.Object.__init__( self, None,
  132. "/org/jackaudio/sessionmanager",
  133. dbus.service.BusName( "org.jackaudio.sessionmanager", bus=dbus.SessionBus() ) )
  134. @dbus.service.method( dbus_interface="org.jackaudio.sessionmanager",
  135. in_signature="s", out_signature="i" )
  136. def save_as( self, name ):
  137. return self.sm.save_session( name )
  138. @dbus.service.method( dbus_interface="org.jackaudio.sessionmanager",
  139. in_signature="s", out_signature="i" )
  140. def quit_as( self, name ):
  141. return self.sm.quit_session( name )
  142. @dbus.service.method( dbus_interface="org.jackaudio.sessionmanager",
  143. in_signature="s", out_signature="i" )
  144. def load( self, name ):
  145. return self.sm.load_session( name )
  146. @dbus.service.method( dbus_interface="org.jackaudio.sessionmanager",
  147. in_signature="", out_signature="as" )
  148. def list( self ):
  149. return self.sm.list_projects()
  150. @dbus.service.method( dbus_interface="org.jackaudio.sessionmanager",
  151. in_signature="", out_signature="" )
  152. def daemon_quit( self ):
  153. loop.quit()
  154. oparser = OptionParser()
  155. oparser.add_option( "--nodbus", action="store_false", dest="dbus", default=have_dbus,
  156. help="Dont use DBUS to issue commands to a running instance" )
  157. oparser.add_option( "--daemon", action="store_true", dest="daemon", default=False,
  158. help="Start in daemon mode, and listen for dbus commands" )
  159. #oparser.add_option( "--save", action="store_true", dest="save", default=False,
  160. # help="Tell SessionManger to save." )
  161. oparser.add_option( "--saveas", action="store", type="string", dest="saveas",
  162. help="Save Session As <name>" )
  163. #oparser.add_option( "--quit", action="store_true", dest="quit", default=False,
  164. # help="Tell SessionManager to Save And Quit" )
  165. oparser.add_option( "--list", action="store_true", dest="list", default=False,
  166. help="List Projects" )
  167. oparser.add_option( "--quitdaemon", action="store_true", dest="quitdaemon", default=False,
  168. help="Tell SessionManager Daemon to Exit" )
  169. oparser.add_option( "--quitas", action="store", dest="quitas", type="string",
  170. help="SaveAs And Quit" )
  171. oparser.add_option( "--load", action="store", dest="load", type="string",
  172. help="Load Session with <name>" )
  173. oparser.add_option( "--renames", action="store_true", dest="renames", default=False,
  174. help="Allow renaming offending clients" )
  175. (opt,args) = oparser.parse_args()
  176. if not opt.dbus:
  177. sm = SessionManager()
  178. try:
  179. if opt.saveas:
  180. sm.save_session( opt.saveas )
  181. if opt.load:
  182. sm.load_session( opt.load )
  183. if opt.quitas:
  184. sm.quit_session( opt.quitas )
  185. except:
  186. sm.exit()
  187. raise
  188. sm.exit()
  189. else:
  190. if opt.daemon:
  191. try:
  192. sm = SessionManager()
  193. from dbus.mainloop.glib import DBusGMainLoop
  194. DBusGMainLoop(set_as_default=True)
  195. dbsm = DbusSM( sm )
  196. loop = gobject.MainLoop()
  197. loop.run()
  198. except:
  199. sm.exit()
  200. raise
  201. sm.exit()
  202. else:
  203. session_bus = dbus.SessionBus()
  204. sm_proxy = session_bus.get_object( "org.jackaudio.sessionmanager", "/org/jackaudio/sessionmanager" )
  205. sm_iface = dbus.Interface( sm_proxy, "org.jackaudio.sessionmanager" )
  206. if opt.saveas:
  207. sm_iface.save_as( opt.saveas )
  208. if opt.quitas:
  209. sm_iface.quit_as( opt.quitas )
  210. if opt.load:
  211. sm_iface.load( opt.load )
  212. if opt.list:
  213. projects = sm_iface.list()
  214. for i in projects:
  215. print i
  216. if opt.quitdaemon:
  217. sm_iface.quit()