![]() |
#1 |
Zealot
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 126
Karma: 20236
Join Date: May 2014
Device: Kinde PW v1, Kobo H2O, Onyx Boox T68
|
Knowing the last serie index number
Greetings,
To improve my "save as" template, i need to know the last number of the serie where the book is part of. Is it possible ?? It would be perfect if i would't need to create a custom column for that (or a dynamic one to avoid the problem of adding a book in the serie). Thanx for your help ![]() |
![]() |
![]() |
![]() |
#2 | |
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,339
Karma: 8012652
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
Quote:
|
|
![]() |
![]() |
Advert | |
|
![]() |
#3 |
Zealot
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 126
Karma: 20236
Join Date: May 2014
Device: Kinde PW v1, Kobo H2O, Onyx Boox T68
|
Thanx for your answer chaley. When i will have more time to spend on this, i will try by using ebook-meta.exe in a batch file.
|
![]() |
![]() |
![]() |
#4 |
Well trained by Cats
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 30,912
Karma: 60358908
Join Date: Aug 2009
Location: The Central Coast of California
Device: Kobo Libra2,Kobo Aura2v1, K4NT(Fixed: New Bat.), Galaxy Tab A
|
|
![]() |
![]() |
![]() |
#5 | |
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,339
Karma: 8012652
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
Quote:
Another solution that is easier than a plugin is to write a python script that uses calibre's API. Here is an example that does what you want (I think) Code:
def init_cache(library_path): from calibre.db.backend import DB from calibre.db.cache import Cache backend = DB(library_path) cache = Cache(backend) cache.init() return cache from collections import defaultdict cache = init_cache(library_path = sys.argv[1]) series_info = {} for id_ in cache.all_book_ids(): series = cache.field_for('series', id_) if series: sidx = cache.field_for('series_index', id_) if series in series_info: sidx = max(sidx, series_info[series]['max_index']) series_info[series]['max_index'] = sidx else: series_info[series] = {'max_index':sidx, 'ids':set()} series_info[series]['ids'].add(id_) for series in series_info.iterkeys(): sidx = series_info[series]['max_index'] dct = {book_id:sidx for book_id in series_info[series]['ids']} cache.set_field('#myfloat', dct) print(series, sidx) You call the script with something like Code:
d:\CBH_Data\calibre.git>calibre-debug -e tests\highest_number_is_series.py Library.test_small |
|
![]() |
![]() |
Advert | |
|
![]() |
#6 |
Zealot
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 126
Karma: 20236
Join Date: May 2014
Device: Kinde PW v1, Kobo H2O, Onyx Boox T68
|
Very interesting !
If I understand correctly, #myfloat is a personnal column : "floating point number", where my max serie number will be automatically stored by your Python script ? And what the "Library.test_small" parameter means ? Thanks for your rich help chaley. Last edited by myki; 06-26-2014 at 02:02 PM. |
![]() |
![]() |
![]() |
#7 | |
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,339
Karma: 8012652
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
Quote:
The "Library.test_small" parameter is the name of the folder containing calibre's library. In my case I ran the script in a command box that has as its current working folder the parent of my library. You could also run it with a full path such as "C:\My Important Stuff\Books\Libraries\Calibre Library". You could just as easily hard-code the path into the script if you have only one calibre library. |
|
![]() |
![]() |
![]() |
#8 |
Zealot
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 126
Karma: 20236
Join Date: May 2014
Device: Kinde PW v1, Kobo H2O, Onyx Boox T68
|
Hello Chaley, i hope you'll still give an eye to this post...
I built a test library before continuing, then i tried your python script... And magic ! It works ! Now i would like to be able to do my own little personnal fields, based on your script but i need to learn python a bit, and how to interact with Calibre. I don't want to bother you with full of newbie questions, so... Can someone please tell me where to find some documentations, about python oriented Calibre ? Thanks in advance ![]() |
![]() |
![]() |
![]() |
#9 |
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,339
Karma: 8012652
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
@myki: the only documentation of calibre apis is the comments in the source, and even those won't help much. So just ask. For most things the needed api is small.
However, if you are thinking of a plugin then the best place to start is calibre's sample on the development section of its web site, then look at other plugins to see how the solve problems. |
![]() |
![]() |
![]() |
#10 |
Zealot
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 126
Karma: 20236
Join Date: May 2014
Device: Kinde PW v1, Kobo H2O, Onyx Boox T68
|
ok thank you chaley, i will look at comments...
but i comfess that it seems very difficult to me ! So... I will ask you and the community my needs : 1) I want to feed a personnal field with the number of books of the serie it is part of. 2) And a true/false one which would be true if a same serie number is found in its serie. 3) And finally, is it possible to execute a python script on selected books only ? If Calibre has to be off to execute a script, maybe the script should be executed for my books with my flag "treated" at false (or playing with the date but... in a next step ![]() Thanx for your patience... |
![]() |
![]() |
![]() |
#11 | |||
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,339
Karma: 8012652
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
Quote:
Code:
for series in series_info.iterkeys(): sidx = series_info[series]['max_index'] book_ids = series_info[series]['ids'] dct = {book_id:sidx for book_id in book_ids} cache.set_field('#myfloat', dct) dct = {book_id:len(book_ids) for book_id in book_ids} cache.set_field('#mycount', dct) print(series, sidx) Quote:
However, you can do this as well. You would create a dictionary of the book ids for each series index for each series. The code would look something like Code:
for id_ in cache.all_book_ids(): series = cache.field_for('series', id_) if series: sidx = cache.field_for('series_index', id_) if series in series_info: sidx = max(sidx, series_info[series]['max_index']) series_info[series]['max_index'] = sidx if sidx not in series_info[series]['indices']: series_info[series]['indices'] = {sidx:set()} else: series_info[series] = {'max_index':sidx, 'ids':set(), 'indices': {sidx: set()} series_info[series]['ids'].add(id_) series_info[series]['indices'][sidx].add(id_) Quote:
You can do a search in a script with the API call Code:
book_ids = cache.search('#fieldname:"=' + value_to_search_for + '"') You must be careful where you use the search results. For example, if you use the results to compute the series info for books then you will get the wrong answer if the search doesn't find all the books in the series. It might be better to use the search results to decide which books to update, not which books to consider when computing the data. |
|||
![]() |
![]() |
![]() |
|
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
Automatically rename books with number of the serie | Ansem_93 | Library Management | 29 | 03-26-2013 06:32 AM |
[Suggestion]: Option to add serie name and number to book name | rolgiati | Calibre | 2 | 12-13-2012 12:02 AM |
Index: Making a linked index in epub | virtual_ink | ePub | 21 | 10-19-2011 11:23 PM |
Feature request: Ability to put a book in a series without an index number | lunixer | Calibre | 6 | 08-29-2011 11:37 AM |
Don't Index Number in Column View | shocampo | Calibre | 5 | 09-20-2010 11:27 PM |