With the release of "PMP Mod v1.02M4g3 + Network Support," a homebrew app for the Sony PSP (firmware v1.5), you are given the ability to stream PMP video media files over your wireless network from your computer to your PSP. The server, on the computer side, is executed from a
.
So, the reason I am here is to ask if anybody is up to the task of making that python script work on XBMC. I would love to see more XBOX-to-PSP connectivity.
################################################################################
# PMP Server
# Copyright (C) 2006 David Voswinkel
#
# Homepage: http://optixx.org
# E-mail:
[email protected]#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
################################################################################
import re
import os
import sys
import string
import linecache
import traceback
import BaseHTTPServer
import threading
import urllib
import urlparse
import types
# curl "http://localhost:3333/open?filename=movie.avi&flags=O_RDONLY"
# curl "http://localhost:3333/read?fd=1&size=100"
# curl "http://localhost:3333/lseek?fd=1&offset=1000&whence=1"
# curl "http://localhost:3333/close?fd=1"
import platform
if platform.system() == 'Windows':
ROOT="C:\"
else:
ROOT="/movies"
class HTTPServer(BaseHTTPServer.HTTPServer):
def __init__(self,addr,handler):
BaseHTTPServer.HTTPServer.__init__(self,addr,handler)
self.RequestHandlerClass.subjects = {}
self.fds = {}
class FileIOObject:
def __init__(self,fd,name):
self.name = name
self.mutex = threading.Semaphore(1)
self.fd = fd
class FileIOServer(BaseHTTPServer.BaseHTTPRequestHandler):
__fds = {}
__fd_max = 0
__mutex = threading.Semaphore(1)
server_version = "PMPServer"
def log_message(self, format, *args):
sys.stdout.write("[%s] %s\n" % (self.address_string(),format%args))
def do_POST(self):
self.do_get()
def do_GET(self):
uri = urlparse.urlparse(self.path)
action = uri[2].replace("/","")
args = uri[4].split("&")
if not isinstance(args,types.ListType):
self.send(str(0))
return
if action not in ['open','close','lseek','read','listdir']:
self.send(str(0))
return
kwds = {}
for arg in args:
if arg.find("=")<0:
continue
tmp = arg.split("=")
kwds[tmp[0]] = urllib.unquote(tmp[1])
args = []
func = getattr(self, 'FileIO' + action)
data = func(*args,**kwds)
self.send(data)
def send(self,data):
self.wfile.write("HTTP/1.0 200 OK\r\n")
self.send_header("Content-type","video/mpeg")
self.end_headers()
self.wfile.write(data)
self.wfile.flush()
def FileIOopen(self,*args,**kwds):
try:
filename = os.path.join(ROOT,kwds['filename'])
if not kwds.has_key('flags'):
flags = "O_RDONLY"
else:
flags = kwds['flags']
if not hasattr(os,flags):
flags = "O_RDONLY"
flags = getattr(os,flags)
if not os.path.isfile(filename):
sys.stderr.write("ERROR: no file %s\n" % filename)
return "-1"
FileIOServer.__mutex.acquire()
FileIOServer.__fd_max = FileIOServer.__fd_max +1
net_fd = FileIOServer.__fd_max
if platform.system() == 'Windows':
flags |= os.O_BINARY
fileno = os.open(filename,flags)
fo = FileIOObject(fileno,filename)
FileIOServer.__fds[net_fd] = fo
sys.stderr.write("Create %s net:%i fd:%s \n" % ( filename, net_fd, fileno))
except:
et, ev, tb = sys.exc_info()
sys.stderr.write("ERROR: %s %s\n" % (et,ev))
FileIOServer.__mutex.release()
return "-1"
FileIOServer.__mutex.release()
return net_fd
def FileIOread(self,*args,**kwds):
try:
fo = None
net_fd = int(kwds['fd'])
size = int(kwds['size'])
FileIOServer.__mutex.acquire()
if not FileIOServer.__fds.has_key(net_fd):
FileIOServer.__mutex.release()
return "-1"
fo = FileIOServer.__fds[net_fd]
fo.mutex.acquire()
FileIOServer.__mutex.release()
recv_data=os.read(fo.fd,size)
recv_len = len(recv_data)
sys.stderr.write("Read from %s %i of %i bytes net:%i fd:%s \n" % (fo.name, recv_len,size, net_fd, fo.fd))
fo.mutex.release()
except:
FileIOServer.__mutex.release()
if fo:
fo.mutex.release()
et, ev, tb = sys.exc_info()
sys.stderr.write("ERROR: %s %s\n" % (et,ev))
return "-1"
return recv_data
def FileIOlseek(self,*args,**kwds):
try:
fo = None
net_fd = int(kwds['fd'])
offset = int(kwds['offset'])
whence = int(kwds['whence'])
FileIOServer.__mutex.acquire()
if not FileIOServer.__fds.has_key(net_fd):
FileIOServer.__mutex.release()
return "-1"
fo = FileIOServer.__fds[net_fd]
fo.mutex.acquire()
FileIOServer.__mutex.release()
ret = os.lseek(fo.fd,offset,whence)
sys.stderr.write("Seek %s offset %i %i net:%i fd:%s \n" % (fo.name, ret, whence, net_fd, fo.fd))
fo.mutex.release()
except:
FileIOServer.__mutex.release()
if fo:
fo.mutex.release()
et, ev, tb = sys.exc_info()
sys.stderr.write("ERROR: %s %s\n" % (et,ev))
return "-1"
return str(ret)
def FileIOclose(self,*args,**kwds):
try:
fo = None
net_fd = int(kwds['fd'])
FileIOServer.__mutex.acquire()
if not FileIOServer.__fds.has_key(net_fd):
FileIOServer.__mutex.release()
return "-1"
fo = FileIOServer.__fds[net_fd]
ret = os.close(fo.fd)
sys.stderr.write("Close %s net:%i fd:%s \n" % (fo.name,net_fd, fo.fd))
fo.mutex.release()
del FileIOServer.__fds[net_fd]
FileIOServer.__mutex.release()
except:
FileIOServer.__mutex.release()
if fo:
fo.mutex.release()
et, ev, tb = sys.exc_info()
sys.stderr.write("ERROR: %s %s\n" % (et,ev))
return "-1"
return str(0)
def FileIOlistdir(self,*args,**kwds):
try:
path = os.path.join(ROOT,kwds['path'])
if kwds.has_key("size"):
size = int(kwds['size'])
else:
size = 4 * 1024
cnt = 0
dlist = str()
d = os.listdir(path)
for dent in d:
if dent.startswith("."):
continue
ext = dent.split(".")
if not len(ext):
continue
if ext.pop().lower() not in ['pmp','avi','mpg','mpeg','divx','xvid']:
continue
if os.path.isfile(os.path.join(path,dent)):
next = "net:/%s\n" % (dent)
if len(dlist) + len(next) > size:
break
dlist += next
cnt +=1
sys.stderr.write("Listdir %i entries \n" % (cnt))
except:
return "-1"
return dlist
if __name__ == '__main__':
try:
httpd = HTTPServer(('',3333),FileIOServer)
while True:
httpd.handle_request()
except Exception, argument:
et, ev, tb = sys.exc_info()
sys.stderr.write('#' * 60 + '\n')
sys.stderr.write('Exception:%s %s\n' % (et,ev))
while tb:
co = tb.tb_frame.f_code
filename = co.co_filename
linenum = traceback.tb_lineno(tb),
line = linecache.getline(filename,linenum[0])
line = re.compile('[\n\t]+|[ ]{2,1000}').sub(' ',line)
sys.stderr.write("File: %s Line: %6s Code: '%s' \n" % (filename,linenum[0],line))
tb = tb.tb_next
sys.stderr.write('#' * 60 + '\n')