From dda96e70f03b054db137eeef196eecb57e76d4c7 Mon Sep 17 00:00:00 2001 From: John-Mark Gurney Date: Fri, 11 Aug 2023 16:03:38 -0700 Subject: [PATCH] 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.. --- .gitignore | 5 + Clip.py | 4 +- ConnectionManager.py | 14 +- ContentDirectory.py | 46 ++--- DIDLLite.py | 46 ++--- FSStorage.py | 29 ++- FileDIDL.py | 7 +- SSDP.py | 51 +++-- ZipStorage.py | 14 -- audio.py | 24 +-- audioraw.py | 26 +-- cdrtoc.py | 10 +- debug.py | 6 +- dvd.py | 1 - et.py | 20 +- item.py | 2 +- iterrarfile.py | 12 -- itertarfile.py | 37 ---- iterzipfile.py | 25 --- mpegts/atschuff.py | 4 +- mpegts/mpegts.py | 436 +++++++++++++++++++++---------------------- mpegts/tssel.py | 1 - mpegtsmod.py | 25 ++- pymediaserv | 20 +- pymeds.py | 32 ++-- pyvr.py | 26 +-- requirements.txt | 2 + slinkemod.py | 69 ++++--- soap_lite.py | 14 +- 29 files changed, 460 insertions(+), 548 deletions(-) create mode 100644 .gitignore delete mode 100644 iterrarfile.py delete mode 100644 itertarfile.py delete mode 100644 iterzipfile.py create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c580011 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.DS_Store +__pycache__ + +# my venv +p diff --git a/Clip.py b/Clip.py index d4713a5..cc68000 100644 --- a/Clip.py +++ b/Clip.py @@ -35,7 +35,7 @@ class ClipProxyFile: fp = self.fp records = iter(self.p[p:]) while s: - rec = records.next() + rec = next(records) diff = self.pos - rec[0] rlen = min(s, rec[1] - diff) fp.seek(rec[2] + diff) @@ -76,7 +76,7 @@ class ClipProxy(static.File): self.origfile = i['file'] self.date = eval(i['datetuple'], { '__builtins__': {} }) # 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 self.pos = par = [] for j in p: diff --git a/ConnectionManager.py b/ConnectionManager.py index e0501e3..b2417de 100644 --- a/ConnectionManager.py +++ b/ConnectionManager.py @@ -11,23 +11,23 @@ from upnp import UPnPPublisher class ConnectionManagerControl(UPnPPublisher): 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': '' } 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): - log.msg('ConnectionComplete(%s, %s)' % (`args`, `kwargs`)) + log.msg('ConnectionComplete(%s, %s)' % (repr(args), repr(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): - log.msg('GetProtocolInfo(%s, %s)' % (`args`, `kwargs`)) + log.msg('GetProtocolInfo(%s, %s)' % (repr(args), repr(kwargs))) class ConnectionManagerServer(resource.Resource): def __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()) diff --git a/ContentDirectory.py b/ContentDirectory.py index 5962820..9dd1c73 100644 --- a/ContentDirectory.py +++ b/ContentDirectory.py @@ -27,7 +27,7 @@ reqname = 'requests' from twisted.python import log 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 DIDLLite import DIDLElement, Container, Movie, Resource, MusicTrack @@ -36,7 +36,7 @@ from twisted.python import failure import debug import traceback -from urllib import quote +from urllib.parse import quote class doRecall(defer.Deferred): '''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): try: return fun(*args, **kwargs) - except defer.Deferred, x: + except defer.Deferred as x: return doRecallgen(x, fun, *args, **kwargs) def doRecallgen(defer, fun, *args, **kwargs): @@ -124,17 +124,17 @@ class ContentDirectoryControl(UPnPPublisher, dict): return 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`) self.children[parent].append(i) self[i.id] = i 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): - if not self.has_key(id): + if id not in self: log.msg('already removed:', id) return #log.msg('removing:', id) @@ -195,7 +195,7 @@ class ContentDirectoryControl(UPnPPublisher, dict): def soap_Browse(self, *args): l = {} debug.appendnamespace(reqname, l) - if self.has_key(args[0]): + if args[0] in self: l['object'] = self[args[0]] l['query'] = 'Browse(ObjectID=%s, BrowseFlags=%s, Filter=%s, ' \ 'StartingIndex=%s RequestedCount=%s SortCriteria=%s)' % \ @@ -261,8 +261,8 @@ class ContentDirectoryControl(UPnPPublisher, dict): log.msg('Search(ContainerID=%s, SearchCriteria=%s, Filter=%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): """Create a new object.""" @@ -270,14 +270,14 @@ class ContentDirectoryControl(UPnPPublisher, dict): (ContainerID, Elements) = args log.msg('CreateObject(ContainerID=%s, Elements=%s)' % - (`ContainerID`, `Elements`)) + (repr(ContainerID), repr(Elements))) def soap_DestroyObject(self, *args, **kwargs): """Destroy the specified object.""" (ObjectID) = args - log.msg('DestroyObject(ObjectID=%s)' % `ObjectID`) + log.msg('DestroyObject(ObjectID=%s)' % repr(ObjectID)) def soap_UpdateObject(self, *args, **kwargs): """Modify, delete or insert object metadata.""" @@ -285,8 +285,8 @@ class ContentDirectoryControl(UPnPPublisher, dict): (ObjectID, CurrentTagValue, NewTagValue) = args 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): """Transfer a file from a remote source to a local @@ -295,7 +295,7 @@ class ContentDirectoryControl(UPnPPublisher, dict): (SourceURI, DestinationURI) = args log.msg('ImportResource(SourceURI=%s, DestinationURI=%s)' % - (`SourceURI`, `DestinationURI`)) + (repr(SourceURI), repr(DestinationURI))) def soap_ExportResource(self, *args, **kwargs): """Transfer a file from a local source to a remote @@ -304,7 +304,7 @@ class ContentDirectoryControl(UPnPPublisher, dict): (SourceURI, DestinationURI) = args log.msg('ExportResource(SourceURI=%s, DestinationURI=%s)' % - (`SourceURI`, `DestinationURI`)) + (repr(SourceURI), repr(DestinationURI))) def soap_StopTransferResource(self, *args, **kwargs): """Stop a file transfer initiated by ImportResource or @@ -322,15 +322,15 @@ class ContentDirectoryControl(UPnPPublisher, dict): log.msg('GetTransferProgress(TransferID=%s, TransferStatus=%s, ' \ 'TransferLength=%s, TransferTotal=%s)' % - (`TransferId`, `TransferStatus`, `TransferLength`, - `TransferTotal`)) + (repr(TransferId), repr(TransferStatus), repr(TransferLength), + repr(TransferTotal))) def soap_DeleteResource(self, *args, **kwargs): """Delete a specified resource.""" (ResourceURI) = args - log.msg('DeleteResource(ResourceURI=%s)' % `ResourceURI`) + log.msg('DeleteResource(ResourceURI=%s)' % repr(ResourceURI)) def soap_CreateReference(self, *args, **kwargs): """Create a reference to an existing object.""" @@ -338,14 +338,14 @@ class ContentDirectoryControl(UPnPPublisher, dict): (ContainerID, ObjectID) = args log.msg('CreateReference(ContainerID=%s, ObjectID=%s)' % - (`ContainerID`, `ObjectID`)) + (repr(ContainerID), repr(ObjectID))) def __repr__(self): - return '' % (len(self), `self.urlbase`, self.nextID) + return '' % (len(self), repr(self.urlbase), self.nextID) class ContentDirectoryServer(resource.Resource): def __init__(self, title, *args, **kwargs): 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.putChild('control', self.control) + self.putChild(b'control', self.control) diff --git a/DIDLLite.py b/DIDLLite.py index 4c5b497..2b1b5e5 100644 --- a/DIDLLite.py +++ b/DIDLLite.py @@ -7,11 +7,12 @@ __version__ = '$Change: 1665 $' # $Id: //depot/python/pymeds/main/DIDLLite.py#32 $ +import functools import itertools import unittest import et -for i in [ 'Element', 'SubElement', 'tostring', '_ElementInterface' ]: +for i in [ 'Element', 'SubElement', 'tostring', ]: locals()[i] = getattr(et.ET, i) class Resource(object): @@ -53,7 +54,7 @@ class Resource(object): try: return self.attrs[key.lower()] except KeyError: - raise AttributeError, key + raise AttributeError(key) def __setattr__(self, key, value): key = key.lower() @@ -72,15 +73,15 @@ class Resource(object): value = getattr(self, funname)(value) else: 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 return root @staticmethod def format_duration(s): - if isinstance(s, basestring): + if isinstance(s, str): return s # assume it is a number @@ -104,7 +105,7 @@ class ResourceList(list): def append(self, k): assert isinstance(k, Resource) mt = k.protocolInfo.split(':')[2] - if self._mt.has_key(mt): + if mt in self._mt: return list.append(self, k) @@ -204,12 +205,12 @@ class Object(object): else: self.restricted = '0' - if kwargs.has_key('content'): + if 'content' in kwargs: self._content = kwargs.pop('content') for i in kwargs: 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]) def __cmp__(self, other): @@ -245,12 +246,12 @@ class Object(object): if obj is None: continue 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: try: resiter = iter(self.res) - except TypeError, x: + except TypeError as x: resiter = [ self.res ] for res in resiter: root.append(res.toElement()) @@ -374,8 +375,11 @@ class Container(Object, list): 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): if self.doingUpdate: @@ -396,12 +400,12 @@ class Container(Object, list): # Delete the old object that no longer exists. # Make a mapping of current names to ids. 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()): if i not in children: didupdate = True # delete - print 'del:', `id`, `i` + print('del:', repr(id), repr(i)) self.cd.delItem(id) self.needcontupdate = True else: @@ -413,7 +417,7 @@ class Container(Object, list): for i in children: if i in names: if isdict: - print 'oc:', `oldchildren[i]`, `children[i]` + print('oc:', repr(oldchildren[i]), repr(children[i])) if oldchildren[i] == children[i]: continue @@ -433,7 +437,7 @@ class Container(Object, list): #print 'i:', `i`, `isdict`, `args`, `self` pass except UnicodeEncodeError: - print 'i decode error' + print('i decode error') klass, name, args, kwargs = self.createObject(i, *args) if klass is not None: @@ -457,7 +461,7 @@ class Container(Object, list): if self.id == '0': self.updateID = (self.updateID + 1) else: - self.updateID = (self.updateID + 1) % (1l << 32) + self.updateID = (self.updateID + 1) % (1 << 32) Container.didUpdate(self.cd['0']) def _addSet(self, e, items): @@ -502,7 +506,7 @@ class MockContainer(object): self.itemiter = itertools.count(1) def addItem(self, *args, **kwargs): - return self.itemiter.next() + return next(self.itemiter) def __getitem__(self, id): return Container(None, '0', None, None) @@ -570,9 +574,9 @@ class StorageFolder(Container): storageUsed = -1 -class DIDLElement(_ElementInterface): +class DIDLElement(Element): def __init__(self): - _ElementInterface.__init__(self, '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: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\OnlineMedia\\', '0\\', 'OnlineMedia')) - print tostring(root) + print(tostring(root)) diff --git a/FSStorage.py b/FSStorage.py index d0a0094..6469522 100644 --- a/FSStorage.py +++ b/FSStorage.py @@ -13,14 +13,13 @@ import FileDIDL import errno import itertools import os -import sets import stat from DIDLLite import StorageFolder, Item, Resource, ResourceList from twisted.web import resource, server, static from twisted.python import log from twisted.internet import abstract, interfaces, process, protocol, reactor -from zope.interface import implements +from zope.interface import implementer __all__ = [ 'registerklassfun', 'registerfiletoignore', 'FSObject', 'FSItem', 'FSDirectory', @@ -71,7 +70,7 @@ class FSObject(object): self.pstat = nstat self.doUpdate(**kwargs) - except OSError, x: + except OSError as x: log.msg('os.stat, OSError: %s' % x) if x.errno in (errno.ENOENT, errno.ENOTDIR, errno.EPERM, ): # We can't access it anymore, delete it @@ -83,17 +82,17 @@ class FSObject(object): def __repr__(self): return '<%s.%s: path: %s, id: %s, parent: %s, title: %s>' % \ (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): def __init__(self, path, mods, request): @@ -166,7 +165,7 @@ class DynamTransfer(protocol.ProcessProtocol): #'-vb', '8000k', #'-sc_threshold', '500000', '-b_strategy', '1', '-max_b_frames', '6', ] + 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, None, None, self) self.proc.closeStdin() diff --git a/FileDIDL.py b/FileDIDL.py index 7f54049..1d5feac 100644 --- a/FileDIDL.py +++ b/FileDIDL.py @@ -30,6 +30,7 @@ mimetoclass = { def getClassMT(name, mimetype = None, fp = None): '''Return a tuple of the DIDLLite class and mimetype responsible for the named/mimetyped/fpd file.''' + if mimetype is None: fn, ext = os.path.splitext(name) ext = ext.lower() @@ -40,9 +41,9 @@ def getClassMT(name, mimetype = None, fp = None): return None, None ty = mimetype.split('/')[0] - if mimetoclass.has_key(mimetype): + if mimetype in mimetoclass: klass = mimetoclass[mimetype] - elif mimetoclass.has_key(ty): + elif ty in mimetoclass: klass = mimetoclass[ty] else: # XXX - We could fall file -i on it @@ -64,7 +65,7 @@ def buildClassMT(baseklass, name, *args, **kwargs): class ret(baseklass, klass): 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 diff --git a/SSDP.py b/SSDP.py index 84c4f66..4a041eb 100644 --- a/SSDP.py +++ b/SSDP.py @@ -52,27 +52,24 @@ class SSDPServer(DatagramProtocol): def doStop(self): '''Make sure we send out the byebye notifications.''' - for st in self.known.keys(): + for st in list(self.known.keys()): self.doByebye(st) del self.known[st] DatagramProtocol.doStop(self) - def datagramReceived(self, data, (host, port)): + def datagramReceived(self, data, hostporttup): """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') 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] == '*': # SSDP discovery @@ -83,20 +80,20 @@ class SSDPServer(DatagramProtocol): else: 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 the address specified by (host, port).""" - + host, port = hostporttup log.msg('Discovery request for %s' % headers['st']) # Do we know about this service? if headers['st'] == 'ssdp:all': for i in self.known: - hcopy = dict(headers.iteritems()) + hcopy = dict(headers.items()) hcopy['st'] = i self.discoveryRequest(hcopy, (host, port)) return - if not self.known.has_key(headers['st']): + if headers['st'] not in self.known: return #print 'responding' @@ -110,7 +107,7 @@ class SSDPServer(DatagramProtocol): response.extend(('', '')) delay = random.randint(0, int(headers['mx'])) 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): """Register a service or device that this SSDP server will @@ -144,12 +141,12 @@ class SSDPServer(DatagramProtocol): 'Host: %s:%d' % (SSDP_ADDR, SSDP_PORT), 'NTS: ssdp:byebye', ] - stcpy = dict(self.known[st].iteritems()) + stcpy = dict(self.known[st].items()) stcpy['NT'] = 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 = '\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)) @@ -162,19 +159,19 @@ class SSDPServer(DatagramProtocol): 'Host: %s:%d' % (SSDP_ADDR, SSDP_PORT), 'NTS: ssdp:alive', ] - stcpy = dict(self.known[st].iteritems()) + stcpy = dict(self.known[st].items()) stcpy['NT'] = 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(('', '')) - 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 details of the SSDP service announced.""" - + host, port = hostporttup if headers['nts'] == 'ssdp:alive': - if not self.elements.has_key(headers['nt']): + if headers['nt'] not in self.elements: # Register device/service self.elements[headers['nt']] = {} self.elements[headers['nt']]['USN'] = headers['usn'] @@ -182,7 +179,7 @@ class SSDPServer(DatagramProtocol): log.msg('Detected presence of %s' % headers['nt']) #log.msg('headers: %s' % `headers`) elif headers['nts'] == 'ssdp:byebye': - if self.elements.has_key(headers['nt']): + if headers['nt'] in self.elements: # Unregister device/service del(self.elements[headers['nt']]) log.msg('Detected absence for %s' % headers['nt']) diff --git a/ZipStorage.py b/ZipStorage.py index bafc989..5273eca 100644 --- a/ZipStorage.py +++ b/ZipStorage.py @@ -6,21 +6,7 @@ __version__ = '$Change$' import itertools import os.path -import sets 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 from DIDLLite import StorageFolder, Item, VideoItem, AudioItem, TextItem, ImageItem, Resource diff --git a/audio.py b/audio.py index d8dba4a..d48cd67 100644 --- a/audio.py +++ b/audio.py @@ -28,7 +28,7 @@ def bytespersecmt(mt): try: r = mttobytes[tmp[0].lower()] except KeyError: - raise ValueError('invalid audio type: %s' % `tmp[0]`) + raise ValueError('invalid audio type: %s' % repr(tmp[0])) v = set(('rate', 'channels')) for i in tmp[1:]: @@ -38,7 +38,7 @@ def bytespersecmt(mt): r *= int(value) else: raise ValueError('invalid audio parameter %s in %s' % - (`arg`, `mt`)) + (repr(arg), repr(mt))) return r @@ -67,7 +67,7 @@ class AudioPlayer(FileDescriptor): self._writeDisconnected = True def writeSomeData(self, data): - print 'wsd:', len(data) + print('wsd:', len(data)) return fdesc.writeToFD(self.fileno(), data) def doRead(self): @@ -76,7 +76,7 @@ class AudioPlayer(FileDescriptor): def connectionLost(self, reason): FileDescriptor.connectionLost(self, reason) - print 'AP, connectionLost' + print('AP, connectionLost') self.fileno = lambda: -1 self.setparameters = None if self._dev is not None: @@ -85,7 +85,7 @@ class AudioPlayer(FileDescriptor): self.attached = None def stopProducing(self): - print 'AP, sp' + print('AP, sp') self.writefun = lambda x: None FileDescriptor.stopProducing(self) @@ -137,13 +137,13 @@ class AudioResource(resource.Resource): nchan = int(nchan) rate = int(rate) except AttributeError: - raise ValueError('Invalid audio format: %s' % `origfmt`) + raise ValueError('Invalid audio format: %s' % repr(origfmt)) try: mt = self.mtformat[fmt] except KeyError: raise KeyError('No mime-type for audio format: %s.' % - `origfmt`) + repr(origfmt)) return '%s;rate=%d;channels=%d' % (mt, rate, nchan) @@ -158,7 +158,7 @@ class AudioResource(resource.Resource): try: request.setHeader('content-type', self.getmimetype(fmt, nchan, rate)) - except (ValueError, AttributeError, KeyError), x: + except (ValueError, AttributeError, KeyError) as x: return error.ErrorPage(http.UNSUPPORTED_MEDIA_TYPE, 'Unsupported Media Type', str(x)).render(request) @@ -188,7 +188,7 @@ class ossaudiodev_fmts: pass 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)) class AudioSource(AudioItem): @@ -219,7 +219,7 @@ def getfmtstrings(f): r.append(i) while f: - print f, f & -f + print(f, f & -f) r.append(f & -f) f ^= f & -f @@ -263,10 +263,10 @@ class FileConsumer: if __name__ == '__main__': if False: i = ossaudiodev.open('/dev/dsp2', 'r') - print getfmtstrings(i.getfmts()) + print(getfmtstrings(i.getfmts())) i.setparameters(ossaudiodev.AFMT_S16_BE, 2, 44100, True) - print `i.read(16)` + print(repr(i.read(16))) else: aplr = AudioPlayer('/dev/dsp2', 'r', (ossaudiodev.AFMT_S16_BE, 2, 44100, True)) diff --git a/audioraw.py b/audioraw.py index 5900bd7..292e661 100644 --- a/audioraw.py +++ b/audioraw.py @@ -29,7 +29,7 @@ def makeaudiomt(bitsps, rate, nchan): mt = mtformat[bitsps] except KeyError: raise KeyError('No mime-type for audio format: %s.' % - `bitsps`) + repr(bitsps)) return '%s;rate=%d;channels=%d' % (mt, rate, nchan) @@ -53,7 +53,7 @@ class DecoderProducer: self.resumeProducing() def __repr__(self): - return '' % (`self.decoder`, self.tbytes, self.skipbytes) + return '' % (repr(self.decoder), self.tbytes, self.skipbytes) def pauseProducing(self): # XXX - bug in Twisted 8.2.0 on pipelined requests this is @@ -99,11 +99,11 @@ class AudioResource(resource.Resource): self.cnt = cnt def __repr__(self): - return '' % (`self.f`, self.dec, self.start, self.cnt) + return '' % (repr(self.f), self.dec, self.start, self.cnt) def calcrange(self, rng, l): rng = rng.strip() unit, rangeset = rng.split('=') - assert unit == 'bytes', `unit` + assert unit == 'bytes', repr(unit) start, end = rangeset.split('-') start = int(start) if end: @@ -238,10 +238,10 @@ class AudioDisc(FSObject, MusicAlbum): return track['offset'] + index['offset'] 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 i = int(i) @@ -273,7 +273,7 @@ class AudioDisc(FSObject, MusicAlbum): if tt in tags: if len(tags[tt]) != 1: # XXX - track this? - print 'hun? ttitle:', `tags[tt]` + print('hun? ttitle:', repr(tags[tt])) ttitle = tags[tt][0] if ' / ' in ttitle: @@ -338,8 +338,8 @@ class AudioRawBase(FSObject): self.res.append(r) 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 #traceback.print_stack() self.baseObject.doUpdate(self) @@ -351,7 +351,7 @@ class AudioRawTrack(AudioRawBase, MusicTrack): baseObject = MusicTrack def detectaudioraw(origpath, fobj): - for i in decoders.itervalues(): + for i in decoders.values(): try: obj = i(origpath) # XXX - don't support down sampling yet @@ -378,7 +378,7 @@ def detectaudioraw(origpath, fobj): pass except: import traceback - print 'WARNING: failed to parse toc:' + print('WARNING: failed to parse toc:') traceback.print_exc() args['cuesheet'] = obj.cuesheet diff --git a/cdrtoc.py b/cdrtoc.py index 657b959..bf038e1 100644 --- a/cdrtoc.py +++ b/cdrtoc.py @@ -23,13 +23,13 @@ def decodestrend(i, pos): r.append('"') pos = bspos + 2 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 elif c == 'n': r.append('\n') pos = bspos + 2 else: - raise ValueError('unknown escape char: %s' % `c`) + raise ValueError('unknown escape char: %s' % repr(c)) else: r.append(i[pos:dqpos]) break @@ -92,7 +92,7 @@ def parsetoc(toc): elif key == '//': pass else: - raise ValueError('unknown line: %s' % `i`) + raise ValueError('unknown line: %s' % repr(i)) elif state == 1: if key == 'LANGUAGE_MAP': state = 2 @@ -135,5 +135,5 @@ if __name__ == '__main__': import sys for i in sys.argv[1:]: - print 'file:', `i` - print parsetoc(open(i).read()) + print('file:', repr(i)) + print(parsetoc(open(i).read())) diff --git a/debug.py b/debug.py index 3a27b03..f2ea40c 100644 --- a/debug.py +++ b/debug.py @@ -28,7 +28,7 @@ class RingBuffer: self.cur=0 self.__class__ = RingBufferFull 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 class RingBufferFull: @@ -47,7 +47,7 @@ def doDebugging(opt): global insertnamespace, appendnamespace, insertringbuf def insertnamespace(k, v): - assert isinstance(k, basestring) + assert isinstance(k, str) sf.namespace[k] = v def appendnamespace(k, v): @@ -71,4 +71,4 @@ def doDebugging(opt): try: reactor.listenTCP(56283, sf) except twisted.internet.error.CannotListenError: - print 'WARNING: cannot bind to debugger port.' + print('WARNING: cannot bind to debugger port.') diff --git a/dvd.py b/dvd.py index cdb420e..bb75aef 100644 --- a/dvd.py +++ b/dvd.py @@ -9,7 +9,6 @@ default_audio_lang = 'en' import itertools import os -import sets import sys sys.path.append('mpegts') diff --git a/et.py b/et.py index 406b717..fb1959c 100644 --- a/et.py +++ b/et.py @@ -29,7 +29,7 @@ except ImportError: from xml import etree as elementtree except ImportError: #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"[&<>\"]+"')) escape = re.compile(eval(r'u"[&<>\"\u0080-\uffff]+"')) @@ -60,12 +60,12 @@ def new_encode_entity(text, pattern=utf8_escape): if t is None: t = "&#%d;" % ord(char) append(t) - if type(text) == unicode: + if isinstance(text, str): return ''.join(out) else: - return u''.encode('utf-8').join(out) + return ''.encode('utf-8').join(out) try: - if type(text) == unicode: + if isinstance(text, str): return elementtree.ElementTree._encode(escape.sub(escape_entities, text), 'ascii') else: 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) -class ElementInterface(elementtree.ElementTree._ElementInterface): +class ElementInterface(elementtree.ElementTree.Element): """ helper class """ def indent(elem, level=0): @@ -128,8 +128,8 @@ def parse_xml(data, encoding="utf-8"): data = data.encode(encoding) except UnicodeDecodeError: pass - except Exception, error: - print "parse_xml encode Exception", error + except Exception as error: + print("parse_xml encode Exception", error) import traceback traceback.print_exc() @@ -137,9 +137,9 @@ def parse_xml(data, encoding="utf-8"): data = data.replace('\x00','') try: 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 else: return ET.ElementTree(p.close()) diff --git a/item.py b/item.py index 398d1d8..a53cf73 100644 --- a/item.py +++ b/item.py @@ -54,7 +54,7 @@ class ItemObject(FSObject, Item): pt = getElementText(rtpel[0]) pi = 'rtsp-rtp-udp:*:%s:*' % pt else: - print 'missing mimetype or rtppayloadtype element, skipping...' + print('missing mimetype or rtppayloadtype element, skipping...') continue url = getElementText(i.getElementsByTagName('url')[0]) diff --git a/iterrarfile.py b/iterrarfile.py deleted file mode 100644 index 16fb131..0000000 --- a/iterrarfile.py +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env python -# Copyright 2008 John-Mark Gurney - -__version__ = '$Change$' -# $Id$ - -import rarfile -from rarfile import * - -class RarFile(rarfile.RarFile): - def readiter(self, name, blksize=16384): - yield self.read(name) diff --git a/itertarfile.py b/itertarfile.py deleted file mode 100644 index 6b0037d..0000000 --- a/itertarfile.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python -# Copyright 2006 John-Mark Gurney - -__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 diff --git a/iterzipfile.py b/iterzipfile.py deleted file mode 100644 index 1d907b4..0000000 --- a/iterzipfile.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python -# Copyright 2006 John-Mark Gurney - -__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 diff --git a/mpegts/atschuff.py b/mpegts/atschuff.py index 0083f98..65bb206 100644 --- a/mpegts/atschuff.py +++ b/mpegts/atschuff.py @@ -60,10 +60,10 @@ try: except ImportError: def foo(*args): - raise NotImplementedError, 'Failed to import ctypes' + raise NotImplementedError('Failed to import ctypes') decode_title = decode_description = foo except OSError: def foo(*args): - raise NotImplementedError, 'Failed to find library huffdecode' + raise NotImplementedError('Failed to find library huffdecode') decode_title = decode_description = foo diff --git a/mpegts/mpegts.py b/mpegts/mpegts.py index 94ec6c2..0e2fe31 100755 --- a/mpegts/mpegts.py +++ b/mpegts/mpegts.py @@ -30,18 +30,18 @@ import atschuff import itertools import os -import sets import struct import time import traceback +from functools import reduce TSSYNC = '\x47' TSPKTLEN = 188 READBLK = 1024 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: def __init__(self, s): @@ -51,7 +51,7 @@ class UnReadSTR: self._buf = [] self._buftot = 0 - def __nonzero__(self): + def __bool__(self): return self._buftot or self.pos < len(self.s) def tell(self): @@ -122,7 +122,7 @@ def DVDAudioFilter(itr, subchan): for i in itr: j = Pack(UnReadSTR(i)) - if filter(checksubchan, j): + if list(filter(checksubchan, j)): yield i def findcodes(buf): @@ -138,53 +138,54 @@ def findcodes(buf): i = j + 4 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): assert len(buf) == 5 assert (ord(buf[0]) & 0x1) == 1 assert (ord(buf[2]) & 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[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[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[2]) & 0x3) << 13) | (ord(buf[3]) << 5) | \ ((ord(buf[4]) & 0xf8) >> 3) @@ -240,7 +241,7 @@ class PES: else: self.length += 6 if len(buf) < self.length: - raise IndexError, 'not enough data' + raise IndexError('not enough data') if self.stream_id == self.PADDING_ID: # Validate padding? @@ -280,8 +281,7 @@ class PES: self.DTS = read_timestamp(buf[i:i + 5]) i += 5 elif ptsdts_flag == 0x1: - raise ValueError, \ - "ptsdts flag forbidden: %d" % ptsdts_flag + raise ValueError("ptsdts flag forbidden: %d" % ptsdts_flag) if escr_flag: self.ESCR = read_escr(buf[i:i + 6]) i += 6 @@ -373,7 +373,7 @@ class Pack(list): assert (ord(d[4]) & 0xc0) == 0x40 self.SCR = read_escr(d[4:10]) 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.stuff_len = ord(d[13]) & 0x7 f.read(self.stuff_len) @@ -384,7 +384,7 @@ class Pack(list): f.read(6) hlen = (ord(d[4]) << 8) | ord(d[5]) header = f.read(hlen) - oh = map(ord, header) + oh = list(map(ord, header)) assert (oh[0] & 0x80) == 0x80 and \ (oh[2] & 0x1) == 0x1 self.rate_bound = ((oh[0] & 0x7f) << 15) | \ @@ -401,7 +401,7 @@ class Pack(list): d = f.peek(1) self.streams = {} while ord(d) & 0x80: - d = map(ord, f.read(3)) + d = list(map(ord, f.read(3))) assert (d[1] & 0xc0) == 0xc0 scaleflag = bool(d[1] & 0x20) self.streams[d[0]] = (((d[1] & 0x1f) << @@ -437,8 +437,8 @@ class Pack(list): def __str__(self): buf = [] 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) | \ ((self.SCR[1] << 1) & 0x3fe) | 0x1 for i in range(6): @@ -449,7 +449,7 @@ class Pack(list): buf.append(chr(((muxr << 2) & 0xfc) | 0x3)) buf.append(chr(0xf8 | (self.stuff_len & 7))) buf.append('\xff' * self.stuff_len) - buf.extend(map(str, self)) + buf.extend(list(map(str, self))) return ''.join(buf) # These are strings due to the floating point numbers @@ -491,7 +491,7 @@ class ISO639LangDescriptor(list): assert len(b) % 4 == 0 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])] self.append((lang, atype)) @@ -601,9 +601,7 @@ class AC3Descriptor: else: assert NotImplementedError, \ '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): v = ['sample_rate', 'bsid', 'br_exact', 'bitrate', @@ -619,11 +617,11 @@ class ContentAdvisory(list): cnt = ord(data[0]) & 0x3f i = 1 - for j in xrange(cnt): + for j in range(cnt): region, dim = struct.unpack('>BB', data[i: i + 2]) i += 2 d = {} - for j in xrange(dim): + for j in range(dim): d[ord(data[i])] = ord(data[i + 1]) & 0xf i += 2 desclen = ord(data[i]) @@ -669,13 +667,13 @@ class MultiStringStruct(dict): return data.decode('UTF-16-BE') elif mode == 0x3e: # 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 assert mode < 0x34, 'Invalid mode: %#x' % mode 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, \ 'Invalid comp: %#x, mode: %#x' % (comp, mode) @@ -707,7 +705,7 @@ class ComponentNameDescriptor(MultiStringStruct): MultiStringStruct.__repr__(self) def FindMe(data): - raise RuntimeError, 'found me' + raise RuntimeError('found me') Descriptors = { # 0-63 Are listed in ISO 13818-1 Table 2-40 @@ -738,82 +736,82 @@ PIDs = { } 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.''' if verbose: - i_crc = 0xffffffffl + i_crc = 0xffffffff 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)] - print hex(i_crc) + print(hex(i_crc)) 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 def psip_crc32(data): @@ -824,7 +822,7 @@ def getdescriptors(tb): i = 0 while i < len(tb): t = ord(tb[i]) - if d.has_key(t): + if t in d: l = ord(tb[i + 1]) data = tb[i + 2: i + 2 + l] #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 # above in the crc calculations. 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) | \ ord(payload[4]) self.version = (ord(payload[5]) & 0x3e) >> 1 @@ -1007,7 +1004,7 @@ class PAT(PSIPObject, dict): self.clear() def has_pid(self, pid): - return self.pid_dict.has_key(pid) + return pid in self.pid_dict def get_prog(self, pid): return self.pid_dict[pid] @@ -1036,8 +1033,8 @@ def getaudiovideopids(pmt, lang = None): vpids.append(cpid) elif i[0] == 129: 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]: apids.append(cpid) else: @@ -1067,7 +1064,7 @@ class PMT(PSIPObject, dict): self.clear() del self.es[:] - def __nonzero__(self): + def __bool__(self): return len(self) or bool(self.es) def parse_table(self, psip): @@ -1092,7 +1089,7 @@ class PMT(PSIPObject, dict): def repr_part(self): return [ 'PCRpid: %d' % self.pcrpid, dict.__repr__(self), - 'ES: %s' % `self.es` ] + 'ES: %s' % repr(self.es) ] def channelmajorminorsort(x, y): if x['major'] != y['major']: @@ -1131,7 +1128,7 @@ class STT(PSIPObject): self.ds_hour = 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): def __init__(self, pidtable): @@ -1149,7 +1146,7 @@ class MGT(list): ntables = struct.unpack('>H', psip.table[1:3])[0] i = 3 - for foo in xrange(ntables): + for foo in range(ntables): type, pid, version, nbytes, desclen = \ struct.unpack('>HHBIH', psip.table[i:i + 11]) i += 11 @@ -1162,7 +1159,7 @@ class MGT(list): # start watch if type >= 0x100 and type <= 0x17f: - if self.pidtable.has_key(pid): + if pid in self.pidtable: # XXX - check that it's in watch pass else: @@ -1171,7 +1168,7 @@ class MGT(list): self.pidtable[pid] = TSPSIPHandler({ 0xcb: EIT() }) elif type >= 0x200 and type <= 0x27f: - if self.pidtable.has_key(pid): + if pid in self.pidtable: # XXX - check that it's in watch pass else: @@ -1189,7 +1186,7 @@ class MGT(list): #print `self` def __repr__(self): - return '' % (`self.desc`, + return '' % (repr(self.desc), list.__repr__(self)) class EIT(list): @@ -1206,7 +1203,7 @@ class EIT(list): ntables = ord(psip.table[1]) i = 2 - for foo in xrange(ntables): + for foo in range(ntables): event_id, start_time, lochilen, lolength, titlelen = \ struct.unpack('>HIBHB', psip.table[i:i + 10]) i += 10 @@ -1249,9 +1246,9 @@ class TVCT(PSIPObject, dict): chancnt = ord(tb[i]) i += 1 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 major = (((ord(tb[i]) << 8) | ord(tb[i + 1])) >> 2) & \ 0x3ff @@ -1337,7 +1334,7 @@ class TSPESHandler: payload = p.payload 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.pes_len = (ord(payload[4]) << 8) | ord(payload[5]) if not self.is_video(): @@ -1373,7 +1370,7 @@ class TSPESHandler: def read_clock(buf): 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[4]) >> 7) extension = ((ord(buf[4]) & 0x1) << 8) | ord(buf[5]) @@ -1609,27 +1606,27 @@ import re import sys def usage(): - print 'Usage: %s -lmty ' % sys.argv[0] - print ' %s -k ' % sys.argv[0] - print ' %s -b [ -p ] ' % sys.argv[0] - print ' %s -c -o ' % 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 Starting pos' - print ' -e Ending pos' + print('Usage: %s -lmty ' % sys.argv[0]) + print(' %s -k ' % sys.argv[0]) + print(' %s -b [ -p ] ' % sys.argv[0]) + print(' %s -c -o ' % 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 Starting pos') + print(' -e Ending pos') def findchannel(tvct, chan): for i in tvct['channels']: @@ -1661,18 +1658,18 @@ def GetTVCT(tsstream): } def getpmt(pid, pm = pmts, psp = psippids): - if not pm.has_key(pid): + if pid not in pm: pm[pid] = PMT() psp[pid] = TSPSIPHandler({ 0x02: pm[pid] }) def needpmts(pm = pmts): - for i in pm.itervalues(): + for i in pm.values(): if not i: return True return False - for i in itertools.imap(TSPacket, tsstream): + for i in map(TSPacket, tsstream): try: psippids[i.pid](i) except ValueError: @@ -1689,7 +1686,7 @@ def GetTVCT(tsstream): if needpat and pat: needpat = False - for j in pat.itervalues(): + for j in pat.values(): getpmt(j) if not (needtvct or needpat or needpmts()): @@ -1700,11 +1697,10 @@ def GetTVCT(tsstream): lst.sort(channelmajorminorsort) except KeyError: # 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, - range(1, len(pat) + 1)) + list(range(1, len(pat) + 1)))) tvct = { 'channels': lst } for i in lst: @@ -1817,12 +1813,12 @@ def main(): }) def getpmt(pid, pm = pmts, psp = psippids): - if not pm.has_key(pid): + if pid not in pm: pm[pid] = PMT() psp[pid] = TSPSIPHandler({ 0x02: pm[pid] }) def needpmts(pm = pmts): - for i in pm.itervalues(): + for i in pm.values(): if not i: return True @@ -1831,7 +1827,7 @@ def main(): lastpcr = 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'): # print 'splice_countdown:', repr(i) #if hasattr(i, 'PCR'): @@ -1847,15 +1843,15 @@ def main(): if lastpcr is not None: # I've only seen 2703 as the largest if i.PCR[0] - lastpcr[0] > 3000: - print lastpatpos + print(lastpatpos) lastpcr = i.PCR try: psippids[i.pid](i) - except ValueError, x: + except ValueError as x: #import traceback #print traceback.print_exc() - print >>sys.stderr, 'bad crc:', repr(i) + print('bad crc:', repr(i), file=sys.stderr) continue except KeyError: pass @@ -1888,7 +1884,7 @@ def main(): if needpat and pat: needpat = False - for pn, j in pat.iteritems(): + for pn, j in pat.items(): if pn == 0: # XXX - NIT continue @@ -1896,8 +1892,8 @@ def main(): getpmt(j) 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 needallmaps = False @@ -1914,11 +1910,11 @@ def main(): output)) if allmaps: - print repr(pat) - print repr(pmts) + print(repr(pat)) + print(repr(pmts)) if printtvct: - print repr(tvct) + print(repr(tvct)) if listchan: #List channels @@ -1935,16 +1931,15 @@ def main(): if i['prog_num'] != 0 and i['prog_num'] != 0xffff: #print repr(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: 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: - totpkts = sum(pidcnt.itervalues()) - i = pidcnt.items() + totpkts = sum(pidcnt.values()) + i = list(pidcnt.items()) if printbandwidthpercent: def secondfirst(x, y): if x[1] == y[1]: @@ -1954,11 +1949,11 @@ def main(): else: i.sort() 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: - print inp.tell() + print(inp.tell()) def justprint(v, p): '''v is pid, p is the data''' @@ -1966,15 +1961,15 @@ def justprint(v, p): return pes = PES(p) if pes.data[3] != '\x00': - print `pes` + print(repr(pes)) return 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): - 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 True: @@ -1984,7 +1979,7 @@ if __name__ == '__main__': if False: ps = UnRead(sys.argv[1]) while ps: - print `Pack(ps)` + print(repr(Pack(ps))) sys.exit() s = TSPStream(open(sys.argv[1])) @@ -2007,7 +2002,7 @@ if __name__ == '__main__': 0x1ffb: TSPSIPHandler({ 0xc8: tvct }), } first = last = None - for j in itertools.imap(TSPacket, s): + for j in map(TSPacket, s): count += 1 if j.pid == 8191 or (j.pid != 0 and j.pid != 48): skipped += 1 @@ -2019,24 +2014,24 @@ if __name__ == '__main__': pidhandlers[j.pid](j) except KeyError: pass - except ValueError, x: - print 'VE:', x + except ValueError as x: + print('VE:', x) #if pidhandlers[0x1ffb][0xc8]: # print repr(pidhandlers[0x1ffb][0xc8]) # We should probably cache which ones we've added, and remove # 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 pmts[k] = PMT() 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) for l in k.es: - if pesstreams.has_key(l[1]): + if l[1] in pesstreams: continue - print repr(l) + print(repr(l)) pesstreams[l[1]] = TSPESHandler(lambda x, y = l[1]: justprint(y, x)) pidhandlers[l[1]] = pesstreams[l[1]] @@ -2053,8 +2048,7 @@ if __name__ == '__main__': pids[j.pid] += 1 except KeyError: 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) diff --git a/mpegts/tssel.py b/mpegts/tssel.py index ab3ffff..e62b140 100755 --- a/mpegts/tssel.py +++ b/mpegts/tssel.py @@ -32,7 +32,6 @@ sys.path.append('/Users/jgurney/p4/bktrau/info') import itertools import mpegts -import sets import struct import sys diff --git a/mpegtsmod.py b/mpegtsmod.py index 1ce07ff..5365f02 100644 --- a/mpegtsmod.py +++ b/mpegtsmod.py @@ -9,9 +9,9 @@ tsselpypath = 'mpegts/tssel.py' default_audio_lang = 'eng' import array +import io import itertools import os -import sets import struct import sys @@ -29,10 +29,9 @@ from twisted.spread import pb from twisted.internet import abstract, process, protocol, reactor from twisted.web import error, http, resource, server -class _LimitedFile(file): +class _LimitedFile(io.FileIO): def __init__(self, *args, **kwargs): - self.__size = kwargs['size'] - del kwargs['size'] + self.__size = kwargs.pop('size') file.__init__(self, *args, **kwargs) def remain(self): @@ -67,7 +66,7 @@ class MPEGTSTransfer(pb.Viewable): return # get data and write to request. try: - data = self.iter.next() + data = next(self.iter) if data: # this .write will spin the reactor, calling # .doWrite and then .resumeProducing again, so @@ -117,9 +116,9 @@ class DynamTSTransfer(pb.Viewable): data = self.fp.read(min(abstract.FileDescriptor.bufferSize, self.size - self.written) // 188 * 188) 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': - print 'bad sync' + print('bad sync') continue frst = dataarray[i + 1] pid = (frst & 0x1f) << 8 | dataarray[i + 2] @@ -141,7 +140,7 @@ class DynamTSTransfer(pb.Viewable): # Remaining fields before array startpmt += 5 arraysize -= 5 - for startpmt in xrange(startpmt, + for startpmt in range(startpmt, min(i + 188 - 3, startpmt + arraysize), 4): prognum, ppid = struct.unpack('>2H', data[startpmt:startpmt + 4]) @@ -149,7 +148,7 @@ class DynamTSTransfer(pb.Viewable): if ppid == self.pmt: break 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.pmt, prognum)) @@ -157,14 +156,14 @@ class DynamTSTransfer(pb.Viewable): if pid == 0 and self.didpat: 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 - pn = self.pats.next() + pn = next(self.pats) data = data[:i] + pn + data[i + 188:] if repcnt > 1: - print 'repcnt:', repcnt, 'len(data):', len(data) + print('repcnt:', repcnt, 'len(data):', len(data)) if data: self.written += len(data) @@ -195,7 +194,7 @@ class DynamTSTransfer(pb.Viewable): try: self.fp = open(path) - except IOError, e: + except IOError as e: import errno if e[0] == errno.EACCESS: return error.ForbiddenResource().render(request) diff --git a/pymediaserv b/pymediaserv index 8098a67..207ba49 100755 --- a/pymediaserv +++ b/pymediaserv @@ -6,11 +6,15 @@ from twisted.internet import reactor from twisted.application import service from twisted.python import log, usage -import ConfigParser +import configparser import pymeds import os.path import sys +#fix for wstools +import collections +collections.MutableMapping = collections.abc.MutableMapping + defconfigfile = 'pymeds.ini' class ConfigFile(pymeds.Options): optParameters = [ [ 'config', 'c', defconfigfile, @@ -21,10 +25,10 @@ if __name__ == '__main__': try: config.checkpath = False config.parseOptions() - print `config` + print(repr(config)) if os.path.exists(config['config']): - print 'foo' - scp = ConfigParser.SafeConfigParser() + print('foo') + scp = configparser.SafeConfigParser() scp.read(config['config']) config.update(scp.items('pymeds')) @@ -32,12 +36,12 @@ if __name__ == '__main__': config.checkpath = True config.postOptions() elif config['config'] != defconfigfile: - print 'bar' + print('bar') raise usage.UsageError( '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) log.startLogging(sys.stdout) diff --git a/pymeds.py b/pymeds.py index d0e1e04..274f4a4 100755 --- a/pymeds.py +++ b/pymeds.py @@ -13,15 +13,15 @@ __version__ = '$Change: 1740 $' # stage, where we simulate a namespace to either be thrown away when the # time comes, or merge into the correct one) 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? def tryloadmodule(mod): try: return __import__(mod) except ImportError: - #import traceback - #traceback.print_exc() + import traceback + traceback.print_exc() pass # 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: checkmodules.sort() - print 'The following modules were not loaded:', ', '.join(checkmodules) + print('The following modules were not loaded:', ', '.join(checkmodules)) from FSStorage import FSDirectory import os @@ -58,12 +58,12 @@ import os.path import random import socket import string -import urlparse +import urllib.parse from twisted.application import internet, service from twisted.python import usage 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): checkpath = True @@ -75,14 +75,14 @@ class Options(usage.Options): def postOptions(self): p = self['path'] 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): # XXX - twisted doesn't let you provide a message on what # arguments are required, so we will do our own work in here. if len(args) not in (1, 2): - raise usage.UsageError, 'Arguments: addr [ port ]' + raise usage.UsageError('Arguments: addr [ port ]') self['addr'] = args[0] if len(args) == 1: @@ -154,8 +154,8 @@ def makeService(config): 'uuid': uuid, '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() 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 # enumerate the directory. 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) debug.insertnamespace('cds', cds) - root.putChild('ContentDirectory', cds) + root.putChild(b'ContentDirectory', cds) 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() @@ -186,7 +186,7 @@ def makeService(config): def 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, 'upnp:rootdevice', rdxml) diff --git a/pyvr.py b/pyvr.py index 171a8d8..7d5417f 100644 --- a/pyvr.py +++ b/pyvr.py @@ -13,8 +13,8 @@ import time from twisted.internet import reactor from twisted.python import log import twisted.web -import urlparse -import urllib2 +import urllib.parse +import urllib.request, urllib.error, urllib.parse def getPage(url, contextFactory=None, *args, **kwargs): """Download a web page as a string. @@ -47,10 +47,10 @@ class PYVRShow(VideoItem): VideoItem.__init__(self, *args, **kwargs) url = self.info['link'] - sc = urlparse.urlparse(url)[0] + sc = urllib.parse.urlparse(url)[0] if not sc: # need to combine w/ base url - url = urlparse.urljoin(baseurl, url) + url = urllib.parse.urljoin(baseurl, url) self.res = Resource(url, 'http-get:*:%s:*' % self.info['mimetype']) self.res.duration = self.info['duration'] @@ -126,7 +126,7 @@ class PYVRShows(Container): i = 1 while True: title = '%s Copy %d' % (ep['subtitle'], i) - if not eps.has_key(title): + if title not in eps: return title i += 1 @@ -135,8 +135,8 @@ class PYVRShows(Container): ret = {} for pos, i in enumerate(eps): 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) i['pos'] = pos ret[title] = i @@ -184,9 +184,9 @@ class PYVR(FSObject, Container): def runCheck(self): while True: try: - self.page = urllib2.urlopen(self.url) + self.page = urllib.request.urlopen(self.url) break - except urllib2.HTTPError: + except urllib.error.HTTPError: time.sleep(.1) #self.page = getPage(self.url, method='HEAD') #self.page.deferred.addErrback(self.errCheck).addCallback( @@ -195,7 +195,7 @@ class PYVR(FSObject, Container): return self.doCheck(self.page) def errCheck(self, x): - print 'errCheck:', `x` + print('errCheck:', repr(x)) self.runCheck() def doCheck(self, x): @@ -225,14 +225,14 @@ class PYVR(FSObject, Container): #self.pend = None self.newobjs = recxmltoobj(page.read()) - print 'pp:', `self.newobjs` + print('pp:', repr(self.newobjs)) self.doUpdate() def genChildren(self): - return self.newobjs.keys() + return list(self.newobjs.keys()) def createObject(self, i, arg=None): - print 'co:', `i`, `arg` + print('co:', repr(i), repr(arg)) return PYVRShows, i, (), { 'show': i, 'pyvr': self } def doUpdate(self): diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..2669939 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +twisted +-e git+https://github.com/Synerty/SOAPpy-py3#egg=SOAPpy-py3 diff --git a/slinkemod.py b/slinkemod.py index 0b9d0d1..e8a859a 100644 --- a/slinkemod.py +++ b/slinkemod.py @@ -57,7 +57,7 @@ class LimitedAudioProducer(object): return r 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 self.write = lambda x: None self.producer.stopProducing() @@ -74,19 +74,19 @@ class LimitedAudioProducer(object): return self.producer.resumeProducing() def stopProducing(self): - print 'lap: sp' + print('lap: sp') self.shutdown() # IConsumer def registerProducer(self, producer, streaming): - print 'lap: regp' + print('lap: regp') self.producer = producer self.streamingProducer = streaming self.consumer.registerProducer(self, streaming) def unregisterProducer(): - print 'lap: unregp' + print('lap: unregp') self.shutdown() def write(self, data): @@ -122,7 +122,7 @@ class ChangerTrack(resource.Resource): return self._res.getmimetype() def render(self, request): - print 'CTrender:', `request.postpath`, `request.method`, `request` + print('CTrender:', repr(request.postpath), repr(request.method), repr(request)) self.setlength(request) if request.method == 'HEAD': @@ -156,7 +156,7 @@ class ChangerTrack(resource.Resource): 'content-length', [ str(r) ]) def docleanup(self, nf, request): - print 'docleanup' + print('docleanup') nf.addBoth(self.dostop) nf.addBoth(lambda x: self.dounlock(request)) @@ -168,19 +168,19 @@ class ChangerTrack(resource.Resource): return None def dostop(self, arg): - print 'dostop' + print('dostop') d = self._obj.stop() # Make sure we have stopped before we continue d.addBoth(lambda x: arg) return d def logerr(self, exc, *args): - print 'logerr:', `args` + print('logerr:', repr(args)) exc.printTraceback() #exc.printDetailedTraceback() 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): self.dounlock(request) # XXX - look at queue and decide @@ -192,7 +192,7 @@ class ChangerTrack(resource.Resource): return exc def printarg(self, args): - print 'pa:', `self`, `args` + print('pa:', repr(self), repr(args)) def unregisterProducer(self): resource.Resource.unregisterProducer(self) @@ -298,15 +298,15 @@ class SLinkEChangerDisc(MusicAlbum): # ContentDirectory calls this def checkUpdate(self): - print 'cU' + print('cU') curid = self.getID() if self._lastid != curid: - print 'dU' + print('dU') self.doUpdate() self._lastid = curid 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): return SLinkEChangerDiscTrack, i, (), { 'discobj': self, 'track': arg } @@ -335,7 +335,7 @@ class SLinkEChanger(StorageSystem, slinke.CDPlayerProtocol): config['audiodefault']) def aftershutdown(self): - print 'in SLinkEChanger after shutdown' + print('in SLinkEChanger after shutdown') self._s.close() self._s = None @@ -350,7 +350,7 @@ class SLinkEChanger(StorageSystem, slinke.CDPlayerProtocol): self._poweroff.cancel() self._poweroff = None self._lock = obj - print 'tl: locked:', `self._lock` + print('tl: locked:', repr(self._lock)) return defer.succeed(True) d = defer.Deferred() @@ -372,24 +372,24 @@ class SLinkEChanger(StorageSystem, slinke.CDPlayerProtocol): return False def unlock(self, obj): - print 'unlock:', `obj` + print('unlock:', repr(obj)) if self._lock is None: - print 'ul: not locked' + print('ul: not locked') raise RuntimeError('unlocked when not locked') 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: - print 'really unlocked' + print('really unlocked') self._lock = None self._poweroff = reactor.callLater(300, self.turnoff) return pobj = self._pendinglocks.pop(0) self._lock = pobj[1] - print 'passing lock:', `self._lock` + print('passing lock:', repr(self._lock)) pobj[2].cancel() pobj[0].callback(True) @@ -402,7 +402,7 @@ class SLinkEChanger(StorageSystem, slinke.CDPlayerProtocol): a = defer.waitForDeferred(self.checkids()) yield a a.getResult() - print 'powering cd changer off' + print('powering cd changer off') # checkids may have rescheduled us. If we don't cancel it, # we'd wake up every five minutes just to turn off again. @@ -415,13 +415,12 @@ class SLinkEChanger(StorageSystem, slinke.CDPlayerProtocol): @defer.deferredGenerator def checkids(self): - print 'starting checkids' + print('starting checkids') a = defer.waitForDeferred(self.transport.poweron()) 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: discnum = i i = str(i) @@ -433,7 +432,7 @@ class SLinkEChanger(StorageSystem, slinke.CDPlayerProtocol): except KeyError: pass - print 'missing:', `i` + print('missing:', repr(i)) # No ID, fetch it. a = defer.waitForDeferred(self.trylock(5, self)) @@ -447,12 +446,12 @@ class SLinkEChanger(StorageSystem, slinke.CDPlayerProtocol): a = defer.waitForDeferred(threads.deferToThread(CDDB.query, cddbid)) yield a queryres = a.getResult() - print 'res:', `i`, `queryres` + print('res:', repr(i), repr(queryres)) self._s[i] = { 'query': queryres, 'cddbid': cddbid, } self._changed = True except slinke.NoDisc: - print 'Disc not present: %d' % discnum + print('Disc not present: %d' % discnum) continue finally: self.unlock(self) @@ -488,7 +487,7 @@ class SLinkEChanger(StorageSystem, slinke.CDPlayerProtocol): # 210 multiple matches return q[1][0] 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): m = self.getMatch(disc, wait) @@ -502,17 +501,17 @@ class SLinkEChanger(StorageSystem, slinke.CDPlayerProtocol): t = t.decode('iso8859-1') if t.count('/') > 1: - print 'tcount:', `t` + print('tcount:', repr(t)) try: return t.split('/', 1)[1] except IndexError: - print 'ie:', `t` + print('ie:', repr(t)) return t # CDPlayerProtocol interface def connectionMade(self): super(SLinkEChanger, self).connectionMade() - print 'attached to cdplayer' + print('attached to cdplayer') self._changed = True # 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() def stateChange(self): - print 'sC' + print('sC') # ContentDirectory calls this def checkUpdate(self): diff --git a/soap_lite.py b/soap_lite.py index d5ac1c3..e1a6319 100644 --- a/soap_lite.py +++ b/soap_lite.py @@ -82,18 +82,16 @@ def build_soap_call(method, arguments, is_response=False, # append the arguments if isinstance(arguments,dict): type_map = {str: 'xsd:string', - unicode: 'xsd:string', + bytes: 'xsd:string', int: 'xsd:int', - long: 'xsd:int', float: 'xsd:float', 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)] - 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': arg_val = arg_val.lower() @@ -109,4 +107,4 @@ def build_soap_call(method, arguments, is_response=False, preamble = """""" - return preamble + ET.tostring(envelope,'utf-8') + return bytes(preamble + ET.tostring(envelope, 'unicode'), 'ascii')