This commit is contained in:
Kovid Goyal 2007-08-06 22:01:32 +00:00
parent 4b3694ac18
commit d8c8b1703b
2 changed files with 65 additions and 29 deletions

View File

@ -21,6 +21,8 @@ from base64 import b64decode as decode
from base64 import b64encode as encode from base64 import b64encode as encode
import time, re import time, re
from libprs500.devices.errors import ProtocolError
MIME_MAP = { \ MIME_MAP = { \
"lrf":"application/x-sony-bbeb", \ "lrf":"application/x-sony-bbeb", \
"rtf":"application/rtf", \ "rtf":"application/rtf", \
@ -103,7 +105,7 @@ class Book(object):
return self.root + self.rpath return self.root + self.rpath
return property(fget=fget, doc=doc) return property(fget=fget, doc=doc)
def __init__(self, node, prefix="xs1:", root="/Data/media/"): def __init__(self, node, prefix="", root="/Data/media/"):
self.elem = node self.elem = node
self.prefix = prefix self.prefix = prefix
self.root = root self.root = root
@ -115,14 +117,19 @@ class Book(object):
def fix_ids(media, cache): def fix_ids(media, cache):
""" '''
Update ids in media, cache to be consistent with their Update ids in media, cache to be consistent with their
current structure current structure
""" '''
media.purge_empty_playlists()
plitems = media.playlist_items()
cid = 0 cid = 0
for child in media.root.childNodes: for child in media.root.childNodes:
if child.nodeType == child.ELEMENT_NODE and \ if child.nodeType == child.ELEMENT_NODE and child.hasAttribute("id"):
child.hasAttribute("id"): old_id = child.getAttribute('id')
for item in plitems:
if item.hasAttribute('id') and item.getAttribute('id') == old_id:
item.setAttribute('id', str(cid))
child.setAttribute("id", str(cid)) child.setAttribute("id", str(cid))
cid += 1 cid += 1
mmaxid = cid - 1 mmaxid = cid - 1
@ -144,19 +151,26 @@ class BookList(list):
__getslice__ = None __getslice__ = None
__setslice__ = None __setslice__ = None
def __init__(self, prefix="xs1:", root="/Data/media/", sfile=None): def __init__(self, root="/Data/media/", sfile=None):
list.__init__(self) list.__init__(self)
if sfile: if sfile:
self.prefix = prefix
self.proot = root
sfile.seek(0) sfile.seek(0)
self.document = dom.parse(sfile) self.document = dom.parse(sfile)
# The root element containing all records self.root = self.document.documentElement
self.root = self.document.documentElement self.prefix = ''
if prefix == "xs1:": records = self.root.getElementsByTagName('records')
self.root = self.root.getElementsByTagName("records")[0] if records:
self.root = records[0]
for child in self.root.childNodes:
if child.nodeType == child.ELEMENT_NODE and child.hasAttribute("id"):
self.prefix = child.tagName.partition(':')[0] + ':'
break
if not self.prefix:
raise ProtocolError, 'Could not determine prefix in media.xml'
self.proot = root
for book in self.document.getElementsByTagName(self.prefix + "text"): for book in self.document.getElementsByTagName(self.prefix + "text"):
self.append(Book(book, root=root, prefix=prefix)) self.append(Book(book, root=root, prefix=self.prefix))
def max_id(self): def max_id(self):
@ -182,27 +196,51 @@ class BookList(list):
break break
return ans return ans
def playlist_items(self):
playlists = self.root.getElementsByTagName(self.prefix+'playlist')
plitems = []
for pl in playlists:
plitems.extend(pl.getElementsByTagName(self.prefix+'item'))
return plitems
def purge_empty_playlists(self):
''' Remove all playlist entries that have no children. '''
playlists = self.root.getElementsByTagName(self.prefix+'playlist')
for pl in playlists:
if not pl.getElementsByTagName(self.prefix + 'item'):
pl.parentNode.removeChild(pl)
pl.unlink()
def _delete_book(self, node):
nid = node.getAttribute('id')
node.parentNode.removeChild(node)
node.unlink()
for pli in self.playlist_items():
if pli.getAttribute('id') == nid:
pli.parentNode.removeChild(pli)
pli.unlink()
def delete_book(self, cid): def delete_book(self, cid):
""" Remove DOM node corresponding to book with C{id == cid}.""" '''
node = None Remove DOM node corresponding to book with C{id == cid}.
Also remove book from any collections it is part of.
'''
for book in self: for book in self:
if book.id == cid: if str(book.id) == str(cid):
node = book
self.remove(book) self.remove(book)
self._delete_book(book.elem)
break break
node.elem.parentNode.removeChild(node.elem)
node.elem.unlink()
def remove_book(self, path): def remove_book(self, path):
node = None '''
Remove DOM node corresponding to book with C{id == cid}.
Also remove book from any collections it is part of.
'''
for book in self: for book in self:
if book.path == path: if book.path == path:
node = book
self.remove(book) self.remove(book)
self._delete_book(book.elem)
break break
if node:
node.elem.parentNode.removeChild(node.elem)
node.elem.unlink()
def add_book(self, info, name, size, ctime): def add_book(self, info, name, size, ctime):
""" Add a node into DOM tree representing a book """ """ Add a node into DOM tree representing a book """

View File

@ -786,10 +786,8 @@ class PRS500(Device):
@return: L{BookList} @return: L{BookList}
""" """
root = "/Data/media/" root = "/Data/media/"
prefix = "xs1:"
tfile = TemporaryFile() tfile = TemporaryFile()
if oncard: if oncard:
prefix = ""
try: try:
self.get_file("a:"+self.CACHE_XML, tfile, end_session=False) self.get_file("a:"+self.CACHE_XML, tfile, end_session=False)
root = "a:/" root = "a:/"
@ -802,7 +800,7 @@ class PRS500(Device):
tfile = None tfile = None
else: else:
self.get_file(self.MEDIA_XML, tfile, end_session=False) self.get_file(self.MEDIA_XML, tfile, end_session=False)
return BookList(prefix=prefix, root=root, sfile=tfile) return BookList(root=root, sfile=tfile)
@safe @safe
def remove_books(self, paths, booklists, end_session=True): def remove_books(self, paths, booklists, end_session=True):
@ -829,9 +827,9 @@ class PRS500(Device):
@safe @safe
def upload_books(self, files, names, on_card=False, end_session=True): def upload_books(self, files, names, on_card=False, end_session=True):
card = self.card(end_session=False) card = self.card(end_session=False)
prefix = card + '/libprs500' if on_card else '/Data/media/books/' prefix = card + '/libprs500/' if on_card else '/Data/media/books/'
if on_card and not self._exists(prefix)[0]: if on_card and not self._exists(prefix)[0]:
self.mkdir(prefix, False) self.mkdir(prefix[:-1], False)
paths, ctimes = [], [] paths, ctimes = [], []
names = iter(names) names = iter(names)
infiles = [file if hasattr(file, 'read') else open(file, 'rb') for file in files] infiles = [file if hasattr(file, 'read') else open(file, 'rb') for file in files]