1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
#!/usr/bin/python2
import subprocess
import os
import time
import sys
import signal
import select
import errno
import inspect
from SimpleXMLRPCServer import SimpleXMLRPCServer
projection_process = None
default_task = [
'./brause.py',
'file://%s' % os.path.join(os.path.abspath(os.path.dirname(__file__)), 'default_page', 'index.html')
]
projection_task = default_task
class ChildProcess(subprocess.Popen):
def __init__(self, *args, **kwargs):
subprocess.Popen.__init__(self, *args, **kwargs)
self._kill = os.kill
def __del__(self):
try:
self._kill(self.pid, 9)
self.poll()
except EnvironmentError as e:
if e.args[0] != errno.ESRCH:
raise
def restart_projection(dummy=None):
global projection_process
global projection_task
print "Replacing projection_process..."
projection_process = ChildProcess(projection_task)
def sigchld(signum, trace):
global projection_process
print "Got SIGCHLD"
if projection_process is not None and \
projection_process.poll() is None:
# This info was not about the current projection_process...
return
# Current projection_process exited, fallback to default
reset_projection()
def display_url(url):
global projection_task
projection_task = [
'./brause.py',
url
]
restart_projection()
return 0 # For RPC
def display_video(url):
global projection_task
if not (url.startswith('http://') or \
url.startswith('ftp://')):
raise ValueError('URL should point to a http/ftp resource...')
projection_task = [
'mplayer',
'-fs',
'-vo',
'x11',
'-ao',
'pulse',
url
]
restart_projection()
return 0 # For RPC
def reset_projection():
global projection_task
global default_task
projection_task = default_task
restart_projection()
return 0 # For RPC
def start_vnc(port):
global projection_task
if type(port) is not int:
raise TypeError("start_vnc expects (port:int) as arguments")
# Worst Monkey Patch ever (tm)
host = inspect.stack()[3][0].f_locals['self'].client_address[0]
print 'Connecting vncviewer to %s:%d' % (host,port)
projection_task = [
"vncviewer", "-fullscreen",
"-viewonly", "%s::%d" % (host,port) ]
restart_projection()
return 0
def main():
global projecting
subprocess.check_call("xset s off".split())
subprocess.check_call("xset -dpms".split())
signal.signal(signal.SIGCHLD, sigchld)
restart_projection()
server = SimpleXMLRPCServer(("0.0.0.0", 8082))
server.register_function(display_url)
server.register_function(display_video)
server.register_function(reset_projection)
server.register_function(start_vnc)
while True:
try:
server.serve_forever()
except select.error as e:
if e.args[0] == errno.EINTR:
continue
raise
if __name__ == '__main__':
main()
|