Browse Source

add a module to parsing my pyvr xml data... This has the shows

showing up, but now I need to figure out why it hangs when browse
into the shows...

looking good...

[git-p4: depot-paths = "//depot/": change = 1113]
replace/b43bf02ddeddd088c0e6b94974ca1a46562eb3db
John-Mark Gurney 17 years ago
parent
commit
df5763129e
2 changed files with 275 additions and 1 deletions
  1. +7
    -1
      pymediaserv
  2. +268
    -0
      pyvr.py

+ 7
- 1
pymediaserv View File

@@ -27,7 +27,13 @@ def tryloadmodule(mod):
# ZipStorage w/ tar support should be last as it will gobble up empty files.
# These should be sorted by how much work they do, the least work the earlier.
# mpegtsmod can be really expensive.
modules = [ 'shoutcast', 'dvd', 'ZipStorage', 'mpegtsmod' ]
modules = [
'shoutcast',
'pyvr',
'dvd',
'ZipStorage',
'mpegtsmod',
]
modmap = {}
for i in modules:
modmap[i] = tryloadmodule(i)


+ 268
- 0
pyvr.py View File

@@ -0,0 +1,268 @@
#!/usr/bin/env python
# Copyright 2008 John-Mark Gurney <jmg@funktaht.com>
'''PVR Interface'''

__version__ = '$Change: 1109 $'
# $Id: //depot/python/pymeds/main/shoutcast.py#13 $

from DIDLLite import Container, Item, VideoItem, Resource
from FSStorage import registerklassfun

import os.path
import time
import twisted.web
from twisted.internet import reactor
from twisted.python import log

def getPage(url, contextFactory=None, *args, **kwargs):
"""Download a web page as a string.

Download a page. Return the HTTPClientFactory, which will
callback with a page (as a string) or errback with a
description of the error.

See HTTPClientFactory to see what extra args can be passed.
"""
from twisted.web.client import _parse, HTTPClientFactory

scheme, host, port, path = _parse(url)
factory = HTTPClientFactory(url, *args, **kwargs)
if scheme == 'https':
from twisted.internet import ssl
if contextFactory is None:
contextFactory = ssl.ClientContextFactory()
reactor.connectSSL(host, port, factory, contextFactory)
else:
reactor.connectTCP(host, port, factory)
return factory

class PYVRShow(VideoItem):
def __init__(self, *args, **kwargs):
baseurl = kwargs['url']
self.info = kwargs['info']
del kwargs['info'], kwargs['url']

VideoItem.__init__(self, *args, **kwargs)

url = self.info['link']
sc = urlparse.urlparse(url)
if not sc:
# need to combine w/ base url
url = urlparse.urljoin(baseurl, url)
self.res = Resource(url,
'http-get:*:%s:*' % self.info['mimetype'])
#self.res.size = self.chapter.size

def doUpdate(self):
pass

import xml.sax
import xml.sax.handler
from xml.sax.saxutils import unescape

class RecordingXML(xml.sax.handler.ContentHandler):
def __init__(self):
self.shows = {}
self.data = None

def characters(self, chars):
if self.data is not None:
self.data.append(chars)

def startElement(self, name, attrs):
if name in ('title', 'subtitle', 'mimetype', 'link', 'delete'):
self.data = []
self.curel = name
elif name == 'record':
self.currec = {}

def endElement(self, name):
if name in ('title', 'subtitle', 'mimetype', 'link', 'delete'):
data = unescape(''.join(self.data))
self.currec[self.curel] = data
elif name == 'record':
rec = self.currec
try:
self.shows[rec['title']].append(rec)
except KeyError:
self.shows[rec['title']] = [ rec ]

self.data = None

def recxmltoobj(page):
obj = RecordingXML()
xml.sax.parseString(page, obj)

return obj.shows

class PYVRShows(Container):
def __init__(self, *args, **kwargs):
self.pyvr = kwargs['pyvr']
del kwargs['pyvr']
self.show = kwargs['show']
del kwargs['show']

