def swap_tracker(user_id): trmnts = Tournaments.get_live(user_id=user_id) if trmnts is None: raise APIException( 'You have not bought into any current tournaments', 404) list_of_swap_trackers = [] for trmnt in trmnts: my_buyin = Buy_ins.get_latest(user_id=user_id, tournament_id=trmnt.id) if my_buyin is None: raise APIException('Can not find buyin', 404) swaps = Swaps.query.filter_by(sender_id=user_id, tournament_id=trmnt.id) if swaps is None: return jsonify( {'message': 'You have no live swaps in this tournament'}) swaps = [{ 'swap': swap.serialize(), 'buyin': (Buy_ins.get_latest(user_id=swap.recipient_id, tournament_id=trmnt.id).serialize()) } for swap in swaps] list_of_swap_trackers.append({ 'tournament': trmnt.serialize(), 'my_buyin': my_buyin.serialize(), 'swaps': swaps }) return jsonify(list_of_swap_trackers)
def swap_tracker_json(trmnt, user_id): my_buyin = Buy_ins.get_latest( user_id=user_id, tournament_id=trmnt.id ) final_profit = 0 swaps = Swaps.query.filter_by( sender_id = user_id, tournament_id = trmnt.id ) # separate swaps by recipient id swaps_by_recipient = {} for swap in swaps: rec_id = str(swap.recipient_id) data = swaps_by_recipient.get( rec_id, [] ) swaps_by_recipient[ rec_id ] = [ *data, swap ] # Loop through swaps to create swap tracker json and append to 'swaps_buyins' swaps_buyins = [] for rec_id, swaps in swaps_by_recipient.items(): recipient_buyin = Buy_ins.get_latest( user_id = rec_id, tournament_id = trmnt.id ) # Catch ERRORS if recipient_buyin is None or my_buyin is None: swap_data_for_error_message = [{ 'recipient_name': f'{x.recipient_user.first_name} {x.recipient_user.last_name}', 'sender_name': f'{x.sender_user.first_name} {x.sender_user.last_name}', 'tournament_name': x.tournament.name } for x in swaps] if recipient_buyin is None: return { 'ERROR':'Recipient has swaps with user in this tournament but no buy-in', 'recipient buyin': None, 'swaps with user': swap_data_for_error_message } if my_buyin is None: return { 'ERROR':'User has swaps in this tournament but no buy-in', 'buyin': None, 'user swaps': swap_data_for_error_message } # Structure and fill most properties for swap tracker json recipient_user = Profiles.query.get( rec_id ) data = { 'recipient_user': recipient_user.serialize(), 'recipient_buyin': recipient_buyin.serialize(), 'their_place': recipient_buyin.place, 'you_won': my_buyin.winnings if my_buyin.winnings else 0, 'they_won': recipient_buyin.winnings if recipient_buyin.winnings else 0, 'available_percentage': recipient_user.available_percentage(trmnt.id), 'agreed_swaps': [], 'other_swaps': [] } # Fill in properties: 'agreed_swaps' and 'other_swaps' lists you_owe_total = 0 they_owe_total = 0 for swap in swaps: single_swap_data = { **swap.serialize(), 'counter_percentage': swap.counter_swap.percentage, 'they_paid': swap.counter_swap.paid, 'they_confirmed': swap.counter_swap.confirmed, } if swap.status._value_ == 'agreed': you_owe = ( float(my_buyin.winnings) * swap.percentage / 100 ) \ if isfloat(my_buyin.winnings) else 0 they_owe = ( float(recipient_buyin.winnings) * swap.counter_swap.percentage / 100 ) \ if isfloat(recipient_buyin.winnings) else 0 you_owe_total += you_owe they_owe_total += they_owe data['agreed_swaps'].append({ **single_swap_data, 'you_owe': you_owe, 'they_owe': they_owe }) else: data['other_swaps'].append(single_swap_data) # Fill in final properties data['you_owe_total'] = you_owe_total data['they_owe_total'] = they_owe_total final_profit -= you_owe_total final_profit += they_owe_total # IF user doesn't owe anything to other guy, # make all agreed swaps paid for themselves # if final_profit >= 0: # for swap in data['agreed_swaps']: # # swap['paid'] = True # the_swap = Swaps.query.get( swap.id) # print('the_swap', the_swap) # the_swap.paid = True # the_swap.paid_at = datetime.utcnow() # the_swap.confirmed = True # the_swap.confirmed_at = datetime.utcnow() # Append json swaps_buyins.append(data) return { 'tournament': trmnt.serialize(), 'my_buyin': my_buyin and my_buyin.serialize(), 'buyins': swaps_buyins, 'final_profit': final_profit }
def update_swap(user_id, id): # Get sender user sender = Profiles.query.get(user_id) req = request.get_json() utils.check_params(req) # Get swaps swap = Swaps.query.get(id) if sender.id != swap.sender_id: raise APIException( 'Access denied: You are not the sender of this swap', 401) current_percentage = swap.percentage if sender.get_coins() < swap.cost: raise APIException('Insufficient coins to see this swap', 402) if swap.status._value_ in ['canceled', 'rejected', 'agreed']: raise APIException('This swap can not be modified', 400) counter_swap_body = {} counter_swap = Swaps.query.get(swap.counter_swap_id) if swap is None or counter_swap is None: raise APIException('Swap not found', 404) # Get recipient user recipient = Profiles.query.get(swap.recipient_id) if recipient is None: raise APIException('Recipient user not found', 404) new_status = req.get('status') current_status = swap.status._value_ if 'percentage' in req and new_status not in [ 'agreed', 'rejected', 'canceled' ]: percentage = req['percentage'] counter = req.get('counter_percentage', percentage) if percentage < 1 or counter < 1: raise APIException('Cannot swap less than %1', 400) sender_availability = sender.available_percentage( swap.tournament_id) considering_this_swap = current_status == 'incoming' actions = percentage if considering_this_swap else ( percentage - swap.percentage) if actions > sender_availability: raise APIException(( 'Swap percentage too large. You can not exceed 50% per tournament. ' f'You have available: {sender_availability}%'), 400) recipient_availability = \ recipient.available_percentage( swap.tournament_id ) if (counter - counter_swap.percentage) > recipient_availability: raise APIException( ('Swap percentage too large for recipient. ' f'He has available to swap: {recipient_availability}%'), 400) # Update percentages swap.percentage = percentage counter_swap.percentage = counter if current_status == 'pending': if new_status == 'agreed': raise APIException('Cannot agree a swap on a pending status', 400) if new_status == 'rejected': raise APIException('Cannot reject this swap', 400) if current_status in ['incoming', 'counter_incoming' ] and new_status == 'canceled': raise APIException('Cannot cancel this swap', 400) # Update status if new_status in ['agreed', 'rejected', 'canceled']: if new_status == 'agreed': if recipient.get_coins() < swap.cost: raise APIException( 'Recipient has insufficient coins to process this swap' ) if current_status == 'incoming': overdraft = current_percentage - sender.available_percentage( swap.tournament_id) if overdraft > 0: raise APIException( f'Cannot agree to this swap, you are overdrafting by {str(overdraft)}%', 400) swap.status = new_status counter_swap.status = Swaps.counter_status(new_status) # If current swap is pending, leave statuses as they are elif current_status != 'pending': swap.status = Swaps.counter_status(swap.status._value_) counter_swap.status = Swaps.counter_status( counter_swap.status._value_) # send_fcm('swap_incoming_notification', recipient.id) db.session.commit() if new_status == 'agreed': db.session.add(Transactions(user_id=user_id, coins=-swap.cost)) db.session.add(Transactions(user_id=recipient.id, coins=-swap.cost)) db.session.commit() # send_fcm('swap_agreed_notificatin', recipient.id) user1_receipt = Buy_ins.get_latest(sender.id, swap.tournament_id) user2_receipt = Buy_ins.get_latest(recipient.id, swap.tournament_id) send_email(template='swap_confirmation', emails=[sender.user.email, recipient.user.email], data={ 'tournament_date': swap.tournament.start_at, 'tournament_name': swap.tournament.name, 'user1_name': f'{sender.first_name} {sender.last_name}', 'user1_prof_pic': sender.profile_pic_url, 'user1_percentage': swap.percentage, 'user1_receipt_url': user1_receipt and user1_receipt.receipt_img_url, 'user2_name': f'{recipient.first_name} {recipient.last_name}', 'user2_prof_pic': recipient.profile_pic_url, 'user2_percentage': counter_swap.percentage, 'user2_receipt_url': user2_receipt and user2_receipt.receipt_img_url }) return jsonify([ swap.serialize(), counter_swap.serialize(), ])
def create_swap(user_id): # Get sender user sender = Profiles.query.get(user_id) # Get request json req = request.get_json() utils.check_params(req, 'tournament_id', 'recipient_id', 'percentage') if user_id == req['recipient_id']: raise APIException( f'Cannot swap with yourself, user_id: {user_id}, ' f'recipient_id: {req["recipient_id"]}') # Check for sufficient coins swap_cost = req.get('cost', 1) if swap_cost < 1: raise APIException('No free swaps', 400) if sender.get_coins() - sender.get_reserved_coins() < swap_cost: raise APIException('Insufficient coins to make this swap', 402) # Get recipient user recipient = Profiles.query.get(req['recipient_id']) if recipient is None: raise APIException('Recipient user not found', 404) # Check recipient swap availability if recipient.swap_availability_status._value_ == 'unavailable': raise APIException('This person is unavailable for swaps', 401) # Can only send one swap offer at a time existing_swaps = Swaps.query.filter_by( sender_id=user_id, recipient_id=recipient.id, tournament_id=req['tournament_id']) unacceptable_status = ['pending', 'incoming', 'counter_incoming'] for swap in existing_swaps: if swap.status._value_ in unacceptable_status: raise APIException( f'Already have a swap with status "{swap.status._value_}"' ' with this player', 401) percentage = req['percentage'] counter = req.get('counter_percentage', percentage) if percentage < 1 or counter < 1: raise APIException('Cannot swap less than %1', 400) # Check tournament existance trmnt = Tournaments.query.get(req['tournament_id']) if trmnt is None: raise APIException('Tournament not found', 404) # Swap percentage availability sender_availability = sender.available_percentage(req['tournament_id']) if percentage > sender_availability: raise APIException(( 'Swap percentage too large. You can not exceed 50% per tournament. ' f'You have available: {sender_availability}%'), 400) recipient_availability = recipient.available_percentage( req['tournament_id']) if counter > recipient_availability: raise APIException( ('Swap percentage too large for recipient. ' f'He has available to swap: {recipient_availability}%'), 400) # Create swap swap = Swaps(sender_id=user_id, tournament_id=req['tournament_id'], recipient_id=recipient.id, percentage=percentage, cost=swap_cost, status='pending') counter_swap = Swaps(sender_id=recipient.id, tournament_id=req['tournament_id'], recipient_id=user_id, percentage=counter, cost=swap_cost, status='incoming', counter_swap=swap) swap.counter_swap = counter_swap db.session.add_all([swap, counter_swap]) db.session.commit() # Notification buyin = Buy_ins.get_latest(user_id=sender.id, tournament_id=swap.tournament_id) send_fcm(user_id=recipient.id, title="New Swap", body=sender.get_name() + ' wants to swap', data={ 'id': counter_swap.id, 'buyin_id': buyin and buyin.id, 'alert': sender.get_name() + ' wants to swap', 'type': 'swap', 'initialPath': 'SwapDashboard', 'finalPath': 'SwapOffer' }) return jsonify({ 'swap_id': swap.id, 'message': 'Swap created successfully.' }), 200
def get_tournaments(user_id, id): # List Flights if id == 'all': # Order by date: ascending or descending order_method = None if request.args.get('asc') == 'true': order_method = Flights.start_at.asc() elif request.args.get('desc') == 'true': order_method = Flights.start_at.desc() # Filter past flights and order by default asc if request.args.get('history') == 'true': flights = Flights.get(history=True) flights = flights.order_by(Flights.start_at.desc( ) if order_method is None else order_method) # Filter current and future flights and order by default desc else: flights = Flights.get(history=False) flights = flights.order_by(Flights.start_at.asc( ) if order_method is None else order_method) # Filter by name name = request.args.get('name') if name is not None: flights = flights.filter( Flights.tournament.has( Tournaments.name.ilike(f'%{name}%'))) # Get zip code LAT LON zip = request.args.get('zip', '') if zip.isnumeric(): path = os.environ['APP_PATH'] with open(path + '/src/zip_codes.json') as zip_file: data = json.load(zip_file) zipcode = data.get(zip) if zipcode is None: raise APIException('Zipcode not in file', 500) lat = zipcode['latitude'] lon = zipcode['longitude'] # Get user LAT LON else: lat = request.args.get('lat', '') lon = request.args.get('lon', '') # Order flights by distance, whithin the day if isfloat(lat) and isfloat(lon): flights = [{ 'flight': f, 'distance': utils.distance(origin=[float(lat), float(lon)], destination=[ f.tournament.latitude, f.tournament.longitude ]) } for f in flights] flights = sorted(flights, key=cmp_to_key(utils.sort_by_location)) # Pagination offset, limit = utils.resolve_pagination(request.args) flights = flights[offset:offset + limit] return jsonify([{ **x['flight'].serialize(), 'casino': x['flight'].tournament.casino, 'address': x['flight'].tournament.address, 'city': x['flight'].tournament.city, 'state': x['flight'].tournament.state, 'zip_code': x['flight'].tournament.zip_code, 'buy_in': Buy_ins.get_latest(user_id, x['flight'].tournament_id) is not None, 'distance': x['distance'] } for x in flights]), 200 else: # Pagination offset, limit = utils.resolve_pagination(request.args) flights = flights.offset(offset).limit(limit) return jsonify([{ **f.serialize(), 'casino': f.tournament.casino, 'address': f.tournament.address, 'city': f.tournament.city, 'state': f.tournament.state, 'zip_code': f.tournament.zip_code, 'buy_in': Buy_ins.get_latest(user_id, f.tournament_id) is not None } for f in flights]), 200 # Single tournament by id elif id.isnumeric(): trmnt = Tournaments.query.get(int(id)) if trmnt is None: raise APIException('Tournament not found', 404) return jsonify(actions.swap_tracker_json(trmnt, user_id)), 200 raise APIException('Invalid id', 400)
def get_results(): ''' results = { "tournament_id": 45, "tournament_buy_in": 150, "tournament_date": "23 Aug, 2020", "tournament_name": "Las Vegas Live Night Hotel", "results_link": "https://poker-society.herokuapp.com/results_link/234" "users": { "*****@*****.**": { "position": 11, "winnings": 200, "total_winning_swaps": 34 } } } ''' results = request.get_json() trmnt = Tournaments.query.get(45) trmnt.results_link = results['results_link'] trmnt.status = 'closed' db.session.commit() for email, user_result in results['users'].items(): user = Profiles.query.filter(Profiles.user.email == email).first() # Consolidate swaps if multiple with same user all_agreed_swaps = user.get_agreed_swaps(results['tournament_id']) swaps = {} for swap in all_agreed_swaps: id = str(swap.recipient_id) if id not in swaps: swaps[id] = { 'count': 1, 'percentage': swap.percentage, 'counter_percentage': swap.counter_swap.percentage } else: x = swaps[id] swaps[id] = { 'count': x['count'] + 1, 'percentage': x['percentage'] + swap.percentage, 'counter_percentage': x['counter_percentage'] + \ swap.counter_swap.percentage } # Create the swap templates msg = lambda x: \ f'You have {x} swaps with this person for the following total amounts:' total_swap_earnings = 0 render_swaps = '' swap_number = 1 for swap in swaps: recipient_email = swap.recipient_user.user.email recipient = Profiles.query.filter( Profiles.user.email == recipient_email) entry_fee = results['tournament_buy_in'] profit_sender = user_result['winnings'] - entry_fee amount_owed_sender = profit_sender * swap['percentage'] / 100 earning_recipient = results[recipient_email]['winnings'] profit_recipient = earning_recipient - entry_fee amount_owed_recipient = profit_recipient * swap[ 'counter_percentage'] / 100 swap_data = { 'swap_number': swap_number, 'amount_of_swaps': msg(swap['count']) if swap['count'] > 1 else '', 'entry_fee': entry_fee, 'total_earnings_sender': user_result['winnings'], 'swap_percentage_sender': swap['percentage'], 'swap_profit_sender': profit_sender, 'amount_owed_sender': amount_owed_sender, 'recipient_name': f'{recipient.firt_name} {recipient.last_name}', 'recipient_profile_pic_url': recipient.profile_pic_url, 'total_earnings_recipient': earning_recipient, 'swap_percentage_recipient': swap['counter_percentage'], 'swap_profit_recipient': profit_recipient, 'amount_owed_recipient': amount_owed_recipient } total_swap_earnings -= amount_owed_sender total_swap_earnings += amount_owed_recipient render_swaps += render_template('swap.html', **swap_data) swap_number += 1 # Update user and buy ins user.calculate_total_swaps_save() user.roi_rating = user_result[ 'total_winning_swaps'] / user.total_swaps * 100 buyin = Buy_ins.get_latest(user.id, trmnt.id) buyin.place = user_result['position'] db.session.commit() sign = '-' if total_swap_earnings < 0 else '+' send_email('swap_results', '*****@*****.**', data={ 'tournament_date': results['tournament_date'], 'tournament_name': results['tournament_name'], 'results_link': results['results_link'], 'total_swaps': swap_number, 'total_swap_earnings': f'{sign}${str(abs(total_swap_earnings))}', 'render_swaps': render_swaps, 'roi_rating': user.roi_rating, 'swap_rating': user.swap_rating })
def get_results(): ''' { "api_token": "oidf8wy373apudk", "tournament_id": 45, "tournament_buyin": 150, "users": { "*****@*****.**": { "place": 11, "winnings": 200 } } } ''' print("GETTING RESULGX") r = request.get_json() print('r', r) print('Token here', r['api_token']) print(os.environ['SP_API_TOKEN_LIVE']) # Security token check if r['api_token'] != os.environ['SP_API_TOKEN_LIVE']: return jsonify({'error': r['api_token']}) print('b') # print('Buyin ID', r['tournament_buyin']) trmnt = Tournaments.query.get(r['tournament_id']) if trmnt is None: return jsonify({ 'error': 'Tournament not found with id: ' + r['tournament_id'] }) print('c') trmnt_buyin = r['tournament_buyin'] trmnt.results_link = (os.environ['POKERSOCIETY_HOST'] + '/results/tournament/' + str(r['tournament_id'])) print('d') # Add all players that haven't won but have swaps in this trmnt all_swaps_in_trmnt = Swaps.query.filter_by( tournament_id=trmnt.id ) \ .filter_by( status='agreed' ) print('d') for swap in all_swaps_in_trmnt: email = swap.sender_user.user.email if email not in r['users']: r['users'][email] = { 'place': None, 'winnings': None, } print('e') # Variable to set swap due date due_date = datetime.utcnow() + timedelta(days=4) # Process each player's data.. update roi and swap rating.. send email for email, userdata in r['users'].items(): print('userdata', userdata) user = Profiles.query.filter( Profiles.user.has(email=email)).first() if user is None: return jsonify( {'error': 'User not found with email: ' + email}) # Consolidate swaps if multiple with same user all_agreed_swaps = user.get_agreed_swaps(r['tournament_id']) swaps = {} # If user has no swaps, don't send email if len(all_agreed_swaps) == 0: continue print(all_agreed_swaps[0]) for swap in all_agreed_swaps: print("SWAP IS", swap) ''' { "2": { "count": 2, "counter_percentage": 11, "percentage": 11, "recipient_email": "*****@*****.**" }, "4": { "count": 1, "counter_percentage": 7, "percentage": 5, "recipient_email": "*****@*****.**" } } ''' id = str(swap.recipient_id) if id not in swaps: swaps[id] = { 'count': 1, 'percentage': swap.percentage, 'counter_percentage': swap.counter_swap.percentage, 'recipient_email': swap.recipient_user.user.email } else: swaps[id]['count'] += 1 swaps[id]['percentage'] += swap.percentage swaps[id][ 'counter_percentage'] += swap.counter_swap.percentage # Set payment due date, swap_rating and result_winnings for each swap swap.due_at = due_date swap.swap_rating = 5 swap.result_winnings = True if userdata[ 'winnings'] != None else False db.session.commit() total_swap_earnings = 0 total_amount_of_swaps = 0 render_swaps = [] # Go thru the consolidated swaps to create the email templates for recipient_id, swapdata in swaps.items(): recipient = Profiles.query.get(recipient_id) if recipient is None: return jsonify( {'error': 'User not found with id: ' + recipient_id}) # Tournament buyin could be "$200" "$0++" "Day 2" regex = re.search(r'\$\s*(\d+)', str(trmnt_buyin)) entry_fee = int(regex.group(1)) if regex else 0 # Winnings are integers, but in case they are a string, ex "Satellite" to_int = lambda x: x if isinstance(x, int) else 0 profit_sender = to_int(userdata['winnings']) - entry_fee amount_owed_sender = profit_sender * swapdata[ 'percentage'] / 100 # recipient_winnings can be None recipient_winnings = r['users'][ swapdata['recipient_email']]['winnings'] or 0 profit_recipient = to_int(recipient_winnings) - entry_fee amount_owed_recipient = profit_recipient * swapdata[ 'counter_percentage'] / 100 render_swaps.append({ 'amount_of_swaps': swapdata['count'], 'entry_fee': entry_fee, 'sender_first_name': user.first_name, 'total_earnings_sender': '{:,}'.format(userdata['winnings']), 'swap_percentage_sender': swapdata['percentage'], 'swap_profit_sender': '{:,}'.format(profit_sender), 'amount_owed_sender': '{:,}'.format(round(amount_owed_sender)), 'recipient_first_name': recipient.first_name, 'recipient_last_name': recipient.last_name, 'recipient_profile_pic_url': recipient.profile_pic_url, 'total_earnings_recipient': '{:,}'.format(recipient_winnings), 'swap_percentage_recipient': swapdata['counter_percentage'], 'swap_profit_recipient': '{:,}'.format(profit_recipient), 'amount_owed_recipient': '{:,}'.format(round(amount_owed_recipient)) }) total_swap_earnings -= amount_owed_sender total_swap_earnings += amount_owed_recipient total_amount_of_swaps += swapdata['count'] if total_swap_earnings >= 0: for swap in all_agreed_swaps: a_swap = Swaps.query.get(swap.id) a_swap.paid = True a_swap.paid_at = datetime.utcnow() a_swap.confirmed = True a_swap.confirmed_at = datetime.utcnow() # Update user and buy ins user.roi_rating = user.calculate_roi_rating() buyin = Buy_ins.get_latest(user.id, trmnt.id) buyin.place = userdata['place'] buyin.winnings = userdata['winnings'] db.session.commit() sign = '-' if total_swap_earnings < 0 else '+' s = 's' if total_amount_of_swaps > 1 else '' # print('coming in') a_user = Profiles.query.get(user.id) # print('isr esult update true', a_user.result_update, user.id) if a_user.result_update == True: send_fcm(user_id=user.id, title="Results Posted", body=trmnt.name + " posted their results.", data={ 'id': trmnt.id, 'alert': trmnt.name + " just posted their results.", 'type': 'result', 'initialPath': 'Event Results', 'finalPath': 'Swap Results' }) send_email( 'swap_results', [email], #'*****@*****.**','*****@*****.**'], data={ 'tournament_date': trmnt.start_at.strftime('%A, %B %d, %Y - %I:%M %p'), 'tournament_name': trmnt.name, 'results_link': trmnt.results_link, 'total_swaps': f"{total_amount_of_swaps} swap{s}", 'total_swappers': f"{len(swaps)} {'person' if len(swaps) == 1 else 'people'}", 'total_swap_earnings': f'{sign}${"{:,.2f}".format( abs(total_swap_earnings) )}', 'render_swaps': render_swaps, 'roi_rating': round(user.roi_rating), 'swap_rating': round(user.swap_rating, 1) }) trmnt.status = 'closed' db.session.commit() return jsonify({'message': 'Results processed successfully'}), 200