-# -*- coding: ISO-8859-1 -*-
-#===============================================================================
-# VLC Player Plugin by A. Lätsch 2007
-#
-# This 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, or (at your option) any later
-# version.
-#===============================================================================
-
-from urllib import urlencode
-from urllib2 import urlopen
-from xml.dom.minidom import parse
-from Components.config import config
-from socket import socket as socket_socket, AF_INET as socket_AF_INET, SOCK_STREAM as socket_SOCK_STREAM
-
-def getText(nodelist):
- rc = ""
- for node in nodelist:
- if node.nodeType == node.TEXT_NODE:
- rc = rc + node.data
- return rc
-
-def getLocalHostIP( remote = ("www.python.org", 80)):
- '''Get the "public" address of the local machine, i.e.
- that address which is connected to the general internet.
- Code by Donn Cave, posted to comp.lang.python'''
- s = socket_socket(socket_AF_INET, socket_SOCK_STREAM)
- s.connect( remote )
- ip, localport = s.getsockname()
- s.close()
- return ip
-
-class VlcControlHttp:
- defaultStreamName = None
-
- def __init__(self, servernum):
- cfg = config.plugins.vlcplayer.servers[servernum]
- self.servercfg = cfg
- self.host = cfg.host.value + ":" + str(cfg.httpport.value)
- self.lastError = None
- if VlcControlHttp.defaultStreamName is None:
- try:
- ip = getLocalHostIP( (cfg.host.value, cfg.httpport.value) )
- VlcControlHttp.defaultStreamName = "dream" + str(ip)
- except Exception, e:
- VlcControlHttp.defaultStreamName = "dreambox"
-
- def connect(self):
- pass
-
- def close(self):
- pass
-
- def xmlRequest(self, request, params):
- uri = "/requests/"+request+".xml"
- if params is not None: uri = uri + "?" + urlencode(params)
- #print "[VLC] SEND:", self.host+uri
- resp = urlopen("http://"+self.host+uri)
- return parse(resp)
-
- def playfile(self, filename, output):
- filename = filename.replace("\\", "\\\\")
- filename = filename.replace("'", "\\'")
- input = filename
- if output is not None:
- input += " :sout=" + output;
- print "[VLC] playfile", input
- xml = self.xmlRequest("status", {"command": "in_play", "input": input})
- error = xml.getElementsByTagName("error")
- if error is not None and len(error) > 0:
- self.lastError = getText(error[0].childNodes).strip()
- if len(self.lastError) == 0:
- self.lastError = None
- else:
- print "[VLC] VlcControl error:", self.lastError
- else:
- self.lastError = None
- return self.lastError
-
- def status(self):
- xml = self.xmlRequest("status", None)
- stats = {}
- for e in xml.documentElement.childNodes:
- if e.nodeType == e.ELEMENT_NODE:
- if e.firstChild is None:
- stats[e.nodeName.encode("latin_1", "replace")] = None
- else:
- stats[e.nodeName.encode("latin_1", "replace")] = e.firstChild.nodeValue.encode("latin_1", "replace")
- return stats
-
- def get_playlist(self):
- xml = self.xmlRequest("playlist", None)
- flist = []
- for e in xml.getElementsByTagName("leaf"):
- fentry = {}
- fentry["id"] = int(e.getAttribute("id"))
- fentry["current"] = e.hasAttribute("current")
- if e.hasAttribute("uri") is not None:
- fentry["name"] = e.getAttribute("uri").encode("latin_1", "replace")
- flist.append(fentry)
- return flist
-
- def get_current_id(self):
- flist = self.get_playlist()
- for f in flist:
- if f["current"]:
- return f["id"]
- return -1
-
- def play(self, listid=None):
- if listid is None:
- self.xmlRequest("status", {"command": "pl_pause"})
- else:
- self.xmlRequest("status", {"command": "pl_play", "id": str(listid)})
-
- def stop(self):
- self.xmlRequest("status", {"command": "pl_stop"})
-
- def pause(self):
- self.xmlRequest("status", {"command": "pl_pause"})
-
- def delete(self, listid=None):
- if listid is None:
- listid = self.get_current_id()
- self.xmlRequest("status", {"command": "pl_delete", "id": str(listid)})
-
- def seek(self, value):
- """ Allowed values are of the form:
- [+ or -][<int><H or h>:][<int><M or m or '>:][<int><nothing or S or s or ">]
- or [+ or -]<int>%
- (value between [ ] are optional, value between < > are mandatory)
-examples:
- 1000 -> seek to the 1000th second
- +1H:2M -> seek 1 hour and 2 minutes forward
- -10% -> seek 10% back"""
- self.xmlRequest("status", {"command": "seek", "val": str(value)})
-
+# -*- coding: ISO-8859-1 -*-\r
+#===============================================================================\r
+# VLC Player Plugin by A. Lätsch 2007\r
+#\r
+# This is free software; you can redistribute it and/or modify it under\r
+# the terms of the GNU General Public License as published by the Free\r
+# Software Foundation; either version 2, or (at your option) any later\r
+# version.\r
+#===============================================================================\r
+\r
+from urllib import urlencode\r
+from urllib2 import urlopen\r
+from xml.dom.minidom import parse\r
+from Components.config import config\r
+from socket import socket as socket_socket, AF_INET as socket_AF_INET, SOCK_STREAM as socket_SOCK_STREAM\r
+import re\r
+\r
+def getText(nodelist):\r
+ if nodelist is None:\r
+ return None\r
+ rc = ""\r
+ for node in nodelist:\r
+ if node.nodeType == node.TEXT_NODE:\r
+ rc = rc + node.data\r
+ return rc\r
+\r
+def getLocalHostIP( remote = ("www.python.org", 80)):\r
+ '''Get the "public" address of the local machine, i.e.\r
+ that address which is connected to the general internet.\r
+ Code by Donn Cave, posted to comp.lang.python'''\r
+ s = socket_socket(socket_AF_INET, socket_SOCK_STREAM)\r
+ s.connect( remote )\r
+ ip, localport = s.getsockname()\r
+ s.close()\r
+ return ip\r
+\r
+class VlcControlHttp:\r
+ defaultStreamName = None\r
+ \r
+ def __init__(self, servernum):\r
+ cfg = config.plugins.vlcplayer.servers[servernum]\r
+ self.servercfg = cfg\r
+ self.host = cfg.host.value + ":" + str(cfg.httpport.value)\r
+ self.lastError = None\r
+ if VlcControlHttp.defaultStreamName is None:\r
+ try:\r
+ ip = getLocalHostIP( (cfg.host.value, cfg.httpport.value) )\r
+ VlcControlHttp.defaultStreamName = "dream" + str(ip)\r
+ except Exception, e:\r
+ VlcControlHttp.defaultStreamName = "dreambox"\r
+\r
+ def connect(self):\r
+ pass\r
+\r
+ def close(self):\r
+ pass\r
+ \r
+ def xmlRequest(self, request, params):\r
+ uri = "/requests/"+request+".xml"\r
+ if params is not None: uri = uri + "?" + urlencode(params)\r
+ #print "[VLC] SEND:", self.host+uri\r
+ resp = urlopen("http://"+self.host+uri)\r
+ return parse(resp)\r
+\r
+ def playfile(self, filename, output):\r
+ # workaround for VLC on Windows: subtitle files are not found, if path is\r
+ # written with '/' instead of '\' on Windows. Detect a Windows pathname if\r
+ # it starts with a drive-letter like "C:"\r
+ if re.match("[a-zA-Z]:", filename):\r
+ filename = filename.replace("/", "\\")\r
+ filename = filename.replace("\\", "\\\\")\r
+ filename = filename.replace("'", "\\'")\r
+ input = filename\r
+ if output is not None:\r
+ input += " :sout=" + output;\r
+ print "[VLC] playfile", input\r
+ xml = self.xmlRequest("status", {"command": "in_play", "input": input})\r
+ error = xml.getElementsByTagName("error")\r
+ if error is not None and len(error) > 0:\r
+ self.lastError = getText(error[0].childNodes).strip()\r
+ if len(self.lastError) == 0:\r
+ self.lastError = None\r
+ else:\r
+ print "[VLC] VlcControl error:", self.lastError\r
+ else:\r
+ self.lastError = None\r
+ return self.lastError\r
+\r
+ def status(self):\r
+ xml = self.xmlRequest("status", None)\r
+ stats = {}\r
+ for e in xml.documentElement.childNodes:\r
+ if e.nodeType == e.ELEMENT_NODE:\r
+ if e.firstChild is None:\r
+ stats[e.nodeName.encode("utf8", "replace")] = None\r
+ else:\r
+ stats[e.nodeName.encode("utf8", "replace")] = e.firstChild.nodeValue.encode("utf8", "replace")\r
+ return stats\r
+ \r
+ def getStreamInfo(self):\r
+ xml = self.xmlRequest("status", None)\r
+ si = []\r
+ infoElem = xml.getElementsByTagName("information")\r
+ if infoElem is None:\r
+ return None\r
+ infoElem = infoElem[0]\r
+ for e in infoElem.getElementsByTagName("category"):\r
+ info = { "Name": e.getAttribute("name").encode("utf8", "replace") }\r
+ for i in e.getElementsByTagName("info"):\r
+ info[i.getAttribute("name").encode("utf8", "replace")] = getText(i.childNodes).encode("utf8", "replace")\r
+ si.append(info)\r
+ return si\r
+\r
+ def get_playlist(self):\r
+ xml = self.xmlRequest("playlist", None)\r
+ flist = []\r
+ for e in xml.getElementsByTagName("leaf"):\r
+ fentry = {}\r
+ fentry["id"] = int(e.getAttribute("id"))\r
+ fentry["current"] = e.hasAttribute("current")\r
+ if e.hasAttribute("uri") is not None:\r
+ fentry["name"] = e.getAttribute("uri").encode("latin_1", "replace")\r
+ flist.append(fentry)\r
+ return flist\r
+ \r
+ def get_current_id(self):\r
+ flist = self.get_playlist()\r
+ for f in flist:\r
+ if f["current"]:\r
+ return f["id"]\r
+ return -1\r
+\r
+ def play(self, listid=None):\r
+ if listid is None:\r
+ self.xmlRequest("status", {"command": "pl_pause"})\r
+ else:\r
+ self.xmlRequest("status", {"command": "pl_play", "id": str(listid)})\r
+ \r
+ def stop(self):\r
+ self.xmlRequest("status", {"command": "pl_stop"})\r
+\r
+ def pause(self):\r
+ self.xmlRequest("status", {"command": "pl_pause"})\r
+ \r
+ def delete(self, listid=None):\r
+ if listid is None:\r
+ listid = self.get_current_id()\r
+ self.xmlRequest("status", {"command": "pl_delete", "id": str(listid)})\r
+ \r
+ def seek(self, value):\r
+ """ Allowed values are of the form:\r
+ [+ or -][<int><H or h>:][<int><M or m or '>:][<int><nothing or S or s or ">]\r
+ or [+ or -]<int>%\r
+ (value between [ ] are optional, value between < > are mandatory)\r
+examples:\r
+ 1000 -> seek to the 1000th second\r
+ +1H:2M -> seek 1 hour and 2 minutes forward\r
+ -10% -> seek 10% back"""\r
+ self.xmlRequest("status", {"command": "seek", "val": str(value)})\r
+ \r
+ def next(self):\r
+ self.xmlRequest("status", {"command": "pl_next"})\r
+ \r
+ def previous(self):\r
+ self.xmlRequest("status", {"command": "pl_previous"})\r