653a49fd70081f486f24464d03ce7fd92ccf7f20
[profile/ivi/remotecontrol.git] / remotecontrol / remoteserver.py
1 #!/usr/bin/env python
2 #
3 # Copyright (c) 2012, Intel Corporation.
4 #
5 # This program is licensed under the terms and conditions of the 
6 # Apache License, version 2.0.  The full text of the Apache License is at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9
10 import os
11 import re
12 import signal
13 import subprocess
14 import socket
15 import sys
16 import threading
17 import simplejson as json
18 import gobject
19 import dbus
20 import dbus.service
21 import dbus.mainloop.glib
22
23 class RemoteControlService(dbus.service.Object):
24
25     def __init__(self, conn, object_path='/com/intel/RemoteControl/server'):
26         dbus.service.Object.__init__(self, conn, object_path)
27
28     @dbus.service.signal(dbus_interface='com.intel.RemoteControl', \
29                          signature='ss')
30     def notification(self, mtype, mvalue):
31         print 'Triggering notification: ', mtype, mvalue
32
33 class DBusThread(threading.Thread):
34
35     def __init__(self):
36         threading.Thread.__init__ ( self )
37     def run(self):
38         dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
39
40         session_bus = dbus.SessionBus()
41         name = dbus.service.BusName('com.intel.RemoteControl', \
42                                      session_bus)
43         self.remoteserver = RemoteControlService(session_bus)        
44
45         loop = gobject.MainLoop()
46         gobject.threads_init()
47
48         print 'Dbus thread started...'
49         loop.run()
50         print 'Dbus thread stopped...'
51
52     def emitMessage(self, mtype, mvalue):
53         self.remoteserver.notification(mtype, mvalue)
54
55 from autobahn.websocket import WebSocketServerFactory, \
56                                WebSocketServerProtocol, \
57                                listenWS
58
59 from api.videoplayer import VideoPlayerAPI
60 from api.dialer import DialerAPI
61 from api.voicecommand import VoiceCommandAPI
62 from api.texttospeech import TextToSpeechAPI
63 from api.remotecontrol import RemoteControlAPI
64
65 class RemoteServerProtocol(WebSocketServerProtocol):
66
67     def __init__(self):
68         self.videoplayerAPI = VideoPlayerAPI(self)
69         self.dialerAPI = DialerAPI(self)
70         self.voicecommandAPI = VoiceCommandAPI(self)
71         self.ttsAPI = TextToSpeechAPI(self)
72         self.remotecontrolAPI = RemoteControlAPI(self)
73
74     def onMessage(self, data, isBinary):
75         jsonData = json.loads(data)
76         print'data received', jsonData
77         try:
78             if jsonData.get('type') == 'connect':
79                 print 'client connected'
80                 return
81             if not 'api_namespace' in jsonData:
82                 raise Exception('method_namespace missing')
83
84             if jsonData.get('api_namespace') == 'tizen.ivi.videoplayer':
85                 self.videoplayerAPI.handleMessage(jsonData)
86             elif jsonData.get('api_namespace') == 'tizen.ivi.dialer':
87                 self.dialerAPI.handleMessage(jsonData)
88             elif jsonData.get('api_namespace') == 'tizen.ivi.voicecommand':
89                 self.voicecommandAPI.handleMessage(jsonData)
90             elif jsonData.get('api_namespace') == 'tizen.ivi.texttospeech':
91                 self.ttsAPI.handleMessage(jsonData)
92             elif jsonData.get('api_namespace') == 'tizen.ivi.remotecontrol':
93                 self.remotecontrolAPI.handleMessage(jsonData)
94             else:
95                 print 'Error, unsupported api'
96         except Exception, e:
97             print 'Error in onMessage() ', e
98             reply = json.dumps({
99                 'type': 'api_error',
100                 'api_error_msg': e.__str__()
101             })
102             self.sendMessage(reply)
103
104 from netifaces import interfaces, ifaddresses, AF_INET
105 from twisted.internet import reactor
106 from twisted.python import log
107 from twisted.web import static
108 from twisted.web.server import Site
109
110 def start():
111     #log.startLogging(sys.stdout)
112     ip = None
113     port = 8080
114     ws_port = 9999
115     for interface in interfaces():
116         try:
117                 if AF_INET not in ifaddresses(interface):
118                         continue
119         except ValueError:
120                 continue
121         for link in ifaddresses(interface)[AF_INET]:
122             address = link['addr']
123             if address != '127.0.0.1':
124                 ip = address
125     if not ip:
126        ip = 'localhost'
127
128     web_url = 'http://' + ip + ':' + str(port)
129     ws_url = 'ws://' + ip + ':' + str(ws_port)
130
131     # search and replace websocket ip addresses in masterControl.js
132     directory = os.path.abspath(os.path.dirname(sys.modules['remotecontrol'].__file__))
133     filename = os.path.join(directory, 'www/js/masterControl.js')
134     print 'filename ', filename
135
136     finput = open(filename, 'r')
137     content = finput.read()
138     for match in re.findall( r'ws://[0-9]+(?:\.[0-9]+){3}:[0-9]+',  content):
139         print 'Replacing existing websocket ip address', match, 'with new ip', ws_url
140         content = content.replace(match, ws_url) 
141
142     tempfile = filename + '~'
143     foutput = open(tempfile, "w")
144     foutput.write(content)
145
146     finput.close()
147     foutput.close()
148     os.rename(tempfile, filename)
149
150     factory = WebSocketServerFactory(ws_url,
151                                      debug = True,
152                                      debugCodePaths = True)
153
154     
155     # disable dbus
156     #dthread = DBusThread()
157     #dthread.setDaemon(True)
158     #dthread.start()
159     dthread = None
160
161     factory.protocol = RemoteServerProtocol
162     factory.protocol.dservice = dthread
163     listenWS(factory)
164     print 'WebSocket server running on ', ws_url, '...'
165
166     # this is the webserver serving remotecontrol webapp on port 8080
167     webdir = static.File(os.path.join(directory, 'www'))
168     web = Site(webdir)
169     reactor.listenTCP(port, web)
170     print 'Http server running on ', web_url, '...'
171
172     reactor.run()
173     print 'Http server stopping...'
174
175 if __name__ == '__main__':
176     start()