View Single Post
Old 03-27-2016, 11:55 AM   #728
JJanssen
Member
JJanssen began at the beginning.
 
Posts: 16
Karma: 24
Join Date: Jun 2009
Device: Kindle Paperwhite 1
Quote:
Originally Posted by JJanssen View Post
That looks remarkably like what I want. Thank you very much!
So, after a false start or two (I accidentally the spaces in the path with a \, also accidentally the destination column) I have a script that reliably puts something useful in the #format_str field of my database. It's not quite the one that I want, but that's an implementation detail that will be easily solved in a few lines of python. I wanted to have the workflow working before I go there.

But how do I use that column in my plugboard?

If I want to replace "{series}{series_index:0>4.1f| – | – }{title}", my obvious naive approach would be "{series}{series_index:{format_str}| – | – }{title}", , or with added #, but it doesn't like that. My perusal of this thread hasn't found it yet either. Since this is obviously a Solved Problem, can someone point me at the solution?

Edit: I was in the python mood anyway, so here's my extra few lines, based on the very nice script by chaley:
Spoiler:
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

import math
from collections import defaultdict
	
cache = init_cache(library_path = '/Users/jasper/Documents/Calibre Test Library/')
series_info = defaultdict(dict)
fract_ids = []

for id_ in cache.all_book_ids():
	series = cache.field_for('series', id_)
	if series:
		sidx = cache.field_for('series_index', id_)
		str_sidx = str(sidx)
		components = str_sidx.split('.')
		if components[1] == '0':
			fract_part = 0
		else:
			fract_part = len(components[1])
			fract_ids.append(id_)
		val_part = len(components[0])
		series_info[series]['val_part'] = max(series_info[series].get('val_part', 0), val_part)
		series_info[series]['fract_part'] = max(series_info[series].get('fract_part', 0), fract_part)

for series,sinfo in series_info.iteritems():
	fract_part = sinfo['fract_part']
#	if fract_part == 1:  # Once fractional parts come into play, always have them at least 2 long.
#		fract_part = 2  # Not sure yet if I actually want that.
	print "Series name:",series
	brief_format_str = '{0:0%df}'%(sinfo['val_part'])
	print "Format String for books without fraction:",brief_format_str
	if fract_part > 0:
		full_format_str = '{0:0%d.%df}'%(sinfo['val_part'] + fract_part + (1 if fract_part > 0 else 0), fract_part)
		print "Format string for books with fraction:",full_format_str
	sids = cache.search('series:"=' + series + '"')
	dct = {}
	for book_id in sids:
		if book_id in fract_ids:
			dct[book_id] = full_format_str
		else:
			dct[book_id] = brief_format_str
	cache.set_field('#format_str', dct)

Last edited by JJanssen; 03-27-2016 at 12:24 PM.
JJanssen is offline   Reply With Quote