from ziface import ZIface import dbus.service import dbus.mainloop.glib import os from brisa.core.reactors import GLib2Reactor reactor = GLib2Reactor() from brisa.core import log from brisa.core import config from brisa.upnp.device import Device from brisa.upnp.services.cds import ContentDirectory from brisa.upnp.services.connmgr import ConnectionManagerServer from zukebox_server.services.playlist.zb_playlist import PlayList dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) class ZukeBoxServer(ZIface, dbus.service.Object): """ Introduction ============ ZukeBox is an abstraction for a JukeBox. How works? In a JukeBox somebody pay and choose a song for play, this way the JukeBox should have default set of songs. ZukeBox has the same idea, except for payment ;) , you can choose a song availble in the server called ZukeBox Server or send a request for server to play your music, Thus the clientes should be scan the network and get services availble in ZukeBox Server. Services availble are: 1. Show the songs availble in the ZukeBox Server. 2. Play a song availble. 3. Play a song sent by a control point. Some services will be availble too throught dbus.service a method for rescan the default paths and save in the database. """ DBUS_SERVICE_NAME = "br.org.zagaia" DBUS_OBJ_PATH = "/br/org/zagaia/ZukeBox" DBUS_IFACE = "br.org.zagaia.ZukeBox" plugins_folder = config.get_parameter("zukebox_server", "plugins") plugins_module_path = "zukebox_server.plugins" def __init__(self, _server_name, _listen_url): """ ZukeBox Server Construct @param _server_name: Name of the ZukeBox Server @param _listen_url: url to listen for requests @type _server_name: string @type _listen_url: string """ ZIface.__init__(self) bus = dbus.SessionBus() busname = dbus.service.BusName(self.DBUS_SERVICE_NAME, bus=bus) dbus.service.Object.__init__(self, busname, self.DBUS_OBJ_PATH) self.server_name = _server_name self.listen_url = _listen_url self.device = None self.cds = None def _create_device(self): model_name = "ZukeBox Server version 0.1" project_page = "http://portal.fucapi.edu.br/nepcomp/zagaia" serial_no = '0000010' model_description = 'A UPnP Audio Server for ZukeBox' self.device = Device('urn:schemas-upnp-org:device:ZukeBoxServer:1', self.server_name, force_listen_url=self.listen_url, manufacturer="Zagaia Laboratory and INdT Brazil", manufacturer_url=project_page, model_description=model_description, model_name=model_name, model_number=serial_no, model_url=project_page, serial_number=serial_no) def _create_services(self): self.cds = ContentDirectory(self.plugins_folder, self.plugins_module_path) cm = ConnectionManagerServer() mod_path = config.get_parameter("zukebox_server", "home") x_path = os.path.join(mod_path, "xml_descriptions") print x_path playlist = PlayList(positions=10, xml_path=x_path) self.device.add_service(self.cds) self.device.add_service(cm) self.device.add_service(playlist) def start(self): """Start the ZukeBox Server""" self._create_device() self._create_services() self.device.start() reactor.add_after_stop_func(self.device.stop) reactor.main() # DBUS @dbus.service.method(DBUS_IFACE) def halt(self): reactor.main_quit() @dbus.service.method(DBUS_IFACE) def rescan_audio_folder(self): if not self.cds: return pm = self.cds.control_controller.plugin_manager if not "audio_library" in pm.plugins_instances: return pm.plugins_instances["audio_library"].process_audio_folder() @dbus.service.method(DBUS_IFACE) def reload_config(self): config.manager.update()