def update_user_info(user_info, recommend_result):
    """ update recommend_result to user_info
        @return None
    """
    #@note:暂时不获取item_feature结构(不管是news还是item类,为了计算用户的feature和feature偏好的pv部分);
    #@note:item_id列表的push由外围世荣处保证
    for reason,item_list in recommend_result.reason2itemidlist.iteritems():
        add_reason(user_info, reason)
        for v in item_list:
            resource_type = ResourceType.get_resource_type(v.item_id)
            assert(resource_type)
            user_info.recent_resource_visit_info.setdefault(resource_type, VisitInfo())
            user_info.recent_resource_visit_info[resource_type].pv_count += 1
    #set online user_feature_reason and user resource visit info
    feature_list = ItemFeatureList()
    for reason,weight in user_info.recent_push_reason_info.iteritems():
        feature = feature_list.feature.add()
        feature.feature_name = reason
        feature.weight = weight
    uid = user_info.uid
    errCode = model.set_online_user_feature_reason(uid, feature_list.SerializeToString())
    if not errCode:
        logger.warn("fail to set_online_user_feature_reason, uid:%s" % uid)
    for resource_type,visit_info in user_info.recent_resource_visit_info.iteritems():
        errCode = model.set_online_user_resource_visitinfo(uid, resource_type, visit_info.SerializeToString())
        if not errCode:
            logger.warn("fail to set_online_user_resource_visitinfo, uid:%s, resource_type:%s" % (uid, resource_type))
    #feedback for show action
    update_user_feature_list_for_show_action(user_info, recommend_result)
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