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
|
#!/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',
'http://sublab.rotefraktion.org/loungescreen/'
]
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',
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()
|