import mongoengine as mongo from apps.rss_feeds.models import Feed from itertools import groupby class MCategory(mongo.Document): title = mongo.StringField() description = mongo.StringField() feed_ids = mongo.ListField(mongo.IntField()) meta = { 'collection': 'category', 'indexes': ['title'], 'allow_inheritance': False, 'index_drop_dups': True, } def __unicode__(self): return "%s: %s sites" % (self.title, len(self.feed_ids)) @classmethod def serialize(cls, category=None): categories = cls.objects.all() if category: categories = categories.filter(title=category) data = dict(categories=[], feeds={}) feed_ids = set() for category in categories: category_output = { 'title': category.title, 'description': category.description, 'feed_ids': category.feed_ids, } data['categories'].append(category_output) feed_ids.update(list(category.feed_ids)) feeds = Feed.objects.filter(pk__in=feed_ids) for feed in feeds: data['feeds'][feed.pk] = feed.canonical() return data @classmethod def reload_sites(cls, category_title=None): category_sites = MCategorySite.objects.all() if category_title: category_sites = category_sites.filter(category_title=category_title) category_groups = groupby(sorted(category_sites, key=lambda c: c.category_title), key=lambda c: c.category_title) for category_title, sites in category_groups: category = cls.objects.get(title=category_title) category.feed_ids = [site.feed_id for site in sites] category.save() print " ---> Reloaded category: %s" % category class MCategorySite(mongo.Document): feed_id = mongo.IntField() category_title = mongo.StringField() meta = { 'collection': 'category_site', 'indexes': ['feed_id', 'category_title'], 'allow_inheritance': False, 'index_drop_dups': True, } def __unicode__(self): feed = Feed.objects.get(pk=self.feed_id) return "%s: %s" % (self.category_title, feed) @classmethod def add(cls, category_title, feed_id): category_site, created = cls.objects.get_or_create(category_title=category_title, feed_id=feed_id) if not created: print " ---> Site is already in category: %s" % category_site else: MCategory.reload_sites(category_title)