Added remote plugin

This plugin will allow me to control Ocarina using an app on another
computer.
This commit is contained in:
Bryan Schumaker 2010-11-13 21:40:55 -05:00
parent dcdbab8e55
commit 77e9cf13ee
7 changed files with 298 additions and 0 deletions

108
plugins/remote.py Normal file
View File

@ -0,0 +1,108 @@
# Bryan Schumaker (11/13/2010)
import socket
import libsaria
from libsaria import threads
server = None
def play_id(arg):
id = int(arg[0])
print "Trying to play id: %s" % id
libsaria.collection.library.play_id(id)
def play(*args):
libsaria.audio.play()
def pause(*args):
libsaria.audio.pause()
def stop(*args):
libsaria.audio.stop()
def next(*args):
print libsaria.collection
libsaria.collection.plist_next()
procs = {"play_id":play_id, "play":play, "pause":pause, "stop":stop, "next":next}
def decode_len(msg):
size, msg = msg.split(' ', 1)
return int(size), msg
def decode_op(msg):
op_len, msg = msg.split(' ', 1)
op = msg[:int(op_len)]
return op, msg[int(op_len) + 1:]
def decode_args(msg):
if msg == "0":
return []
n_args, msg = msg.split(' ', 1)
n_args = n_args
args = []
for i in xrange(int(n_args)):
arg_len, msg = msg.split(' ', 1)
args.append(msg[:int(arg_len)])
msg = msg[int(arg_len) + 1:]
return args
def decode(text):
try:
print "Decoding: %s" % text
size, msg = decode_len(text)
if size != len(msg):
print "Message is wrong length!"
return
except:
print "There was a problem receiving the message"
return
try:
op, msg = decode_op(msg)
except:
print "There was a problem decoding the operation"
return
try:
args = decode_args(msg)
except:
print "There was a problem decoding the argumets"
return
try:
procs[op](args)
except:
print "There was a problem running the operation"
return
def serve():
while 1:
try:
(client, address) = server.accept()
message = client.recv(4096)
decode(message)
except:
break
def start_server():
global server
# Set up a socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
server.bind(("localhost", 4242))
except:
print "Could not open port 4242"
server.listen(5)
serve()
def start():
threads.background(start_server)
def stop():
server.shutdown(socket.SHUT_RDWR)
def check_version():
if libsaria.__major__ != 1:
return False
if libsaria.__minor__ >= 2:
return True
return False

24
remote.py Executable file
View File

@ -0,0 +1,24 @@
#!/usr/bin/python2
# Bryan Schumaker (11/13/2010)
import remote
from remote.gui import buttons
gtk = remote.gtk
win = remote.window()
win.resize(1,1)
vbox = gtk.VBox()
vbox.show()
button_box = gtk.HBox()
button_box.show()
button_box.pack_start(buttons.PlayButton(), False, False)
button_box.pack_start(buttons.PauseButton(), False, False)
button_box.pack_start(buttons.StopButton(), False, False)
button_box.pack_start(buttons.NextButton(), False, False)
vbox.pack_start(button_box, False, False)
win.add(vbox)
remote.start()

51
remote/__init__.py Normal file
View File

@ -0,0 +1,51 @@
# Bryan Schumaker (11/13/2010)
import gtk
import socket
win = None
def send(text):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect( ("localhost", 4242) )
total_sent = 0
length = len(text)
while total_sent < length:
sent = s.send(text[total_sent:])
if sent == 0:
print "Socket connection broken :("
return
total_sent += sent
def encode(func):
op, args = func.split('(', 1)
args = args[:len(args)-1]
args = args.split(',')
msg = "%s %s" % (len(op), op)
msg_args = ""
n_args = 0
for arg in args:
arg = arg.strip()
if len(arg) > 0:
msg_args += " %s %s" % (len(arg), arg)
n_args += 1
msg = msg.strip()
args = msg_args.strip()
msg = "%s %s %s" % (msg, n_args, args)
msg = msg.strip()
return "%s %s" % (len(msg), msg)
# msg_len op_len op n_args arg1_len arg1 arg2_len arg2
def start():
gtk.main()
def quit(*args):
gtk.main_quit()
def window():
global win
if win == None:
from gui import window
win = window.get_window()
return win

3
remote/gui/__init__.py Normal file
View File

@ -0,0 +1,3 @@
# Bryan Schumaker (11/13/2010)
__all__ = ["window", "buttons"]

75
remote/gui/buttons.py Normal file
View File

@ -0,0 +1,75 @@
# Bryan Schumaker (11/13/2010)
import remote
gtk = remote.gtk
play_button = None
pause_button = None
def set_state_playing():
play_button.hide()
pause_button.show()
def set_state_paused():
play_button.show()
pause_button.hide()
from remote import procs
class Button(gtk.Button):
def __init__(self, stock, size=gtk.ICON_SIZE_DIALOG, func=None, show=True):
gtk.Button.__init__(self)
self.func = func
img = gtk.image_new_from_stock(stock, size)
img.show()
self.add(img)
self.set_relief(gtk.RELIEF_NONE)
self.click_id = self.connect("clicked", self.clicked)
if show == True:
Button.show(self)
self.set_alignment(0,0)
def clicked(self, button):
self.func()
def show(self, *args):
gtk.Button.show(self)
def hide(self, *args):
gtk.Button.hide(self)
class PlayButton(Button):
def __init__(self):
global play_button
Button.__init__(self, gtk.STOCK_MEDIA_PLAY)
play_button = self
def clicked(self, button):
procs.play()
def hide(self):
Button.hide(self)
def show(self):
Button.show(self)
class PauseButton(Button):
def __init__(self):
global pause_button
Button.__init__(self, gtk.STOCK_MEDIA_PAUSE, show=False)
pause_button = self
def clicked(self, button):
procs.pause()
def hide(self):
Button.hide(self)
def show(self):
Button.show(self)
class StopButton(Button):
def __init__(self):
Button.__init__(self, gtk.STOCK_MEDIA_STOP)
def clicked(self, button):
procs.stop()
class NextButton(Button):
def __init__(self):
Button.__init__(self, gtk.STOCK_MEDIA_NEXT)
def clicked(self, button):
procs.next()

10
remote/gui/window.py Normal file
View File

@ -0,0 +1,10 @@
# Bryan Schumaker (11/13/2010)
import gtk
import remote
def get_window():
win = gtk.Window()
win.connect("delete-event", remote.quit)
win.show()
return win

27
remote/procs.py Normal file
View File

@ -0,0 +1,27 @@
# Bryan Schumaker (11/13/2010)
import remote
from remote.gui.buttons import set_state_playing, set_state_paused
send = remote.send
encode = remote.encode
def remote_call(func):
msg = encode(func)
res = send(msg)
print "Encoded message: %s" % msg
def play():
remote_call("play()")
set_state_playing()
def pause():
remote_call("pause()")
set_state_paused()
def stop():
remote_call("stop()")
set_state_paused()
def next():
remote_call("next()")