コード例 #1
0
 def fetch(self, logger):
     """update user info, return None"""
     uid = self.uid
     #offline_resource_visit_info
     try:
         errCode, kv_dict = model.get_offline_user_resource_visitinfo(uid, ResourceType.RESOURCE_TYPE_LIST)
         if not is_valid_data(errCode, kv_dict, "offline_user_resource_visitinfo", {"uid":uid, "resource_type_list":"..."}):
             pass
         for k, v in kv_dict.iteritems():
             self.offline_resource_visit_info[k] = VisitInfo()
             self.offline_resource_visit_info[k].ParseFromString(v)
     except:
         logger.error("bad offline_resource_visit_info:%s" % traceback.format_exc())
     #recent_resource_visit_info
     try:
         errCode, kv_dict = model.get_online_user_resource_visitinfo(uid, ResourceType.RESOURCE_TYPE_LIST)
         if not is_valid_data(errCode, kv_dict, "online_user_resource_visitinfo", {"uid":uid, "resource_type_list":"..."}):
             pass
         for k, v in kv_dict.iteritems():
             self.recent_resource_visit_info[k] = VisitInfo()
             self.recent_resource_visit_info[k].ParseFromString(v)
         #final_resource_visit_info
         self.final_resource_visit_info = UserInfo.merge_offline_recent_resource_visit_info(self.offline_resource_visit_info,
                 self.recent_resource_visit_info)
     except:
         logger.error("bad recent_resource_visit_info:%s" % traceback.format_exc())
         self.final_resource_visit_info = self.offline_resource_visit_info
     #pushed_item_id_list
     try:
         errCode, v = model.get_online_user_push_item_list(uid)
         if not is_valid_data(errCode, v, "online_user_push_item_list", {"uid":uid}):
             pass
         if v:
             item_id_list_proto = ItemIdList()
             item_id_list_proto.ParseFromString(v)
             self.recent_push_item_id_list = set()
             self.recent_push_item_id_list.update(item_id_list_proto.item_id)
     except:
         logger.error("bad pushed_item_id_list:%s" % traceback.format_exc())
     #pushed_feature_list
     try:
         errCode, v = model.get_online_user_feature_reason(uid)
         if not is_valid_data(errCode, v, "online_user_feature_reason", {"uid":uid}):
             pass
         if v:
             feature_list_proto = ItemFeatureList()
             feature_list_proto.ParseFromString(v)
             for u in feature_list_proto.feature:
                 self.recent_push_reason_info[u.feature_name] = u.weight
     except:
         logger.error("bad pushed_feature_list:%s" % traceback.format_exc())
     logger.debug("user_info:%s" % self)
     return None
コード例 #2
0
def get_item_list_by_item(user_info, resource_type, count):
    """ get item_list by item recommendation
        @return RecommendItemContainer
    """
    logger.debug("begin get_item_list_by_item")
    uid = user_info.uid
    result = RecommendItemContainer()
    #get favor item_id列表
    errCode, kv_dict = model.get_online_user_favor_item_list(uid, [resource_type])
    if not is_valid_data(errCode, kv_dict, "online_user_favor_item_list", {"uid":uid, "resource_type":resource_type}):
        return result
    if not kv_dict:
        return result
    assert(resource_type in kv_dict)
    try:
        item_id_list_proto = ItemIdList()
        item_id_list_proto.ParseFromString(kv_dict[resource_type])
        reason_list = [resource_type+ITEM_RECOMMEND_FEATURE_TYPE+v for  v in item_id_list_proto.item_id]
        item_id_list = []
        for v in item_id_list_proto.item_id:
            if not check_reason(user_info, resource_type+ITEM_RECOMMEND_FEATURE_TYPE+v):
                continue
            item_id_list.append(v)
        if not item_id_list:
            logger.info("all item id list have no item2item result:%s" % item_id_list)
            return result
        #@note: use latest item first
        item_id_list.reverse()
        #recommend by item id
        errCode, kv_dict = model.get_offline_item_recommend_item_list(item_id_list)
        if not is_valid_data(errCode, kv_dict, "offline_item_recommend_item_list", {"item_id_list":"..."}):
            return result
        if not kv_dict:
            for item_id in item_id_list:
                reason = resource_type + ITEM_RECOMMEND_FEATURE_TYPE + item_id
                ignore_reason(user_info, reason)
            return result
        for item_id in item_id_list:
            if result.size() >= count:
                break
            if item_id not in kv_dict:
                logger.info("no item2itemid list for id:%s" % item_id)
                ignore_reason(user_info, reason)
                continue
            k = item_id
            v = kv_dict[k]
            reason = resource_type + ITEM_RECOMMEND_FEATURE_TYPE + k
            item_id_list_proto = ItemIdList()
            item_id_list_proto.ParseFromString(v)
            filter_and_compose_recommend_item_list(user_info, reason, item_id_list_proto, result)
    except:
        logger.error("bad get_item_list_by_item:%s" % traceback.format_exc())
    return result
