![]() |
#1 |
Sigil developer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 1,274
Karma: 1101600
Join Date: Jan 2011
Location: UK
Device: Kindle PW, K4 NT, K3, Kobo Touch
|
How to get device lpath for a book
I'm looking at using the db to get my book information instead of the written metadata.calibre file (thanks to Chaley for the starting point) so that the device doesn't need to be disconnected/reconnected if columns are added/books deleted, etc.
I can get the data from the db for books on the connected Kindle device, but I can't get the lpath value - it always shows None. db = self.gui.library_view.model().db query = 'ondevice:True' id_list = db.search_getting_ids(query, None) for id in id_list: m = db.get_metadata(id, index_is_id=True) print m.lpath I'd like to get the lpath value as it will be written into the metadata.calibre file on the Kindle - preferably without reading the file (which I do at the moment), or at least the path after 'documents'. If I just use db.title or path then I think I'll just get Calibre's version of the title/path - not the version that might be modified by a save template, etc. |
![]() |
![]() |
![]() |
#2 |
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,353
Karma: 8012652
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)) 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) |
![]() |
![]() |
Advert | |
|
![]() |
#3 |
Sigil developer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 1,274
Karma: 1101600
Join Date: Jan 2011
Location: UK
Device: Kindle PW, K4 NT, K3, Kobo Touch
|
Great, I'll look into option 2. It may allow me to ignore the metadata.calibre file altogether, but I'll have to test.
|
![]() |
![]() |
![]() |
#4 |
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,353
Karma: 8012652
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
There is nothing in metadata.calibre that isn't in the device db booklist, with the exception that metadata.calibre can contain entries for books deleted during the current connection.
|
![]() |
![]() |
![]() |
#5 |
Sigil developer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 1,274
Karma: 1101600
Join Date: Jan 2011
Location: UK
Device: Kindle PW, K4 NT, K3, Kobo Touch
|
Its looking good from testing. Why do you use defaultdict instead of just dict?
I have to test using the library_view versus the memory view for columns, etc - if a new column is created I'm not sure if the device view will have the most current list of columns for books. |
![]() |
![]() |
Advert | |
|
![]() |
#6 | ||
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,353
Karma: 8012652
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
Quote:
If you use a normal dict, then you must do something like: Code:
db_id_map = {} for blist in matching: # blist == list of (row,book) tuples for the mem location for book in blist: if book.application_id not in db_id_map: # defaultdict eliminates these 2 lines db_id_map[book.application_id] = set([]) db_id_map[book.application_id].add(book) Quote:
|
||
![]() |
![]() |
![]() |
#7 |
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,353
Karma: 8012652
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
BTW: if you switch to using the library_view for metadata, then you can probably drop the requirement that people use automatic metadata management. The only items you need from the device are path/lpath, and they don't change.
|
![]() |
![]() |
![]() |
#8 |
Sigil developer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 1,274
Karma: 1101600
Join Date: Jan 2011
Location: UK
Device: Kindle PW, K4 NT, K3, Kobo Touch
|
Yes - that's exactly why I started looking at this and was the first thing I removed in the new code
![]() Now I can also do per library customizations - to show only those custom fields for this library and save them per library name. |
![]() |
![]() |
![]() |
#9 |
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,353
Karma: 8012652
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
Have you found the field_metadata class/instance? (self.gui.db.field_metadata, code in library.field_metadata.py)? It contains data descriptions of all the fields in the current library, custom and standard. You can get column datatypes, sort terms, column headings, the meta2 column the data is in, and all sorts of other things from it.
|
![]() |
![]() |
![]() |
#10 |
Sigil developer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 1,274
Karma: 1101600
Join Date: Jan 2011
Location: UK
Device: Kindle PW, K4 NT, K3, Kobo Touch
|
No, hadn't seen that, but will look it over - it looks extensive. I've been able to get what I need from the functions in database2 at least so far. We'll see when I do more testing. Don't want to go too far down the rabbit hole too soon
![]() |
![]() |
![]() |
![]() |
|
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
Calibre indicates book not on device, but it is | webdoyenne | Calibre | 13 | 06-15-2010 04:02 PM |
E-Book Stores: More Important than the Device | L.J. Sellers | General Discussions | 20 | 06-01-2010 01:06 PM |
All-round device,or specialized E-book? | dream88 | General Discussions | 32 | 05-23-2010 10:52 PM |
Which E-book device do you have? | desertgrandma | Lounge | 368 | 02-16-2009 03:48 PM |
Papyrus e-Book device | pilotbob | News | 11 | 04-20-2008 07:26 PM |