Example #1
0
    def __init__(self, conn_str):
        super(AppMongodbStorage, self).__init__(conn_str, self.db_name)
        self._ids = IncrementalId(self._db)

        self._db.categories.ensure_index("parent_category_id")
        self._db.tops.ensure_index("category_id")

        self._db.apps.ensure_index([("sub_category_id", pymongo.ASCENDING), ("download_count", pymongo.DESCENDING)])
        self._db.apps.ensure_index("id")
        self._db.apps.ensure_index("tid")
        self._db.apps.ensure_index("download_tid")
        self._db.apps.ensure_index("package_sig")
        self._db.apps.ensure_index("sub_category_id")
        self._db.apps.ensure_index("package_name")

        self._db.reviews.ensure_index([("app_id", pymongo.ASCENDING), ("created_time", pymongo.DESCENDING)])

        self._db.recommends.ensure_index([("type", pymongo.ASCENDING), (self.RECOMMENDS_ORDER, pymongo.ASCENDING)])
        self._db.focus_images.ensure_index([("area", pymongo.ASCENDING), ('category_id', pymongo.ASCENDING), ('order', pymongo.ASCENDING)])
        self._db.focus_images.ensure_index([("area", pymongo.ASCENDING), ('recommend_type', pymongo.ASCENDING), ('order', pymongo.ASCENDING)])
Example #2
0
 def __init__(self, conn_str):
     super(UserMongodbStorage, self).__init__(conn_str, self.db_name)
     self._ids = IncrementalId(self._db)