コード例 #3
0
def get_item_list_by_user(user_info, resource_type, count):
    """ get item list by user from offline recommendation
        @return RecommendItemContainer
    """
    logger.debug("begin get_item_list_by_user")
    uid = user_info.uid
    result = RecommendItemContainer()
    errCode, kv_dict = model.get_offline_user_recommend_item_list(uid, [resource_type])
    if not is_valid_data(errCode, kv_dict, "offline_user_recommend_item_list", {"uid":uid, "resource_type":resource_type}):
        return result
    if not kv_dict:
        return result
    try:
        assert(resource_type in kv_dict)
        reason2itemidlist = FeatureNameItemIdList()
        reason2itemidlist.ParseFromString(kv_dict[resource_type])
        for reason2itemid in reason2itemidlist.feature_name_item_id_list:
            if result.size() >= count:
                logger.debug("break for enough result")
                break
            reason = reason2itemid.feature_name
            item_id_list = ItemIdList()
            for i in reason2itemid.item_id:
                item_id_list.item_id.append(i)
            filter_and_compose_recommend_item_list(user_info, reason, item_id_list, result)
    except:
        logger.error("bad ItemIdList from get_offline_user_recommend_item_list:%s" % traceback.format_exc())
    return result
コード例 #4
0
def update_user_recent_resource_visit_info(uid, resource_type, favor_type):
    """ update user recent resource visit info, @return True|False
    """
    errCode, kv_dict = model.get_online_user_resource_visitinfo(uid, [resource_type])
    if not is_valid_data(errCode, kv_dict, "online_user_resource_visitinfo", {"uid":uid, "resource_type":resource_type}):
        return False
    logger.debug("resource_type:%s, kv_dict:%s" % (resource_type, kv_dict))
    visit_info_proto = VisitInfo()
    try:
        if kv_dict:
            assert(resource_type in kv_dict)
            visit_info_proto.ParseFromString(kv_dict[resource_type])
            logger.debug("resource_visit info,resource_type:%s,visit_info:%s" % (resource_type, visit_info_proto))
    except:
        logger.error("bad ItemIdList from get_online_user_favor_item_list:uid:%s, resource_type:%s, exception:%s" % (uid, resource_type, traceback.format_exc()))
        return False
    #TODO:define constants outside
    if favor_type in ["click", "like"]:
        logger.info("update uid:%s, click_count:%s" % (uid, visit_info_proto.click_count))
        visit_info_proto.click_count += 1
    elif favor_type == "show":
        visit_info_proto.pv_count += 1
    else:
        logger.warn("ignore unknown type:%s" % favor_type)
        return False
    errCode = model.set_online_user_resource_visitinfo(uid, resource_type, visit_info_proto.SerializeToString())
    if not errCode:
        logger.warn("fail to update_user_recent_resource_visit_info, uid:%s, resource_type:%s" % (uid, resource_type))
    else:
        logger.info("successfully to update_user_recent_resource_visit_info, uid:%s, resource_type:%s" % (uid, resource_type))
    return errCode