Container.__init__(self, *args, **kwargs)

self.pathObjmap = {}
self.shows = {}
self.lastmodified = None

def checkUpdate(self):
self.pyvr.checkUpdate()
if self.pyvr.lastmodified != self.lastmodified:
self.doUpdate(self)

@staticmethod
def getunique(eps, ep):
i = 1
while True:
title = '%s Copy %d' % (ep['subtitle'], i)
if not ret.has_key(title):
return title
i += 1

@staticmethod
def eplisttodict(eps):
ret = {}
for i in eps:
title = i['subtitle']
if ret.has_key(title):
print 'WARNING: dup:', `i`, `ret[title]`
title = self.getunique(ret, i)
ret[title] = i

return ret

def doUpdate(self):
nl = self.eplisttodict(self.pyvr.shows[self.show])

doupdate = False
for i in self.pathObjmap.keys():
if i not in nl:
# delete
doupdate = True
self.cd.delItem(self.pathObjmap[i])
del self.pathObjmap[i]

for i in nl:
if i in self.pathObjmap and self.shows[i] == nl[i]:
continue
doupdate = True
if i in self.pathObjmap:
# changed
self.cd.delItem(self.pathObjmap[i])
self.pathObjmap[i] = self.cd.addItem(self.id,
PYVRShow, i, url=self.pyvr.url, info=nl[i])

self.shows = nl

# sort our children
self.sort(lambda x, y: cmp(x.title, y.title))
if doupdate:
Container.doUpdate(self)

class PYVR(Container):
def __init__(self, *args, **kwargs):
self.url = kwargs['url']
del kwargs['url']

Container.__init__(self, *args, **kwargs)

self.pathObjmap = {}
self.isPend = False
self.lastmodified = None
self.newobjs = None
self.objs = {}
self.lastcheck = 0

def checkUpdate(self):
if self.isPend:
print 'already'
raise self.pend

if time.time() - self.lastcheck < 5:
print 'escape'
return

# Check to see if any changes have been made
self.isPend = True
self.lastcheck = time.time()
self.page = getPage(self.url, method='HEAD')
self.page.deferred.addCallback(self.doCheck)
self.pend = self.page.deferred

print 'doing raise'
raise self.pend

def doCheck(self, x):
print 'got check'
print `self.page.response_headers`
slm = self.page.response_headers['last-modified']
if slm == self.lastmodified:
# Page the same, don't do anything
self.isPend = False
return

self.page = getPage(self.url)
self.page.deferred.addCallback(self.parsePage)
self.pend = self.page.deferred

return self.pend

def parsePage(self, page):
print 'parsing'
slm = self.page.response_headers['last-modified']
self.lastmodified = slm
self.isPend = False
del self.page
del self.pend

self.newobjs = recxmltoobj(page)
self.doUpdate()

def doUpdate(self):
if self.newobjs is None:
import traceback
traceback.print_stack(file=log.logfile)
return

nl = self.newobjs

doupdate = False
for i in self.pathObjmap.keys():
if i not in nl:
# delete
doupdate = True
self.cd.delItem(self.pathObjmap[i])
del self.pathObjmap[i]

# This data is referenced when adding new shows
self.shows = nl
for i in nl:
if i in self.pathObjmap:
continue
doupdate = True
try:
self.pathObjmap[i] = self.cd.addItem(self.id,
PYVRShows, i, show=i, pyvr=self)
except:
import traceback
traceback.print_exc(file=log.logfile)
raise

self.newobjs = None

# sort our children
self.sort(lambda x, y: cmp(x.title, y.title))
if doupdate:
Container.doUpdate(self)

def detectpyvrfile(path, fobj):
bn = os.path.basename(path)
if bn == 'PYVR':
print 'detected'
return PYVR, { 'url': fobj.readline().strip() }
return None, None

registerklassfun(detectpyvrfile)

Loading…
Cancel
Save