Register Guidelines E-Books Today's Posts Search

Go Back   MobileRead Forums > E-Book Software > Calibre > Development

Notices

Reply
 
Thread Tools Search this Thread
Old 10-14-2022, 10:53 AM   #1
kiwidude
Calibre Plugins Developer
kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.
 
Posts: 4,637
Karma: 2162064
Join Date: Oct 2010
Location: Australia
Device: Kindle Oasis
Is there a way to get author/tag/series/publisher ids+text within a virtual library?

In my Find Duplicates plugin, the main "Find Book Duplicates" functionality respects whatever virtual library search restriction you have applied.

EDIT: On further reading I can see that it uses self.gui.library_view.model() to operate within, and then only where it needs a more specific subset that it uses db.data.search_getting_ids() passing the restriction through.

However the Metadata Variations duplicate check does *not* currently respect the virtual library selection. Looking at the code I wrote forever ago, it seems that for those searches I am invoking one of the following depending on user selection:
  • db.get_authors_with_ids()
  • db.get_series_with_ids()
  • db.get_publishers_with_ids()
  • db.get_tags_with_ids()

Is there an API equivalent I could use for these that could take a search_restriction argument? Or should I just iterate over the model to build up my own dictionaries?

Last edited by kiwidude; 10-14-2022 at 11:02 AM. Reason: Found more info...
kiwidude is offline   Reply With Quote
Old 10-14-2022, 10:59 AM   #2
kovidgoyal
creator of calibre
kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.kovidgoyal ought to be getting tired of karma fortunes by now.
 
kovidgoyal's Avatar
 
Posts: 43,860
Karma: 22666666
Join Date: Oct 2006
Location: Mumbai, India
Device: Various
Not sure what you are asking for exactly, but you first get the set of all book ids in the current virtual library. THen after that call

Code:
ans = set()
for book_id in book_ids:
   ans |= {x for x in db.new_api.field_ids_for('tags', book_id)}
and use get_id_map() to convert the ids from ans into names.
kovidgoyal is offline   Reply With Quote
Old 10-14-2022, 11:16 AM   #3
kiwidude
Calibre Plugins Developer
kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.
 
Posts: 4,637
Karma: 2162064
Join Date: Oct 2010
Location: Australia
Device: Kindle Oasis
Quote:
Originally Posted by kovidgoyal View Post
Not sure what you are asking for exactly, but you first get the set of all book ids in the current virtual library. THen after that call

Code:
ans = set()
for book_id in book_ids:
   ans |= {x for x in db.new_api.field_ids_for('tags', book_id)}
and use get_id_map() to convert the ids from ans into names.
Hi Kovid - thanks for the reply. What I wanted was exactly the same output that the direct db functions above give me, of pairs of ids with their text value. e.g. all the unique author id + their name combinations.

So it appears that indeed the answer is I need to iterate over all the books and build up my own (unique) sets...
kiwidude is offline   Reply With Quote
Old 10-14-2022, 12:13 PM   #4
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,742
Karma: 6997045
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
I think you want something like this ids_for_field() function. I don't know if the order is right. This produces (id, name) but you might want (name, id).
Code:
python:

def ids_for_field(db, ids_of_books, field_name):
	# First get all the names for the desired books.
	# Use a set to make them unique
	unique_names = set()
	for tup in db.all_field_for(field_name, ids_of_books).values():
		for vals in tup:
			unique_names.update((vals,))
	# Now get the ids for the names and build the pairs
	id_field_pairs = list()
	for aut in unique_names:
		id_field_pairs.append((db.get_item_id(field_name, aut), aut))
	return id_field_pairs

def evaluate(book, context):
	db = context.db.new_api
	print('--------------------')
	# Get the list of books in the current VL
	ids_in_vl = db.search('', restriction='authors:a')
	# Get the id,val pairs for the desired field
	field_pairs = ids_for_field(db, ids_in_vl, 'authors')
	print(field_pairs) 
	return ''
NB: I am using the python template facility to test the code, which is why "python:" and "def evaluate()" are there. It hadn't occurred to me when we added it that one use is interactive python code debugging inside calibre.
chaley is offline   Reply With Quote
Old 10-14-2022, 12:29 PM   #5
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,742
Karma: 6997045
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Here is an example that uses the current VL
Code:
python:

def ids_for_field(db, ids_of_books, field_name):
	# First get all the names for the desired books.
	# Use a set to make them unique
	unique_names = set()
	for tup in db.all_field_for(field_name, ids_of_books).values():
		for val in tup:
			unique_names.add(val)
	# Now get the ids for the names and build the pairs
	id_field_pairs = list()
	for name in unique_names:
		id_field_pairs.append((db.get_item_id(field_name, name), name))
	return id_field_pairs

def evaluate(book, context):
	print('--------------------')
	# Get the list of books in the current VL
	ids_in_vl = context.db.data.search_getting_ids('', '', use_virtual_library=True)
	# Get the id,val pairs for the desired field
	field_pairs = ids_for_field(context.db.new_api, ids_in_vl, 'authors')
	print(field_pairs) 
	return ''

Last edited by chaley; 10-14-2022 at 12:44 PM. Reason: Small improvement to ids_for_field
chaley is offline   Reply With Quote
Old 10-14-2022, 01:26 PM   #6
kiwidude
Calibre Plugins Developer
kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.
 
Posts: 4,637
Karma: 2162064
Join Date: Oct 2010
Location: Australia
Device: Kindle Oasis
Awesome, thanks chaley! That will save me much time in experimenting
kiwidude is offline   Reply With Quote
Old 10-14-2022, 04:24 PM   #7
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,742
Karma: 6997045
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Apologies for the churn. I looked at the underlying code for the API methods I used and found a significant inefficiency in what I proposed. The underlying reversed dictionary {id:name} was being generated for *every* field item. For big libraries this could be a significant performance hit.

Here is a version that reverses the id map once then uses it to build the output.
Code:
def ids_for_field(db, ids_of_books, field_name):
	# First get all the names for the desired books.
	# Use a set to make them unique
	unique_names = set()
	for tup in db.all_field_for(field_name, ids_of_books).values():
		for val in tup:
			unique_names.add(val)
	# reverse the map of ids to names so id_map[name] gives the id
	id_map = {v:k for k,v in db.get_id_map(field_name).items()}
	# Now build the pairs (id, name)
	id_field_pairs = list()
	for name in unique_names:
		id_field_pairs.append((id_map[name], name))
	return id_field_pairs
chaley is offline   Reply With Quote
Old 10-15-2022, 12:51 PM   #8
kiwidude
Calibre Plugins Developer
kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.kiwidude ought to be getting tired of karma fortunes by now.
 
Posts: 4,637
Karma: 2162064
Join Date: Oct 2010
Location: Australia
Device: Kindle Oasis
Oh that one made a massive difference indeed on my local library - thanks chaley!
kiwidude is offline   Reply With Quote
Reply


Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
How to show books with only 1 tag? Dynamic tag or virtual library? cd2013 Calibre 4 03-01-2019 06:41 PM
Virtual library from list of title/author melvinwinklie Library Management 3 12-30-2015 12:30 AM
Creating a virtual library according how many books by author mariaclaudia Calibre 5 06-04-2015 12:03 AM
Library skips publisher, goes directly to author kennyc Writers' Corner 5 08-05-2013 06:26 AM
Creating a Library file w/Author, Title, Summary and tag info asktheeightball Calibre 2 01-18-2010 10:28 AM


All times are GMT -4. The time now is 06:25 PM.


MobileRead.com is a privately owned, operated and funded community.