コード例 #5
0
def update_user_favor_item_id_list(uid, resource_type, item_id, favor_type):
    """ update user favor item id list, @return True|False
    """
    resource_type = ResourceType.get_resource_type(item_id)
    assert(resource_type)
    errCode, kv_dict = model.get_online_user_favor_item_list(uid, [resource_type])
    if not is_valid_data(errCode, kv_dict, "online_user_favor_item_list", {"uid":uid, "resource_type":resource_type}):
        return False
    logger.debug("resource_type:%s, kv_dict:%s" % (resource_type, kv_dict))
    item_id_list_proto = ItemIdList()
    try:
        if kv_dict:
            assert(resource_type in kv_dict)
            item_id_list_proto.ParseFromString(kv_dict[resource_type])
            logger.debug("favor item_id_list:%s" % item_id_list_proto)
    except:
        logger.error("bad ItemIdList from get_online_user_favor_item_list:uid:%s, resource_type:%s, exception:%s" % (uid, resource_type, traceback.format_exc()))
        return False
    item_id_list_proto.item_id.append(item_id)
    limit_protobuf_repeated_scala_field_size(item_id_list_proto, "item_id", MAX_FAVOR_ITEM_LIST_COUNT_PER_PERSON)
    logger.debug("new item_id_list:%s" % item_id_list_proto)
    errCode = model.set_online_user_favor_item_list(uid, resource_type, item_id_list_proto.SerializeToString())
    if not errCode:
        logger.warn("fail to set_online_user_favor_item_list, uid:%s, resource_type:%s" % (uid, resource_type))
    else:
        logger.info("successfully to set_online_user_favor_item_list, uid:%s, resource_type:%s" % (uid, resource_type))
    return errCode
コード例 #6
0
def get_item_list_by_feature_list(user_info, resource_type, feature_name_list_proto, count):
    """ get item list by check with all feature list
        @return RecommendItemContainer
    """
    logger.debug("begin get_item_list_by_feature_list")
    feature_name_list = []
    result = RecommendItemContainer()
    filtered_feature_name_list_proto = UserFeatureList()
    for v in feature_name_list_proto.feature:
        feature_name = v.feature_name
        if not check_reason(user_info, feature_name):
            continue
        feature_name_list.append(feature_name)
        cur = filtered_feature_name_list_proto.feature.add()
        cur.feature_name = feature_name
    if not feature_name_list:
        logger.info("no new reason from feature list,current feature_name size:%s" % len(feature_name_list_proto.feature))
        logger.debug("current feature_name_list_proto:%s" % feature_name_list_proto)
        return result
    #news like
    if ResourceType.RESOURCE_TYPE_NEWS == resource_type:
        return get_news_online_item_by_feature_list(user_info, resource_type, filtered_feature_name_list_proto, count)
    #items like
    errCode, kv_dict = model.get_offline_feature_hot_item_list(feature_name_list)
    if not is_valid_data(errCode, kv_dict, "offline_feature_hot_item_list", {"feature_name_list":"..."}):
        return result
    if not kv_dict:
        for k in feature_name_list:
            ignore_reason(user_info, k)
        return result
    try:
        #logger.debug("%s" % feature_name_list)
        for k in feature_name_list: #@note:ordered
            logger.debug("check result with feature_name:%s" % k)
            if result.size() >= count:
                logger.debug("fetch enough recommend result, count:%s" % count)
                break
            if k not in kv_dict:
                logger.info("no result for feature_name:%s" % k)
                ignore_reason(user_info, k)
                continue
            v = kv_dict[k]
            item_id_list = ItemIdList()
            item_id_list.ParseFromString(v)
            filter_and_compose_recommend_item_list(user_info, k, item_id_list, result)
        logger.debug("get_item_list_by_feature_list,result_size:%s, uid:%s, resource_type:%s" % (result.size(), user_info.uid, resource_type))
    except:
        logger.error("bad ItemIdList for get_item_list_by_feature_list:%s" % traceback.format_exc())
    return result
