Author | SHA1 | Message | Date |
---|---|---|---|
|
fcfa5bdded | convert README to markdown and minor updates.. | 1 year ago |
|
a4ed76d890 |
use local forks to fix modern Python issues..
I should think about moving away from these as they are clearly not maintained for quite a few python versions.. |
1 year ago |
|
7666721ed6 | add a date to files using their mtime.. | 1 year ago |
|
a8e8337e96 | a string player requires these changes.. | 1 year ago |
|
dda96e70f0 |
convert mostly to Python 3.. basic functions work...
add a .gitignore and requirements.txt... the later will be converted to setup.py in time... Also, a fix to SOAPpy is needed.. |
1 year ago |
@@ -0,0 +1,5 @@ | |||||
.DS_Store | |||||
__pycache__ | |||||
# my venv | |||||
p |
@@ -35,7 +35,7 @@ class ClipProxyFile: | |||||
fp = self.fp | fp = self.fp | ||||
records = iter(self.p[p:]) | records = iter(self.p[p:]) | ||||
while s: | while s: | ||||
rec = records.next() | |||||
rec = next(records) | |||||
diff = self.pos - rec[0] | diff = self.pos - rec[0] | ||||
rlen = min(s, rec[1] - diff) | rlen = min(s, rec[1] - diff) | ||||
fp.seek(rec[2] + diff) | fp.seek(rec[2] + diff) | ||||
@@ -76,7 +76,7 @@ class ClipProxy(static.File): | |||||
self.origfile = i['file'] | self.origfile = i['file'] | ||||
self.date = eval(i['datetuple'], { '__builtins__': {} }) | self.date = eval(i['datetuple'], { '__builtins__': {} }) | ||||
# date is UTC | # date is UTC | ||||
p = [ map(int, x.split()) for x in i.get_payload().split('\n') if x ] | |||||
p = [ list(map(int, x.split())) for x in i.get_payload().split('\n') if x ] | |||||
pos = 0 | pos = 0 | ||||
self.pos = par = [] | self.pos = par = [] | ||||
for j in p: | for j in p: | ||||
@@ -11,23 +11,23 @@ from upnp import UPnPPublisher | |||||
class ConnectionManagerControl(UPnPPublisher): | class ConnectionManagerControl(UPnPPublisher): | ||||
def soap_GetProtocolInfo(self, *args, **kwargs): | def soap_GetProtocolInfo(self, *args, **kwargs): | ||||
log.msg('GetProtocolInfo(%s, %s)' % (`args`, `kwargs`)) | |||||
log.msg('GetProtocolInfo(%s, %s)' % (repr(args), repr(kwargs))) | |||||
return { 'Source': 'http-get:*:*:*', 'Sink': '' } | return { 'Source': 'http-get:*:*:*', 'Sink': '' } | ||||
def soap_PrepareForConnection(self, *args, **kwargs): | def soap_PrepareForConnection(self, *args, **kwargs): | ||||
log.msg('PrepareForConnection(%s, %s)' % (`args`, `kwargs`)) | |||||
log.msg('PrepareForConnection(%s, %s)' % (repr(args), repr(kwargs))) | |||||
def soap_ConnectionComplete(self, *args, **kwargs): | def soap_ConnectionComplete(self, *args, **kwargs): | ||||
log.msg('ConnectionComplete(%s, %s)' % (`args`, `kwargs`)) | |||||
log.msg('ConnectionComplete(%s, %s)' % (repr(args), repr(kwargs))) | |||||
def soap_GetCurrentConnectionIDs(self, *args, **kwargs): | def soap_GetCurrentConnectionIDs(self, *args, **kwargs): | ||||
log.msg('GetCurrentConnectionIDs(%s, %s)' % (`args`, `kwargs`)) | |||||
log.msg('GetCurrentConnectionIDs(%s, %s)' % (repr(args), repr(kwargs))) | |||||
def soap_GetCurrentConnectionInfo(self, *args, **kwargs): | def soap_GetCurrentConnectionInfo(self, *args, **kwargs): | ||||
log.msg('GetProtocolInfo(%s, %s)' % (`args`, `kwargs`)) | |||||
log.msg('GetProtocolInfo(%s, %s)' % (repr(args), repr(kwargs))) | |||||
class ConnectionManagerServer(resource.Resource): | class ConnectionManagerServer(resource.Resource): | ||||
def __init__(self): | def __init__(self): | ||||
resource.Resource.__init__(self) | resource.Resource.__init__(self) | ||||
self.putChild('scpd.xml', static.File('connection-manager-scpd.xml')) | |||||
self.putChild('control', ConnectionManagerControl()) | |||||
self.putChild(b'scpd.xml', static.File('connection-manager-scpd.xml')) | |||||
self.putChild(b'control', ConnectionManagerControl()) |
@@ -27,7 +27,7 @@ reqname = 'requests' | |||||
from twisted.python import log | from twisted.python import log | ||||
from twisted.web import resource, static | from twisted.web import resource, static | ||||
from elementtree.ElementTree import Element, SubElement, tostring | |||||
from xml.etree.ElementTree import Element, SubElement, tostring | |||||
from upnp import UPnPPublisher, errorCode | from upnp import UPnPPublisher, errorCode | ||||
from DIDLLite import DIDLElement, Container, Movie, Resource, MusicTrack | from DIDLLite import DIDLElement, Container, Movie, Resource, MusicTrack | ||||
@@ -36,7 +36,7 @@ from twisted.python import failure | |||||
import debug | import debug | ||||
import traceback | import traceback | ||||
from urllib import quote | |||||
from urllib.parse import quote | |||||
class doRecall(defer.Deferred): | class doRecall(defer.Deferred): | ||||
'''A class that will upon any callback from the Deferred object passed | '''A class that will upon any callback from the Deferred object passed | ||||
@@ -80,7 +80,7 @@ class doRecall(defer.Deferred): | |||||
def wrapper(fun, *args, **kwargs): | def wrapper(fun, *args, **kwargs): | ||||
try: | try: | ||||
return fun(*args, **kwargs) | return fun(*args, **kwargs) | ||||
except defer.Deferred, x: | |||||
except defer.Deferred as x: | |||||
return doRecallgen(x, fun, *args, **kwargs) | return doRecallgen(x, fun, *args, **kwargs) | ||||
def doRecallgen(defer, fun, *args, **kwargs): | def doRecallgen(defer, fun, *args, **kwargs): | ||||
@@ -124,17 +124,17 @@ class ContentDirectoryControl(UPnPPublisher, dict): | |||||
return | return | ||||
if hasattr(i, 'content'): | if hasattr(i, 'content'): | ||||
self.webbase.putChild(nid, i.content) | |||||
self.webbase.putChild(bytes(nid, 'ascii'), i.content) | |||||
#log.msg('children:', `self.children[parent]`, `i`) | #log.msg('children:', `self.children[parent]`, `i`) | ||||
self.children[parent].append(i) | self.children[parent].append(i) | ||||
self[i.id] = i | self[i.id] = i | ||||
return i.id | return i.id | ||||
def has_key(self, key): | |||||
return dict.has_key(self, key) | |||||
def __in__(self, k): | |||||
return dict.__in__(self, k) | |||||
def delItem(self, id): | def delItem(self, id): | ||||
if not self.has_key(id): | |||||
if id not in self: | |||||
log.msg('already removed:', id) | log.msg('already removed:', id) | ||||
return | return | ||||
#log.msg('removing:', id) | #log.msg('removing:', id) | ||||
@@ -195,7 +195,7 @@ class ContentDirectoryControl(UPnPPublisher, dict): | |||||
def soap_Browse(self, *args): | def soap_Browse(self, *args): | ||||
l = {} | l = {} | ||||
debug.appendnamespace(reqname, l) | debug.appendnamespace(reqname, l) | ||||
if self.has_key(args[0]): | |||||
if args[0] in self: | |||||
l['object'] = self[args[0]] | l['object'] = self[args[0]] | ||||
l['query'] = 'Browse(ObjectID=%s, BrowseFlags=%s, Filter=%s, ' \ | l['query'] = 'Browse(ObjectID=%s, BrowseFlags=%s, Filter=%s, ' \ | ||||
'StartingIndex=%s RequestedCount=%s SortCriteria=%s)' % \ | 'StartingIndex=%s RequestedCount=%s SortCriteria=%s)' % \ | ||||
@@ -261,8 +261,8 @@ class ContentDirectoryControl(UPnPPublisher, dict): | |||||
log.msg('Search(ContainerID=%s, SearchCriteria=%s, Filter=%s, ' \ | log.msg('Search(ContainerID=%s, SearchCriteria=%s, Filter=%s, ' \ | ||||
'StartingIndex=%s, RequestedCount=%s, SortCriteria=%s)' % | 'StartingIndex=%s, RequestedCount=%s, SortCriteria=%s)' % | ||||
(`ContainerID`, `SearchCriteria`, `Filter`, | |||||
`StartingIndex`, `RequestedCount`, `SortCriteria`)) | |||||
(repr(ContainerID), repr(SearchCriteria), repr(Filter), | |||||
repr(StartingIndex), repr(RequestedCount), repr(SortCriteria))) | |||||
def soap_CreateObject(self, *args, **kwargs): | def soap_CreateObject(self, *args, **kwargs): | ||||
"""Create a new object.""" | """Create a new object.""" | ||||
@@ -270,14 +270,14 @@ class ContentDirectoryControl(UPnPPublisher, dict): | |||||
(ContainerID, Elements) = args | (ContainerID, Elements) = args | ||||
log.msg('CreateObject(ContainerID=%s, Elements=%s)' % | log.msg('CreateObject(ContainerID=%s, Elements=%s)' % | ||||
(`ContainerID`, `Elements`)) | |||||
(repr(ContainerID), repr(Elements))) | |||||
def soap_DestroyObject(self, *args, **kwargs): | def soap_DestroyObject(self, *args, **kwargs): | ||||
"""Destroy the specified object.""" | """Destroy the specified object.""" | ||||
(ObjectID) = args | (ObjectID) = args | ||||
log.msg('DestroyObject(ObjectID=%s)' % `ObjectID`) | |||||
log.msg('DestroyObject(ObjectID=%s)' % repr(ObjectID)) | |||||
def soap_UpdateObject(self, *args, **kwargs): | def soap_UpdateObject(self, *args, **kwargs): | ||||
"""Modify, delete or insert object metadata.""" | """Modify, delete or insert object metadata.""" | ||||
@@ -285,8 +285,8 @@ class ContentDirectoryControl(UPnPPublisher, dict): | |||||
(ObjectID, CurrentTagValue, NewTagValue) = args | (ObjectID, CurrentTagValue, NewTagValue) = args | ||||
log.msg('UpdateObject(ObjectID=%s, CurrentTagValue=%s, ' \ | log.msg('UpdateObject(ObjectID=%s, CurrentTagValue=%s, ' \ | ||||
'NewTagValue=%s)' % (`ObjectID`, `CurrentTagValue`, | |||||
`NewTagValue`)) | |||||
'NewTagValue=%s)' % (repr(ObjectID), repr(CurrentTagValue), | |||||
repr(NewTagValue))) | |||||
def soap_ImportResource(self, *args, **kwargs): | def soap_ImportResource(self, *args, **kwargs): | ||||
"""Transfer a file from a remote source to a local | """Transfer a file from a remote source to a local | ||||
@@ -295,7 +295,7 @@ class ContentDirectoryControl(UPnPPublisher, dict): | |||||
(SourceURI, DestinationURI) = args | (SourceURI, DestinationURI) = args | ||||
log.msg('ImportResource(SourceURI=%s, DestinationURI=%s)' % | log.msg('ImportResource(SourceURI=%s, DestinationURI=%s)' % | ||||
(`SourceURI`, `DestinationURI`)) | |||||
(repr(SourceURI), repr(DestinationURI))) | |||||
def soap_ExportResource(self, *args, **kwargs): | def soap_ExportResource(self, *args, **kwargs): | ||||
"""Transfer a file from a local source to a remote | """Transfer a file from a local source to a remote | ||||
@@ -304,7 +304,7 @@ class ContentDirectoryControl(UPnPPublisher, dict): | |||||
(SourceURI, DestinationURI) = args | (SourceURI, DestinationURI) = args | ||||
log.msg('ExportResource(SourceURI=%s, DestinationURI=%s)' % | log.msg('ExportResource(SourceURI=%s, DestinationURI=%s)' % | ||||
(`SourceURI`, `DestinationURI`)) | |||||
(repr(SourceURI), repr(DestinationURI))) | |||||
def soap_StopTransferResource(self, *args, **kwargs): | def soap_StopTransferResource(self, *args, **kwargs): | ||||
"""Stop a file transfer initiated by ImportResource or | """Stop a file transfer initiated by ImportResource or | ||||
@@ -322,15 +322,15 @@ class ContentDirectoryControl(UPnPPublisher, dict): | |||||
log.msg('GetTransferProgress(TransferID=%s, TransferStatus=%s, ' \ | log.msg('GetTransferProgress(TransferID=%s, TransferStatus=%s, ' \ | ||||
'TransferLength=%s, TransferTotal=%s)' % | 'TransferLength=%s, TransferTotal=%s)' % | ||||
(`TransferId`, `TransferStatus`, `TransferLength`, | |||||
`TransferTotal`)) | |||||
(repr(TransferId), repr(TransferStatus), repr(TransferLength), | |||||
repr(TransferTotal))) | |||||
def soap_DeleteResource(self, *args, **kwargs): | def soap_DeleteResource(self, *args, **kwargs): | ||||
"""Delete a specified resource.""" | """Delete a specified resource.""" | ||||
(ResourceURI) = args | (ResourceURI) = args | ||||
log.msg('DeleteResource(ResourceURI=%s)' % `ResourceURI`) | |||||
log.msg('DeleteResource(ResourceURI=%s)' % repr(ResourceURI)) | |||||
def soap_CreateReference(self, *args, **kwargs): | def soap_CreateReference(self, *args, **kwargs): | ||||
"""Create a reference to an existing object.""" | """Create a reference to an existing object.""" | ||||
@@ -338,14 +338,14 @@ class ContentDirectoryControl(UPnPPublisher, dict): | |||||
(ContainerID, ObjectID) = args | (ContainerID, ObjectID) = args | ||||
log.msg('CreateReference(ContainerID=%s, ObjectID=%s)' % | log.msg('CreateReference(ContainerID=%s, ObjectID=%s)' % | ||||
(`ContainerID`, `ObjectID`)) | |||||
(repr(ContainerID), repr(ObjectID))) | |||||
def __repr__(self): | def __repr__(self): | ||||
return '<ContentDirectoryControl: cnt: %d, urlbase: %s, nextID: %d>' % (len(self), `self.urlbase`, self.nextID) | |||||
return '<ContentDirectoryControl: cnt: %d, urlbase: %s, nextID: %d>' % (len(self), repr(self.urlbase), self.nextID) | |||||
class ContentDirectoryServer(resource.Resource): | class ContentDirectoryServer(resource.Resource): | ||||
def __init__(self, title, *args, **kwargs): | def __init__(self, title, *args, **kwargs): | ||||
resource.Resource.__init__(self) | resource.Resource.__init__(self) | ||||
self.putChild('scpd.xml', static.File('content-directory-scpd.xml')) | |||||
self.putChild(b'scpd.xml', static.File('content-directory-scpd.xml')) | |||||
self.control = ContentDirectoryControl(title, *args, **kwargs) | self.control = ContentDirectoryControl(title, *args, **kwargs) | ||||
self.putChild('control', self.control) | |||||
self.putChild(b'control', self.control) |
@@ -7,11 +7,12 @@ | |||||
__version__ = '$Change: 1665 $' | __version__ = '$Change: 1665 $' | ||||
# $Id: //depot/python/pymeds/main/DIDLLite.py#32 $ | # $Id: //depot/python/pymeds/main/DIDLLite.py#32 $ | ||||
import functools | |||||
import itertools | import itertools | ||||
import unittest | import unittest | ||||
import et | import et | ||||
for i in [ 'Element', 'SubElement', 'tostring', '_ElementInterface' ]: | |||||
for i in [ 'Element', 'SubElement', 'tostring', ]: | |||||
locals()[i] = getattr(et.ET, i) | locals()[i] = getattr(et.ET, i) | ||||
class Resource(object): | class Resource(object): | ||||
@@ -53,7 +54,7 @@ class Resource(object): | |||||
try: | try: | ||||
return self.attrs[key.lower()] | return self.attrs[key.lower()] | ||||
except KeyError: | except KeyError: | ||||
raise AttributeError, key | |||||
raise AttributeError(key) | |||||
def __setattr__(self, key, value): | def __setattr__(self, key, value): | ||||
key = key.lower() | key = key.lower() | ||||
@@ -72,15 +73,15 @@ class Resource(object): | |||||
value = getattr(self, funname)(value) | value = getattr(self, funname)(value) | ||||
else: | else: | ||||
value = str(value) | value = str(value) | ||||
assert isinstance(value, basestring), \ | |||||
'value is not a string: %s' % `value` | |||||
assert isinstance(value, str), \ | |||||
'value is not a string: %s' % repr(value) | |||||
root.attrib[attr] = value | root.attrib[attr] = value | ||||
return root | return root | ||||
@staticmethod | @staticmethod | ||||
def format_duration(s): | def format_duration(s): | ||||
if isinstance(s, basestring): | |||||
if isinstance(s, str): | |||||
return s | return s | ||||
# assume it is a number | # assume it is a number | ||||
@@ -104,7 +105,7 @@ class ResourceList(list): | |||||
def append(self, k): | def append(self, k): | ||||
assert isinstance(k, Resource) | assert isinstance(k, Resource) | ||||
mt = k.protocolInfo.split(':')[2] | mt = k.protocolInfo.split(':')[2] | ||||
if self._mt.has_key(mt): | |||||
if mt in self._mt: | |||||
return | return | ||||
list.append(self, k) | list.append(self, k) | ||||
@@ -204,12 +205,12 @@ class Object(object): | |||||
else: | else: | ||||
self.restricted = '0' | self.restricted = '0' | ||||
if kwargs.has_key('content'): | |||||
if 'content' in kwargs: | |||||
self._content = kwargs.pop('content') | self._content = kwargs.pop('content') | ||||
for i in kwargs: | for i in kwargs: | ||||
if i not in self._optionattrs: | if i not in self._optionattrs: | ||||
raise TypeError('invalid keyword arg: %s' % `i`) | |||||
raise TypeError('invalid keyword arg: %s' % repr(i)) | |||||
setattr(self, i, kwargs[i]) | setattr(self, i, kwargs[i]) | ||||
def __cmp__(self, other): | def __cmp__(self, other): | ||||
@@ -245,12 +246,12 @@ class Object(object): | |||||
if obj is None: | if obj is None: | ||||
continue | continue | ||||
SubElement(root, '%s:%s' % (self._optionattrs[i], | SubElement(root, '%s:%s' % (self._optionattrs[i], | ||||
i)).text = unicode(getattr(self, i)) | |||||
i)).text = str(getattr(self, i)) | |||||
if self.res is not None: | if self.res is not None: | ||||
try: | try: | ||||
resiter = iter(self.res) | resiter = iter(self.res) | ||||
except TypeError, x: | |||||
except TypeError as x: | |||||
resiter = [ self.res ] | resiter = [ self.res ] | ||||
for res in resiter: | for res in resiter: | ||||
root.append(res.toElement()) | root.append(res.toElement()) | ||||
@@ -374,8 +375,11 @@ class Container(Object, list): | |||||
raise NotImplementedError | raise NotImplementedError | ||||
def sort(self, fun=lambda x, y: cmp(x.title, y.title)): | |||||
return list.sort(self, fun) | |||||
def sort(self, fun=None): | |||||
if fun is not None: | |||||
return list.sort(self, key=functools.cmp_to_key(fun)) | |||||
else: | |||||
return list.sort(self, key=lambda x: x.title) | |||||
def doUpdate(self): | def doUpdate(self): | ||||
if self.doingUpdate: | if self.doingUpdate: | ||||
@@ -396,12 +400,12 @@ class Container(Object, list): | |||||
# Delete the old object that no longer exists. | # Delete the old object that no longer exists. | ||||
# Make a mapping of current names to ids. | # Make a mapping of current names to ids. | ||||
names = {} | names = {} | ||||
print 'i:', `self`, `self.genCurrent`, `self.__class__` | |||||
print('i:', repr(self), repr(self.genCurrent), repr(self.__class__)) | |||||
for id, i in tuple(self.genCurrent()): | for id, i in tuple(self.genCurrent()): | ||||
if i not in children: | if i not in children: | ||||
didupdate = True | didupdate = True | ||||
# delete | # delete | ||||
print 'del:', `id`, `i` | |||||
print('del:', repr(id), repr(i)) | |||||
self.cd.delItem(id) | self.cd.delItem(id) | ||||
self.needcontupdate = True | self.needcontupdate = True | ||||
else: | else: | ||||
@@ -413,7 +417,7 @@ class Container(Object, list): | |||||
for i in children: | for i in children: | ||||
if i in names: | if i in names: | ||||
if isdict: | if isdict: | ||||
print 'oc:', `oldchildren[i]`, `children[i]` | |||||
print('oc:', repr(oldchildren[i]), repr(children[i])) | |||||
if oldchildren[i] == children[i]: | if oldchildren[i] == children[i]: | ||||
continue | continue | ||||
@@ -433,7 +437,7 @@ class Container(Object, list): | |||||
#print 'i:', `i`, `isdict`, `args`, `self` | #print 'i:', `i`, `isdict`, `args`, `self` | ||||
pass | pass | ||||
except UnicodeEncodeError: | except UnicodeEncodeError: | ||||
print 'i decode error' | |||||
print('i decode error') | |||||
klass, name, args, kwargs = self.createObject(i, *args) | klass, name, args, kwargs = self.createObject(i, *args) | ||||
if klass is not None: | if klass is not None: | ||||
@@ -457,7 +461,7 @@ class Container(Object, list): | |||||
if self.id == '0': | if self.id == '0': | ||||
self.updateID = (self.updateID + 1) | self.updateID = (self.updateID + 1) | ||||
else: | else: | ||||
self.updateID = (self.updateID + 1) % (1l << 32) | |||||
self.updateID = (self.updateID + 1) % (1 << 32) | |||||
Container.didUpdate(self.cd['0']) | Container.didUpdate(self.cd['0']) | ||||
def _addSet(self, e, items): | def _addSet(self, e, items): | ||||
@@ -502,7 +506,7 @@ class MockContainer(object): | |||||
self.itemiter = itertools.count(1) | self.itemiter = itertools.count(1) | ||||
def addItem(self, *args, **kwargs): | def addItem(self, *args, **kwargs): | ||||
return self.itemiter.next() | |||||
return next(self.itemiter) | |||||
def __getitem__(self, id): | def __getitem__(self, id): | ||||
return Container(None, '0', None, None) | return Container(None, '0', None, None) | ||||
@@ -570,10 +574,10 @@ class StorageFolder(Container): | |||||
storageUsed = -1 | storageUsed = -1 | ||||
class DIDLElement(_ElementInterface): | |||||
class DIDLElement(Element): | |||||
def __init__(self): | def __init__(self): | ||||
_ElementInterface.__init__(self, 'DIDL-Lite', {}) | |||||
self.attrib['xmlns'] = 'urn:schemas-upnp-org:metadata-1-0/DIDL-Lite' | |||||
super().__init__('DIDL-Lite', {}) | |||||
self.attrib['xmlns'] = 'urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/' | |||||
self.attrib['xmlns:dc'] = 'http://purl.org/dc/elements/1.1/' | self.attrib['xmlns:dc'] = 'http://purl.org/dc/elements/1.1/' | ||||
self.attrib['xmlns:upnp'] = 'urn:schemas-upnp-org:metadata-1-0/upnp' | self.attrib['xmlns:upnp'] = 'urn:schemas-upnp-org:metadata-1-0/upnp' | ||||
@@ -594,4 +598,4 @@ if __name__ == '__main__': | |||||
root.addItem(Container(None, '0\Photo\\', '0\\', 'Photo')) | root.addItem(Container(None, '0\Photo\\', '0\\', 'Photo')) | ||||
root.addItem(Container(None, '0\OnlineMedia\\', '0\\', 'OnlineMedia')) | root.addItem(Container(None, '0\OnlineMedia\\', '0\\', 'OnlineMedia')) | ||||
print tostring(root) | |||||
print(tostring(root)) |
@@ -9,18 +9,18 @@ ffmpeg_path = '/usr/local/bin/ffmpeg' | |||||
ffmpeg_path = '/a/home/jmg/src/ffmpeg.tmp/ffmpeg' | ffmpeg_path = '/a/home/jmg/src/ffmpeg.tmp/ffmpeg' | ||||
ffmpeg_path = '/usr/local/bin/ffmpeg-devel' | ffmpeg_path = '/usr/local/bin/ffmpeg-devel' | ||||
import datetime | |||||
import FileDIDL | import FileDIDL | ||||
import errno | import errno | ||||
import itertools | import itertools | ||||
import os | import os | ||||
import sets | |||||
import stat | import stat | ||||
from DIDLLite import StorageFolder, Item, Resource, ResourceList | from DIDLLite import StorageFolder, Item, Resource, ResourceList | ||||
from twisted.web import resource, server, static | from twisted.web import resource, server, static | ||||
from twisted.python import log | from twisted.python import log | ||||
from twisted.internet import abstract, interfaces, process, protocol, reactor | from twisted.internet import abstract, interfaces, process, protocol, reactor | ||||
from zope.interface import implements | |||||
from zope.interface import implementer | |||||
__all__ = [ 'registerklassfun', 'registerfiletoignore', | __all__ = [ 'registerklassfun', 'registerfiletoignore', | ||||
'FSObject', 'FSItem', 'FSDirectory', | 'FSObject', 'FSItem', 'FSDirectory', | ||||
@@ -71,7 +71,7 @@ class FSObject(object): | |||||
self.pstat = nstat | self.pstat = nstat | ||||
self.doUpdate(**kwargs) | self.doUpdate(**kwargs) | ||||
except OSError, x: | |||||
except OSError as x: | |||||
log.msg('os.stat, OSError: %s' % x) | log.msg('os.stat, OSError: %s' % x) | ||||
if x.errno in (errno.ENOENT, errno.ENOTDIR, errno.EPERM, ): | if x.errno in (errno.ENOENT, errno.ENOTDIR, errno.EPERM, ): | ||||
# We can't access it anymore, delete it | # We can't access it anymore, delete it | ||||
@@ -83,17 +83,17 @@ class FSObject(object): | |||||
def __repr__(self): | def __repr__(self): | ||||
return '<%s.%s: path: %s, id: %s, parent: %s, title: %s>' % \ | return '<%s.%s: path: %s, id: %s, parent: %s, title: %s>' % \ | ||||
(self.__class__.__module__, self.__class__.__name__, | (self.__class__.__module__, self.__class__.__name__, | ||||
`self.FSpath`, self.id, self.parentID, `self.title`) | |||||
class NullConsumer(file, abstract.FileDescriptor): | |||||
implements(interfaces.IConsumer) | |||||
def __init__(self): | |||||
file.__init__(self, '/dev/null', 'w') | |||||
abstract.FileDescriptor.__init__(self) | |||||
def write(self, data): | |||||
pass | |||||
repr(self.FSpath), self.id, self.parentID, repr(self.title)) | |||||
#@implementer(interfaces.IConsumer) | |||||
#class NullConsumer(file, abstract.FileDescriptor): | |||||
# | |||||
# def __init__(self): | |||||
# file.__init__(self, '/dev/null', 'w') | |||||
# abstract.FileDescriptor.__init__(self) | |||||
# | |||||
# def write(self, data): | |||||
# pass | |||||
class DynamTransfer(protocol.ProcessProtocol): | class DynamTransfer(protocol.ProcessProtocol): | ||||
def __init__(self, path, mods, request): | def __init__(self, path, mods, request): | ||||
@@ -166,7 +166,7 @@ class DynamTransfer(protocol.ProcessProtocol): | |||||
#'-vb', '8000k', | #'-vb', '8000k', | ||||
#'-sc_threshold', '500000', '-b_strategy', '1', '-max_b_frames', '6', | #'-sc_threshold', '500000', '-b_strategy', '1', '-max_b_frames', '6', | ||||
] + optdict[vcodec] + [ '-', ] | ] + optdict[vcodec] + [ '-', ] | ||||
log.msg(*[`i` for i in args]) | |||||
log.msg(*[repr(i) for i in args]) | |||||
self.proc = process.Process(reactor, ffmpeg_path, args, | self.proc = process.Process(reactor, ffmpeg_path, args, | ||||
None, None, self) | None, None, self) | ||||
self.proc.closeStdin() | self.proc.closeStdin() | ||||
@@ -203,6 +203,9 @@ class FSItem(FSObject, Item): | |||||
mimetype = kwargs.pop('mimetype') | mimetype = kwargs.pop('mimetype') | ||||
kwargs['content'] = DynamicTrans(self.FSpath, | kwargs['content'] = DynamicTrans(self.FSpath, | ||||
static.File(self.FSpath, mimetype)) | static.File(self.FSpath, mimetype)) | ||||
kwargs['date'] = datetime.datetime.utcfromtimestamp(os.stat(self.FSpath).st_mtime).isoformat() + '+00:00' | |||||
Item.__init__(self, *args, **kwargs) | Item.__init__(self, *args, **kwargs) | ||||
self.url = '%s/%s' % (self.cd.urlbase, self.id) | self.url = '%s/%s' % (self.cd.urlbase, self.id) | ||||
self.mimetype = mimetype | self.mimetype = mimetype | ||||
@@ -30,6 +30,7 @@ mimetoclass = { | |||||
def getClassMT(name, mimetype = None, fp = None): | def getClassMT(name, mimetype = None, fp = None): | ||||
'''Return a tuple of the DIDLLite class and mimetype responsible for the named/mimetyped/fpd file.''' | '''Return a tuple of the DIDLLite class and mimetype responsible for the named/mimetyped/fpd file.''' | ||||
if mimetype is None: | if mimetype is None: | ||||
fn, ext = os.path.splitext(name) | fn, ext = os.path.splitext(name) | ||||
ext = ext.lower() | ext = ext.lower() | ||||
@@ -40,9 +41,9 @@ def getClassMT(name, mimetype = None, fp = None): | |||||
return None, None | return None, None | ||||
ty = mimetype.split('/')[0] | ty = mimetype.split('/')[0] | ||||
if mimetoclass.has_key(mimetype): | |||||
if mimetype in mimetoclass: | |||||
klass = mimetoclass[mimetype] | klass = mimetoclass[mimetype] | ||||
elif mimetoclass.has_key(ty): | |||||
elif ty in mimetoclass: | |||||
klass = mimetoclass[ty] | klass = mimetoclass[ty] | ||||
else: | else: | ||||
# XXX - We could fall file -i on it | # XXX - We could fall file -i on it | ||||
@@ -64,7 +65,7 @@ def buildClassMT(baseklass, name, *args, **kwargs): | |||||
class ret(baseklass, klass): | class ret(baseklass, klass): | ||||
pass | pass | ||||
ret.__name__ = '+'.join(map(lambda x: '%s.%s' % (x.__module__, x.__name__), (baseklass, klass))) | |||||
ret.__name__ = '+'.join(['%s.%s' % (x.__module__, x.__name__) for x in (baseklass, klass)]) | |||||
classdict[(baseklass, klass)] = ret | classdict[(baseklass, klass)] = ret | ||||
@@ -1,39 +1,39 @@ | |||||
This code is based upon code by Tim Potter. | |||||
It is licensed under the MIT license at: | |||||
http://opensource.org/licenses/mit-license.php | |||||
PyMedS | |||||
====== | |||||
I got a D-Link DSM-520 but I needed a UPnP Media Server to stream data | |||||
with. I tried one, but it had issues running under FreeBSD's Linux | |||||
emulation. Since I know Python, I went looking for a python server | |||||
and found this code. The code was a good framework, so I expanded upon | |||||
it. | |||||
This is a UPnP Media Server based upon a plugable architecture to allow | |||||
other media repositories than just a file system. | |||||
Tested basic functionality with the following devices and/or programs: | Tested basic functionality with the following devices and/or programs: | ||||
Sony PlayStation 3 | |||||
VLC | |||||
BubbleUPnP (Android) | |||||
Historically tested basic functionality with the following devices and/or programs: | |||||
Cidero UPnP A/V Controller | Cidero UPnP A/V Controller | ||||
Intel's Media Control Point and Media Renderer | Intel's Media Control Point and Media Renderer | ||||
D-Link DSM-520 | D-Link DSM-520 | ||||
Sony PlayStation 3 | Sony PlayStation 3 | ||||
Linksys DMC-250 | Linksys DMC-250 | ||||
The Intel tools are good for testing (though Windows only) but have been | |||||
moved. Not sure where they are located now. | |||||
Usage | |||||
----- | |||||
Either make a directory media and put the files there, or make a symlink | Either make a directory media and put the files there, or make a symlink | ||||
named media to your media files. Either will work. Run it as: | named media to your media files. Either will work. Run it as: | ||||
./pymediaserv <localip> [ <http server port> ] | |||||
``` | |||||
./pymediaserv <localip> [ <http server port> ] | |||||
``` | |||||
The following packages are required to run the media server: | The following packages are required to run the media server: | ||||
* Twisted (tested w/ 8.2.0) - http://twistedmatrix.com/trac/ | |||||
* ElementTree (only pre-Python 2.5) - | |||||
http://effbot.org/zone/element-index.htm | |||||
* SOAPpy - http://pywebsvcs.sourceforge.net/ | |||||
* fpconst (required by SOAPpy) - | |||||
http://sourceforge.net/project/showfiles.php?group_id=71248 | |||||
* Twisted (tested w/ 22.10.0) - https://twisted.org/ | |||||
* SOAPpy-py3 - https://github.com/Synerty/SOAPpy-py3 | |||||
The requirements are in `requirements.txt` and can be installed | |||||
via `pip intall -r requirements.txt`. | |||||
Optional software packages: | |||||
* rarfile - http://grue.l-t.ee/~marko/src/rarfile/ | |||||
* CDDB-py - http://cddb-py.sourceforge.net/ | |||||
Misc Issues | |||||
----------- | |||||
Thanks to Coherence for soap_lite that solved the issues w/ PS3 not seeing | Thanks to Coherence for soap_lite that solved the issues w/ PS3 not seeing | ||||
the media server. The PS3 with the latest firmware (2.50 and later) now | the media server. The PS3 with the latest firmware (2.50 and later) now | ||||
@@ -50,6 +50,15 @@ Good Luck! | |||||
John-Mark Gurney <jmg@funkthat.com> | John-Mark Gurney <jmg@funkthat.com> | ||||
License Information | |||||
------------------- | |||||
This code is based upon code by Tim Potter. | |||||
It is licensed under the MIT license at: | |||||
http://opensource.org/licenses/mit-license.php | |||||
Ideas for future improvements: | Ideas for future improvements: | ||||
I have received a few ECONNABORTED errors at times. The patch | I have received a few ECONNABORTED errors at times. The patch | ||||
twisted.internet.tcp.py.patch catches this error, and handles | twisted.internet.tcp.py.patch catches this error, and handles |
@@ -52,27 +52,24 @@ class SSDPServer(DatagramProtocol): | |||||
def doStop(self): | def doStop(self): | ||||
'''Make sure we send out the byebye notifications.''' | '''Make sure we send out the byebye notifications.''' | ||||
for st in self.known.keys(): | |||||
for st in list(self.known.keys()): | |||||
self.doByebye(st) | self.doByebye(st) | ||||
del self.known[st] | del self.known[st] | ||||
DatagramProtocol.doStop(self) | DatagramProtocol.doStop(self) | ||||
def datagramReceived(self, data, (host, port)): | |||||
def datagramReceived(self, data, hostporttup): | |||||
"""Handle a received multicast datagram.""" | """Handle a received multicast datagram.""" | ||||
# Break up message in to command and headers | |||||
# TODO: use the email module after trimming off the request line.. | |||||
# This gets us much better header support. | |||||
host, port = hostporttup | |||||
data = data.decode('ascii') | |||||
header, payload = data.split('\r\n\r\n') | header, payload = data.split('\r\n\r\n') | ||||
lines = header.split('\r\n') | lines = header.split('\r\n') | ||||
cmd = string.split(lines[0], ' ') | |||||
lines = map(lambda x: x.replace(': ', ':', 1), lines[1:]) | |||||
lines = filter(lambda x: len(x) > 0, lines) | |||||
cmd = lines[0].split(' ') | |||||
lines = [x.replace(': ', ':', 1) for x in lines[1:]] | |||||
lines = [x for x in lines if len(x) > 0] | |||||
headers = [string.split(x, ':', 1) for x in lines] | |||||
headers = dict(map(lambda x: (x[0].lower(), x[1]), headers)) | |||||
headers = [x.split(':', 1) for x in lines] | |||||
headers = dict([(x[0].lower(), x[1]) for x in headers]) | |||||
if cmd[0] == 'M-SEARCH' and cmd[1] == '*': | if cmd[0] == 'M-SEARCH' and cmd[1] == '*': | ||||
# SSDP discovery | # SSDP discovery | ||||
@@ -83,20 +80,20 @@ class SSDPServer(DatagramProtocol): | |||||
else: | else: | ||||
log.msg('Unknown SSDP command %s %s' % cmd) | log.msg('Unknown SSDP command %s %s' % cmd) | ||||
def discoveryRequest(self, headers, (host, port)): | |||||
def discoveryRequest(self, headers, hostporttup): | |||||
"""Process a discovery request. The response must be sent to | """Process a discovery request. The response must be sent to | ||||
the address specified by (host, port).""" | the address specified by (host, port).""" | ||||
host, port = hostporttup | |||||
log.msg('Discovery request for %s' % headers['st']) | log.msg('Discovery request for %s' % headers['st']) | ||||
# Do we know about this service? | # Do we know about this service? | ||||
if headers['st'] == 'ssdp:all': | if headers['st'] == 'ssdp:all': | ||||
for i in self.known: | for i in self.known: | ||||
hcopy = dict(headers.iteritems()) | |||||
hcopy = dict(headers.items()) | |||||
hcopy['st'] = i | hcopy['st'] = i | ||||
self.discoveryRequest(hcopy, (host, port)) | self.discoveryRequest(hcopy, (host, port)) | ||||
return | return | ||||
if not self.known.has_key(headers['st']): | |||||
if headers['st'] not in self.known: | |||||
return | return | ||||
#print 'responding' | #print 'responding' | ||||
@@ -110,7 +107,7 @@ class SSDPServer(DatagramProtocol): | |||||
response.extend(('', '')) | response.extend(('', '')) | ||||
delay = random.randint(0, int(headers['mx'])) | delay = random.randint(0, int(headers['mx'])) | ||||
reactor.callLater(delay, self.transport.write, | reactor.callLater(delay, self.transport.write, | ||||
'\r\n'.join(response), (host, port)) | |||||
b'\r\n'.join((bytes(x, 'ascii') for x in response)), (host, port)) | |||||
def register(self, usn, st, location): | def register(self, usn, st, location): | ||||
"""Register a service or device that this SSDP server will | """Register a service or device that this SSDP server will | ||||
@@ -144,12 +141,12 @@ class SSDPServer(DatagramProtocol): | |||||
'Host: %s:%d' % (SSDP_ADDR, SSDP_PORT), | 'Host: %s:%d' % (SSDP_ADDR, SSDP_PORT), | ||||
'NTS: ssdp:byebye', | 'NTS: ssdp:byebye', | ||||
] | ] | ||||
stcpy = dict(self.known[st].iteritems()) | |||||
stcpy = dict(self.known[st].items()) | |||||
stcpy['NT'] = stcpy['ST'] | stcpy['NT'] = stcpy['ST'] | ||||
del stcpy['ST'] | del stcpy['ST'] | ||||
resp.extend(map(lambda x: ': '.join(x), stcpy.iteritems())) | |||||
resp.extend([': '.join(x) for x in stcpy.items()]) | |||||
resp.extend(('', '')) | resp.extend(('', '')) | ||||
resp = '\r\n'.join(resp) | |||||
resp = b'\r\n'.join(bytes(x, 'ascii') for x in resp) | |||||
self.transport.write(resp, (SSDP_ADDR, SSDP_PORT)) | self.transport.write(resp, (SSDP_ADDR, SSDP_PORT)) | ||||
self.transport.write(resp, (SSDP_ADDR, SSDP_PORT)) | self.transport.write(resp, (SSDP_ADDR, SSDP_PORT)) | ||||
@@ -162,19 +159,19 @@ class SSDPServer(DatagramProtocol): | |||||
'Host: %s:%d' % (SSDP_ADDR, SSDP_PORT), | 'Host: %s:%d' % (SSDP_ADDR, SSDP_PORT), | ||||
'NTS: ssdp:alive', | 'NTS: ssdp:alive', | ||||
] | ] | ||||
stcpy = dict(self.known[st].iteritems()) | |||||
stcpy = dict(self.known[st].items()) | |||||
stcpy['NT'] = stcpy['ST'] | stcpy['NT'] = stcpy['ST'] | ||||
del stcpy['ST'] | del stcpy['ST'] | ||||
resp.extend(map(lambda x: ': '.join(x), stcpy.iteritems())) | |||||
resp.extend([': '.join(x) for x in stcpy.items()]) | |||||
resp.extend(('', '')) | resp.extend(('', '')) | ||||
self.transport.write('\r\n'.join(resp), (SSDP_ADDR, SSDP_PORT)) | |||||
self.transport.write(b'\r\n'.join(bytes(x, 'ascii') for x in resp), (SSDP_ADDR, SSDP_PORT)) | |||||
def notifyReceived(self, headers, (host, port)): | |||||
def notifyReceived(self, headers, hostporttup): | |||||
"""Process a presence announcement. We just remember the | """Process a presence announcement. We just remember the | ||||
details of the SSDP service announced.""" | details of the SSDP service announced.""" | ||||
host, port = hostporttup | |||||
if headers['nts'] == 'ssdp:alive': | if headers['nts'] == 'ssdp:alive': | ||||
if not self.elements.has_key(headers['nt']): | |||||
if headers['nt'] not in self.elements: | |||||
# Register device/service | # Register device/service | ||||
self.elements[headers['nt']] = {} | self.elements[headers['nt']] = {} | ||||
self.elements[headers['nt']]['USN'] = headers['usn'] | self.elements[headers['nt']]['USN'] = headers['usn'] | ||||
@@ -182,7 +179,7 @@ class SSDPServer(DatagramProtocol): | |||||
log.msg('Detected presence of %s' % headers['nt']) | log.msg('Detected presence of %s' % headers['nt']) | ||||
#log.msg('headers: %s' % `headers`) | #log.msg('headers: %s' % `headers`) | ||||
elif headers['nts'] == 'ssdp:byebye': | elif headers['nts'] == 'ssdp:byebye': | ||||
if self.elements.has_key(headers['nt']): | |||||
if headers['nt'] in self.elements: | |||||
# Unregister device/service | # Unregister device/service | ||||
del(self.elements[headers['nt']]) | del(self.elements[headers['nt']]) | ||||
log.msg('Detected absence for %s' % headers['nt']) | log.msg('Detected absence for %s' % headers['nt']) | ||||
@@ -6,21 +6,7 @@ __version__ = '$Change$' | |||||
import itertools | import itertools | ||||
import os.path | import os.path | ||||
import sets | |||||
import time | import time | ||||
import iterzipfile | |||||
zipfile = iterzipfile | |||||
import itertarfile | |||||
tarfile = itertarfile | |||||
try: | |||||
import iterrarfile | |||||
rarfile = iterrarfile | |||||
except ImportError: | |||||
class rarfile: | |||||
pass | |||||
rarfile = rarfile() | |||||
rarfile.is_rarfile = lambda x: False | |||||
import FileDIDL | import FileDIDL | ||||
from DIDLLite import StorageFolder, Item, VideoItem, AudioItem, TextItem, ImageItem, Resource | from DIDLLite import StorageFolder, Item, VideoItem, AudioItem, TextItem, ImageItem, Resource | ||||
@@ -28,7 +28,7 @@ def bytespersecmt(mt): | |||||
try: | try: | ||||
r = mttobytes[tmp[0].lower()] | r = mttobytes[tmp[0].lower()] | ||||
except KeyError: | except KeyError: | ||||
raise ValueError('invalid audio type: %s' % `tmp[0]`) | |||||
raise ValueError('invalid audio type: %s' % repr(tmp[0])) | |||||
v = set(('rate', 'channels')) | v = set(('rate', 'channels')) | ||||
for i in tmp[1:]: | for i in tmp[1:]: | ||||
@@ -38,7 +38,7 @@ def bytespersecmt(mt): | |||||
r *= int(value) | r *= int(value) | ||||
else: | else: | ||||
raise ValueError('invalid audio parameter %s in %s' % | raise ValueError('invalid audio parameter %s in %s' % | ||||
(`arg`, `mt`)) | |||||
(repr(arg), repr(mt))) | |||||
return r | return r | ||||
@@ -67,7 +67,7 @@ class AudioPlayer(FileDescriptor): | |||||
self._writeDisconnected = True | self._writeDisconnected = True | ||||
def writeSomeData(self, data): | def writeSomeData(self, data): | ||||
print 'wsd:', len(data) | |||||
print('wsd:', len(data)) | |||||
return fdesc.writeToFD(self.fileno(), data) | return fdesc.writeToFD(self.fileno(), data) | ||||
def doRead(self): | def doRead(self): | ||||
@@ -76,7 +76,7 @@ class AudioPlayer(FileDescriptor): | |||||
def connectionLost(self, reason): | def connectionLost(self, reason): | ||||
FileDescriptor.connectionLost(self, reason) | FileDescriptor.connectionLost(self, reason) | ||||
print 'AP, connectionLost' | |||||
print('AP, connectionLost') | |||||
self.fileno = lambda: -1 | self.fileno = lambda: -1 | ||||
self.setparameters = None | self.setparameters = None | ||||
if self._dev is not None: | if self._dev is not None: | ||||
@@ -85,7 +85,7 @@ class AudioPlayer(FileDescriptor): | |||||
self.attached = None | self.attached = None | ||||
def stopProducing(self): | def stopProducing(self): | ||||
print 'AP, sp' | |||||
print('AP, sp') | |||||
self.writefun = lambda x: None | self.writefun = lambda x: None | ||||
FileDescriptor.stopProducing(self) | FileDescriptor.stopProducing(self) | ||||
@@ -137,13 +137,13 @@ class AudioResource(resource.Resource): | |||||
nchan = int(nchan) | nchan = int(nchan) | ||||
rate = int(rate) | rate = int(rate) | ||||
except AttributeError: | except AttributeError: | ||||
raise ValueError('Invalid audio format: %s' % `origfmt`) | |||||
raise ValueError('Invalid audio format: %s' % repr(origfmt)) | |||||
try: | try: | ||||
mt = self.mtformat[fmt] | mt = self.mtformat[fmt] | ||||
except KeyError: | except KeyError: | ||||
raise KeyError('No mime-type for audio format: %s.' % | raise KeyError('No mime-type for audio format: %s.' % | ||||
`origfmt`) | |||||
repr(origfmt)) | |||||
return '%s;rate=%d;channels=%d' % (mt, rate, nchan) | return '%s;rate=%d;channels=%d' % (mt, rate, nchan) | ||||
@@ -158,7 +158,7 @@ class AudioResource(resource.Resource): | |||||
try: | try: | ||||
request.setHeader('content-type', | request.setHeader('content-type', | ||||
self.getmimetype(fmt, nchan, rate)) | self.getmimetype(fmt, nchan, rate)) | ||||
except (ValueError, AttributeError, KeyError), x: | |||||
except (ValueError, AttributeError, KeyError) as x: | |||||
return error.ErrorPage(http.UNSUPPORTED_MEDIA_TYPE, | return error.ErrorPage(http.UNSUPPORTED_MEDIA_TYPE, | ||||
'Unsupported Media Type', str(x)).render(request) | 'Unsupported Media Type', str(x)).render(request) | ||||
@@ -188,7 +188,7 @@ class ossaudiodev_fmts: | |||||
pass | pass | ||||
for i in (k for k in dir(ossaudiodev) if k[:5] == 'AFMT_' and \ | for i in (k for k in dir(ossaudiodev) if k[:5] == 'AFMT_' and \ | ||||
isinstance(getattr(ossaudiodev, k), (int, long))): | |||||
isinstance(getattr(ossaudiodev, k), int)): | |||||
setattr(ossaudiodev_fmts, i, getattr(ossaudiodev, i)) | setattr(ossaudiodev_fmts, i, getattr(ossaudiodev, i)) | ||||
class AudioSource(AudioItem): | class AudioSource(AudioItem): | ||||
@@ -219,7 +219,7 @@ def getfmtstrings(f): | |||||
r.append(i) | r.append(i) | ||||
while f: | while f: | ||||
print f, f & -f | |||||
print(f, f & -f) | |||||
r.append(f & -f) | r.append(f & -f) | ||||
f ^= f & -f | f ^= f & -f | ||||
@@ -263,10 +263,10 @@ class FileConsumer: | |||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
if False: | if False: | ||||
i = ossaudiodev.open('/dev/dsp2', 'r') | i = ossaudiodev.open('/dev/dsp2', 'r') | ||||
print getfmtstrings(i.getfmts()) | |||||
print(getfmtstrings(i.getfmts())) | |||||
i.setparameters(ossaudiodev.AFMT_S16_BE, 2, 44100, True) | i.setparameters(ossaudiodev.AFMT_S16_BE, 2, 44100, True) | ||||
print `i.read(16)` | |||||
print(repr(i.read(16))) | |||||
else: | else: | ||||
aplr = AudioPlayer('/dev/dsp2', 'r', | aplr = AudioPlayer('/dev/dsp2', 'r', | ||||
(ossaudiodev.AFMT_S16_BE, 2, 44100, True)) | (ossaudiodev.AFMT_S16_BE, 2, 44100, True)) | ||||
@@ -29,7 +29,7 @@ def makeaudiomt(bitsps, rate, nchan): | |||||
mt = mtformat[bitsps] | mt = mtformat[bitsps] | ||||
except KeyError: | except KeyError: | ||||
raise KeyError('No mime-type for audio format: %s.' % | raise KeyError('No mime-type for audio format: %s.' % | ||||
`bitsps`) | |||||
repr(bitsps)) | |||||
return '%s;rate=%d;channels=%d' % (mt, rate, nchan) | return '%s;rate=%d;channels=%d' % (mt, rate, nchan) | ||||
@@ -53,7 +53,7 @@ class DecoderProducer: | |||||
self.resumeProducing() | self.resumeProducing() | ||||
def __repr__(self): | def __repr__(self): | ||||
return '<DecoderProducer: decoder: %s, bytes left: %d, skip: %d>' % (`self.decoder`, self.tbytes, self.skipbytes) | |||||
return '<DecoderProducer: decoder: %s, bytes left: %d, skip: %d>' % (repr(self.decoder), self.tbytes, self.skipbytes) | |||||
def pauseProducing(self): | def pauseProducing(self): | ||||
# XXX - bug in Twisted 8.2.0 on pipelined requests this is | # XXX - bug in Twisted 8.2.0 on pipelined requests this is | ||||
@@ -99,11 +99,11 @@ class AudioResource(resource.Resource): | |||||
self.cnt = cnt | self.cnt = cnt | ||||
def __repr__(self): | def __repr__(self): | ||||
return '<AudioResource file: %s, dec: %s, start:%d, cnt: %d>' % (`self.f`, self.dec, self.start, self.cnt) | |||||
return '<AudioResource file: %s, dec: %s, start:%d, cnt: %d>' % (repr(self.f), self.dec, self.start, self.cnt) | |||||
def calcrange(self, rng, l): | def calcrange(self, rng, l): | ||||
rng = rng.strip() | rng = rng.strip() | ||||
unit, rangeset = rng.split('=') | unit, rangeset = rng.split('=') | ||||
assert unit == 'bytes', `unit` | |||||
assert unit == 'bytes', repr(unit) | |||||
start, end = rangeset.split('-') | start, end = rangeset.split('-') | ||||
start = int(start) | start = int(start) | ||||
if end: | if end: | ||||
@@ -238,10 +238,10 @@ class AudioDisc(FSObject, MusicAlbum): | |||||
return track['offset'] + index['offset'] | return track['offset'] + index['offset'] | ||||
def createObject(self, i, arg=None): | def createObject(self, i, arg=None): | ||||
'''This function returns the (class, name, *args, **kwargs) | |||||
that will be passed to the addItem method of the | |||||
ContentDirectory. arg will be passed the value of the dict | |||||
keyed by i if genChildren is a dict.''' | |||||
'''This function returns the (class, name, *args, **kwargs) | |||||
that will be passed to the addItem method of the | |||||
ContentDirectory. arg will be passed the value of the dict | |||||
keyed by i if genChildren is a dict.''' | |||||
oi = i | oi = i | ||||
i = int(i) | i = int(i) | ||||
@@ -273,7 +273,7 @@ class AudioDisc(FSObject, MusicAlbum): | |||||
if tt in tags: | if tt in tags: | ||||
if len(tags[tt]) != 1: | if len(tags[tt]) != 1: | ||||
# XXX - track this? | # XXX - track this? | ||||
print 'hun? ttitle:', `tags[tt]` | |||||
print('hun? ttitle:', repr(tags[tt])) | |||||
ttitle = tags[tt][0] | ttitle = tags[tt][0] | ||||
if ' / ' in ttitle: | if ' / ' in ttitle: | ||||
@@ -338,8 +338,8 @@ class AudioRawBase(FSObject): | |||||
self.res.append(r) | self.res.append(r) | ||||
def doUpdate(self): | def doUpdate(self): | ||||
print 'dU:', `self`, self.baseObject.doUpdate | |||||
print self.__class__.__bases__ | |||||
print('dU:', repr(self), self.baseObject.doUpdate) | |||||
print(self.__class__.__bases__) | |||||
#import traceback | #import traceback | ||||
#traceback.print_stack() | #traceback.print_stack() | ||||
self.baseObject.doUpdate(self) | self.baseObject.doUpdate(self) | ||||
@@ -351,7 +351,7 @@ class AudioRawTrack(AudioRawBase, MusicTrack): | |||||
baseObject = MusicTrack | baseObject = MusicTrack | ||||
def detectaudioraw(origpath, fobj): | def detectaudioraw(origpath, fobj): | ||||
for i in decoders.itervalues(): | |||||
for i in decoders.values(): | |||||
try: | try: | ||||
obj = i(origpath) | obj = i(origpath) | ||||
# XXX - don't support down sampling yet | # XXX - don't support down sampling yet | ||||
@@ -378,7 +378,7 @@ def detectaudioraw(origpath, fobj): | |||||
pass | pass | ||||
except: | except: | ||||
import traceback | import traceback | ||||
print 'WARNING: failed to parse toc:' | |||||
print('WARNING: failed to parse toc:') | |||||
traceback.print_exc() | traceback.print_exc() | ||||
args['cuesheet'] = obj.cuesheet | args['cuesheet'] = obj.cuesheet | ||||
@@ -23,13 +23,13 @@ def decodestrend(i, pos): | |||||
r.append('"') | r.append('"') | ||||
pos = bspos + 2 | pos = bspos + 2 | ||||
elif c in string.digits: | elif c in string.digits: | ||||
r.append(unichr(int(i[bspos + 1:bspos + 4], 8))) | |||||
r.append(chr(int(i[bspos + 1:bspos + 4], 8))) | |||||
pos = bspos + 4 | pos = bspos + 4 | ||||
elif c == 'n': | elif c == 'n': | ||||
r.append('\n') | r.append('\n') | ||||
pos = bspos + 2 | pos = bspos + 2 | ||||
else: | else: | ||||
raise ValueError('unknown escape char: %s' % `c`) | |||||
raise ValueError('unknown escape char: %s' % repr(c)) | |||||
else: | else: | ||||
r.append(i[pos:dqpos]) | r.append(i[pos:dqpos]) | ||||
break | break | ||||
@@ -92,7 +92,7 @@ def parsetoc(toc): | |||||
elif key == '//': | elif key == '//': | ||||
pass | pass | ||||
else: | else: | ||||
raise ValueError('unknown line: %s' % `i`) | |||||
raise ValueError('unknown line: %s' % repr(i)) | |||||
elif state == 1: | elif state == 1: | ||||
if key == 'LANGUAGE_MAP': | if key == 'LANGUAGE_MAP': | ||||
state = 2 | state = 2 | ||||
@@ -135,5 +135,5 @@ if __name__ == '__main__': | |||||
import sys | import sys | ||||
for i in sys.argv[1:]: | for i in sys.argv[1:]: | ||||
print 'file:', `i` | |||||
print parsetoc(open(i).read()) | |||||
print('file:', repr(i)) | |||||
print(parsetoc(open(i).read())) |
@@ -28,7 +28,7 @@ class RingBuffer: | |||||
self.cur=0 | self.cur=0 | ||||
self.__class__ = RingBufferFull | self.__class__ = RingBufferFull | ||||
def get(self): | def get(self): | ||||
""" return a list of elements from the oldest to the newest""" | |||||
""" return a list of elements from the oldest to the newest""" | |||||
return self.data | return self.data | ||||
class RingBufferFull: | class RingBufferFull: | ||||
@@ -47,7 +47,7 @@ def doDebugging(opt): | |||||
global insertnamespace, appendnamespace, insertringbuf | global insertnamespace, appendnamespace, insertringbuf | ||||
def insertnamespace(k, v): | def insertnamespace(k, v): | ||||
assert isinstance(k, basestring) | |||||
assert isinstance(k, str) | |||||
sf.namespace[k] = v | sf.namespace[k] = v | ||||
def appendnamespace(k, v): | def appendnamespace(k, v): | ||||
@@ -71,4 +71,4 @@ def doDebugging(opt): | |||||
try: | try: | ||||
reactor.listenTCP(56283, sf) | reactor.listenTCP(56283, sf) | ||||
except twisted.internet.error.CannotListenError: | except twisted.internet.error.CannotListenError: | ||||
print 'WARNING: cannot bind to debugger port.' | |||||
print('WARNING: cannot bind to debugger port.') |
@@ -9,7 +9,6 @@ default_audio_lang = 'en' | |||||
import itertools | import itertools | ||||
import os | import os | ||||
import sets | |||||
import sys | import sys | ||||
sys.path.append('mpegts') | sys.path.append('mpegts') | ||||
@@ -29,7 +29,7 @@ except ImportError: | |||||
from xml import etree as elementtree | from xml import etree as elementtree | ||||
except ImportError: | except ImportError: | ||||
#print "no ElementTree module found, critical error" | #print "no ElementTree module found, critical error" | ||||
raise ImportError, "no ElementTree module found, critical error" | |||||
raise ImportError("no ElementTree module found, critical error") | |||||
utf8_escape = re.compile(eval(r'u"[&<>\"]+"')) | utf8_escape = re.compile(eval(r'u"[&<>\"]+"')) | ||||
escape = re.compile(eval(r'u"[&<>\"\u0080-\uffff]+"')) | escape = re.compile(eval(r'u"[&<>\"\u0080-\uffff]+"')) | ||||
@@ -60,12 +60,12 @@ def new_encode_entity(text, pattern=utf8_escape): | |||||
if t is None: | if t is None: | ||||
t = "&#%d;" % ord(char) | t = "&#%d;" % ord(char) | ||||
append(t) | append(t) | ||||
if type(text) == unicode: | |||||
if isinstance(text, str): | |||||
return ''.join(out) | return ''.join(out) | ||||
else: | else: | ||||
return u''.encode('utf-8').join(out) | |||||
return ''.encode('utf-8').join(out) | |||||
try: | try: | ||||
if type(text) == unicode: | |||||
if isinstance(text, str): | |||||
return elementtree.ElementTree._encode(escape.sub(escape_entities, text), 'ascii') | return elementtree.ElementTree._encode(escape.sub(escape_entities, text), 'ascii') | ||||
else: | else: | ||||
return elementtree.ElementTree._encode(utf8_escape.sub(escape_entities, text.decode('utf-8')), 'utf-8') | return elementtree.ElementTree._encode(utf8_escape.sub(escape_entities, text.decode('utf-8')), 'utf-8') | ||||
@@ -95,7 +95,7 @@ def namespace_map_update(namespaces): | |||||
elementtree.ElementTree._namespace_map.update(namespaces) | elementtree.ElementTree._namespace_map.update(namespaces) | ||||
class ElementInterface(elementtree.ElementTree._ElementInterface): | |||||
class ElementInterface(elementtree.ElementTree.Element): | |||||
""" helper class """ | """ helper class """ | ||||
def indent(elem, level=0): | def indent(elem, level=0): | ||||
@@ -128,8 +128,8 @@ def parse_xml(data, encoding="utf-8"): | |||||
data = data.encode(encoding) | data = data.encode(encoding) | ||||
except UnicodeDecodeError: | except UnicodeDecodeError: | ||||
pass | pass | ||||
except Exception, error: | |||||
print "parse_xml encode Exception", error | |||||
except Exception as error: | |||||
print("parse_xml encode Exception", error) | |||||
import traceback | import traceback | ||||
traceback.print_exc() | traceback.print_exc() | ||||
@@ -137,9 +137,9 @@ def parse_xml(data, encoding="utf-8"): | |||||
data = data.replace('\x00','') | data = data.replace('\x00','') | ||||
try: | try: | ||||
p.feed(data) | p.feed(data) | ||||
except Exception, error: | |||||
print "parse_xml feed Exception", error | |||||
print error, repr(data) | |||||
except Exception as error: | |||||
print("parse_xml feed Exception", error) | |||||
print(error, repr(data)) | |||||
return None | return None | ||||
else: | else: | ||||
return ET.ElementTree(p.close()) | return ET.ElementTree(p.close()) |
@@ -54,7 +54,7 @@ class ItemObject(FSObject, Item): | |||||
pt = getElementText(rtpel[0]) | pt = getElementText(rtpel[0]) | ||||
pi = 'rtsp-rtp-udp:*:%s:*' % pt | pi = 'rtsp-rtp-udp:*:%s:*' % pt | ||||
else: | else: | ||||
print 'missing mimetype or rtppayloadtype element, skipping...' | |||||
print('missing mimetype or rtppayloadtype element, skipping...') | |||||
continue | continue | ||||
url = getElementText(i.getElementsByTagName('url')[0]) | url = getElementText(i.getElementsByTagName('url')[0]) | ||||
@@ -1,12 +0,0 @@ | |||||
#!/usr/bin/env python | |||||
# Copyright 2008 John-Mark Gurney <jmg@funkthat.com> | |||||
__version__ = '$Change$' | |||||
# $Id$ | |||||
import rarfile | |||||
from rarfile import * | |||||
class RarFile(rarfile.RarFile): | |||||
def readiter(self, name, blksize=16384): | |||||
yield self.read(name) |
@@ -1,37 +0,0 @@ | |||||
#!/usr/bin/env python | |||||
# Copyright 2006 John-Mark Gurney <jmg@funkthat.com> | |||||
__version__ = '$Change$' | |||||
# $Id$ | |||||
import tarfile | |||||
from tarfile import * | |||||
TAR_PLAIN = tarfile.TAR_PLAIN | |||||
TAR_GZIPPED = tarfile.TAR_GZIPPED | |||||
TAR_BZ2 = 'bz2' | |||||
__all__ = tarfile.__all__ | |||||
class TarFileCompat(tarfile.TarFileCompat): | |||||
def __init__(self, file, mode="r", compression=TAR_PLAIN): | |||||
if compression != TAR_BZ2: | |||||
tarfile.TarFileCompat.__init__(self, file, mode, compression) | |||||
return | |||||
self.tarfile = TarFile.bz2open(file, mode) | |||||
if mode[0:1] == "r": | |||||
members = self.tarfile.getmembers() | |||||
for i in xrange(len(members)): | |||||
m = members[i] | |||||
m.filename = m.name | |||||
m.file_size = m.size | |||||
m.date_time = time.gmtime(m.mtime)[:6] | |||||
def readiter(self, name, blksize=16384): | |||||
f = self.tarfile.extractfile(self.tarfile.getmember(name)) | |||||
while True: | |||||
data = f.read(blksize) | |||||
if data == '': | |||||
break | |||||
yield data |
@@ -1,25 +0,0 @@ | |||||
#!/usr/bin/env python | |||||
# Copyright 2006 John-Mark Gurney <jmg@funkthat.com> | |||||
__version__ = '$Change$' | |||||
# $Id$ | |||||
import binascii | |||||
import os | |||||
import twisted.python.zipstream | |||||
import zipfile | |||||
from zipfile import * | |||||
__all__ = zipfile.__all__ | |||||
class ZipFile(twisted.python.zipstream.ChunkingZipFile): | |||||
def readiter(self, name, blksize=16384): | |||||
"""Return file bytes (as a string) for name.""" | |||||
#print 'ri:', `self`, `name` | |||||
fp = self.readfile(name) | |||||
while True: | |||||
d = fp.read(blksize) | |||||
if not d: | |||||
break | |||||
yield d |
@@ -60,10 +60,10 @@ try: | |||||
except ImportError: | except ImportError: | ||||
def foo(*args): | def foo(*args): | ||||
raise NotImplementedError, 'Failed to import ctypes' | |||||
raise NotImplementedError('Failed to import ctypes') | |||||
decode_title = decode_description = foo | decode_title = decode_description = foo | ||||
except OSError: | except OSError: | ||||
def foo(*args): | def foo(*args): | ||||
raise NotImplementedError, 'Failed to find library huffdecode' | |||||
raise NotImplementedError('Failed to find library huffdecode') | |||||
decode_title = decode_description = foo | decode_title = decode_description = foo |
@@ -30,18 +30,18 @@ | |||||
import atschuff | import atschuff | ||||
import itertools | import itertools | ||||
import os | import os | ||||
import sets | |||||
import struct | import struct | ||||
import time | import time | ||||
import traceback | import traceback | ||||
from functools import reduce | |||||
TSSYNC = '\x47' | TSSYNC = '\x47' | ||||
TSPKTLEN = 188 | TSPKTLEN = 188 | ||||
READBLK = 1024 | READBLK = 1024 | ||||
def attribreprlist(obj, attrs): | def attribreprlist(obj, attrs): | ||||
return map(lambda x, y = obj: '%s: %s' % (x, repr(getattr(y, x))), | |||||
itertools.ifilter(lambda x, y = obj: hasattr(y, x), attrs)) | |||||
return list(map(lambda x, y = obj: '%s: %s' % (x, repr(getattr(y, x))), | |||||
list(filter(lambda x, y = obj: hasattr(y, x), attrs)))) | |||||
class UnReadSTR: | class UnReadSTR: | ||||
def __init__(self, s): | def __init__(self, s): | ||||
@@ -51,7 +51,7 @@ class UnReadSTR: | |||||
self._buf = [] | self._buf = [] | ||||
self._buftot = 0 | self._buftot = 0 | ||||
def __nonzero__(self): | |||||
def __bool__(self): | |||||
return self._buftot or self.pos < len(self.s) | return self._buftot or self.pos < len(self.s) | ||||
def tell(self): | def tell(self): | ||||
@@ -122,7 +122,7 @@ def DVDAudioFilter(itr, subchan): | |||||
for i in itr: | for i in itr: | ||||
j = Pack(UnReadSTR(i)) | j = Pack(UnReadSTR(i)) | ||||
if filter(checksubchan, j): | |||||
if list(filter(checksubchan, j)): | |||||
yield i | yield i | ||||
def findcodes(buf): | def findcodes(buf): | ||||
@@ -138,53 +138,54 @@ def findcodes(buf): | |||||
i = j + 4 | i = j + 4 | ||||
return ret | return ret | ||||
class UnRead(file): | |||||
def __init__(self, *args, **kwargs): | |||||
super(UnRead, self).__init__(*args, **kwargs) | |||||
self._buf = [] | |||||
self._buftot = 0 | |||||
def unread(self, buf): | |||||
self._buf.append(buf) | |||||
self._buftot += len(buf) | |||||
def peek(self, size): | |||||
r = self.read(size) | |||||
self.unread(r) | |||||
return r | |||||
def read(self, size = None): | |||||
if size is None and self._buf: | |||||
ret = self._buf.pop() | |||||
self._buftot -= len(ret) | |||||
elif size is None: | |||||
ret = super(UnRead, self).read() | |||||
else: | |||||
ret = [] | |||||
while size and self._buftot: | |||||
ret.append(self._buf[-1][:size]) | |||||
l = len(ret[-1]) | |||||
if size > l: | |||||
assert len(self._buf[-1]) == l | |||||
self._buf.pop() | |||||
else: | |||||
self._buf[-1] = self._buf[-1][size:] | |||||
self._buftot -= l | |||||
size -= l | |||||
if False: | |||||
class UnRead(file): | |||||
def __init__(self, *args, **kwargs): | |||||
super(UnRead, self).__init__(*args, **kwargs) | |||||
self._buf = [] | |||||
self._buftot = 0 | |||||
def unread(self, buf): | |||||
self._buf.append(buf) | |||||
self._buftot += len(buf) | |||||
def peek(self, size): | |||||
r = self.read(size) | |||||
self.unread(r) | |||||
return r | |||||
def read(self, size = None): | |||||
if size is None and self._buf: | |||||
ret = self._buf.pop() | |||||
self._buftot -= len(ret) | |||||
elif size is None: | |||||
ret = super(UnRead, self).read() | |||||
else: | |||||
ret = [] | |||||
while size and self._buftot: | |||||
ret.append(self._buf[-1][:size]) | |||||
l = len(ret[-1]) | |||||
if size > l: | |||||
assert len(self._buf[-1]) == l | |||||
self._buf.pop() | |||||
else: | |||||
self._buf[-1] = self._buf[-1][size:] | |||||
self._buftot -= l | |||||
size -= l | |||||
if size: | |||||
ret.append(super(UnRead, self).read(size)) | |||||
if size: | |||||
ret.append(super(UnRead, self).read(size)) | |||||
ret = ''.join(ret) | |||||
ret = ''.join(ret) | |||||
return ret | |||||
return ret | |||||
def read_timestamp(buf): | def read_timestamp(buf): | ||||
assert len(buf) == 5 | assert len(buf) == 5 | ||||
assert (ord(buf[0]) & 0x1) == 1 | assert (ord(buf[0]) & 0x1) == 1 | ||||
assert (ord(buf[2]) & 0x1) == 1 | assert (ord(buf[2]) & 0x1) == 1 | ||||
assert (ord(buf[4]) & 0x1) == 1 | assert (ord(buf[4]) & 0x1) == 1 | ||||
return (long(ord(buf[0]) & 0xe) << 29) | (ord(buf[1]) << 21) | \ | |||||
return (int(ord(buf[0]) & 0xe) << 29) | (ord(buf[1]) << 21) | \ | |||||
((ord(buf[2]) & 0xfe) << 14) | (ord(buf[3]) << 7) | \ | ((ord(buf[2]) & 0xfe) << 14) | (ord(buf[3]) << 7) | \ | ||||
((ord(buf[4]) & 0xfe) >> 1) | ((ord(buf[4]) & 0xfe) >> 1) | ||||
@@ -193,7 +194,7 @@ def read_escr(buf): | |||||
assert (ord(buf[0]) & 0x4) == 0x4 and (ord(buf[2]) & 0x4) == 0x4 | assert (ord(buf[0]) & 0x4) == 0x4 and (ord(buf[2]) & 0x4) == 0x4 | ||||
assert (ord(buf[4]) & 0x4) == 0x4 and (ord(buf[5]) & 0x1) == 0x1 | assert (ord(buf[4]) & 0x4) == 0x4 and (ord(buf[5]) & 0x1) == 0x1 | ||||
base = (long(ord(buf[0]) & 0x38) << 27) | ((ord(buf[0]) & 0x3) << 28) |\ | |||||
base = (int(ord(buf[0]) & 0x38) << 27) | ((ord(buf[0]) & 0x3) << 28) |\ | |||||
(ord(buf[1]) << 20) | ((ord(buf[2]) & 0xf8) << 15) | \ | (ord(buf[1]) << 20) | ((ord(buf[2]) & 0xf8) << 15) | \ | ||||
((ord(buf[2]) & 0x3) << 13) | (ord(buf[3]) << 5) | \ | ((ord(buf[2]) & 0x3) << 13) | (ord(buf[3]) << 5) | \ | ||||
((ord(buf[4]) & 0xf8) >> 3) | ((ord(buf[4]) & 0xf8) >> 3) | ||||
@@ -240,7 +241,7 @@ class PES: | |||||
else: | else: | ||||
self.length += 6 | self.length += 6 | ||||
if len(buf) < self.length: | if len(buf) < self.length: | ||||
raise IndexError, 'not enough data' | |||||
raise IndexError('not enough data') | |||||
if self.stream_id == self.PADDING_ID: | if self.stream_id == self.PADDING_ID: | ||||
# Validate padding? | # Validate padding? | ||||
@@ -280,8 +281,7 @@ class PES: | |||||
self.DTS = read_timestamp(buf[i:i + 5]) | self.DTS = read_timestamp(buf[i:i + 5]) | ||||
i += 5 | i += 5 | ||||
elif ptsdts_flag == 0x1: | elif ptsdts_flag == 0x1: | ||||
raise ValueError, \ | |||||
"ptsdts flag forbidden: %d" % ptsdts_flag | |||||
raise ValueError("ptsdts flag forbidden: %d" % ptsdts_flag) | |||||
if escr_flag: | if escr_flag: | ||||
self.ESCR = read_escr(buf[i:i + 6]) | self.ESCR = read_escr(buf[i:i + 6]) | ||||
i += 6 | i += 6 | ||||
@@ -373,7 +373,7 @@ class Pack(list): | |||||
assert (ord(d[4]) & 0xc0) == 0x40 | assert (ord(d[4]) & 0xc0) == 0x40 | ||||
self.SCR = read_escr(d[4:10]) | self.SCR = read_escr(d[4:10]) | ||||
assert ord(d[12]) & 0x3 == 0x3 | assert ord(d[12]) & 0x3 == 0x3 | ||||
m = map(ord, d[10:13]) | |||||
m = list(map(ord, d[10:13])) | |||||
self.muxr = (m[0] << 14) | (m[1] << 6) | (m[2] >> 2) | self.muxr = (m[0] << 14) | (m[1] << 6) | (m[2] >> 2) | ||||
self.stuff_len = ord(d[13]) & 0x7 | self.stuff_len = ord(d[13]) & 0x7 | ||||
f.read(self.stuff_len) | f.read(self.stuff_len) | ||||
@@ -384,7 +384,7 @@ class Pack(list): | |||||
f.read(6) | f.read(6) | ||||
hlen = (ord(d[4]) << 8) | ord(d[5]) | hlen = (ord(d[4]) << 8) | ord(d[5]) | ||||
header = f.read(hlen) | header = f.read(hlen) | ||||
oh = map(ord, header) | |||||
oh = list(map(ord, header)) | |||||
assert (oh[0] & 0x80) == 0x80 and \ | assert (oh[0] & 0x80) == 0x80 and \ | ||||
(oh[2] & 0x1) == 0x1 | (oh[2] & 0x1) == 0x1 | ||||
self.rate_bound = ((oh[0] & 0x7f) << 15) | \ | self.rate_bound = ((oh[0] & 0x7f) << 15) | \ | ||||
@@ -401,7 +401,7 @@ class Pack(list): | |||||
d = f.peek(1) | d = f.peek(1) | ||||
self.streams = {} | self.streams = {} | ||||
while ord(d) & 0x80: | while ord(d) & 0x80: | ||||
d = map(ord, f.read(3)) | |||||
d = list(map(ord, f.read(3))) | |||||
assert (d[1] & 0xc0) == 0xc0 | assert (d[1] & 0xc0) == 0xc0 | ||||
scaleflag = bool(d[1] & 0x20) | scaleflag = bool(d[1] & 0x20) | ||||
self.streams[d[0]] = (((d[1] & 0x1f) << | self.streams[d[0]] = (((d[1] & 0x1f) << | ||||
@@ -437,8 +437,8 @@ class Pack(list): | |||||
def __str__(self): | def __str__(self): | ||||
buf = [] | buf = [] | ||||
buf.append('\x00\x00\x01\xba') | buf.append('\x00\x00\x01\xba') | ||||
clock = (1l << 46) | (((self.SCR[0] >> 30) & 0x7) << 43) | \ | |||||
(1l << 42) | (((self.SCR[0] >> 15) & 0x7ffff) << 27) | \ | |||||
clock = (1 << 46) | (((self.SCR[0] >> 30) & 0x7) << 43) | \ | |||||
(1 << 42) | (((self.SCR[0] >> 15) & 0x7ffff) << 27) | \ | |||||
(1 << 26) | ((self.SCR[0] & 0x7fff) << 11) | (1 << 10) | \ | (1 << 26) | ((self.SCR[0] & 0x7fff) << 11) | (1 << 10) | \ | ||||
((self.SCR[1] << 1) & 0x3fe) | 0x1 | ((self.SCR[1] << 1) & 0x3fe) | 0x1 | ||||
for i in range(6): | for i in range(6): | ||||
@@ -449,7 +449,7 @@ class Pack(list): | |||||
buf.append(chr(((muxr << 2) & 0xfc) | 0x3)) | buf.append(chr(((muxr << 2) & 0xfc) | 0x3)) | ||||
buf.append(chr(0xf8 | (self.stuff_len & 7))) | buf.append(chr(0xf8 | (self.stuff_len & 7))) | ||||
buf.append('\xff' * self.stuff_len) | buf.append('\xff' * self.stuff_len) | ||||
buf.extend(map(str, self)) | |||||
buf.extend(list(map(str, self))) | |||||
return ''.join(buf) | return ''.join(buf) | ||||
# These are strings due to the floating point numbers | # These are strings due to the floating point numbers | ||||
@@ -491,7 +491,7 @@ class ISO639LangDescriptor(list): | |||||
assert len(b) % 4 == 0 | assert len(b) % 4 == 0 | ||||
for i in range(len(b) / 4): | for i in range(len(b) / 4): | ||||
lang = unicode(b[i * 4:i * 4 + 3], 'iso8859-1') | |||||
lang = str(b[i * 4:i * 4 + 3], 'iso8859-1') | |||||
atype = self.atypedict[ord(b[i * 4 + 3])] | atype = self.atypedict[ord(b[i * 4 + 3])] | ||||
self.append((lang, atype)) | self.append((lang, atype)) | ||||
@@ -601,9 +601,7 @@ class AC3Descriptor: | |||||
else: | else: | ||||
assert NotImplementedError, \ | assert NotImplementedError, \ | ||||
'the following code is untested' | 'the following code is untested' | ||||
self.text = ''.join(map(lambda x: | |||||
unichr(ord(x[0]) * 256 + ord(x[1])), | |||||
[txt[i:i+2] for i in range(0, len(txt), 2)])) | |||||
self.text = ''.join([chr(ord(x[0]) * 256 + ord(x[1])) for x in [txt[i:i+2] for i in range(0, len(txt), 2)]]) | |||||
def __repr__(self): | def __repr__(self): | ||||
v = ['sample_rate', 'bsid', 'br_exact', 'bitrate', | v = ['sample_rate', 'bsid', 'br_exact', 'bitrate', | ||||
@@ -619,11 +617,11 @@ class ContentAdvisory(list): | |||||
cnt = ord(data[0]) & 0x3f | cnt = ord(data[0]) & 0x3f | ||||
i = 1 | i = 1 | ||||
for j in xrange(cnt): | |||||
for j in range(cnt): | |||||
region, dim = struct.unpack('>BB', data[i: i + 2]) | region, dim = struct.unpack('>BB', data[i: i + 2]) | ||||
i += 2 | i += 2 | ||||
d = {} | d = {} | ||||
for j in xrange(dim): | |||||
for j in range(dim): | |||||
d[ord(data[i])] = ord(data[i + 1]) & 0xf | d[ord(data[i])] = ord(data[i + 1]) & 0xf | ||||
i += 2 | i += 2 | ||||
desclen = ord(data[i]) | desclen = ord(data[i]) | ||||
@@ -669,13 +667,13 @@ class MultiStringStruct(dict): | |||||
return data.decode('UTF-16-BE') | return data.decode('UTF-16-BE') | ||||
elif mode == 0x3e: | elif mode == 0x3e: | ||||
# http://www.unicode.org/reports/tr6/ | # http://www.unicode.org/reports/tr6/ | ||||
raise NotImplementedError, 'Unicode Technical Report #6, A Standard Compression Scheme for Unicode' | |||||
raise NotImplementedError('Unicode Technical Report #6, A Standard Compression Scheme for Unicode') | |||||
# There are additional limitations | # There are additional limitations | ||||
assert mode < 0x34, 'Invalid mode: %#x' % mode | assert mode < 0x34, 'Invalid mode: %#x' % mode | ||||
return ''.join(map(lambda x, y = mode * 256: | return ''.join(map(lambda x, y = mode * 256: | ||||
unichr(ord(x) + y), data)) | |||||
chr(ord(x) + y), data)) | |||||
assert (comp == 1 or comp == 2) and mode == 0xff, \ | assert (comp == 1 or comp == 2) and mode == 0xff, \ | ||||
'Invalid comp: %#x, mode: %#x' % (comp, mode) | 'Invalid comp: %#x, mode: %#x' % (comp, mode) | ||||
@@ -707,7 +705,7 @@ class ComponentNameDescriptor(MultiStringStruct): | |||||
MultiStringStruct.__repr__(self) | MultiStringStruct.__repr__(self) | ||||
def FindMe(data): | def FindMe(data): | ||||
raise RuntimeError, 'found me' | |||||
raise RuntimeError('found me') | |||||
Descriptors = { | Descriptors = { | ||||
# 0-63 Are listed in ISO 13818-1 Table 2-40 | # 0-63 Are listed in ISO 13818-1 Table 2-40 | ||||
@@ -738,82 +736,82 @@ PIDs = { | |||||
} | } | ||||
def psip_calc_crc32(data, verbose = False, table = ( | def psip_calc_crc32(data, verbose = False, table = ( | ||||
0x00000000l, 0x04c11db7l, 0x09823b6el, 0x0d4326d9l, | |||||
0x130476dcl, 0x17c56b6bl, 0x1a864db2l, 0x1e475005l, | |||||
0x2608edb8l, 0x22c9f00fl, 0x2f8ad6d6l, 0x2b4bcb61l, | |||||
0x350c9b64l, 0x31cd86d3l, 0x3c8ea00al, 0x384fbdbdl, | |||||
0x4c11db70l, 0x48d0c6c7l, 0x4593e01el, 0x4152fda9l, | |||||
0x5f15adacl, 0x5bd4b01bl, 0x569796c2l, 0x52568b75l, | |||||
0x6a1936c8l, 0x6ed82b7fl, 0x639b0da6l, 0x675a1011l, | |||||
0x791d4014l, 0x7ddc5da3l, 0x709f7b7al, 0x745e66cdl, | |||||
0x9823b6e0l, 0x9ce2ab57l, 0x91a18d8el, 0x95609039l, | |||||
0x8b27c03cl, 0x8fe6dd8bl, 0x82a5fb52l, 0x8664e6e5l, | |||||
0xbe2b5b58l, 0xbaea46efl, 0xb7a96036l, 0xb3687d81l, | |||||
0xad2f2d84l, 0xa9ee3033l, 0xa4ad16eal, 0xa06c0b5dl, | |||||
0xd4326d90l, 0xd0f37027l, 0xddb056fel, 0xd9714b49l, | |||||
0xc7361b4cl, 0xc3f706fbl, 0xceb42022l, 0xca753d95l, | |||||
0xf23a8028l, 0xf6fb9d9fl, 0xfbb8bb46l, 0xff79a6f1l, | |||||
0xe13ef6f4l, 0xe5ffeb43l, 0xe8bccd9al, 0xec7dd02dl, | |||||
0x34867077l, 0x30476dc0l, 0x3d044b19l, 0x39c556ael, | |||||
0x278206abl, 0x23431b1cl, 0x2e003dc5l, 0x2ac12072l, | |||||
0x128e9dcfl, 0x164f8078l, 0x1b0ca6a1l, 0x1fcdbb16l, | |||||
0x018aeb13l, 0x054bf6a4l, 0x0808d07dl, 0x0cc9cdcal, | |||||
0x7897ab07l, 0x7c56b6b0l, 0x71159069l, 0x75d48ddel, | |||||
0x6b93dddbl, 0x6f52c06cl, 0x6211e6b5l, 0x66d0fb02l, | |||||
0x5e9f46bfl, 0x5a5e5b08l, 0x571d7dd1l, 0x53dc6066l, | |||||
0x4d9b3063l, 0x495a2dd4l, 0x44190b0dl, 0x40d816bal, | |||||
0xaca5c697l, 0xa864db20l, 0xa527fdf9l, 0xa1e6e04el, | |||||
0xbfa1b04bl, 0xbb60adfcl, 0xb6238b25l, 0xb2e29692l, | |||||
0x8aad2b2fl, 0x8e6c3698l, 0x832f1041l, 0x87ee0df6l, | |||||
0x99a95df3l, 0x9d684044l, 0x902b669dl, 0x94ea7b2al, | |||||
0xe0b41de7l, 0xe4750050l, 0xe9362689l, 0xedf73b3el, | |||||
0xf3b06b3bl, 0xf771768cl, 0xfa325055l, 0xfef34de2l, | |||||
0xc6bcf05fl, 0xc27dede8l, 0xcf3ecb31l, 0xcbffd686l, | |||||
0xd5b88683l, 0xd1799b34l, 0xdc3abdedl, 0xd8fba05al, | |||||
0x690ce0eel, 0x6dcdfd59l, 0x608edb80l, 0x644fc637l, | |||||
0x7a089632l, 0x7ec98b85l, 0x738aad5cl, 0x774bb0ebl, | |||||
0x4f040d56l, 0x4bc510e1l, 0x46863638l, 0x42472b8fl, | |||||
0x5c007b8al, 0x58c1663dl, 0x558240e4l, 0x51435d53l, | |||||
0x251d3b9el, 0x21dc2629l, 0x2c9f00f0l, 0x285e1d47l, | |||||
0x36194d42l, 0x32d850f5l, 0x3f9b762cl, 0x3b5a6b9bl, | |||||
0x0315d626l, 0x07d4cb91l, 0x0a97ed48l, 0x0e56f0ffl, | |||||
0x1011a0fal, 0x14d0bd4dl, 0x19939b94l, 0x1d528623l, | |||||
0xf12f560el, 0xf5ee4bb9l, 0xf8ad6d60l, 0xfc6c70d7l, | |||||
0xe22b20d2l, 0xe6ea3d65l, 0xeba91bbcl, 0xef68060bl, | |||||
0xd727bbb6l, 0xd3e6a601l, 0xdea580d8l, 0xda649d6fl, | |||||
0xc423cd6al, 0xc0e2d0ddl, 0xcda1f604l, 0xc960ebb3l, | |||||
0xbd3e8d7el, 0xb9ff90c9l, 0xb4bcb610l, 0xb07daba7l, | |||||
0xae3afba2l, 0xaafbe615l, 0xa7b8c0ccl, 0xa379dd7bl, | |||||
0x9b3660c6l, 0x9ff77d71l, 0x92b45ba8l, 0x9675461fl, | |||||
0x8832161al, 0x8cf30badl, 0x81b02d74l, 0x857130c3l, | |||||
0x5d8a9099l, 0x594b8d2el, 0x5408abf7l, 0x50c9b640l, | |||||
0x4e8ee645l, 0x4a4ffbf2l, 0x470cdd2bl, 0x43cdc09cl, | |||||
0x7b827d21l, 0x7f436096l, 0x7200464fl, 0x76c15bf8l, | |||||
0x68860bfdl, 0x6c47164al, 0x61043093l, 0x65c52d24l, | |||||
0x119b4be9l, 0x155a565el, 0x18197087l, 0x1cd86d30l, | |||||
0x029f3d35l, 0x065e2082l, 0x0b1d065bl, 0x0fdc1becl, | |||||
0x3793a651l, 0x3352bbe6l, 0x3e119d3fl, 0x3ad08088l, | |||||
0x2497d08dl, 0x2056cd3al, 0x2d15ebe3l, 0x29d4f654l, | |||||
0xc5a92679l, 0xc1683bcel, 0xcc2b1d17l, 0xc8ea00a0l, | |||||
0xd6ad50a5l, 0xd26c4d12l, 0xdf2f6bcbl, 0xdbee767cl, | |||||
0xe3a1cbc1l, 0xe760d676l, 0xea23f0afl, 0xeee2ed18l, | |||||
0xf0a5bd1dl, 0xf464a0aal, 0xf9278673l, 0xfde69bc4l, | |||||
0x89b8fd09l, 0x8d79e0bel, 0x803ac667l, 0x84fbdbd0l, | |||||
0x9abc8bd5l, 0x9e7d9662l, 0x933eb0bbl, 0x97ffad0cl, | |||||
0xafb010b1l, 0xab710d06l, 0xa6322bdfl, 0xa2f33668l, | |||||
0xbcb4666dl, 0xb8757bdal, 0xb5365d03l, 0xb1f740b4l | |||||
0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, | |||||
0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, | |||||
0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, | |||||
0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, | |||||
0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, | |||||
0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, | |||||
0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, | |||||
0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd, | |||||
0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, | |||||
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, | |||||
0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, | |||||
0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, | |||||
0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, | |||||
0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, | |||||
0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, | |||||
0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, | |||||
0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, | |||||
0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, | |||||
0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, | |||||
0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, | |||||
0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, | |||||
0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, | |||||
0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, | |||||
0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, | |||||
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, | |||||
0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692, | |||||
0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, | |||||
0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, | |||||
0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, | |||||
0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, | |||||
0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, | |||||
0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a, | |||||
0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, | |||||
0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, | |||||
0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, | |||||
0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, | |||||
0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, | |||||
0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b, | |||||
0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, | |||||
0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, | |||||
0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, | |||||
0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, | |||||
0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, | |||||
0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, | |||||
0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, | |||||
0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, | |||||
0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, | |||||
0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, | |||||
0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, | |||||
0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, | |||||
0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, | |||||
0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, | |||||
0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, | |||||
0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, | |||||
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, | |||||
0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, | |||||
0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, | |||||
0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, | |||||
0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, | |||||
0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, | |||||
0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, | |||||
0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c, | |||||
0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, | |||||
0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 | |||||
)): | )): | ||||
'''Validate a PSIP CRC. Include the CRC in the data. The return value will be the valid data, or an exception will be raised if invalid.''' | '''Validate a PSIP CRC. Include the CRC in the data. The return value will be the valid data, or an exception will be raised if invalid.''' | ||||
if verbose: | if verbose: | ||||
i_crc = 0xffffffffl | |||||
i_crc = 0xffffffff | |||||
for i in data: | for i in data: | ||||
i_crc = ((i_crc << 8) & 0xffffffffl) ^ table[(i_crc >> | |||||
i_crc = ((i_crc << 8) & 0xffffffff) ^ table[(i_crc >> | |||||
24) ^ ord(i)] | 24) ^ ord(i)] | ||||
print hex(i_crc) | |||||
print(hex(i_crc)) | |||||
else: | else: | ||||
i_crc = reduce(lambda x, y: ((x << 8) & 0xffffffffl) ^ | |||||
table[(x >> 24) ^ ord(y)], data, 0xffffffffl) | |||||
i_crc = reduce(lambda x, y: ((x << 8) & 0xffffffff) ^ | |||||
table[(x >> 24) ^ ord(y)], data, 0xffffffff) | |||||
return i_crc | return i_crc | ||||
def psip_crc32(data): | def psip_crc32(data): | ||||
@@ -824,7 +822,7 @@ def getdescriptors(tb): | |||||
i = 0 | i = 0 | ||||
while i < len(tb): | while i < len(tb): | ||||
t = ord(tb[i]) | t = ord(tb[i]) | ||||
if d.has_key(t): | |||||
if t in d: | |||||
l = ord(tb[i + 1]) | l = ord(tb[i + 1]) | ||||
data = tb[i + 2: i + 2 + l] | data = tb[i + 2: i + 2 + l] | ||||
#print repr(d[t]), t, repr(data) | #print repr(d[t]), t, repr(data) | ||||
@@ -918,9 +916,8 @@ and the key is the table number.''' | |||||
# XXX I may need to include the skipped part | # XXX I may need to include the skipped part | ||||
# above in the crc calculations. | # above in the crc calculations. | ||||
if not psip_crc32(payload[:self.sect_len]): | if not psip_crc32(payload[:self.sect_len]): | ||||
raise ValueError, \ | |||||
'CRC check failed: %s' % \ | |||||
`payload[:self.sect_len]` | |||||
raise ValueError('CRC check failed: %s' % \ | |||||
repr(payload[:self.sect_len])) | |||||
self.extension = (ord(payload[3]) << 8) | \ | self.extension = (ord(payload[3]) << 8) | \ | ||||
ord(payload[4]) | ord(payload[4]) | ||||
self.version = (ord(payload[5]) & 0x3e) >> 1 | self.version = (ord(payload[5]) & 0x3e) >> 1 | ||||
@@ -1007,7 +1004,7 @@ class PAT(PSIPObject, dict): | |||||
self.clear() | self.clear() | ||||
def has_pid(self, pid): | def has_pid(self, pid): | ||||
return self.pid_dict.has_key(pid) | |||||
return pid in self.pid_dict | |||||
def get_prog(self, pid): | def get_prog(self, pid): | ||||
return self.pid_dict[pid] | return self.pid_dict[pid] | ||||
@@ -1036,8 +1033,8 @@ def getaudiovideopids(pmt, lang = None): | |||||
vpids.append(cpid) | vpids.append(cpid) | ||||
elif i[0] == 129: | elif i[0] == 129: | ||||
apids.append(cpid) | apids.append(cpid) | ||||
elif j.has_key(5) and i[0] != 5: | |||||
assert 'AC-3' in map(lambda x: x[:4], j[5]), (i, j) | |||||
elif 5 in j and i[0] != 5: | |||||
assert 'AC-3' in [x[:4] for x in j[5]], (i, j) | |||||
if lang is None or lang == j[10][0][0]: | if lang is None or lang == j[10][0][0]: | ||||
apids.append(cpid) | apids.append(cpid) | ||||
else: | else: | ||||
@@ -1067,7 +1064,7 @@ class PMT(PSIPObject, dict): | |||||
self.clear() | self.clear() | ||||
del self.es[:] | del self.es[:] | ||||
def __nonzero__(self): | |||||
def __bool__(self): | |||||
return len(self) or bool(self.es) | return len(self) or bool(self.es) | ||||
def parse_table(self, psip): | def parse_table(self, psip): | ||||
@@ -1092,7 +1089,7 @@ class PMT(PSIPObject, dict): | |||||
def repr_part(self): | def repr_part(self): | ||||
return [ 'PCRpid: %d' % self.pcrpid, dict.__repr__(self), | return [ 'PCRpid: %d' % self.pcrpid, dict.__repr__(self), | ||||
'ES: %s' % `self.es` ] | |||||
'ES: %s' % repr(self.es) ] | |||||
def channelmajorminorsort(x, y): | def channelmajorminorsort(x, y): | ||||
if x['major'] != y['major']: | if x['major'] != y['major']: | ||||
@@ -1131,7 +1128,7 @@ class STT(PSIPObject): | |||||
self.ds_hour = ds_hour | self.ds_hour = ds_hour | ||||
def repr_part(self, v=('ds_status', 'ds_day_of_month', 'ds_hour', )): | def repr_part(self, v=('ds_status', 'ds_day_of_month', 'ds_hour', )): | ||||
return [ `time.ctime(self.utc)`, ] + attribreprlist(self, v) | |||||
return [ repr(time.ctime(self.utc)), ] + attribreprlist(self, v) | |||||
class MGT(list): | class MGT(list): | ||||
def __init__(self, pidtable): | def __init__(self, pidtable): | ||||
@@ -1149,7 +1146,7 @@ class MGT(list): | |||||
ntables = struct.unpack('>H', psip.table[1:3])[0] | ntables = struct.unpack('>H', psip.table[1:3])[0] | ||||
i = 3 | i = 3 | ||||
for foo in xrange(ntables): | |||||
for foo in range(ntables): | |||||
type, pid, version, nbytes, desclen = \ | type, pid, version, nbytes, desclen = \ | ||||
struct.unpack('>HHBIH', psip.table[i:i + 11]) | struct.unpack('>HHBIH', psip.table[i:i + 11]) | ||||
i += 11 | i += 11 | ||||
@@ -1162,7 +1159,7 @@ class MGT(list): | |||||
# start watch | # start watch | ||||
if type >= 0x100 and type <= 0x17f: | if type >= 0x100 and type <= 0x17f: | ||||
if self.pidtable.has_key(pid): | |||||
if pid in self.pidtable: | |||||
# XXX - check that it's in watch | # XXX - check that it's in watch | ||||
pass | pass | ||||
else: | else: | ||||
@@ -1171,7 +1168,7 @@ class MGT(list): | |||||
self.pidtable[pid] = TSPSIPHandler({ | self.pidtable[pid] = TSPSIPHandler({ | ||||
0xcb: EIT() }) | 0xcb: EIT() }) | ||||
elif type >= 0x200 and type <= 0x27f: | elif type >= 0x200 and type <= 0x27f: | ||||
if self.pidtable.has_key(pid): | |||||
if pid in self.pidtable: | |||||
# XXX - check that it's in watch | # XXX - check that it's in watch | ||||
pass | pass | ||||
else: | else: | ||||
@@ -1189,7 +1186,7 @@ class MGT(list): | |||||
#print `self` | #print `self` | ||||
def __repr__(self): | def __repr__(self): | ||||
return '<MGT: descriptors: %s, loop: %s>' % (`self.desc`, | |||||
return '<MGT: descriptors: %s, loop: %s>' % (repr(self.desc), | |||||
list.__repr__(self)) | list.__repr__(self)) | ||||
class EIT(list): | class EIT(list): | ||||
@@ -1206,7 +1203,7 @@ class EIT(list): | |||||
ntables = ord(psip.table[1]) | ntables = ord(psip.table[1]) | ||||
i = 2 | i = 2 | ||||
for foo in xrange(ntables): | |||||
for foo in range(ntables): | |||||
event_id, start_time, lochilen, lolength, titlelen = \ | event_id, start_time, lochilen, lolength, titlelen = \ | ||||
struct.unpack('>HIBHB', psip.table[i:i + 10]) | struct.unpack('>HIBHB', psip.table[i:i + 10]) | ||||
i += 10 | i += 10 | ||||
@@ -1249,9 +1246,9 @@ class TVCT(PSIPObject, dict): | |||||
chancnt = ord(tb[i]) | chancnt = ord(tb[i]) | ||||
i += 1 | i += 1 | ||||
for foo in range(chancnt): | for foo in range(chancnt): | ||||
shrtnm = ''.join(map(lambda x: unichr((ord(x[0]) << | |||||
8) | ord(x[1])), [tb[i + x * 2:i + (x + 1) * 2] for | |||||
x in range(7)])).rstrip(unichr(0)) | |||||
shrtnm = ''.join([chr((ord(x[0]) << | |||||
8) | ord(x[1])) for x in [tb[i + x * 2:i + (x + 1) * 2] for | |||||
x in range(7)]]).rstrip(chr(0)) | |||||
i += 7 * 2 | i += 7 * 2 | ||||
major = (((ord(tb[i]) << 8) | ord(tb[i + 1])) >> 2) & \ | major = (((ord(tb[i]) << 8) | ord(tb[i + 1])) >> 2) & \ | ||||
0x3ff | 0x3ff | ||||
@@ -1337,7 +1334,7 @@ class TSPESHandler: | |||||
payload = p.payload | payload = p.payload | ||||
if payload[:3] != '\x00\x00\x01': | if payload[:3] != '\x00\x00\x01': | ||||
raise ValueError, 'packet start code invalid' | |||||
raise ValueError('packet start code invalid') | |||||
self.stream_id = ord(payload[3]) | self.stream_id = ord(payload[3]) | ||||
self.pes_len = (ord(payload[4]) << 8) | ord(payload[5]) | self.pes_len = (ord(payload[4]) << 8) | ord(payload[5]) | ||||
if not self.is_video(): | if not self.is_video(): | ||||
@@ -1373,7 +1370,7 @@ class TSPESHandler: | |||||
def read_clock(buf): | def read_clock(buf): | ||||
assert len(buf) == 6 | assert len(buf) == 6 | ||||
base = (long(ord(buf[0])) << 25) | (ord(buf[1]) << 17) | \ | |||||
base = (int(ord(buf[0])) << 25) | (ord(buf[1]) << 17) | \ | |||||
(ord(buf[2]) << 9) | (ord(buf[3]) << 1) | \ | (ord(buf[2]) << 9) | (ord(buf[3]) << 1) | \ | ||||
(ord(buf[4]) >> 7) | (ord(buf[4]) >> 7) | ||||
extension = ((ord(buf[4]) & 0x1) << 8) | ord(buf[5]) | extension = ((ord(buf[4]) & 0x1) << 8) | ord(buf[5]) | ||||
@@ -1609,27 +1606,27 @@ import re | |||||
import sys | import sys | ||||
def usage(): | def usage(): | ||||
print 'Usage: %s -lmty <mpegtsstream>' % sys.argv[0] | |||||
print ' %s -k <pid> <mpegtsstream>' % sys.argv[0] | |||||
print ' %s -b [ -p ] <mpegtsstream>' % sys.argv[0] | |||||
print ' %s -c <channel> -o <output> <mpegtsstream>' % sys.argv[0] | |||||
print '' | |||||
print ' -l list channels' | |||||
print ' -m print PAT and PMT' | |||||
print ' -t print TVCT' | |||||
print '' | |||||
print ' -b bandwidth' | |||||
print ' -p sort by percentage' | |||||
print '' | |||||
print ' -c channel to capture' | |||||
print ' -o file to output channel' | |||||
print '' | |||||
print ' -k print PCR of pid stream' | |||||
print '' | |||||
print 'Options for all:' | |||||
print ' -y file offset when done' | |||||
print ' -s <start> Starting pos' | |||||
print ' -e <end> Ending pos' | |||||
print('Usage: %s -lmty <mpegtsstream>' % sys.argv[0]) | |||||
print(' %s -k <pid> <mpegtsstream>' % sys.argv[0]) | |||||
print(' %s -b [ -p ] <mpegtsstream>' % sys.argv[0]) | |||||
print(' %s -c <channel> -o <output> <mpegtsstream>' % sys.argv[0]) | |||||
print('') | |||||
print(' -l list channels') | |||||
print(' -m print PAT and PMT') | |||||
print(' -t print TVCT') | |||||
print('') | |||||
print(' -b bandwidth') | |||||
print(' -p sort by percentage') | |||||
print('') | |||||
print(' -c channel to capture') | |||||
print(' -o file to output channel') | |||||
print('') | |||||
print(' -k print PCR of pid stream') | |||||
print('') | |||||
print('Options for all:') | |||||
print(' -y file offset when done') | |||||
print(' -s <start> Starting pos') | |||||
print(' -e <end> Ending pos') | |||||
def findchannel(tvct, chan): | def findchannel(tvct, chan): | ||||
for i in tvct['channels']: | for i in tvct['channels']: | ||||
@@ -1661,18 +1658,18 @@ def GetTVCT(tsstream): | |||||
} | } | ||||
def getpmt(pid, pm = pmts, psp = psippids): | def getpmt(pid, pm = pmts, psp = psippids): | ||||
if not pm.has_key(pid): | |||||
if pid not in pm: | |||||
pm[pid] = PMT() | pm[pid] = PMT() | ||||
psp[pid] = TSPSIPHandler({ 0x02: pm[pid] }) | psp[pid] = TSPSIPHandler({ 0x02: pm[pid] }) | ||||
def needpmts(pm = pmts): | def needpmts(pm = pmts): | ||||
for i in pm.itervalues(): | |||||
for i in pm.values(): | |||||
if not i: | if not i: | ||||
return True | return True | ||||
return False | return False | ||||
for i in itertools.imap(TSPacket, tsstream): | |||||
for i in map(TSPacket, tsstream): | |||||
try: | try: | ||||
psippids[i.pid](i) | psippids[i.pid](i) | ||||
except ValueError: | except ValueError: | ||||
@@ -1689,7 +1686,7 @@ def GetTVCT(tsstream): | |||||
if needpat and pat: | if needpat and pat: | ||||
needpat = False | needpat = False | ||||
for j in pat.itervalues(): | |||||
for j in pat.values(): | |||||
getpmt(j) | getpmt(j) | ||||
if not (needtvct or needpat or needpmts()): | if not (needtvct or needpat or needpmts()): | ||||
@@ -1700,11 +1697,10 @@ def GetTVCT(tsstream): | |||||
lst.sort(channelmajorminorsort) | lst.sort(channelmajorminorsort) | ||||
except KeyError: | except KeyError: | ||||
# unable to find TVCT | # unable to find TVCT | ||||
lst = pat.items() | |||||
lst.sort() | |||||
lst = map(lambda x, y: { 'name': 'PAT%d' % x[1], | |||||
lst = sorted(list(pat.items())) | |||||
lst = list(map(lambda x, y: { 'name': 'PAT%d' % x[1], | |||||
'prog_num': x[1], 'major': '?', 'minor': y}, lst, | 'prog_num': x[1], 'major': '?', 'minor': y}, lst, | ||||
range(1, len(pat) + 1)) | |||||
list(range(1, len(pat) + 1)))) | |||||
tvct = { 'channels': lst } | tvct = { 'channels': lst } | ||||
for i in lst: | for i in lst: | ||||
@@ -1817,12 +1813,12 @@ def main(): | |||||
}) | }) | ||||
def getpmt(pid, pm = pmts, psp = psippids): | def getpmt(pid, pm = pmts, psp = psippids): | ||||
if not pm.has_key(pid): | |||||
if pid not in pm: | |||||
pm[pid] = PMT() | pm[pid] = PMT() | ||||
psp[pid] = TSPSIPHandler({ 0x02: pm[pid] }) | psp[pid] = TSPSIPHandler({ 0x02: pm[pid] }) | ||||
def needpmts(pm = pmts): | def needpmts(pm = pmts): | ||||
for i in pm.itervalues(): | |||||
for i in pm.values(): | |||||
if not i: | if not i: | ||||
return True | return True | ||||
@@ -1831,7 +1827,7 @@ def main(): | |||||
lastpcr = None | lastpcr = None | ||||
lastpatpos = None | lastpatpos = None | ||||
for i in itertools.imap(TSPacket, s): | |||||
for i in map(TSPacket, s): | |||||
#if hasattr(i, 'splice_countdown') or hasattr(i, 'DTS_next_AU'): | #if hasattr(i, 'splice_countdown') or hasattr(i, 'DTS_next_AU'): | ||||
# print 'splice_countdown:', repr(i) | # print 'splice_countdown:', repr(i) | ||||
#if hasattr(i, 'PCR'): | #if hasattr(i, 'PCR'): | ||||
@@ -1847,15 +1843,15 @@ def main(): | |||||
if lastpcr is not None: | if lastpcr is not None: | ||||
# I've only seen 2703 as the largest | # I've only seen 2703 as the largest | ||||
if i.PCR[0] - lastpcr[0] > 3000: | if i.PCR[0] - lastpcr[0] > 3000: | ||||
print lastpatpos | |||||
print(lastpatpos) | |||||
lastpcr = i.PCR | lastpcr = i.PCR | ||||
try: | try: | ||||
psippids[i.pid](i) | psippids[i.pid](i) | ||||
except ValueError, x: | |||||
except ValueError as x: | |||||
#import traceback | #import traceback | ||||
#print traceback.print_exc() | #print traceback.print_exc() | ||||
print >>sys.stderr, 'bad crc:', repr(i) | |||||
print('bad crc:', repr(i), file=sys.stderr) | |||||
continue | continue | ||||
except KeyError: | except KeyError: | ||||
pass | pass | ||||
@@ -1888,7 +1884,7 @@ def main(): | |||||
if needpat and pat: | if needpat and pat: | ||||
needpat = False | needpat = False | ||||
for pn, j in pat.iteritems(): | |||||
for pn, j in pat.items(): | |||||
if pn == 0: | if pn == 0: | ||||
# XXX - NIT | # XXX - NIT | ||||
continue | continue | ||||
@@ -1896,8 +1892,8 @@ def main(): | |||||
getpmt(j) | getpmt(j) | ||||
if needallmaps and pat and pmts: | if needallmaps and pat and pmts: | ||||
for i in pat.itervalues(): | |||||
if not pmts.has_key(i): | |||||
for i in pat.values(): | |||||
if i not in pmts: | |||||
break | break | ||||
needallmaps = False | needallmaps = False | ||||
@@ -1914,11 +1910,11 @@ def main(): | |||||
output)) | output)) | ||||
if allmaps: | if allmaps: | ||||
print repr(pat) | |||||
print repr(pmts) | |||||
print(repr(pat)) | |||||
print(repr(pmts)) | |||||
if printtvct: | if printtvct: | ||||
print repr(tvct) | |||||
print(repr(tvct)) | |||||
if listchan: | if listchan: | ||||
#List channels | #List channels | ||||
@@ -1935,16 +1931,15 @@ def main(): | |||||
if i['prog_num'] != 0 and i['prog_num'] != 0xffff: | if i['prog_num'] != 0 and i['prog_num'] != 0xffff: | ||||
#print repr(pmts[pat[i['prog_num']]]) | #print repr(pmts[pat[i['prog_num']]]) | ||||
av = getaudiovideopids(pmts[pat[i['prog_num']]]) | av = getaudiovideopids(pmts[pat[i['prog_num']]]) | ||||
prog_info = '\t'.join(map(lambda x: | |||||
','.join(map(str, x)), av)) | |||||
prog_info = '\t'.join([','.join(map(str, x)) for x in av]) | |||||
else: | else: | ||||
prog_info = '' | prog_info = '' | ||||
print ('%(major)d.%(minor)d\t%(name)s\t' % i) + \ | |||||
prog_info | |||||
print(('%(major)d.%(minor)d\t%(name)s\t' % i) + \ | |||||
prog_info) | |||||
if printbandwidth: | if printbandwidth: | ||||
totpkts = sum(pidcnt.itervalues()) | |||||
i = pidcnt.items() | |||||
totpkts = sum(pidcnt.values()) | |||||
i = list(pidcnt.items()) | |||||
if printbandwidthpercent: | if printbandwidthpercent: | ||||
def secondfirst(x, y): | def secondfirst(x, y): | ||||
if x[1] == y[1]: | if x[1] == y[1]: | ||||
@@ -1954,11 +1949,11 @@ def main(): | |||||
else: | else: | ||||
i.sort() | i.sort() | ||||
for pid, cnt in i: | for pid, cnt in i: | ||||
print '%4d\t%d\t%5.2f' % (pid, cnt, | |||||
float(cnt) * 100 / totpkts) | |||||
print('%4d\t%d\t%5.2f' % (pid, cnt, | |||||
float(cnt) * 100 / totpkts)) | |||||
if printbyteoffset: | if printbyteoffset: | ||||
print inp.tell() | |||||
print(inp.tell()) | |||||
def justprint(v, p): | def justprint(v, p): | ||||
'''v is pid, p is the data''' | '''v is pid, p is the data''' | ||||
@@ -1966,15 +1961,15 @@ def justprint(v, p): | |||||
return | return | ||||
pes = PES(p) | pes = PES(p) | ||||
if pes.data[3] != '\x00': | if pes.data[3] != '\x00': | ||||
print `pes` | |||||
print(repr(pes)) | |||||
return | return | ||||
fc = findcodes(pes.data) | fc = findcodes(pes.data) | ||||
print 'justprint', v, len(p), repr(pes), repr(pes.data[:20]), fc | |||||
for i in filter(lambda x: x[1] == '\x00', fc): | |||||
print `pes.data[i[0] + 3: i[0] + 7]` | |||||
print('justprint', v, len(p), repr(pes), repr(pes.data[:20]), fc) | |||||
for i in [x for x in fc if x[1] == '\x00']: | |||||
print(repr(pes.data[i[0] + 3: i[0] + 7])) | |||||
if ((ord(pes.data[i[0] + 5]) & 0x38) >> 3) in (2, 3): | if ((ord(pes.data[i[0] + 5]) & 0x38) >> 3) in (2, 3): | ||||
print 'non I frame found: %d' % \ | |||||
((ord(pes.data[i[0] + 5]) & 0x38) >> 3) | |||||
print('non I frame found: %d' % \ | |||||
((ord(pes.data[i[0] + 5]) & 0x38) >> 3)) | |||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
if True: | if True: | ||||
@@ -1984,7 +1979,7 @@ if __name__ == '__main__': | |||||
if False: | if False: | ||||
ps = UnRead(sys.argv[1]) | ps = UnRead(sys.argv[1]) | ||||
while ps: | while ps: | ||||
print `Pack(ps)` | |||||
print(repr(Pack(ps))) | |||||
sys.exit() | sys.exit() | ||||
s = TSPStream(open(sys.argv[1])) | s = TSPStream(open(sys.argv[1])) | ||||
@@ -2007,7 +2002,7 @@ if __name__ == '__main__': | |||||
0x1ffb: TSPSIPHandler({ 0xc8: tvct }), | 0x1ffb: TSPSIPHandler({ 0xc8: tvct }), | ||||
} | } | ||||
first = last = None | first = last = None | ||||
for j in itertools.imap(TSPacket, s): | |||||
for j in map(TSPacket, s): | |||||
count += 1 | count += 1 | ||||
if j.pid == 8191 or (j.pid != 0 and j.pid != 48): | if j.pid == 8191 or (j.pid != 0 and j.pid != 48): | ||||
skipped += 1 | skipped += 1 | ||||
@@ -2019,24 +2014,24 @@ if __name__ == '__main__': | |||||
pidhandlers[j.pid](j) | pidhandlers[j.pid](j) | ||||
except KeyError: | except KeyError: | ||||
pass | pass | ||||
except ValueError, x: | |||||
print 'VE:', x | |||||
except ValueError as x: | |||||
print('VE:', x) | |||||
#if pidhandlers[0x1ffb][0xc8]: | #if pidhandlers[0x1ffb][0xc8]: | ||||
# print repr(pidhandlers[0x1ffb][0xc8]) | # print repr(pidhandlers[0x1ffb][0xc8]) | ||||
# We should probably cache which ones we've added, and remove | # We should probably cache which ones we've added, and remove | ||||
# Ones that aren't there. Or do a clean_up callback. | # Ones that aren't there. Or do a clean_up callback. | ||||
for k in pidhandlers[0][0].itervalues(): | |||||
if pmts.has_key(k): | |||||
for k in pidhandlers[0][0].values(): | |||||
if k in pmts: | |||||
continue | continue | ||||
pmts[k] = PMT() | pmts[k] = PMT() | ||||
pidhandlers[k] = TSPSIPHandler({ 0x02: pmts[k] }) | pidhandlers[k] = TSPSIPHandler({ 0x02: pmts[k] }) | ||||
for k in itertools.ifilter(lambda x: x.es, pmts.itervalues()): | |||||
for k in filter(lambda x: x.es, iter(pmts.values())): | |||||
#print repr(k) | #print repr(k) | ||||
for l in k.es: | for l in k.es: | ||||
if pesstreams.has_key(l[1]): | |||||
if l[1] in pesstreams: | |||||
continue | continue | ||||
print repr(l) | |||||
print(repr(l)) | |||||
pesstreams[l[1]] = TSPESHandler(lambda x, y = | pesstreams[l[1]] = TSPESHandler(lambda x, y = | ||||
l[1]: justprint(y, x)) | l[1]: justprint(y, x)) | ||||
pidhandlers[l[1]] = pesstreams[l[1]] | pidhandlers[l[1]] = pesstreams[l[1]] | ||||
@@ -2053,8 +2048,7 @@ if __name__ == '__main__': | |||||
pids[j.pid] += 1 | pids[j.pid] += 1 | ||||
except KeyError: | except KeyError: | ||||
pids[j.pid] = 1 | pids[j.pid] = 1 | ||||
p = pids.items() | |||||
p.sort() | |||||
print p | |||||
print 'skipped:', skipped | |||||
print 'total:', count | |||||
p = sorted(list(pids.items())) | |||||
print(p) | |||||
print('skipped:', skipped) | |||||
print('total:', count) |
@@ -32,7 +32,6 @@ sys.path.append('/Users/jgurney/p4/bktrau/info') | |||||
import itertools | import itertools | ||||
import mpegts | import mpegts | ||||
import sets | |||||
import struct | import struct | ||||
import sys | import sys | ||||
@@ -9,9 +9,9 @@ tsselpypath = 'mpegts/tssel.py' | |||||
default_audio_lang = 'eng' | default_audio_lang = 'eng' | ||||
import array | import array | ||||
import io | |||||
import itertools | import itertools | ||||
import os | import os | ||||
import sets | |||||
import struct | import struct | ||||
import sys | import sys | ||||
@@ -29,10 +29,9 @@ from twisted.spread import pb | |||||
from twisted.internet import abstract, process, protocol, reactor | from twisted.internet import abstract, process, protocol, reactor | ||||
from twisted.web import error, http, resource, server | from twisted.web import error, http, resource, server | ||||
class _LimitedFile(file): | |||||
class _LimitedFile(io.FileIO): | |||||
def __init__(self, *args, **kwargs): | def __init__(self, *args, **kwargs): | ||||
self.__size = kwargs['size'] | |||||
del kwargs['size'] | |||||
self.__size = kwargs.pop('size') | |||||
file.__init__(self, *args, **kwargs) | file.__init__(self, *args, **kwargs) | ||||
def remain(self): | def remain(self): | ||||
@@ -67,7 +66,7 @@ class MPEGTSTransfer(pb.Viewable): | |||||
return | return | ||||
# get data and write to request. | # get data and write to request. | ||||
try: | try: | ||||
data = self.iter.next() | |||||
data = next(self.iter) | |||||
if data: | if data: | ||||
# this .write will spin the reactor, calling | # this .write will spin the reactor, calling | ||||
# .doWrite and then .resumeProducing again, so | # .doWrite and then .resumeProducing again, so | ||||
@@ -117,9 +116,9 @@ class DynamTSTransfer(pb.Viewable): | |||||
data = self.fp.read(min(abstract.FileDescriptor.bufferSize, | data = self.fp.read(min(abstract.FileDescriptor.bufferSize, | ||||
self.size - self.written) // 188 * 188) | self.size - self.written) // 188 * 188) | ||||
dataarray = array.array('B', data) | dataarray = array.array('B', data) | ||||
for i in xrange(0, len(data), 188): | |||||
for i in range(0, len(data), 188): | |||||
if data[i] != 'G': | if data[i] != 'G': | ||||
print 'bad sync' | |||||
print('bad sync') | |||||
continue | continue | ||||
frst = dataarray[i + 1] | frst = dataarray[i + 1] | ||||
pid = (frst & 0x1f) << 8 | dataarray[i + 2] | pid = (frst & 0x1f) << 8 | dataarray[i + 2] | ||||
@@ -141,7 +140,7 @@ class DynamTSTransfer(pb.Viewable): | |||||
# Remaining fields before array | # Remaining fields before array | ||||
startpmt += 5 | startpmt += 5 | ||||
arraysize -= 5 | arraysize -= 5 | ||||
for startpmt in xrange(startpmt, | |||||
for startpmt in range(startpmt, | |||||
min(i + 188 - 3, startpmt + arraysize), 4): | min(i + 188 - 3, startpmt + arraysize), 4): | ||||
prognum, ppid = struct.unpack('>2H', | prognum, ppid = struct.unpack('>2H', | ||||
data[startpmt:startpmt + 4]) | data[startpmt:startpmt + 4]) | ||||
@@ -149,7 +148,7 @@ class DynamTSTransfer(pb.Viewable): | |||||
if ppid == self.pmt: | if ppid == self.pmt: | ||||
break | break | ||||
else: | else: | ||||
raise KeyError, 'unable to find pmt(%d) in pkt: %s' % (pmt, `data[i:i + 188]`) | |||||
raise KeyError('unable to find pmt(%d) in pkt: %s' % (pmt, repr(data[i:i + 188]))) | |||||
self.pats = itertools.cycle(tssel.genpats( | self.pats = itertools.cycle(tssel.genpats( | ||||
self.pmt, prognum)) | self.pmt, prognum)) | ||||
@@ -157,14 +156,14 @@ class DynamTSTransfer(pb.Viewable): | |||||
if pid == 0 and self.didpat: | if pid == 0 and self.didpat: | ||||
assert data[i + 4] =='\x00' and \ | assert data[i + 4] =='\x00' and \ | ||||
data[i + 5] == '\x00', 'error: %s' % `data[i:i + 10]` | |||||
data[i + 5] == '\x00', 'error: %s' % repr(data[i:i + 10]) | |||||
repcnt += 1 | repcnt += 1 | ||||
pn = self.pats.next() | |||||
pn = next(self.pats) | |||||
data = data[:i] + pn + data[i + | data = data[:i] + pn + data[i + | ||||
188:] | 188:] | ||||
if repcnt > 1: | if repcnt > 1: | ||||
print 'repcnt:', repcnt, 'len(data):', len(data) | |||||
print('repcnt:', repcnt, 'len(data):', len(data)) | |||||
if data: | if data: | ||||
self.written += len(data) | self.written += len(data) | ||||
@@ -195,7 +194,7 @@ class DynamTSTransfer(pb.Viewable): | |||||
try: | try: | ||||
self.fp = open(path) | self.fp = open(path) | ||||
except IOError, e: | |||||
except IOError as e: | |||||
import errno | import errno | ||||
if e[0] == errno.EACCESS: | if e[0] == errno.EACCESS: | ||||
return error.ForbiddenResource().render(request) | return error.ForbiddenResource().render(request) | ||||
@@ -6,11 +6,15 @@ | |||||
from twisted.internet import reactor | from twisted.internet import reactor | ||||
from twisted.application import service | from twisted.application import service | ||||
from twisted.python import log, usage | from twisted.python import log, usage | ||||
import ConfigParser | |||||
import configparser | |||||
import pymeds | import pymeds | ||||
import os.path | import os.path | ||||
import sys | import sys | ||||
#fix for wstools | |||||
import collections | |||||
collections.MutableMapping = collections.abc.MutableMapping | |||||
defconfigfile = 'pymeds.ini' | defconfigfile = 'pymeds.ini' | ||||
class ConfigFile(pymeds.Options): | class ConfigFile(pymeds.Options): | ||||
optParameters = [ [ 'config', 'c', defconfigfile, | optParameters = [ [ 'config', 'c', defconfigfile, | ||||
@@ -21,10 +25,10 @@ if __name__ == '__main__': | |||||
try: | try: | ||||
config.checkpath = False | config.checkpath = False | ||||
config.parseOptions() | config.parseOptions() | ||||
print `config` | |||||
print(repr(config)) | |||||
if os.path.exists(config['config']): | if os.path.exists(config['config']): | ||||
print 'foo' | |||||
scp = ConfigParser.SafeConfigParser() | |||||
print('foo') | |||||
scp = configparser.SafeConfigParser() | |||||
scp.read(config['config']) | scp.read(config['config']) | ||||
config.update(scp.items('pymeds')) | config.update(scp.items('pymeds')) | ||||
@@ -32,12 +36,12 @@ if __name__ == '__main__': | |||||
config.checkpath = True | config.checkpath = True | ||||
config.postOptions() | config.postOptions() | ||||
elif config['config'] != defconfigfile: | elif config['config'] != defconfigfile: | ||||
print 'bar' | |||||
print('bar') | |||||
raise usage.UsageError( | raise usage.UsageError( | ||||
'config file %s does not exist' % config['config']) | 'config file %s does not exist' % config['config']) | ||||
except usage.UsageError, errortext: | |||||
print '%s: %s' % (sys.argv[0], errortext) | |||||
print '%s: Try --help for usage details.' % sys.argv[0] | |||||
except usage.UsageError as errortext: | |||||
print('%s: %s' % (sys.argv[0], errortext)) | |||||
print('%s: Try --help for usage details.' % sys.argv[0]) | |||||
sys.exit(1) | sys.exit(1) | ||||
log.startLogging(sys.stdout) | log.startLogging(sys.stdout) | ||||
@@ -13,15 +13,15 @@ __version__ = '$Change: 1740 $' | |||||
# stage, where we simulate a namespace to either be thrown away when the | # stage, where we simulate a namespace to either be thrown away when the | ||||
# time comes, or merge into the correct one) | # time comes, or merge into the correct one) | ||||
import debug # my debugging module | import debug # my debugging module | ||||
debug.doDebugging(True) # open up debugging port | |||||
debug.doDebugging(False) # open up debugging port | |||||
# Modules to import, maybe config file or something? | # Modules to import, maybe config file or something? | ||||
def tryloadmodule(mod): | def tryloadmodule(mod): | ||||
try: | try: | ||||
return __import__(mod) | return __import__(mod) | ||||
except ImportError: | except ImportError: | ||||
#import traceback | |||||
#traceback.print_exc() | |||||
import traceback | |||||
traceback.print_exc() | |||||
pass | pass | ||||
# ZipStorage w/ tar support should be last as it will gobble up empty files. | # ZipStorage w/ tar support should be last as it will gobble up empty files. | ||||
@@ -50,7 +50,7 @@ checkmodules = [ x for x in modmap if modmap[x] is None ] | |||||
if checkmodules: | if checkmodules: | ||||
checkmodules.sort() | checkmodules.sort() | ||||
print 'The following modules were not loaded:', ', '.join(checkmodules) | |||||
print('The following modules were not loaded:', ', '.join(checkmodules)) | |||||
from FSStorage import FSDirectory | from FSStorage import FSDirectory | ||||
import os | import os | ||||
@@ -58,12 +58,12 @@ import os.path | |||||
import random | import random | ||||
import socket | import socket | ||||
import string | import string | ||||
import urlparse | |||||
import urllib.parse | |||||
from twisted.application import internet, service | from twisted.application import internet, service | ||||
from twisted.python import usage | from twisted.python import usage | ||||
def generateuuid(): | def generateuuid(): | ||||
return ''.join([ 'uuid:'] + map(lambda x: random.choice(string.letters), xrange(20))) | |||||
return ''.join([ 'uuid:'] + [random.choice(string.ascii_letters) for x in range(20)]) | |||||
class Options(usage.Options): | class Options(usage.Options): | ||||
checkpath = True | checkpath = True | ||||
@@ -75,14 +75,14 @@ class Options(usage.Options): | |||||
def postOptions(self): | def postOptions(self): | ||||
p = self['path'] | p = self['path'] | ||||
if self.checkpath and not os.path.isdir(p): | if self.checkpath and not os.path.isdir(p): | ||||
raise usage.UsageError, 'path %s does not exist' % `p` | |||||
raise usage.UsageError('path %s does not exist' % repr(p)) | |||||
def parseArgs(self, *args): | def parseArgs(self, *args): | ||||
# XXX - twisted doesn't let you provide a message on what | # XXX - twisted doesn't let you provide a message on what | ||||
# arguments are required, so we will do our own work in here. | # arguments are required, so we will do our own work in here. | ||||
if len(args) not in (1, 2): | if len(args) not in (1, 2): | ||||
raise usage.UsageError, 'Arguments: addr [ port ]' | |||||
raise usage.UsageError('Arguments: addr [ port ]') | |||||
self['addr'] = args[0] | self['addr'] = args[0] | ||||
if len(args) == 1: | if len(args) == 1: | ||||
@@ -154,8 +154,8 @@ def makeService(config): | |||||
'uuid': uuid, | 'uuid': uuid, | ||||
'urlbase': urlbase, | 'urlbase': urlbase, | ||||
} | } | ||||
d = file('root-device.xml').read() % r | |||||
static.Data.__init__(self, d, 'text/xml') | |||||
d = open('root-device.xml').read() % r | |||||
static.Data.__init__(self, bytes(d, 'ascii'), 'text/xml') | |||||
root = WebServer() | root = WebServer() | ||||
debug.insertnamespace('root', root) | debug.insertnamespace('root', root) | ||||
@@ -163,14 +163,14 @@ def makeService(config): | |||||
# This sets up the root to be the media dir so we don't have to | # This sets up the root to be the media dir so we don't have to | ||||
# enumerate the directory. | # enumerate the directory. | ||||
cds = ContentDirectoryServer(config['title'], klass=FSDirectory, | cds = ContentDirectoryServer(config['title'], klass=FSDirectory, | ||||
path=config['path'], urlbase=urlparse.urljoin(urlbase, 'content'), | |||||
path=config['path'], urlbase=urllib.parse.urljoin(urlbase, 'content'), | |||||
webbase=content) | webbase=content) | ||||
debug.insertnamespace('cds', cds) | debug.insertnamespace('cds', cds) | ||||
root.putChild('ContentDirectory', cds) | |||||
root.putChild(b'ContentDirectory', cds) | |||||
cds = cds.control | cds = cds.control | ||||
root.putChild('ConnectionManager', ConnectionManagerServer()) | |||||
root.putChild('root-device.xml', RootDevice()) | |||||
root.putChild('content', content) | |||||
root.putChild(b'ConnectionManager', ConnectionManagerServer()) | |||||
root.putChild(b'root-device.xml', RootDevice()) | |||||
root.putChild(b'content', content) | |||||
fixupmimetypes() | fixupmimetypes() | ||||
@@ -186,7 +186,7 @@ def makeService(config): | |||||
def startService(self): | def startService(self): | ||||
service.MultiService.startService(self) | service.MultiService.startService(self) | ||||
rdxml = urlparse.urljoin(urlbase, 'root-device.xml') | |||||
rdxml = urllib.parse.urljoin(urlbase, 'root-device.xml') | |||||
s.register('%s::upnp:rootdevice' % uuid, | s.register('%s::upnp:rootdevice' % uuid, | ||||
'upnp:rootdevice', rdxml) | 'upnp:rootdevice', rdxml) | ||||
@@ -13,8 +13,8 @@ import time | |||||
from twisted.internet import reactor | from twisted.internet import reactor | ||||
from twisted.python import log | from twisted.python import log | ||||
import twisted.web | import twisted.web | ||||
import urlparse | |||||
import urllib2 | |||||
import urllib.parse | |||||
import urllib.request, urllib.error, urllib.parse | |||||
def getPage(url, contextFactory=None, *args, **kwargs): | def getPage(url, contextFactory=None, *args, **kwargs): | ||||
"""Download a web page as a string. | """Download a web page as a string. | ||||
@@ -47,10 +47,10 @@ class PYVRShow(VideoItem): | |||||
VideoItem.__init__(self, *args, **kwargs) | VideoItem.__init__(self, *args, **kwargs) | ||||
url = self.info['link'] | url = self.info['link'] | ||||
sc = urlparse.urlparse(url)[0] | |||||
sc = urllib.parse.urlparse(url)[0] | |||||
if not sc: | if not sc: | ||||
# need to combine w/ base url | # need to combine w/ base url | ||||
url = urlparse.urljoin(baseurl, url) | |||||
url = urllib.parse.urljoin(baseurl, url) | |||||
self.res = Resource(url, | self.res = Resource(url, | ||||
'http-get:*:%s:*' % self.info['mimetype']) | 'http-get:*:%s:*' % self.info['mimetype']) | ||||
self.res.duration = self.info['duration'] | self.res.duration = self.info['duration'] | ||||
@@ -126,7 +126,7 @@ class PYVRShows(Container): | |||||
i = 1 | i = 1 | ||||
while True: | while True: | ||||
title = '%s Copy %d' % (ep['subtitle'], i) | title = '%s Copy %d' % (ep['subtitle'], i) | ||||
if not eps.has_key(title): | |||||
if title not in eps: | |||||
return title | return title | ||||
i += 1 | i += 1 | ||||
@@ -135,8 +135,8 @@ class PYVRShows(Container): | |||||
ret = {} | ret = {} | ||||
for pos, i in enumerate(eps): | for pos, i in enumerate(eps): | ||||
title = i['subtitle'] | title = i['subtitle'] | ||||
if ret.has_key(title): | |||||
print 'WARNING: dup:', `i`, `ret[title]` | |||||
if title in ret: | |||||
print('WARNING: dup:', repr(i), repr(ret[title])) | |||||
title = PYVRShows.getunique(ret, i) | title = PYVRShows.getunique(ret, i) | ||||
i['pos'] = pos | i['pos'] = pos | ||||
ret[title] = i | ret[title] = i | ||||
@@ -184,9 +184,9 @@ class PYVR(FSObject, Container): | |||||
def runCheck(self): | def runCheck(self): | ||||
while True: | while True: | ||||
try: | try: | ||||
self.page = urllib2.urlopen(self.url) | |||||
self.page = urllib.request.urlopen(self.url) | |||||
break | break | ||||
except urllib2.HTTPError: | |||||
except urllib.error.HTTPError: | |||||
time.sleep(.1) | time.sleep(.1) | ||||
#self.page = getPage(self.url, method='HEAD') | #self.page = getPage(self.url, method='HEAD') | ||||
#self.page.deferred.addErrback(self.errCheck).addCallback( | #self.page.deferred.addErrback(self.errCheck).addCallback( | ||||
@@ -195,7 +195,7 @@ class PYVR(FSObject, Container): | |||||
return self.doCheck(self.page) | return self.doCheck(self.page) | ||||
def errCheck(self, x): | def errCheck(self, x): | ||||
print 'errCheck:', `x` | |||||
print('errCheck:', repr(x)) | |||||
self.runCheck() | self.runCheck() | ||||
def doCheck(self, x): | def doCheck(self, x): | ||||
@@ -225,14 +225,14 @@ class PYVR(FSObject, Container): | |||||
#self.pend = None | #self.pend = None | ||||
self.newobjs = recxmltoobj(page.read()) | self.newobjs = recxmltoobj(page.read()) | ||||
print 'pp:', `self.newobjs` | |||||
print('pp:', repr(self.newobjs)) | |||||
self.doUpdate() | self.doUpdate() | ||||
def genChildren(self): | def genChildren(self): | ||||
return self.newobjs.keys() | |||||
return list(self.newobjs.keys()) | |||||
def createObject(self, i, arg=None): | def createObject(self, i, arg=None): | ||||
print 'co:', `i`, `arg` | |||||
print('co:', repr(i), repr(arg)) | |||||
return PYVRShows, i, (), { 'show': i, 'pyvr': self } | return PYVRShows, i, (), { 'show': i, 'pyvr': self } | ||||
def doUpdate(self): | def doUpdate(self): | ||||
@@ -0,0 +1,3 @@ | |||||
twisted | |||||
-e git+https://www.funkthat.com/gitea/jmg/SOAPpy@main#egg=SOAPpy-py3 | |||||
-e git+https://www.funkthat.com/gitea/jmg/wstools-py3@main#egg=wstools-py3 |
@@ -21,16 +21,16 @@ | |||||
<service> | <service> | ||||
<serviceType>urn:schemas-upnp-org:service:ConnectionManager:1</serviceType> | <serviceType>urn:schemas-upnp-org:service:ConnectionManager:1</serviceType> | ||||
<serviceId>urn:upnp-org:serviceId:urn:schemas-upnp-org:service:ConnectionManager</serviceId> | <serviceId>urn:upnp-org:serviceId:urn:schemas-upnp-org:service:ConnectionManager</serviceId> | ||||
<SCPDURL>ConnectionManager/scpd.xml</SCPDURL> | |||||
<controlURL>ConnectionManager/control</controlURL> | |||||
<eventSubURL>ConnectionManager/event</eventSubURL> | |||||
<SCPDURL>/ConnectionManager/scpd.xml</SCPDURL> | |||||
<controlURL>/ConnectionManager/control</controlURL> | |||||
<eventSubURL>/ConnectionManager/event</eventSubURL> | |||||
</service> | </service> | ||||
<service> | <service> | ||||
<serviceType>urn:schemas-upnp-org:service:ContentDirectory:1</serviceType> | <serviceType>urn:schemas-upnp-org:service:ContentDirectory:1</serviceType> | ||||
<serviceId>urn:upnp-org:serviceId:urn:schemas-upnp-org:service:ContenDirectory</serviceId> | <serviceId>urn:upnp-org:serviceId:urn:schemas-upnp-org:service:ContenDirectory</serviceId> | ||||
<SCPDURL>ContentDirectory/scpd.xml</SCPDURL> | |||||
<controlURL>ContentDirectory/control</controlURL> | |||||
<eventSubURL>ContentDirectory/event</eventSubURL> | |||||
<SCPDURL>/ContentDirectory/scpd.xml</SCPDURL> | |||||
<controlURL>/ContentDirectory/control</controlURL> | |||||
<eventSubURL>/ContentDirectory/event</eventSubURL> | |||||
</service> | </service> | ||||
</serviceList> | </serviceList> | ||||
<deviceList/> | <deviceList/> | ||||
@@ -57,7 +57,7 @@ class LimitedAudioProducer(object): | |||||
return r | return r | ||||
def shutdown(self): | def shutdown(self): | ||||
print 'lap: shutdown', `self.consumer` | |||||
print('lap: shutdown', repr(self.consumer)) | |||||
# XXX - I still get writes after I've asked my producer to stop | # XXX - I still get writes after I've asked my producer to stop | ||||
self.write = lambda x: None | self.write = lambda x: None | ||||
self.producer.stopProducing() | self.producer.stopProducing() | ||||
@@ -74,19 +74,19 @@ class LimitedAudioProducer(object): | |||||
return self.producer.resumeProducing() | return self.producer.resumeProducing() | ||||
def stopProducing(self): | def stopProducing(self): | ||||
print 'lap: sp' | |||||
print('lap: sp') | |||||
self.shutdown() | self.shutdown() | ||||
# IConsumer | # IConsumer | ||||
def registerProducer(self, producer, streaming): | def registerProducer(self, producer, streaming): | ||||
print 'lap: regp' | |||||
print('lap: regp') | |||||
self.producer = producer | self.producer = producer | ||||
self.streamingProducer = streaming | self.streamingProducer = streaming | ||||
self.consumer.registerProducer(self, streaming) | self.consumer.registerProducer(self, streaming) | ||||
def unregisterProducer(): | def unregisterProducer(): | ||||
print 'lap: unregp' | |||||
print('lap: unregp') | |||||
self.shutdown() | self.shutdown() | ||||
def write(self, data): | def write(self, data): | ||||
@@ -122,7 +122,7 @@ class ChangerTrack(resource.Resource): | |||||
return self._res.getmimetype() | return self._res.getmimetype() | ||||
def render(self, request): | def render(self, request): | ||||
print 'CTrender:', `request.postpath`, `request.method`, `request` | |||||
print('CTrender:', repr(request.postpath), repr(request.method), repr(request)) | |||||
self.setlength(request) | self.setlength(request) | ||||
if request.method == 'HEAD': | if request.method == 'HEAD': | ||||
@@ -156,7 +156,7 @@ class ChangerTrack(resource.Resource): | |||||
'content-length', [ str(r) ]) | 'content-length', [ str(r) ]) | ||||
def docleanup(self, nf, request): | def docleanup(self, nf, request): | ||||
print 'docleanup' | |||||
print('docleanup') | |||||
nf.addBoth(self.dostop) | nf.addBoth(self.dostop) | ||||
nf.addBoth(lambda x: self.dounlock(request)) | nf.addBoth(lambda x: self.dounlock(request)) | ||||
@@ -168,19 +168,19 @@ class ChangerTrack(resource.Resource): | |||||
return None | return None | ||||
def dostop(self, arg): | def dostop(self, arg): | ||||
print 'dostop' | |||||
print('dostop') | |||||
d = self._obj.stop() | d = self._obj.stop() | ||||
# Make sure we have stopped before we continue | # Make sure we have stopped before we continue | ||||
d.addBoth(lambda x: arg) | d.addBoth(lambda x: arg) | ||||
return d | return d | ||||
def logerr(self, exc, *args): | def logerr(self, exc, *args): | ||||
print 'logerr:', `args` | |||||
print('logerr:', repr(args)) | |||||
exc.printTraceback() | exc.printTraceback() | ||||
#exc.printDetailedTraceback() | #exc.printDetailedTraceback() | ||||
def failed(self, exc, request): | def failed(self, exc, request): | ||||
print 'in this failed case', self._obj.haslock(request), `request` | |||||
print('in this failed case', self._obj.haslock(request), repr(request)) | |||||
if self._obj.haslock(request): | if self._obj.haslock(request): | ||||
self.dounlock(request) | self.dounlock(request) | ||||
# XXX - look at queue and decide | # XXX - look at queue and decide | ||||
@@ -192,7 +192,7 @@ class ChangerTrack(resource.Resource): | |||||
return exc | return exc | ||||
def printarg(self, args): | def printarg(self, args): | ||||
print 'pa:', `self`, `args` | |||||
print('pa:', repr(self), repr(args)) | |||||
def unregisterProducer(self): | def unregisterProducer(self): | ||||
resource.Resource.unregisterProducer(self) | resource.Resource.unregisterProducer(self) | ||||
@@ -298,15 +298,15 @@ class SLinkEChangerDisc(MusicAlbum): | |||||
# ContentDirectory calls this | # ContentDirectory calls this | ||||
def checkUpdate(self): | def checkUpdate(self): | ||||
print 'cU' | |||||
print('cU') | |||||
curid = self.getID() | curid = self.getID() | ||||
if self._lastid != curid: | if self._lastid != curid: | ||||
print 'dU' | |||||
print('dU') | |||||
self.doUpdate() | self.doUpdate() | ||||
self._lastid = curid | self._lastid = curid | ||||
def genChildren(self): | def genChildren(self): | ||||
return dict(('%02d' % i, i) for i in xrange(1, self.getID()[1] + 1)) | |||||
return dict(('%02d' % i, i) for i in range(1, self.getID()[1] + 1)) | |||||
def createObject(self, i, arg): | def createObject(self, i, arg): | ||||
return SLinkEChangerDiscTrack, i, (), { 'discobj': self, 'track': arg } | return SLinkEChangerDiscTrack, i, (), { 'discobj': self, 'track': arg } | ||||
@@ -335,7 +335,7 @@ class SLinkEChanger(StorageSystem, slinke.CDPlayerProtocol): | |||||
config['audiodefault']) | config['audiodefault']) | ||||
def aftershutdown(self): | def aftershutdown(self): | ||||
print 'in SLinkEChanger after shutdown' | |||||
print('in SLinkEChanger after shutdown') | |||||
self._s.close() | self._s.close() | ||||
self._s = None | self._s = None | ||||
@@ -350,7 +350,7 @@ class SLinkEChanger(StorageSystem, slinke.CDPlayerProtocol): | |||||
self._poweroff.cancel() | self._poweroff.cancel() | ||||
self._poweroff = None | self._poweroff = None | ||||
self._lock = obj | self._lock = obj | ||||
print 'tl: locked:', `self._lock` | |||||
print('tl: locked:', repr(self._lock)) | |||||
return defer.succeed(True) | return defer.succeed(True) | ||||
d = defer.Deferred() | d = defer.Deferred() | ||||
@@ -372,24 +372,24 @@ class SLinkEChanger(StorageSystem, slinke.CDPlayerProtocol): | |||||
return False | return False | ||||
def unlock(self, obj): | def unlock(self, obj): | ||||
print 'unlock:', `obj` | |||||
print('unlock:', repr(obj)) | |||||
if self._lock is None: | if self._lock is None: | ||||
print 'ul: not locked' | |||||
print('ul: not locked') | |||||
raise RuntimeError('unlocked when not locked') | raise RuntimeError('unlocked when not locked') | ||||
if obj is not self._lock: | if obj is not self._lock: | ||||
print 'ul: wrong obj' | |||||
raise ValueError('unlocking when not locked by: %s, was locked by: %s' % (`obj`, self._lock)) | |||||
print('ul: wrong obj') | |||||
raise ValueError('unlocking when not locked by: %s, was locked by: %s' % (repr(obj), self._lock)) | |||||
if not self._pendinglocks: | if not self._pendinglocks: | ||||
print 'really unlocked' | |||||
print('really unlocked') | |||||
self._lock = None | self._lock = None | ||||
self._poweroff = reactor.callLater(300, self.turnoff) | self._poweroff = reactor.callLater(300, self.turnoff) | ||||
return | return | ||||
pobj = self._pendinglocks.pop(0) | pobj = self._pendinglocks.pop(0) | ||||
self._lock = pobj[1] | self._lock = pobj[1] | ||||
print 'passing lock:', `self._lock` | |||||
print('passing lock:', repr(self._lock)) | |||||
pobj[2].cancel() | pobj[2].cancel() | ||||
pobj[0].callback(True) | pobj[0].callback(True) | ||||
@@ -402,7 +402,7 @@ class SLinkEChanger(StorageSystem, slinke.CDPlayerProtocol): | |||||
a = defer.waitForDeferred(self.checkids()) | a = defer.waitForDeferred(self.checkids()) | ||||
yield a | yield a | ||||
a.getResult() | a.getResult() | ||||
print 'powering cd changer off' | |||||
print('powering cd changer off') | |||||
# checkids may have rescheduled us. If we don't cancel it, | # checkids may have rescheduled us. If we don't cancel it, | ||||
# we'd wake up every five minutes just to turn off again. | # we'd wake up every five minutes just to turn off again. | ||||
@@ -415,13 +415,12 @@ class SLinkEChanger(StorageSystem, slinke.CDPlayerProtocol): | |||||
@defer.deferredGenerator | @defer.deferredGenerator | ||||
def checkids(self): | def checkids(self): | ||||
print 'starting checkids' | |||||
print('starting checkids') | |||||
a = defer.waitForDeferred(self.transport.poweron()) | a = defer.waitForDeferred(self.transport.poweron()) | ||||
yield a | yield a | ||||
print 'power should be on:', `a.getResult()` | |||||
discs = list(self.transport.discs()) | |||||
discs.sort() | |||||
print discs | |||||
print('power should be on:', repr(a.getResult())) | |||||
discs = sorted(self.transport.discs()) | |||||
print(discs) | |||||
for i in self.transport: | for i in self.transport: | ||||
discnum = i | discnum = i | ||||
i = str(i) | i = str(i) | ||||
@@ -433,7 +432,7 @@ class SLinkEChanger(StorageSystem, slinke.CDPlayerProtocol): | |||||
except KeyError: | except KeyError: | ||||
pass | pass | ||||
print 'missing:', `i` | |||||
print('missing:', repr(i)) | |||||
# No ID, fetch it. | # No ID, fetch it. | ||||
a = defer.waitForDeferred(self.trylock(5, self)) | a = defer.waitForDeferred(self.trylock(5, self)) | ||||
@@ -447,12 +446,12 @@ class SLinkEChanger(StorageSystem, slinke.CDPlayerProtocol): | |||||
a = defer.waitForDeferred(threads.deferToThread(CDDB.query, cddbid)) | a = defer.waitForDeferred(threads.deferToThread(CDDB.query, cddbid)) | ||||
yield a | yield a | ||||
queryres = a.getResult() | queryres = a.getResult() | ||||
print 'res:', `i`, `queryres` | |||||
print('res:', repr(i), repr(queryres)) | |||||
self._s[i] = { 'query': queryres, | self._s[i] = { 'query': queryres, | ||||
'cddbid': cddbid, } | 'cddbid': cddbid, } | ||||
self._changed = True | self._changed = True | ||||
except slinke.NoDisc: | except slinke.NoDisc: | ||||
print 'Disc not present: %d' % discnum | |||||
print('Disc not present: %d' % discnum) | |||||
continue | continue | ||||
finally: | finally: | ||||
self.unlock(self) | self.unlock(self) | ||||
@@ -488,7 +487,7 @@ class SLinkEChanger(StorageSystem, slinke.CDPlayerProtocol): | |||||
# 210 multiple matches | # 210 multiple matches | ||||
return q[1][0] | return q[1][0] | ||||
else: | else: | ||||
raise ValueError('what to do? %s' % `self._s[disc]`) | |||||
raise ValueError('what to do? %s' % repr(self._s[disc])) | |||||
def getDiscTitle(self, disc, wait=False): | def getDiscTitle(self, disc, wait=False): | ||||
m = self.getMatch(disc, wait) | m = self.getMatch(disc, wait) | ||||
@@ -502,17 +501,17 @@ class SLinkEChanger(StorageSystem, slinke.CDPlayerProtocol): | |||||
t = t.decode('iso8859-1') | t = t.decode('iso8859-1') | ||||
if t.count('/') > 1: | if t.count('/') > 1: | ||||
print 'tcount:', `t` | |||||
print('tcount:', repr(t)) | |||||
try: | try: | ||||
return t.split('/', 1)[1] | return t.split('/', 1)[1] | ||||
except IndexError: | except IndexError: | ||||
print 'ie:', `t` | |||||
print('ie:', repr(t)) | |||||
return t | return t | ||||
# CDPlayerProtocol interface | # CDPlayerProtocol interface | ||||
def connectionMade(self): | def connectionMade(self): | ||||
super(SLinkEChanger, self).connectionMade() | super(SLinkEChanger, self).connectionMade() | ||||
print 'attached to cdplayer' | |||||
print('attached to cdplayer') | |||||
self._changed = True | self._changed = True | ||||
# Make sure we start out off, or if we are missing CDDB id's, | # Make sure we start out off, or if we are missing CDDB id's, | ||||
@@ -520,7 +519,7 @@ class SLinkEChanger(StorageSystem, slinke.CDPlayerProtocol): | |||||
self.turnoff() | self.turnoff() | ||||
def stateChange(self): | def stateChange(self): | ||||
print 'sC' | |||||
print('sC') | |||||
# ContentDirectory calls this | # ContentDirectory calls this | ||||
def checkUpdate(self): | def checkUpdate(self): | ||||
@@ -82,18 +82,16 @@ def build_soap_call(method, arguments, is_response=False, | |||||
# append the arguments | # append the arguments | ||||
if isinstance(arguments,dict): | if isinstance(arguments,dict): | ||||
type_map = {str: 'xsd:string', | type_map = {str: 'xsd:string', | ||||
unicode: 'xsd:string', | |||||
bytes: 'xsd:string', | |||||
int: 'xsd:int', | int: 'xsd:int', | ||||
long: 'xsd:int', | |||||
float: 'xsd:float', | float: 'xsd:float', | ||||
bool: 'xsd:boolean'} | bool: 'xsd:boolean'} | ||||
for arg_name, arg_val in arguments.iteritems(): | |||||
for arg_name, arg_val in arguments.items(): | |||||
arg_type = type_map[type(arg_val)] | arg_type = type_map[type(arg_val)] | ||||
if arg_type == 'xsd:string' and type(arg_val) == unicode: | |||||
arg_val = arg_val.encode('utf-8') | |||||
if arg_type == 'xsd:int' or arg_type == 'xsd:float': | |||||
arg_val = str(arg_val) | |||||
if isinstance(arg_val, bytes): | |||||
arg_val = arg_val.decode('utf-8') | |||||
arg_val = str(arg_val) | |||||
if arg_type == 'xsd:boolean': | if arg_type == 'xsd:boolean': | ||||
arg_val = arg_val.lower() | arg_val = arg_val.lower() | ||||
@@ -109,4 +107,4 @@ def build_soap_call(method, arguments, is_response=False, | |||||
preamble = """<?xml version="1.0" encoding="utf-8"?>""" | preamble = """<?xml version="1.0" encoding="utf-8"?>""" | ||||
return preamble + ET.tostring(envelope,'utf-8') | |||||
return bytes(preamble + ET.tostring(envelope, 'unicode'), 'ascii') |