View Single Post
Old 02-19-2011, 07:31 AM   #2
chaley
Grand Sorcerer
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 11,741
Karma: 6997045
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
There is no convenient way to get the lpath if the device is not connected. It is computed by the device driver.

If the device is connected, then there are two ways to get it.

1) from metadata.calibre. You already know how to do this. You get the relative lpath this way, which is what you say you want.

2) from the 'device view database'. This will give you the 'book' entry that metadata.calibre is built from. It contains both path and lpath.

To see how to do the second, look at the remove_matching_books_from_device function (gui2.actions.delete.py). It calls paths_for_db_ids (gui2.library.models.py) to get a list of tuples of books on the device matching a list of db_ids. The tuple is (row, book), where row is the device view gui row (not useful to you I think) and book is the metadata instance for the book.

The complexity you see comes from the fact that each memory location on the device has its own db, so all of them must be checked. The loop:
Code:
        for model,name in ((self.gui.memory_view.model(), _('Main memory')),
                           (self.gui.card_a_view.model(), _('Storage Card A')),
                           (self.gui.card_b_view.model(), _('Storage Card B'))):
            to_delete[name] = (model, model.paths_for_db_ids(ids))
does that by looping through all the possible memory locations. You probably don't need the name, and the kindle might not use all the memory locations.

Once you have the three (or fewer) lists, then you should create a map of db_id to book(s). The complete code will look something like:
Code:
  # using your id_list ....
  matching = []
  for model in [self.gui.memory_view.model(),
                    self.gui.card_a_view.model(),
                    self.gui.card_b_view.model()]:
    # append a list of books. Throw away the row value
    matching.append([tup[1] for tup in model.paths_for_db_ids(id_list)])

  db_id_map = defaultdict(set)
  for blist in matching: # blist == list of (row,book) tuples for the mem location
    for book in blist:
      db_id_map[book.application_id].add(book)
At this point you have a map of db_id to sets of matching books. You can extract whatever information you need, such as lpath.
chaley is offline   Reply With Quote