First pass at converting db2.get_categories to return a complete dict

This commit is contained in:
Charles Haley 2010-05-23 21:34:19 +01:00
parent 4946a2f2ad
commit 3b557de4c7
4 changed files with 141 additions and 32 deletions

View File

@ -199,8 +199,8 @@ class TagsModel(QAbstractItemModel): # {{{
categories_orig = [_('Authors'), _('Series'), _('Formats'), _('Publishers'),
_('Ratings'), _('News'), _('Tags')]
row_map_orig = ['author', 'series', 'format', 'publisher', 'rating',
'news', 'tag']
row_map_orig = ['authors', 'series', 'formats', 'publishers', 'ratings',
'news', 'tags']
tags_categories_start= 7
search_keys=['search', _('Searches')]
@ -264,8 +264,8 @@ class TagsModel(QAbstractItemModel): # {{{
self.cat_icon_map.append(self.cat_icon_map_orig[i])
# Clean up the author's tags, getting rid of the '|' characters
if data['author'] is not None:
for t in data['author']:
if data['authors'] is not None:
for t in data['authors']:
t.name = t.name.replace('|', ',')
# Now do the user-defined categories. There is a time/space tradeoff here.

View File

@ -144,8 +144,8 @@ class CustomColumns(object):
for i, v in self.custom_column_num_map.items():
if v['normalized']:
tn = 'custom_column_{0}'.format(i)
self.tag_browser_categories[tn] = [v['label'], 'value']
self.tag_browser_datatype[v['label']] = v['datatype']
self.tag_browser_categories[v['label']] = {'table':tn, 'column':'value', 'type':v['datatype'], 'name':v['name']}
#self.tag_browser_datatype[v['label']] = v['datatype']
def get_custom(self, idx, label=None, num=None, index_is_id=False):
if label is not None:

View File

