Composite column based categories

This commit is contained in:
Kovid Goyal 2013-01-25 14:37:57 +05:30
parent dc0f280cae
commit dc4e43371c
4 changed files with 32 additions and 5 deletions

View File

@ -135,11 +135,19 @@ def get_categories(dbcache, sort='name', book_ids=None, icon_map=None):
categories = {} categories = {}
book_ids = frozenset(book_ids) if book_ids else book_ids book_ids = frozenset(book_ids) if book_ids else book_ids
get_metadata = partial(dbcache._get_metadata, get_user_categories=False)
bids = None
for category, is_multiple, is_composite in find_categories(fm): for category, is_multiple, is_composite in find_categories(fm):
tag_class = create_tag_class(category, fm, icon_map) tag_class = create_tag_class(category, fm, icon_map)
# TODO: Handle composite column based categories (both is_multiple and # TODO: Handle composite column based categories (both is_multiple and
# not is_multiple) # not is_multiple)
if category == 'news': if is_composite:
if bids is None:
bids = dbcache._all_book_ids() if book_ids is None else book_ids
cats = dbcache.fields[category].get_composite_categories(
tag_class, book_rating_map, bids, is_multiple, get_metadata)
elif category == 'news':
cats = dbcache.fields['tags'].get_news_category(tag_class, book_ids) cats = dbcache.fields['tags'].get_news_category(tag_class, book_ids)
else: else:
cats = dbcache.fields[category].get_categories( cats = dbcache.fields[category].get_categories(

View File

@ -186,6 +186,25 @@ class CompositeField(OneToOneField):
for val, book_ids in val_map.iteritems(): for val, book_ids in val_map.iteritems():
yield val, book_ids yield val, book_ids
def get_composite_categories(self, tag_class, book_rating_map, book_ids,
is_multiple, get_metadata):
ans = []
id_map = defaultdict(set)
for book_id in book_ids:
val = self.get_value_with_cache(book_id, get_metadata)
vals = [x.strip() for x in val.split(is_multiple)] if is_multiple else [val]
for val in vals:
if val:
id_map[val].add(book_id)
for item_id, item_book_ids in id_map.iteritems():
ratings = tuple(r for r in (book_rating_map.get(book_id, 0) for
book_id in item_book_ids) if r > 0)
avg = sum(ratings)/len(ratings) if ratings else 0
c = tag_class(item_id, id=item_id, sort=item_id, avg=avg,
id_set=item_book_ids, count=len(item_book_ids))
ans.append(c)
return ans
class OnDeviceField(OneToOneField): class OnDeviceField(OneToOneField):
def __init__(self, name, table): def __init__(self, name, table):

View File

@ -98,10 +98,10 @@ class CompositeTable(OneToOneTable):
self.book_col_map = {} self.book_col_map = {}
d = self.metadata['display'] d = self.metadata['display']
self.composite_template = ['composite_template'] self.composite_template = ['composite_template']
self.contains_html = d['contains_html'] self.contains_html = d.get('contains_html', False)
self.make_category = d['make_category'] self.make_category = d.get('make_category', False)
self.composite_sort = d['composite_sort'] self.composite_sort = d.get('composite_sort', False)
self.use_decorations = d['use_decorations'] self.use_decorations = d.get('use_decorations', False)
class ManyToOneTable(Table): class ManyToOneTable(Table):

Binary file not shown.