e390531e02c1caadb672f79ef36ac6f160898de3
[zukebox] / zukebox_server / src / server / zb_server.py
1
2 from ziface import ZIface
3 import dbus.service
4 import dbus.mainloop.glib
5 import os
6
7 from brisa.core.reactors import GLib2Reactor
8 reactor = GLib2Reactor()
9
10 from brisa.core import log
11 from brisa.core import config
12 from brisa.upnp.device import Device
13 from brisa.upnp.services.cds import ContentDirectory
14 from brisa.upnp.services.connmgr import ConnectionManagerServer
15
16 from zukebox_server.services.playlist.zb_playlist import PlayList
17 from zukebox_server.services.search.zb_search import Search
18
19 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
20
21 class ZukeBoxServer(ZIface, dbus.service.Object):
22     """
23     Introduction
24     ============
25     ZukeBox is an abstraction for a JukeBox.
26     How works?
27         In a JukeBox somebody pay and choose a song for play, this way the
28     JukeBox should have default set of songs. ZukeBox has the same idea,
29     except for payment ;) , you can choose a song availble in the server 
30     called ZukeBox Server or send a request for server to play your music, 
31     
32     Thus the clientes should be scan the network and get services availble 
33     in ZukeBox Server.
34     Services availble are:
35         1. Show the songs availble in the ZukeBox Server.
36         2. Play a song availble.
37         3. Play a song sent by a control point.
38     Some services will be availble too throught dbus.service a method for 
39     rescan the default paths and save in the database.
40     """
41
42     DBUS_SERVICE_NAME = "br.org.zagaia"
43     DBUS_OBJ_PATH = "/br/org/zagaia/zukebox/ZukeBoxServer"
44     DBUS_IFACE = "br.org.zagaia.zukebox.ZukeBoxServer"
45
46     plugins_folder = config.get_parameter("zukebox_server", "plugins")
47     plugins_module_path = "zukebox_server.plugins"
48
49     def __init__(self, _server_name, _listen_url):
50         """ ZukeBox Server Construct
51         @param _server_name: Name of the ZukeBox Server
52         @param _listen_url: url to listen for requests
53
54         @type _server_name: string
55         @type _listen_url: string
56         """
57         ZIface.__init__(self)
58         bus = dbus.SessionBus()
59         busname = dbus.service.BusName(self.DBUS_SERVICE_NAME, bus=bus)
60
61         dbus.service.Object.__init__(self, busname, self.DBUS_OBJ_PATH)
62         self.server_name = _server_name
63         self.listen_url = _listen_url
64         self.device = None
65         self.cds = None
66
67     def _create_device(self):
68         model_name = "ZukeBox Server version 0.1"
69         project_page = "http://portal.fucapi.edu.br/nepcomp/zagaia"
70         serial_no = '0000010'
71         model_description = 'A UPnP Audio Server for ZukeBox'
72
73         self.device = Device('urn:schemas-upnp-org:device:ZukeBoxServer:1',
74                 self.server_name, force_listen_url=self.listen_url,
75                 manufacturer="Zagaia Laboratory",
76                 manufacturer_url=project_page,
77                 model_description=model_description,
78                 model_name=model_name, model_number="1.0",
79                 model_url=project_page, serial_number=serial_no)
80
81     def _create_services(self):
82         self.cds = ContentDirectory(self.plugins_folder, self.plugins_module_path)
83         self.cds = ContentDirectory(self.plugins_folder,
84                 self.plugins_module_path)
85         cm = ConnectionManagerServer()
86         x_path = config.get_parameter("zukebox_server", "xml_path")
87         playlist = PlayList(positions=10, xml_path=x_path)
88         search = Search(xml_path=x_path)
89
90         self.device.add_service(self.cds)
91         self.device.add_service(cm)
92         self.device.add_service(playlist)
93         self.device.add_service(search)
94
95     def start(self):
96         """Start the ZukeBox Server"""
97         self._create_device()
98         self._create_services()
99         self.device.start()
100         reactor.add_after_stop_func(self.device.stop)
101         reactor.main()
102
103     # DBUS
104     @dbus.service.method(DBUS_IFACE)
105     def halt(self):
106         reactor.main_quit()
107
108     @dbus.service.method(DBUS_IFACE)
109     def rescan_audio_folder(self):
110         if not self.cds:
111             return
112         pm = self.cds.control_controller.plugin_manager
113         if not "audio_library" in pm.plugins_instances:
114             return
115         pm.plugins_instances["audio_library"].process_audio_folder()
116
117     @dbus.service.method(DBUS_IFACE)
118     def reload_config(self):
119         config.manager.update()
120