@ -33,6 +33,7 @@ from calibre.customize.ui import run_plugins_on_import
from calibre.utils.filenames import ascii_filename
from calibre.utils.date import utcnow, now as nowf, utcfromtimestamp
from calibre.utils.ordered_dict import OrderedDict
from calibre.ebooks import BOOK_EXTENSIONS, check_ebook_format
if iswindows:
@ -123,22 +124,25 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
if isinstance(self.dbpath, unicode):
self.dbpath = self.dbpath.encode(filesystem_encoding)
self.tag_browser_categories = {
'tags' : ['tag', 'name'],
'series' : ['series', 'name'],
'publishers': ['publisher', 'name'],
'authors' : ['author', 'name'],
'news' : ['news', 'name'],
'ratings' : ['rating', 'rating']
}
self.tag_browser_datatype = {
'tag' : 'textmult',
'series' : None,
'publisher' : 'text',
'author' : 'text',
'news' : None,
'rating' : 'rating',
}
# Order as has been customary in the tags pane.
self.tag_browser_categories = OrderedDict([
('authors', {'table':'authors', 'column':'name', 'type':'text', 'name':_('Authors')}),
('series', {'table':'series', 'column':'name', 'type':None, 'name':_('Series')}),
('formats', {'table':None, 'column':None, 'type':None, 'name':_('Formats')}),
('publishers',{'table':'publishers', 'column':'name', 'type':'text', 'name':_('Publishers')}),
('ratings', {'table':'ratings', 'column':'rating', 'type':'rating', 'name':_('Ratings')}),
('news', {'table':'news', 'column':'name', 'type':None, 'name':_('News')}),
('tags', {'table':'tags', 'column':'name', 'type':'textmult', 'name':_('Tags')}),
])
# self.tag_browser_datatype = {
# 'tag' : 'textmult',
# 'series' : None,
# 'publisher' : 'text',
# 'author' : 'text',
# 'news' : None,
# 'rating' : 'rating',
# }
self.tag_browser_formatters = {'rating': lambda x:u'\u2605'*int(round(x/2.))}
@ -653,17 +657,22 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
self.books_list_filter.change([] if not ids else ids)
categories = {}
for tn, cn in self.tag_browser_categories.items():
for category in self.tag_browser_categories.keys():
tn = self.tag_browser_categories[category]['table']
categories[category] = [] #reserve the position in the ordered list
if tn is None:
continue
cn = self.tag_browser_categories[category]['column']
if ids is None:
query = 'SELECT id, {0}, count FROM tag_browser_{1}'.format(cn[1], tn)
query = 'SELECT id, {0}, count FROM tag_browser_{1}'.format(cn, tn)
else:
query = 'SELECT id, {0}, count FROM tag_browser_filtered_{1}'.format(cn[1], tn)
query = 'SELECT id, {0}, count FROM tag_browser_filtered_{1}'.format(cn, tn)
if sort_on_count:
query += ' ORDER BY count DESC'
else:
query += ' ORDER BY {0} ASC'.format(cn[1])
query += ' ORDER BY {0} ASC'.format(cn)
data = self.conn.get(query)
category = cn[0]
# category = cn[0]
icon, tooltip = None, ''
if icon_map:
if category in icon_map:
@ -671,14 +680,14 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
else:
icon = icon_map['*custom']
tooltip = self.custom_column_label_map[category]['name']
datatype = self.tag_browser_datatype[category]
datatype = self.tag_browser_categories[category]['type']
formatter = self.tag_browser_formatters.get(datatype, lambda x: x)
categories[category] = [Tag(formatter(r[1]), count=r[2], id=r[0],
icon=icon, tooltip = tooltip)
for r in data
if r[2] > 0 and
(datatype != 'rating' or len(formatter(r[1])) > 0)]
categories['format'] = []
categories['formats'] = []
for fmt in self.conn.get('SELECT DISTINCT format FROM data'):
fmt = fmt[0]
if ids is not None:
@ -693,13 +702,13 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
WHERE format="%s"'''%fmt,
all=False)
if count > 0:
categories['format'].append(Tag(fmt, count=count))
categories['formats'].append(Tag(fmt, count=count))
if sort_on_count:
categories['format'].sort(cmp=lambda x,y:cmp(x.count, y.count),
categories['formats'].sort(cmp=lambda x,y:cmp(x.count, y.count),
reverse=True)
else:
categories['format'].sort(cmp=lambda x,y:cmp(x.name, y.name))
categories['formats'].sort(cmp=lambda x,y:cmp(x.name, y.name))
return categories
def tags_older_than(self, tag, delta):

View File

@ -0,0 +1,100 @@
from UserDict import DictMixin
class OrderedDict(dict, DictMixin):
def __init__(self, *args, **kwds):
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
try:
self.__end
except AttributeError:
self.clear()
self.update(*args, **kwds)
def clear(self):
self.__end = end = []
end += [None, end, end] # sentinel node for doubly linked list
self.__map = {} # key --> [key, prev, next]
dict.clear(self)
def __setitem__(self, key, value):
if key not in self:
end = self.__end
curr = end[1]
curr[2] = end[1] = self.__map[key] = [key, curr, end]
dict.__setitem__(self, key, value)
def __delitem__(self, key):
dict.__delitem__(self, key)
key, prev, next = self.__map.pop(key)
prev[2] = next
next[1] = prev
def __iter__(self):
end = self.__end
curr = end[2]
while curr is not end:
yield curr[0]
curr = curr[2]
def __reversed__(self):
end = self.__end
curr = end[1]
while curr is not end:
yield curr[0]
curr = curr[1]
def popitem(self, last=True):
if not self:
raise KeyError('dictionary is empty')
if last:
key = reversed(self).next()
else:
key = iter(self).next()
value = self.pop(key)
return key, value
def __reduce__(self):
items = [[k, self[k]] for k in self]
tmp = self.__map, self.__end
del self.__map, self.__end
inst_dict = vars(self).copy()
self.__map, self.__end = tmp
if inst_dict:
return (self.__class__, (items,), inst_dict)
return self.__class__, (items,)
def keys(self):
return list(self)
setdefault = DictMixin.setdefault
update = DictMixin.update
pop = DictMixin.pop
values = DictMixin.values
items = DictMixin.items
iterkeys = DictMixin.iterkeys
itervalues = DictMixin.itervalues
iteritems = DictMixin.iteritems
def __repr__(self):
if not self:
return '%s()' % (self.__class__.__name__,)
return '%s(%r)' % (self.__class__.__name__, self.items())
def copy(self):
return self.__class__(self)
@classmethod
def fromkeys(cls, iterable, value=None):
d = cls()
for key in iterable:
d[key] = value
return d
def __eq__(self, other):
if isinstance(other, OrderedDict):
return len(self)==len(other) and self.items() == other.items()
return dict.__eq__(self, other)
def __ne__(self, other):
return not self == other