From 3d80025b7fe79339c7985e2e10161447eea46d1e Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Wed, 16 Nov 2011 04:22:27 +0100 Subject: Initial commit --- remote/projector.py | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100755 remote/projector.py (limited to 'remote/projector.py') diff --git a/remote/projector.py b/remote/projector.py new file mode 100755 index 0000000..16cceb8 --- /dev/null +++ b/remote/projector.py @@ -0,0 +1,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() -- cgit v1.2.1