View Single Post
Old 07-01-2014, 11:25 AM   #11
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: 12,452
Karma: 8012886
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Quote:
Originally Posted by myki View Post
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.
Add a second field assignment, probably like this:
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:
2) And a true/false one which would be true if a same serie number is found in its serie.
I assume you mean a duplicate series number? I think that the series plugin can find these.

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_)
Next you would iterate through the series_info[series]['indices'] dictionary looking for sidx values with more than one element (book id) in the set, then do what you want with that value.
Quote:
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 ).
Calibre definitely must not be running when you execute a script.

You can do a search in a script with the API call
Code:
book_ids = cache.search('#fieldname:"=' + value_to_search_for + '"')
The parameter is an arbitrary calibre search expression, including "and" and "or" if you need them. It returns a list of book ids matching that expression. You would then use that list as needed.

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.
chaley is offline   Reply With Quote