コード例 #7
0
def get_item_features_for_item(resource_type, item_id):
    """ get item features list proto for item, fail if item_id not exist or other failure
        @return errCode, item_feature_list_proto
    """
    errCode, data = model.get_offline_item_features([item_id])
    if not is_valid_data(errCode, data, "offline_item_features", {"item_id":item_id}):
        return False, None
    try:
        assert(item_id in data)
        result = ItemFeatureList()
        result.ParseFromString(data[item_id])
        return True, result
    except:
        logger.error("bad get_offline_item_features:%s" % traceback.format_exc())
        return False, None
コード例 #8
0
def convert_user_feature_list(errCode, kv_dict, uid, resource_type, desc):
    """ convert user feature list kv_dict to user_feature_list_proto
        @return (errCode, user_feature_list_proto) 
    """
    if not is_valid_data(errCode, kv_dict, desc, {"uid":uid, "resource_type":resource_type}):
        return (False, None)
    if not kv_dict:
        return (True, UserFeatureList())
    result = UserFeatureList()
    assert(resource_type in kv_dict)
    try:
        result.ParseFromString(kv_dict[resource_type])
    except:
        logger.error("bad convert_user_feature_list:%s" % traceback.format_exc())
        return False, result
    return True, result 
コード例 #9
0
def update_user_recent_feature_list(uid, resource_type, item_id, card_feature, favor_type):
    """ update user feature list, @return True|False
    """
    errCode, kv_dict = model.get_online_user_feature_list(uid, [resource_type])
    if not is_valid_data(errCode, kv_dict, "online_user_feature_list", {"uid":uid, "resource_type":resource_type}):
        return False
    user_feature_list = UserFeatureList()
    try:
        if kv_dict:
            assert(resource_type in kv_dict)
            user_feature_list.ParseFromString(kv_dict[resource_type])
            logger.debug("user_feature_list:%s" % user_feature_list)
    except:
        logger.error("bad get_online_user_feature_list:%s" % traceback.format_exc())
        return False
    errCode, item_feature_list_proto = get_item_features(resource_type, item_id)
    logger.debug("resource_type:%s, item_id:%s, user_feature_list:%s, item_feature_list:%s, card_feature:%s, favor_type:%s" % (
        resource_type, item_id, user_feature_list, item_feature_list_proto, card_feature, favor_type))
    if not errCode:
        logger.info("fail to get item feature list for click feedback:%s" % item_id)
        #still continue process for update by card_feature
    return raw_update_user_action(uid, resource_type, user_feature_list, item_feature_list_proto, card_feature, favor_type)
コード例 #10
0
def get_resource_hot_feature_list(user_info, count):
    """ get resource hot feature list, maybe top level category for per resource type, filter existing feature_name list pushed to user
        @return {resource_type:feature_name_list}
    """
    #@note:下期推荐策略:从最重要的resource开始.这里均匀选取
    #1.确定各个resource_type的数量比例:均匀选取
    #2.取每个resource的feature list按照重要性从高到低排列
    result = {}
    errCode, kv_dict = model.get_offline_global_hot_feature_list(ResourceType.RESOURCE_TYPE_LIST)
    if not is_valid_data(errCode, kv_dict, "global_hot_feature_list", {"resource_type_list":"..."}):
        return {}
    if not kv_dict:
        return {}
    try:
        for k,v in kv_dict.iteritems():
            item_feature_list = ItemFeatureList()
            item_feature_list.ParseFromString(v)
            result[k] = item_feature_list
            logger.debug("resource_type:%s, hot_feature_list:%s" % (k, result[k]))
    except:
        logger.error("bad get_offline_global_hot_feature_list:%s" % traceback.format_exc())
    logger.info("input resource_type_size:%s, result resource_type_size:%s" % (len(ResourceType.RESOURCE_TYPE_LIST), len(kv_dict)))
    logger.debug("get_resource_hot_feature_list, user_info:%s, count:%s, result:%s" % (user_info, count, result))
    return result