Example #3
0
class AppMongodbStorage(MongodbStorage):

    db_name = "app"

    #CATEGORY_APPS_ORDER_DOWNLOADS = "download_count"
    CATEGORY_APPS_ORDER_DOWNLOADS = "order"
    CATEGORY_APPS_ORDER_RATING = "rate"

    RECOMMENDS_ORDER = 'order'
    RECOMMEND_TYPE_NEWEST = 10
    RECOMMEND_TYPE_HOTEST = 11
    RECOMMEND_TYPE_BESTMATCH = 12
    RECOMMEND_TYPE_HOMENEW = 13

    AREA_RECOMMEND = 2
    AREA_TOP = 1
    AREA_CATEGORY = 3

    def __init__(self, conn_str):
        super(AppMongodbStorage, self).__init__(conn_str, self.db_name)
        self._ids = IncrementalId(self._db)

        self._db.categories.ensure_index("parent_category_id")
        self._db.tops.ensure_index("category_id")

        self._db.apps.ensure_index([("sub_category_id", pymongo.ASCENDING), ("download_count", pymongo.DESCENDING)])
        self._db.apps.ensure_index("id")
        self._db.apps.ensure_index("tid")
        self._db.apps.ensure_index("download_tid")
        self._db.apps.ensure_index("package_sig")
        self._db.apps.ensure_index("sub_category_id")
        self._db.apps.ensure_index("package_name")

        self._db.reviews.ensure_index([("app_id", pymongo.ASCENDING), ("created_time", pymongo.DESCENDING)])

        self._db.recommends.ensure_index([("type", pymongo.ASCENDING), (self.RECOMMENDS_ORDER, pymongo.ASCENDING)])
        self._db.focus_images.ensure_index([("area", pymongo.ASCENDING), ('category_id', pymongo.ASCENDING), ('order', pymongo.ASCENDING)])
        self._db.focus_images.ensure_index([("area", pymongo.ASCENDING), ('recommend_type', pymongo.ASCENDING), ('order', pymongo.ASCENDING)])

    @cursor_to_list
    @set_default_order
    def query_categories(self, parent_category_id=0, level=1, start_index=0, count=20, order=None):
        cond = {'parent_category_id': parent_category_id}  # current only support get l level sub category
        return self._db.categories.find(cond, skip=start_index, limit=count, sort=order)

    @cursor_to_list
    @set_default_order
    def query_category_tops(self, category_id, start_index=0, count=20, order=None):
        cond = {'category_id': category_id}
        return self._db.tops.find(cond, skip=start_index, limit=count, sort=order, fields=APP_FIELDS_LIST_MEDIUM)

    @cursor_to_list
    @set_default_order
    def query_category_apps(self, category_id=0, start_index=0, count=20, order=None):
        if not order:
            order = [('download_count', self.ORDER_DESC)]
        else:
            if isinstance(order, str):
                order = [(order, self.ORDER_ASC if order == self.CATEGORY_APPS_ORDER_DOWNLOADS else self.ORDER_DESC)]
        cond = {'sub_category_id': category_id}
        return self._db.apps.find(cond, skip=start_index, limit=count, sort=order, fields=APP_FIELDS_LIST_MEDIUM)

    @cursor_to_list
    @set_default_order
    def query_category_focus_images(self, category_id, recommend_type, area, start_index=0, count=20, order=None):
        if order is None:
            order = [('order', self.ORDER_ASC)]
        if category_id > 0:
            cond = {'area': area, 'category_id': category_id}
        else:
            cond = {'area': area, 'recommend_type': recommend_type}
        return self._db.focus_images.find(cond, skip=start_index, limit=count, sort=order)

    @cursor_to_list
    @set_default_order
    def query_subjects(self, start_index=0, count=20, order=None):
        return self._db.subjects.find({}, skip=start_index, limit=count, sort=order)

    @cursor_to_list
    @set_default_order
    def query_subject_apps(self, subject_id, start_index=0, count=20, order=None):
        cond = {'subject_id': subject_id}
        return self._db.subject_apps.find(cond, skip=start_index, limit=count, sort=order, fields=SUBJECT_ITEM_FIELDS)

    @cursor_to_list
    @set_default_order
    def query_kuwan_items(self, start_index=0, count=20, order=None):
        return self._db.kuwan_items.find({}, skip=start_index, limit=count, sort=order, fields=KUWAN_ITEM_FIELDS)

    @cursor_to_list
    @set_default_order
    def query_kuwan_app_list(self, kuwan_id, start_index=0, count=20, order=None):
        cond = {'id': kuwan_id}
        return self._db.kuwan_items.find(cond, skip=start_index, limit=count, sort=order, fields=KUWAN_APP_LIST_FIELDS)

    def get_info(self, app_id):
        cond = {'id': app_id}
        return self._db.apps.find_one(cond, fields=APP_FIELDS_LIST_DETAILS)

    def get_info_by_tid(self, app_tid):
        cond = {'backup_tid': app_tid}
        return self._db.apps.find_one(cond, fields=APP_FIELDS_LIST_DETAILS)

    def get_app_by_package(self, package_name):
        cond = {'package_name': package_name}
        return self._db.apps.find_one(cond, fields = APP_FIELDS_LIST_DETAILS)

    def get_info_for_related_apps(self, app_id_list, count=10):
        cond = {'id': {'$in': app_id_list}}
        related_apps = self._db.apps.find(cond, limit=count, fields=APP_FIELDS_LIST_SIMPLE)

        # Since we use $in operator to query, ordering is not preserved in returned result.
        # In order to preserve the related app ordering in app_id_list, we use an extra dict to do the lookup.
        related_apps_dict = dict((app['id'], app) for app in related_apps)
        return [related_apps_dict[app_id] for app_id in app_id_list if app_id in related_apps_dict]

    def get_info_for_same_developer_apps(self, developer_package_sig, exclude_app_id=0, count=10):
        cond = {'package_sig': developer_package_sig}
        results = self._db.apps.find(cond, limit=count, fields=APP_FIELDS_LIST_SIMPLE)
        results = [x for x in results if x['id'] != exclude_app_id]
        results = sorted(results, key = lambda x: x['download_count'], reverse=True)
        return results

    def get_download_info(self, app_id):
        cond = {'id': app_id}
        # remove {'$inc': {'download_count': 1}}, : we will count the downloads offline
        result = self._db.apps.find_one(cond, fields=APP_FIELDS_DOWNLOAD)
        return result

    def get_app_backup_tid(self, app_id):
        cond = {'id': app_id}
        # remove {'$inc': {'download_count': 1}}, : we will count the downloads offline
        result = self._db.apps.find_one(cond, fields={'_id': 0, 'backup_tid': 1})
        if result:
            result = result['backup_tid']
        return result

    @cursor_to_list
    @set_default_order
    def query_recommends(self, start_index=0, count=20, recommend_type=RECOMMEND_TYPE_NEWEST, order=None):
        if not order:
            order = [(self.RECOMMENDS_ORDER, self.ORDER_ASC)]
        return self._db.recommends.find({'type': recommend_type}, skip=start_index, limit=count, sort=order, fields=RECOMMEND_FIELDS_DETAILS)

    def is_home_new(self, app_id):
        return self._db.recommends.find({'id': app_id, 'type': self.RECOMMEND_TYPE_HOMENEW}, limit=1).count() > 0

    @cursor_to_list
    @set_default_order
    def query_must_haves(self, start_index=0, count=20, order=None):
        return self._db.must_haves.find({}, skip=start_index, limit=count, sort=order, fields=APP_FIELDS_LIST_MEDIUM)

    @cursor_to_list
    @set_default_order
    def query_boot_apps(self, client_id, os, device_name, device_type, resolution, start_index=0, count=20, order=None):
        return self._db.bootapps.find({}, skip=start_index, limit=count, sort=order, fields=APP_FIELDS_LIST_MEDIUM)

    @cursor_to_list
    @set_default_order
    def query_extra_boot_apps(self, client_id, os, device_name, device_type, resolution, start_index=0, count=20, order=None):
        return self._db.extrabootapps.find({}, skip=start_index, limit=count, sort=order, fields=APP_FIELDS_LIST_MEDIUM)

    def query_app_lists(self):
        results = self._db.app_lists.find({})
        type_dict = {}
        for t in results:
            type_dict[str(t['id'])] = t['id']
            type_dict[str(t['codename'])] = t['id']

        return type_dict

    def _try_parse_app_list_id(self, app_list_id):
        try:
            app_list_id = int(app_list_id)
        except:
            app_list = self._db.app_lists.find_one({'codename': app_list_id})
            if app_list:
                return app_list['id']
        else:
            return app_list_id
        return None

    def _convert_extra_infos(self, extra_infos):
        if 'views_count' in extra_infos:
            if extra_infos['views_count'] >= 10000:
                extra_infos['display_views_count'] = u'%d万+' % (extra_infos['views_count'] / 10000)
            elif extra_infos['views_count'] >= 1000:
                extra_infos['display_views_count'] = u'%d千+' % (extra_infos['views_count'] / 1000)
            else:
                extra_infos['display_views_count'] = u'<1千'
        return extra_infos

    def _convert_app_list_items(self, results, fields):
        r_list = []
        for r in results:
            cr = {}
            if 'extra_infos' in r:
                cr['extra_infos'] = self._convert_extra_infos(r['extra_infos'])
            if 'image_url' in r:
                cr['image_url'] = r['image_url']

            if 'app' in r:
                if 'id' in r['app']:
                    cr['id'] = r['app']['id']
                for f in [k for k, v in fields.iteritems() if v == 1]:
                    if f in r['app']:
                        cr[f] = r['app'][f]
                    elif f == 'large_icon_url':
                        cr[f] = r['large_icon_url']
            else:
                for f in [k for k, v in RICH_ITEM_FILEDS.iteritems() if v == 1]:
                    if f in r:
                        cr[f] = r[f]
                if 'attr' in r and r['type'] == APPLIST_ITEM_TYPE_APPDETAIL:
                    cr['id'] = int(r['attr'])
                else:
                    cr['id'] = int(r['pk'])
            r_list.append(cr)
        return r_list

    @set_default_order
    def query_apps_from_list(self, app_list_id=None, start_index=0, count=20, order=None, fields=APP_LIST_ITEM_FIELDS_DETAILS):
        app_list_id = self._try_parse_app_list_id(app_list_id)
        if app_list_id is None:
            return []
        cond = {'app_list_id': app_list_id}
        results = self._db.app_list_items.find(cond, skip=start_index, limit=count, sort=order)
        results = self._convert_app_list_items(results, fields)
        return results

    # parameter: app_list: list of package_names
    @cursor_to_list
    def query_updates(self, app_list):
        if not app_list:
            return []

        if isinstance(app_list[0], dict):
            # support old app update API
            app_list = [app['packageName'] for app in app_list]

        cond = { 'package_name': {'$in': app_list} }
        fields = APP_FIELDS_LIST_MEDIUM.copy()
        fields.update({'package_hash': 1})
        return self._db.apps.find(cond, fields=fields)

    @cursor_to_list
    def query_reviews(self, app_id, start_index=0, count=20, order=None):
        if order is None:
            order = [('created_time', self.ORDER_DESC)]
        cond = {'app_id': app_id}
        return self._db.reviews.find(cond, skip=start_index, limit=count, sort=order, fields=REVIEW_FIELDS_DETAILS)

    def save_reviews(self, reviews):
        for review in reviews:
            try:
                review.update({
                        'id': self._ids.next_id("reviews"),
                        'user_id': int(review.get('user_id', 0)),
                        'user_name': review.get('user_name', ''),
                        'app_id': int(review.get('app_id', 0)),
                        'rate': float(review.get('rate', 0)),
                        'comment': review.get('comment', ''),
                        'created_time': timestamp_utc_now()
                    })
                self._db.reviews.save(review)
            except Exception, e:
                print e
                continue

            if review['app_id'] == 0:
                continue

            app = self._db.apps.find_one({'id': review['app_id']}, fields=APP_FIELDS_RATING)
            if app is None:
                continue

            self._db.reviews.save(review)

            app_rate_count = app['rate_count'] if 'rate_count' in app else 0
            app_rate = app['rate'] if 'rate' in app else 0
            app_rate = (app_rate + review['rate']) / (app_rate_count + 1.0)
            self._db.apps.update({'_id': app['_id']}, {'$set': {'rate': app_rate, 'rate_count': app_rate_count}})