def like_comment(): """赞评论 (GET|POST&LOGIN) :uri: /user/opt/like-comment :param comment_id: 被赞评论id :returns: {} """ user = request.authed_user cid = request.values.get('comment_id', None) comment = Comment.get_one(cid) if not comment: return error.CommentNotExist ulc = UserLikeComment.get_by_ship(str(user._id), cid) if not ulc: key = 'lock:like_comment:%s:%s' % (str(user._id), cid) with util.Lockit(Redis, key) as locked: if locked: return error.LikeCommentFailed ulc = UserLikeComment.init() ulc.source = ObjectId(str(user._id)) ulc.target = ObjectId(cid) ulc.create_model() # 发送点赞消息 Message.send_comment_msg(str(user._id), str(cid), 'like') return {}
def follow_user(): """关注用户 (GET|POST&LOGIN) :uri: /user/opt/follow-user :param target_user_id: 被关注用户id :returns: {} """ user = request.authed_user params = request.values target_uid = params.get('target_user_id', None) target_user = User.get_one(target_uid) if not target_user: return error.UserNotExist if target_uid == str(user._id): return error.FollowFailed("不能关注自己哦") fs = FriendShip.get_by_ship(str(user._id), target_uid) if not fs: key = 'lock:follow:%s:%s' % (str(user._id), target_uid) with util.Lockit(Redis, key) as locked: if locked: return error.FollowFailed fs = FriendShip.init() fs.source = ObjectId(str(user._id)) fs.target = ObjectId(target_uid) fs.create_model() # 关注主播任务检查 if user: UserTask.check_user_tasks(str(user._id), FOLLOW_USER, 1) return {}
def sub_show(): """ 订阅栏目 :uri: /show/sub :param: show_id :return: {} """ show_id = request.values.get('show_id') if not show_id: return error.InvalidArguments show = Show.get_one(show_id) if not show: return error.ShowNotExist uid = str(request.authed_user._id) key = 'lock:subshow:%s' % uid with util.Lockit(Redis, key) as locked: if locked: return error.SubGameFailed if not UserSubShow.is_followed(uid, show_id): uss = UserSubShow.init() uss.source = ObjectId(uid) uss.target = ObjectId(show_id) uss.create_model() return {}
def unlike_video(): """取消赞视频 (GET|POST&LOGIN) :uri: /user/opt/like-video :param video_id: 被赞视频id :returns: {} """ user = request.authed_user vid = request.values.get('video_id', None) video = Video.get_one(vid) if not video: return error.VideoNotExist key = 'lock:unlike_video:%s:%s' % (str(user._id), vid) with util.Lockit(Redis, key) as locked: if locked: return error.LikeVideoFailed('取消赞失败') ulv = UserLikeVideo.get_by_ship(str(user._id), vid) ulv.delete_model() if ulv else None # 更新活动点赞数 avideos = ActivityVideo.get_activity_video(vid=vid) for avideo in avideos: ts = time.time() aconfig = ActivityConfig.get_one(str(avideo['activity_id']), check_online=False) if aconfig and aconfig.status == const.ACTIVITY_BEGIN \ and (aconfig.begin_at < ts and aconfig.end_at > ts): avideo = ActivityVideo.get_one(avideo['_id'], check_online=False) avideo.update_model({'$inc': {'like_count': -1}}) return {}
def query_shared_redpacket(): """分享红包争抢(POST) :uri: /share/redpacket/query_new :param: source_id: 红包ID :return: {'ret': bool} """ user = request.authed_user params = request.values source_id = params.get('source_id', None) uid = str(user._id) if not source_id: return error.InvalidArguments source_rp = UserRedPacket.get_one(source_id) if not source_rp: return error.RedPacketError(u'分享红包不存在!') acticity = LiveRedPacket.get_one(source_rp.active_id) if not acticity: return error.RedPacketError(u'分享红包不存在!') if time.time() >= acticity.share_expire_at: return error.RedPacketError(u'不好意思,红包已经过期啦') # 检查红包是否还有剩余领取机会 if source_rp.item_count < 1: return error.RedPacketError(u'不好意思,红包已经被抢完啦') # 检查用户是否已领取红包 if UserRedPacket.check_shared_redpacket(uid, source_rp.campaign_id, source_rp.resource_id): return error.RedPacketError(u'已领取过该红包!') # 锁定分享红包ID,防止分享红包被抢次数超出限制 key = 'lock:share_red_packet:%s' % (str(source_rp._id)) with util.Lockit(Redis, key) as locked: if locked: return error.RedPacketError(u'领取分享红包失败,请稍后再试!') # 减少被分享红包可领取次数 source_rp.take_item() _urp = UserRedPacket.init() _urp.active_id = source_rp.active_id _urp.campaign_id = source_rp.campaign_id _urp.resource_id = source_rp.resource_id _urp.chance = 1 _urp.expire_at = source_rp.expire_at _urp.item_count = source_rp.item_count _urp.user_id = uid _urp.from_user = source_rp.from_user _urp.source = 1 # 不可被分享 _urp.create_model() return {'ret': True}
def pop_game(): """设置常用游戏 (GET|POST&LOGIN) :uri: /user/opt/popular_game :param game_id: 游戏id(批量订阅游戏id以逗号隔开) :returns: {} """ user = request.authed_user gids = request.values.get('game_id', None) uid = UserPopularGame.get_user_id(user._id) game_ids_list = UserPopularGame.get_game_ids(user._id) if not gids: for game_id in game_ids_list: usg = UserPopularGame.get_by_ship(str(user._id), str(game_id)) usg.delete_model() if usg else None if not uid: usg = UserPopularGame.init() usg.source = ObjectId(str(user._id)) usg.create_model() return {} gids = [gid.strip() for gid in gids.split(',')] games = Game.get_list(gids, check_online=False) if not games: return error.GameNotExist key = 'lock:popgame:%s' % (str(user._id)) with util.Lockit(Redis, key) as locked: if locked: return error.PopGameFailed # 删除游戏 for game_id in game_ids_list: # if game_id not in gids: usg = UserPopularGame.get_by_ship(str(user._id), str(game_id)) usg.delete_model() if usg else None # 保存游戏 for index, game in enumerate(games): # usg = UserPopularGame.get_by_ship(str(user._id), str(game._id)) # if not usg: usg = UserPopularGame.init() usg.source = ObjectId(str(user._id)) usg.target = ObjectId(str(game._id)) usg.order = index usg.create_model() return {}
def unsub_game(): """取消订阅游戏 (GET|POST&LOGIN) :uri: /user/opt/unsubscribe-game :param game_id: 游戏id :returns: {} """ user = request.authed_user gid = request.values.get('game_id', None) game = Game.get_one(gid, check_online=False) if not game: return error.GameNotExist key = 'lock:unsubgame:%s' % (str(user._id)) with util.Lockit(Redis, key) as locked: if locked: return error.SubGameFailed('取消订阅失败') usg = UserSubGame.get_by_ship(str(user._id), gid) usg.delete_model() if usg else None return {}
def add_barrage_color(event_id): """发送彩色弹幕(POST) :uri: /store/<int:event_id>/add_barrage_color :参数: text 弹幕内容 colorid 颜色id :return: {} """ user = request.authed_user text = request.values.get('text', None) cid = request.values.get('colorid', None) if not text or not cid: return error.InvalidArguments color = BarrageColor.get_color(int(cid)) if not color: return error.StoreError('该颜色的弹幕不存在') uc = UserCredit.get_or_create_user_credit(user_id=str(user._id)) if color.credit_type == const.SALE_GEM and uc.gem < color.credit_value: return error.StoreError('游票不足,颜料还在调制中!') elif color.credit_type == const.SALE_GOLD and uc.gold < color.credit_value: return error.StoreError('游米不足,颜料还在调制中!') key = 'lock:store:%s' % (str(user._id)) with util.Lockit(Redis, key) as locked: if locked: return error.StoreError('购买太频繁') # 扣除货币 if color.credit_type == const.SALE_GEM: uc.reduce_gem(color.credit_value, const.BARRAGE) elif color.credit_type == const.SALE_GOLD: uc.reduce_gold(color.credit_value, const.BARRAGE) data = dict(event_id=event_id, nickname=user.nickname or user.name, text=spam.Spam.replace_words(text), color=color.format()['desc']) from wanx.platforms.xlive import Xlive Xlive.send_live_msg(data, 'danmu') return {}
def unlike_comment(): """取消赞评论 (GET|POST&LOGIN) :uri: /user/opt/unlike-comment :param comment_id: 被赞评论id :returns: {} """ user = request.authed_user cid = request.values.get('comment_id', None) comment = Comment.get_one(cid) if not comment: return error.CommentNotExist key = 'lock:unlike_comment:%s:%s' % (str(user._id), cid) with util.Lockit(Redis, key) as locked: if locked: return error.LikeCommentFailed('取消赞评论失败') ulc = UserLikeComment.get_by_ship(str(user._id), cid) ulc.delete_model() if ulc else None return {}
def unfavorite_video(): """取消收藏视频 (GET|POST&LOGIN) :uri: /user/opt/unfavorite-video :param video_id: 收藏视频id :returns: {} """ user = request.authed_user vid = request.values.get('video_id', None) video = Video.get_one(vid) if not video: return error.VideoNotExist key = 'lock:unfavor_video:%s:%s' % (str(user._id), vid) with util.Lockit(Redis, key) as locked: if locked: return error.FavorVideoFailed('取消收藏失败') ufv = UserFaverVideo.get_by_ship(str(user._id), vid) ufv.delete_model() if ufv else None return {}
def unfollow_user(): """取消关注用户 (GET|POST&LOGIN) :uri: /user/opt/unfollow-user :param target_user_id: 被取消关注用户id :returns: {} """ user = request.authed_user params = request.values target_uid = params.get('target_user_id', None) target_user = User.get_one(target_uid) if not target_user: return error.UserNotExist key = 'lock:unfollow:%s:%s' % (str(user._id), target_uid) with util.Lockit(Redis, key) as locked: if locked: return error.FollowFailed('取消关注失败') fs = FriendShip.get_by_ship(str(user._id), target_uid) fs.delete_model() if fs else None return {}
def like_video(): """赞视频 (GET|POST&LOGIN) :uri: /user/opt/like-video :param video_id: 被赞视频id :returns: {} """ user = request.authed_user vid = request.values.get('video_id', None) video = Video.get_one(vid) if not video: return error.VideoNotExist ulv = UserLikeVideo.get_by_ship(str(user._id), vid) if not ulv: key = 'lock:like_video:%s:%s' % (str(user._id), vid) with util.Lockit(Redis, key) as locked: if locked: return error.LikeVideoFailed ulv = UserLikeVideo.init() ulv.source = ObjectId(str(user._id)) ulv.target = ObjectId(vid) _id = ulv.create_model() if _id: # 发送点赞消息 Message.send_video_msg(str(user._id), str(vid), 'like') # 更新活动点赞数 avideos = ActivityVideo.get_activity_video(vid=vid) for avideo in avideos: ts = time.time() aconfig = ActivityConfig.get_one(str( avideo['activity_id']), check_online=False) if aconfig and aconfig.status == const.ACTIVITY_BEGIN \ and (aconfig.begin_at < ts and aconfig.end_at > ts): avideo = ActivityVideo.get_one(avideo['_id'], check_online=False) avideo.update_model({'$inc': {'like_count': 1}}) return {}
def favorite_video(): """收藏视频 (GET|POST&LOGIN) :uri: /user/opt/favorite-video :param video_id: 被收藏视频id :returns: {} """ user = request.authed_user vid = request.values.get('video_id', None) video = Video.get_one(vid) if not video: return error.VideoNotExist ufv = UserFaverVideo.get_by_ship(str(user._id), vid) if not ufv: key = 'lock:favor_video:%s:%s' % (str(user._id), vid) with util.Lockit(Redis, key) as locked: if locked: return error.FavorVideoFailed ufv = UserFaverVideo.init() ufv.source = ObjectId(str(user._id)) ufv.target = ObjectId(vid) ufv.create_model() return {}
def unsub_show(): """ 取消订阅栏目 :uri: /show/sub :param: show_id :return: {} """ show_id = request.values.get('show_id') if not show_id: return error.InvalidArguments show = Show.get_one(show_id) if not show: return error.ShowNotExist uid = str(request.authed_user._id) key = 'lock:unsubshow:%s' % uid with util.Lockit(Redis, key) as locked: if locked: return error.SubGameFailed('取消订阅失败') uss = UserSubShow.get_by_ship(uid, show_id) uss and uss.delete_model() return {}
def sub_game(): """订阅游戏 (GET|POST&LOGIN) :uri: /user/opt/subscribe-game :param game_id: 游戏id(批量订阅游戏id以逗号隔开) :returns: {} """ user = request.authed_user gids = request.values.get('game_id', None) if not gids: return error.GameNotExist gids = [gid.strip() for gid in gids.split(',')] games = Game.get_list(gids, check_online=False) if not games: return error.GameNotExist key = 'lock:subgame:%s' % (str(user._id)) with util.Lockit(Redis, key) as locked: if locked: return error.SubGameFailed sub_num = 0 for game in games: usg = UserSubGame.get_by_ship(str(user._id), str(game._id)) if not usg: usg = UserSubGame.init() usg.source = ObjectId(str(user._id)) usg.target = ObjectId(str(game._id)) usg.create_model() sub_num += 1 # 订阅游戏任务检查 if user: UserTask.check_user_tasks(str(user._id), SUB_GAME, sub_num) return {}
def upload_put_file(file_id): """大文件断点上传(PUT&LOGIN) :uri: /upload/<file_id> :header Range: 片段信息(bytes=offset-length) :header Content-Type: application/octet-stream :returns: {'size': int, 'total': tuple, 'ranges': list, 'complete': bool, 'url': url} """ meta = _get_upload_file_meta(file_id) if not os.path.exists(meta['path']): return error.UploadFailed('临时文件不存在') new_range = None start_bytes = 0 # 'Range: bytes=offset-length' if 'Range' in request.headers: range_str = request.headers['Range'] start_bytes = int(range_str.split('=')[1].split('-')[0]) if start_bytes < 0 or start_bytes >= meta['size']: return error.UploadFailed('上传Range数据有问题') with open(meta['path'], 'r+') as f: f.seek(start_bytes) f.write(request.data) new_range = [start_bytes, len(request.data)] url = None # 处理多线程问题, 进行上锁 key = 'lock:upload:%s' % (file_id) while Redis.get(key): time.sleep(0.1) with util.Lockit(Redis, key) as locked: if locked: return error.RedisFailed meta = _get_upload_file_meta(file_id) file_range = meta['ranges'] file_range.append(new_range) file_range.sort() meta['ranges'] = reduce(_range_merge, file_range, [[0, 0]]) try: _set_upload_file_meta(file_id, meta) except: return error.RedisFailed total = reduce(lambda x, y: (0, x[1] + y[1]), meta['ranges'], [0, 0]) complete = False if len(meta['ranges']) == 1 and meta['ranges'][0][1] == meta['size']: _path = 'videos' if meta['type'] == 'videos.url' else 'images' _file = Media(app.config.get("STATIC_BASE"), _path, None) try: url = _file.upload_large_file(meta['path'], None, '.%s' % meta['ext']) except: return error.UploadFailed # 更新对象 obj, attr = meta['type'].split(".") data = {attr: url} if obj == 'videos': if attr == 'url': data['status'] = const.ONLINE model = Video.get_one(meta['target_id'], check_online=False) elif obj == 'users': model = User.get_one(meta['target_id'], check_online=False) model.update_model({"$set": data}) complete = True abs_url = urljoin(app.config.get('STATIC_URL'), url) if url else None return { 'size': len(request.data), 'total': total, 'url': abs_url, 'ranges': meta['ranges'], 'complete': complete }
def share_activity_rewards(): """ 请求分享活动奖励 :uri: /activity/share/rewards :param: aid 活动ID :param: device 设备ID :return: """ user = request.authed_user params = request.values aid = params.get('aid', None) device = params.get('device', None) uid = str(user._id) if not aid or not device: return error.InvalidArguments activity = ShareActivityConfig.get_one(aid, check_online=True) if not activity: return error.ActivityNotExist if not activity.get_left_today(): return error.UserTrafficZero shared = UserShareActivityLog.check_user_activity(aid, user.phone, device) if shared: return error.UserTrafficExists # 获取分享活动的视频id vids = TopicVideo.topic_video_ids(activity.share_video_topic, 1, 99) # 查看用户活动期间内的分享数据 user_shares = UserShare.get_user_shares_by_time(uid, activity.begin_at, activity.end_at) finished = False for us_id in user_shares: us = UserShare.get_one(us_id) if not us: continue if us.target_type not in ['video', 'url']: continue if us.target_type == 'url' and us.target_value != activity.share_url: continue if us.target_type == 'video' and us.target_value not in vids: continue finished = True break # 如果活动期间,用户没有分享过,则不可领取 if not finished: return error.UserTrafficInvalid(u'您还没有分享活动规定的URL或视频') key = 'lock:share:activity:%s' % (uid) with util.Lockit(Redis, key) as locked: if locked: return error.UserTrafficInvalid(u'领取分享活动奖励失败') # 创建用户参与分享活动记录 usa_log = UserShareActivityLog.init() usa_log.activity = activity._id usa_log.owner = user._id usa_log.phone = user.phone usa_log.device = device usa_log.charge_status = 2 usa_log.active_type = us.target_type usa_log.reward_order = activity.incr_counter() usa_log.create_model() # 只有序号尾数为9的订单,才能获得抽奖机会 if usa_log.reward_order % 10 != 9: return {'ret': False} # 抽奖 # 查看是否有抽奖机会 left_chances = Marketing.query_lottery_chance(user.partner_migu['id'], activity.campaign_id) if isinstance(left_chances, error.ApiError): # 抽奖失败则记录领取状态为失败 usa_log.update_model({'$set': {'charge_status': 1}}) return {'ret': False} # 进行抽奖机会的兑换 ret = Marketing.execute_campaign(user.partner_migu['id'], user.phone, [activity.campaign_id]) if not ret or isinstance(ret, error.ApiError): # 抽奖失败则记录领取状态为失败 usa_log.update_model({'$set': {'charge_status': 1}}) return {'ret': False} # 调用营销平台进行抽奖 prize = Marketing.draw_lottery(user.partner_migu['id'], activity.campaign_id) if isinstance(prize, error.ApiError) or not prize: # 抽奖失败则记录领取状态为失败 usa_log.update_model({'$set': {'charge_status': 1}}) return {'ret': False} # 抽中物品则记录领取成功 usa_log.update_model({'$set': {'charge_status': 0}}) # 更新活动剩余奖励 data = { '$set': { 'left_num': activity.left_num - 1, 'use_num': activity.use_num + 1 } } activity.update_model(data) # 增加当日已领取次数 ShareActivityConfig.incr_used_today(aid) return {'ret': True}
def draw_gift_code(): """ VIP用户获取礼包兑换码 :uri: /games/vip/giftcode/draw :param: giftcode_id 会员游戏礼包id :return: """ user = request.authed_user uid = str(user._id) gcid = request.values.get('giftcode_id') if not gcid: return error.InvalidArguments giftcode = VipGiftCode.get_one(gcid, check_online=True) if not giftcode: return error.GiftCodeNotExist if giftcode.left <= 0: return error.StoreError('没有可领取的礼包了!') vip = MiguPay.check_user_vip_level(user.phone) if isinstance(vip, error.ApiError): return vip if not (vip['vip5']['subscribed'] or vip['vip10']['subscribed']): return error.StoreError('没有领取权限!') # 查看是否有抽奖机会 left_chances = Marketing.query_lottery_chance(user.partner_migu['id'], giftcode.campaign_id) if isinstance(left_chances, error.ApiError): return error.StoreError('领取礼包失败,请稍后重试') # 当前没有剩余机会的时候,需要先验证是否可以抽奖并获取抽奖机会 if left_chances <= 0: key = 'lock:store:%s' % (str(user._id)) with util.Lockit(Redis, key) as locked: if locked: return error.StoreError('领取礼包太频繁') if gcid in UserGiftCodeOrder.get_user_gift_code_ids(uid): return error.StoreError('已经领取过该礼包') # 进行抽奖机会的兑换 ret = Marketing.execute_campaign(user.partner_migu['id'], user.phone, [giftcode.campaign_id], trigger=10218) if not ret or isinstance(ret, error.ApiError): return error.StoreError('兑换领取机会失败') # 调用营销平台进行抽奖 prize = Marketing.draw_lottery(user.partner_migu['id'], giftcode.campaign_id) if isinstance(prize, error.ApiError): return prize if not prize: return error.StoreError('获取游戏兑换码失败') exchange_code = None for row in prize.get('extensionInfo', []): if row['key'] == 'exchangeCode': exchange_code = row['value'] break if not exchange_code: return error.StoreError('获取游戏兑换码失败') order = UserGiftCodeOrder.create(user_id=str(user._id), vgc_id=gcid, vgc_name=giftcode.name, campaign_id=giftcode.campaign_id, gift_code=exchange_code, result=json.dumps(prize), recid=prize.get('id', ''), expire_at=util.timestamp2datetime( giftcode.exchange_expire_at), status=const.ORDER_FINISHED, user_ip=request.access_route[0]) UserGiftCodeOrder.clear_redis(str(user._id)) # 更新库存 giftcode.update_model({'$inc': {'left': -1, 'used': 1}}) return {'order': order.format()}
def activity_team_support(): """战队支持 :uri: activity/team_support :param source: 投票来源(app_play, activity, activity_share, video_share) :param device: 设备唯一ID :param battle_id: 对战ID :param team_name: 支持战队名字 :return: {'support_count': int} """ params = request.values team_name = params.get('team_name', None) battle_id = params.get('battle_id', None) source = params.get('source', None) device = params.get('device', None) requ_type = params.get('requ_type', None) if not team_name or not source or not device or not battle_id or not requ_type: return error.InvalidArguments # 增加ip限制,每个ip每天限制20次 user_ip = request.remote_addr ip_key = 'ip_limit:%s:%s:%s:%s' % (user_ip, battle_id, team_name, str(datetime.date.today())) ip_limit = Redis.incr(ip_key) if ip_limit == 1: # 第一次设置key过期时间 Redis.expire(ip_key, 86400) if ip_limit > 2000: return error.ActivityVideoNotExist("超出IP限制") battle = Battle.get_one_data(battle_id) if battle: if team_name != battle['team_1'] and team_name != battle['team_2']: return error.MteamNotExist else: return error.MteamNotExist team_support = TeamSupport.get_team_support(battle_id, team_name) if not team_support: team_support = TeamSupport.init() team_support.team_name = team_name team_support.battle_id = ObjectId(battle_id) team_support.ticket = 0 team_support.create_model() support_count = int(team_support['ticket']) if team_support else 0 team_support_record = TeamSupportRecord.get_team_support_record( device, battle_id, team_name) if requ_type == 'support': if not team_support_record: key = 'lock:team_support:%s:%s:%s' % (device, battle_id, team_name) with util.Lockit(Redis, key) as locked: if locked: return error.VoteVideoFailed team_support_record = TeamSupportRecord.init() team_support_record.device = device team_support_record.source = source team_support_record.team_name = team_name team_support_record.battle_id = ObjectId(battle_id) team_support_record.create_model() support_count = support_count + 1 # 票数加1 elif requ_type == 'cancel_support': if team_support_record: key = 'lock:team_support:%s:%s:%s' % (device, battle_id, team_name) with util.Lockit(Redis, key) as locked: if locked: return error.VoteVideoFailed team_support_record.delete_model() support_count = support_count - 1 # 票数减1 else: return error.InvalidArguments return {'support_count': support_count}
def report(): """举报 :uri: /user/report :param target_id: 被举报id :param type: 举报原因 :param content: 举报内容 :param source: 举报来源,0:来自视频,1:来自直播,2:来自评论,3:来自回复 :returns: {} """ params = request.values tid = params.get('target_id', None) _type = int(params.get('type', 0)) content = params.get('content', None) source = int(params.get('source', 0)) from_user = request.authed_user if not tid or not _type or source not in range(4): return error.InvalidArguments if source == 0: video = Video.get_one(tid) if not video: return error.VideoNotExist uid = video.author title = video.title elif source == 1: live = Xlive.get_live(tid) if not live: return error.LiveError('直播不存在') uid = live.get('user_id') title = live.get('name') elif source == 2: comment = Comment.get_one(tid) if not comment: return error.CommentNotExist uid = comment.author title = comment.content elif source == 3: reply = Reply.get_one(tid) if not reply: return error.ReplyNotExist uid = reply.owner title = reply.content key = 'lock:reports:object:%s' % (tid) with util.Lockit(Redis, key) as locked: if locked: return error.ReportVideoFailed('举报失败,请稍后再试') if ReportVideo.check_reported(tid, source, from_user._id): return error.ReportVideoExists rv = ReportVideo.init() rv.uid = uid rv.vid = tid rv.type = _type rv.content = content if content else '' rv.source = source rv.from_user = from_user._id rv.status = 0 rv.deleted = 0 rv.bannef = 0 rv.create_model() rpc_id = ReportConfig.get_limit_config(source) rpconfig = ReportConfig.get_one(rpc_id) if not rpconfig: return {} max_limit = rpconfig.max_limit if max_limit and ReportVideo.reach_max_limit(tid, max_limit): _templates = [ u'用户ID %(id)s,标题为"%(title)s"的视频正在被举报,请尽快审核', u'房间号为%(id)s,标题为"%(title)s"的直播正在被举报,请尽快审核', u'用户%(id)s针对"%(title)s"视频的评论正在被举报,请尽快审核', u'用户%(id)s针对"%(title)s"评论的回复正在被举报,请尽快审核' ] _id = tid if source == 1 else uid try: job = 'send_sms' data = dict(group=str(rpconfig.group), content=_templates[source] % { 'id': str(_id), 'title': title }) gm_client = gearman.GearmanClient( app.config['GEARMAN_SERVERS']) gm_client.submit_job(job, json.dumps(data), background=True, wait_until_complete=False, max_retries=5) except gearman.errors.GearmanError: pass except Exception, e: print_log('send_sms_err', str(e))
def live_task(): """观看直播时长任务 (GET) :uri: /lives/task :param task_id: 直播任务ID :param os: 平台 :param channels: 渠道(可选) :param version_code: 版本号 :param live_id: 直播间ID :return: {'ret': bool} """ user = request.authed_user params = request.values task_id = params.get('task_id', None) os = params.get('os', None) channels = params.get('channels', None) version_code = int(params.get('version_code', 0)) live_id = request.values.get('live_id') if not os or not version_code or not task_id or not live_id: return error.InvalidArguments uid = str(user._id) phone = str(user.phone) province = None if user.province: province = user.province if not user.province and util.is_mobile_phone(phone): province = Migu.get_user_info_by_account_name(phone) if not isinstance(province, error.ApiError): user.update_model({'$set': {'province': province}}) else: province = None # 避免出现跨天时出现没有任务的情况 tids = WatchLiveTask.get_user_tids(uid) task = WatchLiveTask.get_one(task_id) if not task: return error.TaskError(u'观看直播时长任务不存在!') if task.os not in ['all', os]: return error.TaskError(u'不符合任务条件!') if (task.version_code_mix and task.version_code_mix > version_code) or \ (task.version_code_max and task.version_code_max < version_code): return error.TaskError(u'不符合任务条件!') if channels and task.channels and channels not in task.channels: return error.TaskError(u'不符合任务条件!') if task.login == 'login' and ( not uid or not task.user_in_group(str(task.group), uid)): return error.TaskError(u'不符合任务条件!') if task.province and not province: return error.TaskError(u'不符合任务条件!') if task.province and province and province not in task.province: return error.TaskError(u'不符合任务条件!') extra = dict(migu_id=user.partner_migu['id'], phone=user.phone, campaign_id=task.campaign_id) msg = u"恭喜%(name)s获得%(gift)s" def send_default_gift(uid, task_id, user, extra, msg): item = WatchLiveTaskItem.get_item_by_identity(task_id, 'default') if not item: return {'ret': False, 'task': task.format(uid), 'item': None} # 更新库存 item.update_left() # 进行物品的发放 product = Product.get_product(item.product_id) status = product.add_product2user(uid, item.product_num, const.TASK, extra) _msg = msg % ({'name': user.nickname or user.name, 'gift': item.title}) data = dict(message=_msg, event_id=live_id) Xlive.send_live_msg(data, 'activity') return {'ret': True, 'task': task.format(uid), 'item': item.format()} lockkey = 'lock:task:%s:%s' % (uid, task_id) with util.Lockit(Redis, lockkey) as locked: if locked: return error.TaskError(u'请求频率过高') # 查看是否有抽奖机会 stat = WatchLiveTask.update_left_chance(uid, task_id) if not stat: return error.TaskError(u'无抽奖机会!') # 从营销中心查询/请求抽奖机会 left_chances = Marketing.query_lottery_chance(user.partner_migu['id'], task.campaign_id) if isinstance(left_chances, error.ApiError): return send_default_gift(uid, task_id, user, extra, msg) if left_chances <= 0: # 进行抽奖机会的兑换 ret = Marketing.execute_campaign(user.partner_migu['id'], user.phone, [task.campaign_id]) if not ret or isinstance(ret, error.ApiError): return send_default_gift(uid, task_id, user, extra, msg) # 调用营销平台进行抽奖 prize = Marketing.draw_lottery(user.partner_migu['id'], task.campaign_id) if isinstance(prize, error.ApiError): prize = None if not prize: # 如果没有抽中奖品,发放默认奖品 return send_default_gift(uid, task_id, user, extra, msg) prize_name = None for i in prize['extensionInfo']: if i['key'] == 'levelName': prize_name = i['value'] break item = WatchLiveTaskItem.get_item_by_identity(task_id, prize_name) # 更新库存 item.update_left() # 生成兑奖订单 order = UserLiveOrder.create(user_id=uid, item_id=str(item._id), activity_id=task_id, activity_type=0, campaign_id=task.campaign_id, title=item.title, product_id=item.product_id, product_num=item.product_num, status=const.ORDER_FINISHED, result=json.dumps(prize)) order.save() # 进行物品的发放 product = Product.get_product(item.product_id) status = product.add_product2user(uid, item.product_num, const.TASK, extra) _msg = msg % ({'name': user.nickname or user.name, 'gift': item.title}) data = dict(message=_msg, event_id=live_id) Xlive.send_live_msg(data, 'activity') return {'ret': True, 'task': task.format(uid), 'item': item.format()}
def draw_lottery(): """抽奖接口(POST&LOGIN) :uri: /store/draw_lottery :param store_id: 抽奖活动ID :return: {'item': <Item>object, 'order': <Order>object} """ user = request.authed_user store_id = request.values.get('store_id', None) trigger = request.values.get('trigger', None) user_ip = request.remote_addr device = request.values.get('device', None) if not store_id: return error.InvalidArguments store = Store.get_store(store_id) if not store or not store.online(): return error.StoreError('该抽奖活动不存在或已下线') if store.pause(): return error.StoreError('该抽奖活动还未开始') if store.yxmember: uservip = MiguPay.check_user_vip_level(user.phone) if isinstance(uservip, error.ApiError): return uservip if not (uservip['vip5']['subscribed'] or uservip['vip10']['subscribed']): return error.MemberError('该抽奖需要游戏会员才能参加') # 进行抽奖奖项库存判断 items = StoreItem.get_store_items(store_id) left_num = sum(map(lambda x: x.left_num, items)) if left_num < 0: return error.StoreError('该抽奖活动奖项已被领取完') # 判断号码是否符合规则 info = Marketing.query_campaign(store.campaign_id) if isinstance(info, error.ApiError): return info if info['mobile_phone_only'] and not util.is_mobile_phone(user.phone): return error.StoreError('该抽奖活动只对移动手机号开放') # 查看是否有抽奖机会 left_chances = Marketing.query_lottery_chance(user.partner_migu['id'], store.campaign_id) if isinstance(left_chances, error.ApiError): return error.StoreError('获取抽奖机会失败') if left_chances <= 0: uc = UserCredit.get_or_create_user_credit(user_id=str(user._id)) if store.credit_type == const.SALE_GEM and uc.gem < store.credit_value: return error.StoreError('你的游票不足,无法参与抽奖哦!') elif store.credit_type == const.SALE_GOLD and uc.gold < store.credit_value: return error.StoreError('你的游米不足,无法参与抽奖哦!') key = 'lock:store:%s' % (str(user._id)) with util.Lockit(Redis, key) as locked: if locked: return error.StoreError('抽奖太频繁') # 进行抽奖机会的兑换 if not trigger: ret = Marketing.execute_campaign(user.partner_migu['id'], user.phone, [store.campaign_id]) else: ret = Marketing.execute_campaign(user.partner_migu['id'], user.phone, [store.campaign_id], trigger=trigger) if not ret or isinstance(ret, error.ApiError): return error.StoreError('兑换抽奖机会失败') else: # 扣除货币 if store.credit_type == const.SALE_GEM: uc.reduce_gem(store.credit_value, const.LOTTERY_REWAED) elif store.credit_type == const.SALE_GOLD: uc.reduce_gold(store.credit_value, const.LOTTERY_REWAED) # 调用营销平台进行抽奖 prize = Marketing.draw_lottery(user.partner_migu['id'], store.campaign_id) if isinstance(prize, error.ApiError): return prize # 营销数据入库经分 抽奖活动 data_dict = dict(cmd="lottery", opt="1", deviceid=request.values.get('device', ''), mobile=user.phone, source=request.values.get('source', 'activity'), activityid=store_id, activityname=store.title) Marketing.jf_report(data_dict) # 营销平台奖项有各种限制, 会导致用户抽不中任何物品的可能。 # 比如有A/B/C三个抽奖奖项,概率分别为20%/30%/50%,如果A物品配置为一个手机号只能中一次, # 那当用户抽中过A之后,以后再抽奖,就会有20%(A)的几率啥也抽不中。如果B物品库存又没有了, # 那用户就会有20%(A)+30%(B)的几率啥也抽不中。为了处理这种情况,目前默认如果抽不中就给 # 用户发一个抽奖活动配置的"default"奖项(运营后台: 营销平台奖项ID配置为'default') if not prize: item = StoreItem.get_item_by_identity(store.store_id, 'default') if not item: return {'item': None, 'order': None} else: # 更新库存 item.left_num -= 1 item.use_num += 1 item.save() # 生成兑奖订单 order = UserOrder.create( user_id=str(user._id), item_id=item.item_id, store_id=item.store_id, store_type=store.store_type, campaign_id=store.campaign_id, title=item.title, product_id=item.product_id, product_num=item.product_num, status=const.ORDER_NEED_DRAW, result='', user_ip=request.access_route[0], ) extra = dict(migu_id=user.partner_migu['id'], phone=user.phone, campaign_id=store.resource_campaign_id) # 进行物品的发放 product = Product.get_product(item.product_id) status = product.add_product2user(str(user._id), item.product_num, const.LOTTERY, extra) # 订单状态更新 if status != order.status: order.status = status order.save() return {'item': item.format(), 'order': order.format()} # 由于营销平台看不到id, 暂时只能用奖项名称进行对应 prize_name = None for i in prize['extensionInfo']: if i['key'] == 'levelName': prize_name = i['value'] break item = StoreItem.get_item_by_identity(store.store_id, prize_name) # 更新库存 item.left_num -= 1 item.use_num += 1 item.save() # 无领取规则的活动营销平台会自动领取 status = const.ORDER_NEED_DRAW if info[ 'is_exchange_rule'] else const.ORDER_IN_HAND # 生成兑奖订单 order = UserOrder.create( user_id=str(user._id), item_id=item.item_id, store_id=item.store_id, store_type=store.store_type, campaign_id=store.campaign_id, title=item.title, product_id=item.product_id, product_num=item.product_num, status=status, result=json.dumps(prize), user_ip=request.access_route[0], ) product = Product.get_product(item.product_id) if product.product_type != PHYSICAL_OBJECT: # 非实物物品直接去营销平台进行奖励兑换 # 有领取规则的抽奖活动的非实物物品自动领取, 无领取规则的活动营销平台会自动领取 if info['is_exchange_rule']: # 获取用户可兑换奖励信息 prizes = Marketing.query_exchengable_prizes( user.partner_migu['id'], order.campaign_id) if isinstance(prizes, error.ApiError): return prizes # 进行奖励的兑换, 目前最后一条为最近获得的奖励 for _prize in prizes[::-1]: exchenge_ids = map(lambda x: x['id'], _prize['exchengeResources']) exchengeable_id = _prize['exchengableResource']['id'] if [prize['id']] == exchenge_ids: exchenge_ids = [prize['id']] ret = Marketing.draw_exchengable_prize( user.partner_migu['id'], order.campaign_id, exchenge_ids, exchengeable_id, prize['amount']) if isinstance(ret, error.ApiError): return ret # 由于对方没有返回订单ID, 只能通过获取用户最近一个已兑换奖励的订单ID, 实物物品需要手动领取 ret, _ = Marketing.query_exchenged_prizes(user.partner_migu['id'], order.campaign_id, page=1, pagesize=1) if isinstance(ret, error.ApiError): return ret # 更新订单信息 if isinstance(ret, list) and len(ret) > 0 and 'recId' in ret[0]: order.recid = ret[0]['recId'] order.status = const.ORDER_IN_HAND order.save() extra = dict(migu_id=user.partner_migu['id'], phone=user.phone, campaign_id=store.resource_campaign_id) # 进行物品的发放 status = product.add_product2user(str(user._id), item.product_num, const.LOTTERY, extra) # 订单状态更新 if status != order.status: order.status = status order.save() return {'item': item.format(), 'order': order.format()}
def grab_redpacket(): """直播间红包争抢(POST) :uri: /lives/redpacket/grab :param os: 平台 :param channels: 渠道(可选) :param version_code: 版本号 :param live_id: 直播间ID :param source_id: 红包ID :return: {'ret': bool} """ user = request.authed_user params = request.values os = params.get('os', None) channels = params.get('channels', None) version_code = int(params.get('version_code', 0)) live_id = params.get('live_id', None) source_id = params.get('source_id', None) if not os or not version_code or not source_id or not live_id: return error.InvalidArguments uid = None province = None if user: uid = str(user._id) phone = str(user.phone) if user.province: province = user.province if not user.province and util.is_mobile_phone(phone): province = Migu.get_user_info_by_account_name(phone) if not isinstance(province, error.ApiError): user.update_model({'$set': {'province': province}}) else: province = None red_packet = UserRedPacket.get_one(source_id) if not red_packet: return error.RedPacketError(u'红包不存在!') activity = LiveRedPacket.get_one(red_packet.active_id) if not activity: return error.RedPacketError(u'直播红包活动不存在!') # 查看是否有抽奖机会 if red_packet.chance <= 0: return error.RedPacketError(u'已达到领取红包次数上限!') def get_user_redpackets(): # 先获取已存在的红包,以及已经参与的直播间抢红包 _red_packet, _red_packet_count = None, 0 _ids = UserRedPacket.user_red_packets(uid) for urp in UserRedPacket.get_list(_ids): if not LiveRedPacket.get_one(urp.active_id): continue if urp.source == 0: # 过滤掉所有直播间抽奖机会 continue if urp.chance <= 0: continue if _red_packet is None or _red_packet.expire_at > urp.expire_at: _red_packet = urp _red_packet_count += 1 # 如果是直播间红包,返回直播间红包;如果不是,返回新红包 if red_packet.from_user == red_packet.user_id: _red_packet = red_packet # 如果没有新红包,返回当前红包,并标记剩余红包数为0 if not _red_packet: _red_packet = red_packet return _red_packet.format(_red_packet_count) def send_default_gift(uid, task_id, user, extra): return { 'ret': True, 'red_packet': get_user_redpackets(True), 'item': None, 'current_red_packet': red_packet.format(0, True) } extra = dict(migu_id=user.partner_migu['id'], phone=user.phone, campaign_id=red_packet.campaign_id) item = None key = 'lock:receive_red_packet:%s' % (uid) with util.Lockit(Redis, key) as locked: if locked: return error.RedPacketError(u'领取红包失败,请稍后再试!') # 如果是直播间红包抽奖,则需要先调用抽奖接口再获取红包物品 if not red_packet.source: # 从营销中心查询/请求抽奖机会 left_chances = Marketing.query_lottery_chance( user.partner_migu['id'], red_packet.campaign_id) if isinstance(left_chances, error.ApiError): return send_default_gift(uid, source_id, user, extra) if left_chances <= 0: # 进行抽奖机会的兑换 ret = Marketing.execute_campaign(user.partner_migu['id'], user.phone, [red_packet.campaign_id]) if not ret or isinstance(ret, error.ApiError): return send_default_gift(uid, source_id, user, extra) # 扣除用户抽奖次数 red_packet.take_chance() # 调用营销平台进行抽奖 prize = Marketing.draw_lottery(user.partner_migu['id'], red_packet.campaign_id) if isinstance(prize, error.ApiError): prize = None if not prize: # 如果没有抽中奖品,发放默认奖品 return send_default_gift(uid, source_id, user, extra) # 先请求红包机会 extra.update({'campaign_id': activity.redpacket_id}) ret = Marketing.execute_campaign(user.partner_migu['id'], user.phone, [activity.redpacket_id]) if not ret or isinstance(ret, error.ApiError): return send_default_gift(uid, source_id, user, extra) # 抢红包 rps = Marketing.query_red_package_by_user(user.partner_migu['id'], activity.redpacket_id) if isinstance(rps, error.ApiError): return send_default_gift(uid, source_id, user, extra) if not rps: return send_default_gift(uid, source_id, user, extra) # 将最新的红包放到最前面 rps.sort(key=lambda x: x['createDate']['time'], reverse=True) # 将红包放入用户可分享红包 _urp = UserRedPacket.init() _urp.active_id = activity._id _urp.campaign_id = activity.redpacket_id _urp.resource_id = rps[0]['id'] _urp.chance = 1 _urp.expire_at = activity.share_expire_at _urp.item_count = activity.share_count _urp.user_id = uid _urp.from_user = uid _urp.source = 1 _urp.create_model() red_packet = _urp # 扣除红包领取次数 red_packet.take_chance() # 从分享红包获取物品 prize = Marketing.grab_red_package(user.partner_migu['id'], red_packet.campaign_id, red_packet.resource_id) if isinstance(prize, error.ApiError): return { 'ret': False, 'red_packet': get_user_redpackets(), 'item': None, 'current_red_packet': red_packet.format(0, True) } if not prize: # 如果没有抽中奖品,发放默认奖品 return send_default_gift(uid, source_id, user, extra) # 发放物品 prize_name = prize.get('name') item = LiveRedPacketItem.get_item_by_identity(activity._id, prize_name) # 更新库存 item.update_left() # 生成兑奖订单 order = UserLiveOrder.create(user_id=str(user._id), item_id=str(item._id), activity_id=str(activity._id), activity_type=1, campaign_id=red_packet.campaign_id, title=item.title, product_id=item.product_id, product_num=item.product_num, status=const.ORDER_FINISHED, result=json.dumps(prize)) order.save() # 进行物品的发放 product = Product.get_product(item.product_id) product.add_product2user(uid, item.product_num, const.TASK, extra) return { 'ret': True, 'red_packet': get_user_redpackets(), 'item': item and item.format(), 'current_red_packet': red_packet.format(0, item is None) }
def query_new_redpacket(): """ :uri: /lives/redpacket/query_new :param os: 平台 :param channels: 渠道(可选) :param version_code: 版本号 :param live_id: 直播间ID :param active_id: 活动ID :return: """ user = request.authed_user params = request.values os = params.get('os', None) channels = params.get('channels', None) version_code = int(params.get('version_code', 0)) live_id = params.get('live_id', None) active_id = params.get('active_id', None) if not os or not version_code or not active_id or not live_id: return error.InvalidArguments live = Xlive.get_live(live_id) if not live: return error.LiveError(u'直播不存在') activity = LiveRedPacket.get_one(active_id) if not activity: return error.RedPacketError(u'直播红包活动不存在!') uid = None province = None if user: uid = str(user._id) phone = str(user.phone) if user.province: province = user.province if not user.province and util.is_mobile_phone(phone): province = Migu.get_user_info_by_account_name(phone) if not isinstance(province, error.ApiError): user.update_model({'$set': {'province': province}}) else: province = None else: return {'red_packet': activity.format()} live_authors = [] if not activity.live_authors else activity.live_authors.split( '\r\n') live_games = [] if not activity.live_games else activity.live_games.split( '\r\n') key_words = [] if not activity.keyword else activity.keyword.split(u',') # 过滤主播 if live_authors and live['user_id'] not in live_authors: return error.RedPacketError(u'不符合活动条件!') # 过滤游戏 if live_games and live['game_id'] not in live_games: return error.RedPacketError(u'不符合活动条件!') # 过滤关键字 if key_words and not any(map(lambda x: x in live['name'], key_words)): return error.RedPacketError(u'不符合活动条件!') if activity.os not in ['all', os]: return error.RedPacketError(u'不符合活动条件!') if (activity.version_code_mix and activity.version_code_mix > version_code) or \ (activity.version_code_max and activity.version_code_max < version_code): return error.RedPacketError(u'不符合活动条件!') if channels and activity.channels and channels not in activity.channels: return error.RedPacketError(u'不符合活动条件!') if activity.login == 'login' and ( not uid or not activity.user_in_group(str(activity.group), uid)): return error.RedPacketError(u'不符合活动条件!') if activity.province and not province: return error.RedPacketError(u'不符合活动条件!') if activity.province and province and province not in activity.province: return error.RedPacketError(u'不符合活动条件!') key = 'lock:receive_red_packet:%s' % (uid) with util.Lockit(Redis, key) as locked: if locked: return error.RedPacketError(u'领取红包失败,请稍后再试!') # 查看用户是否已领取该红包 if UserRedPacket.check_live_redpacket(uid, activity._id): return error.RedPacketError(u'用户已领取该红包!') _urp = UserRedPacket.init() _urp.active_id = activity._id _urp.campaign_id = activity.campaign_id _urp.chance = activity.chance _urp.expire_at = activity.expire_at _urp.user_id = uid _urp.source = 0 # 不可被分享 _urp.create_model() return {'red_packet': _urp.format(activity.chance)}
def exchange_product(): """兑换物品接口(POST&LOGIN) :uri: /store/exchange_product :param store_id: 兑换活动ID :param item_id: 兑换物品ID :return: {'item': <Item>object, 'order': <Order>object} """ user = request.authed_user store_id = request.values.get('store_id', None) item_id = request.values.get('item_id', None) user_ip = request.remote_addr device = request.values.get('device', None) if not store_id or not item_id: return error.InvalidArguments store = Store.get_store(store_id) if not store or not store.online(): return error.StoreError('该兑换活动不存在或已下线') item = StoreItem.get_store_item(store_id, item_id) if not item: return error.StoreError('该兑换奖品不存在') # 库存判断 if item.left_num < 1: return error.StoreError('该兑换奖品已卖完') product = Product.get_product(item.product_id) # 判断手机号 if product.product_type == MOBILE_TRAFFIC and not util.is_mobile_phone( user.phone): return error.StoreError('非移动手机号不能兑换此商品') if product.product_type == UNICOM_TRAFFIC and not util.is_unicom_phone( user.phone): return error.StoreError('非联通手机号不能兑换此商品') if product.product_type == TELECOM_TRAFFIC and not util.is_telecom_phone( user.phone): return error.StoreError('非电信手机号不能兑换此商品') uc = UserCredit.get_or_create_user_credit(user_id=str(user._id)) if item.credit_type == const.SALE_GEM and uc.gem < item.credit_value: return error.StoreError('你的游票不足,无法兑换此物品哦!') elif item.credit_type == const.SALE_GOLD and uc.gold < item.credit_value: return error.StoreError('你的游米不足,无法兑换此物品哦!') key = 'lock:store:%s' % (str(user._id)) status = None with util.Lockit(Redis, key) as locked: if locked: return error.StoreError('兑换太频繁') extra = dict(migu_id=user.partner_migu['id'], phone=user.phone, campaign_id=store.resource_campaign_id) status = product.add_product2user(str(user._id), item.product_num, const.EXCHANGE, extra) if status == const.ORDER_FAILED: return error.StoreError('兑换失败') else: # 扣除货币 if item.credit_type == const.SALE_GEM: uc.reduce_gem(item.credit_value, const.EXCHANGE) elif item.credit_type == const.SALE_GOLD: uc.reduce_gold(item.credit_value, const.EXCHANGE) # 更新库存 item.left_num -= 1 item.use_num += 1 item.save() # 记录订单 order = UserOrder.create( user_id=str(user._id), item_id=item.item_id, store_id=item.store_id, store_type=store.store_type, campaign_id=store.campaign_id, title=item.title, product_id=item.product_id, product_num=item.product_num, status=status, user_ip=request.access_route[0], ) # 营销数据入库经分 兑换活动 data_dict = dict(cmd="exchange", opt="1", deviceid=request.values.get('device', ''), mobile=user.phone, source=request.values.get('source', 'activity'), activityid=store_id, activityname=store.title) Marketing.jf_report(data_dict) return {'item': item.format(), 'order': order.format()}
def activity_team_vote(): """战队投票 :uri: activity/team_vote :param source: 投票来源(app_play, activity, activity_share, video_share) :param device: 设备唯一ID :param team_id: 战队ID :param ut: 用户ut :return: {'team_vote_count': int} """ user = request.authed_user print_log('activity/team_vote', '[user]: {0}'.format(user)) params = request.values.to_dict() tid = params.get('team_id', None) source = params.get('source', None) device = params.get('device', None) uid = user and str(user._id) if not tid or not source or not device: return error.InvalidArguments # 增加ip限制,每个ip每天限制20次 user_ip = request.remote_addr ip_key = 'ip_limit:%s:%s:%s' % (user_ip, tid, str(datetime.date.today())) ip_limit = Redis.incr(ip_key) if ip_limit == 1: # 第一次设置key过期时间 Redis.expire(ip_key, 86400) if ip_limit > 20: return error.ActivityVideoNotExist("超出IP限制") mteam = Mteam.get_one(tid) if not mteam: return error.MteamNotExist vote_count = int(mteam['ticket']) mname = str(mteam['mname']) course = MatchCourse.get_course_by_mname(mname) now = int(time.time()) if course: if int(course.course_end) < now: return error.VoteVideoFailed else: return error.VoteVideoFailed vote = VoteMteam.get_vote(uid=uid, device=device, tid=tid) if not vote: key = 'lock:vote_mteam:%s:%s' % (device, tid) with util.Lockit(Redis, key) as locked: if locked: return error.VoteVideoFailed vote = VoteMteam.init() vote.device = device vote.source = source vote.author = ObjectId(uid) vote.target = ObjectId(tid) vote.mname = ObjectId(mname) vote.create_model() # 票数加1 vote_count = vote_count + 1 return {'vote_count': vote_count}
def traffic_send(): """发放流量 (GET|POST&LOGIN) :uri: /traffic/send :param traffic_type: (first_login, video_share) :returns: {'message': str} """ user = request.authed_user traffic_type = request.values.get('traffic_type', None) device = request.values.get('device', None) status = ActivityConfig.activity_status() if const.ACTIVITY_PAUSE == status: print_log('app_traffic', '[%s][%s]: activity is pause' % (traffic_type, user.phone)) return error.TrafficSendFail(u'小伙伴们太热情了,稍后再来吧!') elif const.ACTIVITY_END == status: print_log('app_traffic', '[%s][%s]: activity is end' % (traffic_type, user.phone)) return error.UserTrafficZero(u'亲,我们的奖品已经送完啦,下次要早点来哦!') utl = UserTrafficLog.get_traffic_by_type(str(user._id), traffic_type) if not utl and traffic_type == 'video_share': print_log('app_traffic', '[video_share][%s]: UserTrafficExists' % user.phone) return error.UserTrafficExists(u'亲,你还没有分享自己的作品哦,赶快去分享你的游戏视频,再来领取吧!') elif utl and utl.status in [ const.TRAFFIC_SUCCESS, const.TRAFFIC_RECEIVED_SUCCESS, const.TRAFFIC_RECEIVED_PROCESS ]: print_log('app_traffic', '[%s][%s]: TrafficExists' % (traffic_type, user.phone)) return error.TrafficExists utl_device = UserTrafficLog.get_traffic_by_device(device, traffic_type) if utl_device: print_log( 'app_traffic', '[%s][%s][%s]: device repeat' % (traffic_type, user.phone, device)) return error.UserTrafficInvalid(u'亲,同一部终端只能领取一次流量哦!') utl_count = UserTrafficLog.traffic_count_by_type(traffic_type) if utl_count and utl_count > const.TRAFFIC_CATEGORY_NUM.get( traffic_type, None): print_log('app_traffic', '[%s][%s]: UserTrafficZero' % (traffic_type, user.phone)) return error.UserTrafficZero(u'亲,我们的奖品已经送完啦,下次要早点来哦!') key = 'lock:traffic:%s:%s' % (user.phone, utl.order_id) with util.Lockit(Redis, key) as locked: if locked: return error.TrafficSendFail # 移动接口返回 if Traffic.send_traffic(utl.order_id, user.phone): utl.update_model( {'$set': { 'status': const.TRAFFIC_SUCCESS, 'device': device }}) else: utl.update_model({'$set': {'status': const.TRAFFIC_FAIL}}) return error.TrafficSendFail(u'小伙伴们太热情了,稍后再来吧!') return {"message": "你已经成功分享视频, 恭喜你获得免费流量150M, 礼物将以光速飞到你的碗里去哦, 请注意查收!"}
def gifts_exchange(): user = request.authed_user requ_type = request.values.get('requ_type') value = PayForGift.get_all_value() # 现已兑换的总金额 cfg = GiftExchangeCfg.get_gift_config() total_exchange_value = cfg.total_exchange_value # 兑换上限 break_rate = cfg.break_rate # 折损率 exchange_thresthold = cfg.exchange_thresthold # 兑换下限 gift_value = UserProduct.get_total_money(user) # 当前用户礼物价值 _gift_value = float(gift_value) / float(100) # gift_value = UserCredit.get_or_create_user_credit(user._id).current_money # 当前用户礼物价值 _value = _gift_value * float(break_rate) exchange_value = int(_value) + 1 if _value > int(_value) else int( _value) # 折损后的价值 current_exchange_value = int(total_exchange_value) - int( value) # 当前还可兑换的金额 # 营销数据入库经分 data_dict = dict(cmd="exchange_huafei", deviceid=request.values.get('device', ''), mobile=user.phone, source=request.values.get('source', 'activity'), activityid="0", activityname=u"兑换话费活动") if requ_type == 'get_judge': certify_status = UserCertify.get_certify_status(user._id) is_anchor_wlist = AnchorWlist.is_anchor_wlist(user._id) # 是否是签约主播 if is_anchor_wlist: return {'exchange_status': 1, 'exchange_msg': '签约主播无法兑换'} user_certify = True if certify_status == 3 else False if not user_certify: return { 'exchange_status': 2, 'exchange_msg': '只有实名认证的用户才可以兑换哦,快去认证吧' } is_exchange_time = GiftExchangeCfg.is_exchange_time() # 是否在兑换时间内 if not is_exchange_time: return { 'exchange_status': 3, 'exchange_msg': '当前时间不在礼物兑换期内,请在兑换期内进行礼物兑换' } if int(exchange_value) >= int(current_exchange_value): # 超过总额度 return { 'exchange_status': 4, 'exchange_msg': '本月额度已经被全部兑换完啦,下个月请早了' } is_exchange = PayForGift.is_exchange(user) # 兑换次数 if is_exchange: return { 'exchange_status': 5, 'exchange_msg': '每个月只能兑换一次哦,您本月已经兑换过啦' } if int(exchange_value) < int(exchange_thresthold): # 不满足兑换门槛 return {'exchange_status': 6, 'exchange_msg': '您的礼物还不够提现哦'} data_dict["opt"] = "1:{0}:{1}".format(gift_value, exchange_value) Marketing.jf_report(data_dict) return { 'exchange_status': 0, 'exchange_msg': '您有价值{0}元的礼物,可以兑换{1}元话费,话费将发放到您登录的手机号码内,兑换完成后付费礼物全部清零'.format( _gift_value, exchange_value) } elif requ_type == 'pay_exchange': is_anchor_wlist = AnchorWlist.is_anchor_wlist(user._id) # 是否是签约主播 if is_anchor_wlist: return error.StoreError certify_status = UserCertify.get_certify_status(user._id) user_certify = True if certify_status == 3 else False if not user_certify: return error.StoreError is_exchange_time = GiftExchangeCfg.is_exchange_time() if not is_exchange_time: return error.StoreError if int(exchange_value) >= int(current_exchange_value): return error.StoreError is_exchange = PayForGift.is_exchange(user) if is_exchange: return error.StoreError if int(exchange_value) < int(exchange_thresthold): return error.StoreError lock_key = 'lock:exchange_fee:%s' % (str(user._id)) with util.Lockit(Redis, lock_key) as locked: if locked: return error.StoreError('兑换太频繁') try: uc = UserCredit.get_or_create_user_credit(user._id) uc.reduce_money(gift_value) UserProduct.clear_gifts_num(user, True) PayForGift.create_log(user, const.SUCCESS, _gift_value, exchange_value, const.GIFT_EXCHANGE) data_dict["opt"] = "1:{0}:{1}".format(gift_value, exchange_value) Marketing.jf_report(data_dict) return { 'exchange_status': 0, 'exchange_msg': '兑换成功,{0}元的话费将在30个工作日内发到您登录的咪咕游玩手机账户'.format( exchange_value) } except: PayForGift.create_log(user, const.FAIL, _gift_value, exchange_value, const.GIFT_EXCHANGE) return {'exchange_status': 7, 'exchange_msg': '兑换失败,请稍后再试哦'} elif requ_type == 'gold_exchange': lock_key = 'lock:exchange_gold:%s' % (str(user._id)) with util.Lockit(Redis, lock_key) as locked: if locked: return error.StoreError('兑换太频繁') try: total_gold_value = UserProduct.get_total_gold(user) uc = UserCredit.get_or_create_user_credit(user._id) uc.add_gold(total_gold_value, const.GIFT_EXCHANGE) UserProduct.clear_gifts_num(user, False) data_dict["opt"] = "1:{0}:{1}".format(gift_value, exchange_value) Marketing.jf_report(data_dict) return { 'exchange_status': 0, 'exchange_msg': '您已兑换成功,请去游米账户中进行查询' } except: data_dict["opt"] = "0:0:0" Marketing.jf_report(data_dict) return {'exchange_status': 7, 'exchange_msg': '兑换失败,请稍后再试哦'} else: return {'exchange_status': 7, 'exchange_msg': '兑换失败,请稍后再试哦'}
def do_task(worker, job): from wanx.base.log import print_log from wanx.base import const, util, jpush from wanx.models.user import User from wanx.models.game import Game from wanx.models.live import Live_Activity from wanx.models.activity import ActivityConfig from wanx.models.game import GameActivity from wanx.models.task import BEGIN_LIVE, UserTask from wanx.base.xredis import Redis from wanx.base.xmysql import MYDB from wanx.platforms.xmatch import Xmatch data = job.data # 记录日志 print_log('create_live_activity', data) data = json.loads(data) # 记录日志 print_log('create_live_activity', '%s ==========================> Start' % (data['event_id'])) user = User.get_one(data['user_id'], check_online=False) if not user: return '' # 主播上线push推送 push_content = u"您关注的主播 {0} 正在直播,点击围观".format(user.nickname) message_content = u"您关注的主播 {0} 正在直播,速速去围观吧!".format(user.nickname) an_link = "playsdk://video_live/{0}/".format(data['event_id']) ios_link = "playsdk://live/{0}".format(data['event_id']) jpush.jpush_schedule_create(data['event_id'], user, push_content, message_content, an_link, ios_link) # 赛事预约直播上线推送 battle = Xmatch.getbattle(user._id, data['name']) if battle: battle = battle['data']['battle'] push_title = u'您预约的比赛正在进行' push_content = u"{0} vs {1}正在直播,点击围观".format(battle['team_1'], battle['team_2']) message_content = u"您预约的比赛{0} vs {1}正在直播!".format( battle['team_1'], battle['team_2']) if battle.get('players', '') != "": push_content = message_content = battle['live_name'] an_link = "playsdk://video_live/{0}/".format(data['event_id']) ios_link = "playsdk://live/{0}".format(data['event_id']) jpush.jpush_withtitle_create(data['event_id'], battle['_id'], push_title, push_content, message_content, an_link, ios_link) game = Game.get_one(data['game_id'], check_online=False) if not game: return '' aid = None aids = ActivityConfig.get_by_type(const.FROM_LIVE) for a in ActivityConfig.get_list(aids): gids = GameActivity.game_activity_ids(a['_id']) if gids and data['game_id'] not in gids: continue aid = a['_id'] break if not aid: return '' print_log('create_live_activity', '%s ==========================> activity_id' % (aid)) activity_live = Live_Activity.get_activity_live(str(user._id), aid) if not activity_live: key = 'lock:activity:live:%s:%s' % (str(user._id), aid) with util.Lockit(Redis, key) as locked: if locked: return '' activity_live = Live_Activity.init() activity_live.author = ObjectId(data['user_id']) activity_live.game = ObjectId(data['game_id']) activity_live.event_id = data['event_id'] activity_live.activity_id = ObjectId(aid) activity_live.create_model() # 如果没有活动任务则创建 UserTask.create_and_init_user_tasks(str(user._id)) if not MYDB.is_closed(): MYDB.close() try: UserTask.check_user_tasks(user._id, BEGIN_LIVE, 1, data['game_id'], aid) except Exception as e: print_log('create_live_activity', '%s ========' % e) if not MYDB.is_closed(): MYDB.close() # 记录日志 print_log('create_live_activity', '%s ==========================> Finished' % (data['event_id'])) return ''
def send_gift(): """赠送礼物 (GET|POST&LOGIN) :uri: /gifts/send_gift :param user_id: 主播ID :param gift_id: 礼物ID :param num: 礼物数量 :param gift_from: 礼物来源(1:直播, 2:录播) :param from_id:来源ID(直播ID或者录播视频ID) :return: {'ret: bool} :if money need cs(充值来源),SDKVersion,dId """ user = request.authed_user gift_id = int(request.values.get('gift_id')) to_user_id = request.values.get('user_id') num = int(request.values.get('num', 1)) gift_from = int(request.values.get('gift_from')) from_id = request.values.get('from_id') user_ip = request.remote_addr device = request.values.get('device', None) if not gift_id or not to_user_id or num < 1 or not gift_from: return error.InvalidArguments if to_user_id == str(user._id): return error.GiftError('不能给自己赠送礼物哦') to_user = User.get_one(to_user_id, check_online=False) if not to_user: return error.UserNotExist('该视频没有主播') available_num = _gift_num() if num not in available_num: return error.GiftError('礼物数量不符合规则') gift = Gift.get_gift(gift_id) if not gift: return error.GiftError('该礼物不能赠送') money_data = {} transactionId = '' if gift.credit_type == const.MONEY: # today_times = UserGiftLog.user_today_gift_id_times(user._id,gift_id,num) gift_data = gift.format() # max_times = gift_data['per_piece_limit'].get(num) # if max_times <= today_times: # return error.GiftError('该档礼物今天的次数已用完') from wanx.platforms.migu import PayByMg consumeCode = gift_data['per_piece_id'].get(num) cs = 6 SDKVersion = request.values.get('SDKVersion') dId = request.values.get('dId', 'null') goodsname = gift_data['product_name'] + '_' + str(num) pay_mg_data = PayByMg.get_payurl(user, cs, SDKVersion, dId, consumeCode, 1, goodsname=goodsname) if isinstance(pay_mg_data, error.ApiError): return pay_mg_data # 创建订单 pay_order_obj = PayOrder.init() # [set(pay_order_obj,attr,value) for attr,value in pay_mg_data.items()] pay_order_obj.pay_mg_data = pay_mg_data transactionId = pay_mg_data['resultData']['transactionId'] pay_order_obj.transactionId = transactionId pay_order_obj.phone = user.phone pay_order_obj.nickname = user.nickname pay_order_obj.credit_value = gift.credit_value pay_order_obj.total_value = gift.credit_value * num pay_order_obj.gift_num = num pay_order_obj.finished = 0 pay_order_obj.product_name = gift_data['product_name'] pay_order_obj.check_pay_data = {} pay_order_obj.pay_info = {"from_user_id": user._id, 'to_user_id': to_user_id, "num": num, 'gift_id': gift_id, \ 'gift_from': gift_from, "from_id": from_id} pay_order_obj.create_model() money_data = { 'is_money': True, "pay_data": pay_mg_data.get("resultData", {}) } ret = False key = 'lock:send_gift:%s' % (str(user._id)) with util.Lockit(Redis, key) as locked: if locked: return error.GiftError('赠送礼物失败') ret = gift.send_to_user(str(user._id), to_user_id, num, gift_from, from_id, transactionId=transactionId) if isinstance(ret, error.ApiError): return ret if money_data: return money_data # 录播发送消息到中心消息 if ret and gift_from == const.FROM_RECORD: video = Video.get_one(from_id, check_online=False) if video: Message.send_gift_msg(str(user._id), from_id, 'gift') video.update_model({'$inc': {'gift_count': 1, 'gift_num': num}}) # 直播发送广播信息 if ret and gift_from == const.FROM_LIVE: total = Xlive.get_user_send_gift_count(from_id, str(user._id), gift_id, num) data = dict(user_id=str(user._id), username=user.nickname or user.name, userphoto=user.get_photo(), gift_name=gift.format()['product_name'], gift_image=gift.format()['product_image'], gift_num=num, event_id=from_id, total=total) Xlive.send_live_msg(data) # 营销数据入库经分 打赏活动 from wanx.models.activity import ActivityConfig, ActivityVideo from wanx.platforms.migu import Marketing activity_config = None if gift_from == const.FROM_RECORD: activity_video = ActivityVideo.get_activity_video_by_vid(from_id) if activity_video: activity_config = ActivityConfig.get_one( activity_video['activity_id']) else: aids = ActivityConfig.get_by_type(const.FROM_LIVE) for a in ActivityConfig.get_list(aids): activity_config = a break if activity_config: data_dict = dict(cmd="deliver_gift", opt="{0}/{1}".format(gift.gold_price, to_user_id), deviceid=request.values.get('device', ''), mobile=user.phone, source=request.values.get('source', 'activity'), activityid=str(activity_config['_id']), activityname=activity_config['name']) Marketing.jf_report(data_dict) # 1118 task1 # Marketing.trigger_report(user.partner_migu['id'], user.phone, 'send_gift') return {'ret': ret}