def do_list(): from calibre.constants import terminal_controller as tc terminal_controller = tc() separator = ' ' widths = list(map(lambda x : 0, fields)) for i in data: for j, field in enumerate(fields): widths[j] = max(widths[j], max(len(field), len(unicode(i[field])))) screen_width = terminal_controller.COLS if opts.width < 0 else opts.width if not screen_width: screen_width = 80 field_width = screen_width//len(fields) base_widths = map(lambda x: min(x+1, field_width), widths) while sum(base_widths) < screen_width: adjusted = False for i in range(len(widths)): if base_widths[i] < widths[i]: base_widths[i] += min(screen_width-sum(base_widths), widths[i]-base_widths[i]) adjusted = True break if not adjusted: break widths = list(base_widths) titles = map(lambda x, y: '%-*s%s'%(x-len(separator), y, separator), widths, fields) print terminal_controller.GREEN + ''.join(titles)+terminal_controller.NORMAL wrappers = map(lambda x: TextWrapper(x-1), widths) o = cStringIO.StringIO() for record in data: text = [wrappers[i].wrap(unicode(record[field]).encode('utf-8')) for i, field in enumerate(fields)] lines = max(map(len, text)) for l in range(lines): for i, field in enumerate(text): ft = text[i][l] if l < len(text[i]) else '' filler = '%*s'%(widths[i]-len(ft)-1, '') o.write(ft) o.write(filler+separator) print >>o print o.getvalue()
def do_list(db, fields, afields, sort_by, ascending, search_text, line_width, separator, prefix, subtitle='Books in the calibre database'): from calibre.constants import terminal_controller as tc terminal_controller = tc() if sort_by: db.sort(sort_by, ascending) if search_text: db.search(search_text) data = db.get_data_as_dict(prefix, authors_as_string=True) fields = ['id'] + fields title_fields = fields def field_name(f): ans = f if f[0] == '*': if f.endswith('_index'): fkey = f[1:-len('_index')] num = db.custom_column_label_map[fkey]['num'] ans = '%d_index'%num else: ans = db.custom_column_label_map[f[1:]]['num'] return ans fields = list(map(field_name, fields)) for f in data: fmts = [x for x in f['formats'] if x is not None] f['formats'] = u'[%s]'%u','.join(fmts) widths = list(map(lambda x : 0, fields)) for record in data: for f in record.keys(): if hasattr(record[f], 'isoformat'): record[f] = isoformat(record[f], as_utc=False) else: record[f] = unicode(record[f]) record[f] = record[f].replace('\n', ' ') for i in data: for j, field in enumerate(fields): widths[j] = max(widths[j], len(unicode(i[field]))) screen_width = terminal_controller.COLS if line_width < 0 else line_width if not screen_width: screen_width = 80 field_width = screen_width//len(fields) base_widths = map(lambda x: min(x+1, field_width), widths) while sum(base_widths) < screen_width: adjusted = False for i in range(len(widths)): if base_widths[i] < widths[i]: base_widths[i] += min(screen_width-sum(base_widths), widths[i]-base_widths[i]) adjusted = True break if not adjusted: break widths = list(base_widths) titles = map(lambda x, y: '%-*s%s'%(x-len(separator), y, separator), widths, title_fields) print terminal_controller.GREEN + ''.join(titles)+terminal_controller.NORMAL wrappers = map(lambda x: TextWrapper(x-1), widths) o = cStringIO.StringIO() for record in data: text = [wrappers[i].wrap(unicode(record[field]).encode('utf-8')) for i, field in enumerate(fields)] lines = max(map(len, text)) for l in range(lines): for i, field in enumerate(text): ft = text[i][l] if l < len(text[i]) else '' filler = '%*s'%(widths[i]-len(ft)-1, '') o.write(ft) o.write(filler+separator) print >>o return o.getvalue()