Merge branch 'effects'
[blynken.git] / client / context.py
blob4fd585f2cee9d0352037048ec9d25da84c0bc043
1 from __future__ import with_statement
2 from contextlib import contextmanager
3 from functools import partial
4 import socket
6 def parse_command(line):
7 command, _, doc = line.partition(':')
8 command = command.split(' ')
9 command, args = command[0], [i[1:-1] for i in command[1:]]
10 yield (command, args, doc)
12 @contextmanager
13 def connection(host, name, *args):
14 try:
15 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
16 sock.connect(host)
17 sock.sendall(name + ' ' + ' '.join(str(i) for i in args) + '\r\n')
18 yield sock
19 finally:
20 sock.close()
23 # TODO Error handling
24 class BaseContext(object):
25 def __init__(self, host):
26 self.connection = partial(connection, host)
28 def command(func, name=None, cmd_args=None, doc=None):
29 def decorate(*args, **kwargs):
30 if not kwargs:
31 my_args = args[:len(cmd_args)]
32 # args = args[len(cmd_args):]
33 else:
34 # .pop(i) statt [i]
35 my_args = [kwargs[i] for i in cmd_args]
36 print my_args
37 with self.connection(func.func_name, *my_args) as sock:
38 return func(sock, *args, **kwargs)
39 decorate.func_name = func.func_name if not name else name
40 decorate.func_doc = func.func_doc if not doc else doc
41 return decorate
43 self.command = command
45 with self.connection('commands') as socket:
46 for line in socket.makefile().readlines():
47 for cmd, args, doc in parse_command(line):
48 func = None if not hasattr(self, cmd) else getattr(self, cmd)
49 if not hasattr(func, '__call__'):
50 func = lambda sock: sock.makefile().read()
51 setattr(self, cmd, command(func, cmd, args, doc))
54 class Context(BaseContext):
55 def control(self, sock):
56 pass
58 def display(self, sock, x, y):
59 while sock:
60 print sock.recv(x * y)
62 def add_movie(self, sock, name, data):
63 if hasattr(data, 'read'):
64 data = data.read()
65 sock.sendall(data)