コード例 #1
0
ファイル: slack.py プロジェクト: aurelion314/foosbot
def slack(data, account_id):
    return {
        'status': 'failed',
        'result': 'This method of slack notification is depreciated.'
    }
    db = database.builder('foosbot')
    account = db.table('accounts').where('id', account_id).first()
    url = account['slack_url']

    if not url:
        return {
            'status': 'failed',
            'result': 'Slack not configured for this account'
        }

    message = data['message']

    data = {'text': message}

    # url = 'https://hooks.slack.com/services/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'

    #ping slack
    response = requests.post(url, json=data)

    if response.status_code == 200:
        return {'status': 'success'}
    else:
        return {'status': 'failed', 'result': response.content}
コード例 #2
0
ファイル: slack.py プロジェクト: aurelion314/foosbot
    def end_match(match_id, winner, loser, streak, points):
        db = database.builder("foosbot")
        slack_record = db.table("slack_records").where("match",
                                                       match_id).first()
        if not slack_record:
            print('no slack record for match', match_id)
            return False

        slack_connection = db.table('slack_connections').where(
            'id', slack_record['slack_connection']).first()
        if not slack_connection:
            print('no slack connection for match', match_id, 'connection',
                  slack_record['slack_connection'])
            return False  #In case they remove the connection mid match, don't throw an error.

        win_message = winner['fname'] + " was Victorious! (+" + str(
            points) + " points)"
        if streak > 1:
            win_message += " - That's " + str(streak) + " in a row!"

        data = json.loads(slack_record["data"])
        data['ts'] = slack_record['timestamp']
        data["attachments"] = json.dumps([
            {
                "text": win_message,
                "color": "good"
            },
        ])
        # {"text": "Match Complete!", "color": "good"},

        print('updating slack', data)
        r = Slack.updateMessage(slack_connection, data)
コード例 #3
0
ファイル: leaderboard.py プロジェクト: aurelion314/foosbot
def get_table_leaderboard(data, account_id):
    db = database.builder('foosbot')
    users = db.table('users').select(
        'id', 'fname', 'lname', 'elo',
        'photo').where('account_id',
                       account_id).where_null('deleted_at').order_by(
                           'elo', 'desc').limit(100).get()
    data = []
    for i, user in enumerate(users):
        #only show players who have played a game
        has_games = db.table('matches').where('player1', user['id']).or_where(
            'player2', user['id']).exists()
        if not has_games:
            continue
        #add rank
        user['rank'] = len(data) + 1
        user['elo'] = int(round(user['elo'])) if user['elo'] else 0
        data.append(user)
        #Limit 20 results
        if len(data) >= 10: break

    #also get matches
    matches = list(get_match_history(account_id))

    return {
        'status': 'success',
        'leaderboard_data': data,
        'match_history': matches
    }
コード例 #4
0
ファイル: handler.py プロジェクト: aurelion314/foosbot
    def ping(self, request):
        client_data = []
        for key in request.META:
            #We don't need all meta-data, just some more interesting peices that may be useful in the future.
            if 'HTTP' in key and key in ['HTTP_HOST', 'HTTP_USER_AGENT', 'HTTP_REFERER', 'HTTP_COOKIE']:
                client_data.append({key: request.META[key]})

        # print(client_data)
        #insert ping row with time, account_id, and ping data.
        db = database.builder('foosbot')

        insert_data = {}
        insert_data['account_id'] = self.account_id
        insert_data['reader_id'] = request.session['reader_id']
        insert_data['ip'] = self.get_client_ip(request)
        insert_data['created_at'] = str(datetime.now())
        insert_data['meta_data'] = str(client_data)
        
        db.table('ping').insert(insert_data)

        # sending the following will force a page reload.
        needs_reload = db.table('accounts').where('id', self.account_id).where('refresh_reader', 1).exists()
        if needs_reload: 
            db.table('accounts').where('id', self.account_id).update({'refresh_reader': 0})
            return {'status':'success', 'result':'reload'}
            
        return {'status':'success'}
コード例 #5
0
def leaderboard(request, account_id):
    if not request.user.is_authenticated or request.user.account != account_id:
        raise PermissionDenied
    db = database.builder('foosbot')
    account = db.table('accounts').where('id', account_id).first()
    if not account: return HttpResponseNotFound()
    #redirect to the token based leaderboard to keep render logic in one place
    return redirect(leaderboard_token, token=account['token'])
コード例 #6
0
ファイル: leaderboard.py プロジェクト: aurelion314/foosbot
def get_leaderboard(account_id):
    db = database.builder('foosbot')
    players = db.table('users').where(
        'users.account_id',
        account_id).where_null('deleted_at').order_by('elo', 'desc').get()
    # players = db.table('users').left_join('player_stats', 'users.id','=', 'player_stats.player_id')\
    # .select('users.id', 'users.fname', 'users.elo', 'player_stats.matches', 'users.photo')\
    # .where('users.account_id', account_id).where_null('deleted_at').order_by(db.raw('(matches > 0) desc, elo'), 'desc').get()#).order_by('elo', 'desc').get()
    return players
コード例 #7
0
def remove(data, account_id, reader_id):
    db = database.builder('foosbot')
    #are there any floating matches that need clearing?
    matches = db.table('matches').where('account_id', account_id).where('reader_id', reader_id).where('status', 'in_progress').get()
    for match in matches:
        db.table('matches').where('id', match['id']).update({'status':'failed', 'updated_at': str(datetime.now())})
        
        #also update any slack messages.
        Slack.clear_match(match)
コード例 #8
0
ファイル: slack.py プロジェクト: aurelion314/foosbot
    def post_message(slack_connection, data):
        db = database.builder('foosbot')
        data['token'] = slack_connection['token']
        data['channel'] = slack_connection['channel_id']

        url = "https://slack.com/api/chat.postMessage"

        r = Slack.call(url, data)
        return json.loads(r.content)
コード例 #9
0
def remove_slack(request, account_id):
    if not request.user.is_authenticated or request.user.account != account_id:
        raise PermissionDenied
    db = database.builder('foosbot')

    db.table('accounts').where('id', account_id).update({
        'slack_url': None,
        'slack_config_url': None,
        'slack_channel': None
    })
    db.table('slack_connections').where('account_id', account_id).delete()
    return HttpResponse(dumps({'status': 'success'}))
コード例 #10
0
ファイル: player.py プロジェクト: aurelion314/foosbot
def create_player(player):
    #We need to specify starting ELO before insertion.
    db = database.builder('foosbot')

    #set initial elo
    # player['elo'] = set_starting_elo(player)
    player['elo'] = None

    #strip RFID in case there are spaces
    player['rfid'] = str(player['rfid']).strip()

    #save
    db.table('users').insert(player)
コード例 #11
0
def get_real_elo_change(elo_change, account_id):
    if elo_change < 5: return [elo_change, elo_change]
    db = database.builder('foosbot')

    elo_average = db.table('users').where(
        'account_id', account_id).where_null('deleted_at').select(
            db.raw('avg(elo) as average_elo')).first()['average_elo']
    print('elo average', elo_average)
    if elo_average > 1525:
        return [elo_change - 1, elo_change + 1]  #win less, lose more
    if elo_average < 1475:
        return [elo_change + 1, elo_change - 1]  #win more, lose less

    return [elo_change, elo_change]
コード例 #12
0
ファイル: leaderboard.py プロジェクト: aurelion314/foosbot
def get_details(account_id, player_id):
    db = database.builder('foosbot')

    player = db.table('users').where('account_id',
                                     account_id).where('id',
                                                       player_id).first()

    matches = db.table('matches').where(
        db.query().where('player1', player['id']).or_where('player2', player['id'])
    )\
    .where('status', 'complete')\
    .select('player1', 'player2', 'winner', 'points', 'created_at')\
    .order_by('created_at', 'desc').get()

    #add names for displaying
    PName = PlayerName()
    longest_streak = 0
    streak = 0
    won = 0
    for match in matches:
        player2 = match.player1 if match.player1 != player[
            'id'] else match.player2
        if match['winner'] == player['id']:
            match['winner_name'] = player['fname']
            match['loser_name'] = PName.getName(player2)
            won += 1
            streak += 1
        else:
            match['winner_name'] = PName.getName(player2)
            match['loser_name'] = player['fname']
            streak = 0

        match['points'] = int(match['points'])
        match['created_at'] = parser.parse(str(match['created_at'])[:11])
        match['created_at'] = match['created_at'].strftime("%b %d")

        if streak > longest_streak: longest_streak = streak

    data = {
        'player': player,
        'matches': matches[:25],
        'total_played': len(matches),
        'total_won': won,
        'win_percent': '%.1f%%' % (100 * won / len(matches)),
        'longest_streak': longest_streak,
        'account_id': account_id
    }

    return data
コード例 #13
0
def leaderboard_token(request, token):
    db = database.builder('foosbot')
    account = db.table('accounts').where('token', token).first()
    if not account: return HttpResponseNotFound()

    from foosbot.modules.leaderboard import get_leaderboard

    players = get_leaderboard(account['id'])
    return render(request,
                  'foosbot/leaderboard.html',
                  context={
                      'players': players,
                      'account_id': account['id'],
                      'account_name': account['name']
                  })
コード例 #14
0
ファイル: auth.py プロジェクト: aurelion314/foosbot
 def authenticate(self, request, account_id=None, token=None):
     db = database.builder('foosbot')
     client = db.table('clients').where('account_id',
                                        account_id).where('token',
                                                          'token').first()
     if client:
         try:
             user = User.objects.get(pk=account_id)
         except User.DoesNotExist:
             # Create a new user. There's no need to set a password
             # because only the password from settings.py is checked.
             user = User(pk=account_id, username=str(account_id))
             user.is_staff = False
             user.is_superuser = False
             user.save()
         return user
コード例 #15
0
ファイル: leaderboard.py プロジェクト: aurelion314/foosbot
    def getName(self, player_id):
        #have we checked for this id before?
        if id not in self.players:
            #nope, so find it from DB
            db = database.builder('foosbot')
            player = db.table('users').where('id', player_id).select(
                'id', 'fname').first()
            if not player: return None

            #cache it for later
            self.players[player['id']] = player['fname']

            return player['fname']
        else:
            #returned the cached name
            return self.players[player_id]
コード例 #16
0
def match_history(request, account_id):
    if not request.user.is_authenticated or request.user.account != account_id:
        raise PermissionDenied
    db = database.builder('foosbot')
    account = db.table('accounts').where('id', account_id).first()
    if not account: return HttpResponseNotFound()
    #get matches and which ones are editable
    matches = db.table('matches').where('account_id', account_id).order_by(
        'id', 'desc').limit(50).get()
    return render(request,
                  'foosbot/match_history.html',
                  context={
                      'matches': matches,
                      'account_id': account['id'],
                      'account_name': account['name']
                  })
コード例 #17
0
ファイル: start.py プロジェクト: aurelion314/foosbot
def start(data, account_id, reader_id):
    import foosbot.database as database
    from datetime import datetime, timedelta
    db = database.builder('foosbot')

    #New game starting. There should be no in progress games. If there are, set it to failed.
    in_progress_matches = db.table('matches').where(
        'account_id',
        account_id).where('reader_id',
                          reader_id).where('status', 'in_progress').get()
    for in_progress_match in in_progress_matches:
        Slack.clear_match(in_progress_match)
        db.table('matches').where('account_id', account_id).where(
            'status', 'in_progress').where('id',
                                           in_progress_match['id']).update({
                                               'status':
                                               'failed',
                                               'updated_at':
                                               str(datetime.now())
                                           })

    match = {
        'account_id': account_id,
        'reader_id': reader_id,
        'player1': data['player1'],
        'player2': data['player2'],
        'status': 'in_progress',
        'created_at': str(datetime.now()),
    }

    res = db.table('matches').insert_get_id(match)
    match['id'] = res

    #return results
    if res:
        try:
            Slack.new_match(match)
        except Exception as e:
            print(e)
        return {'status': 'success'}
    else:
        return {'status': 'failed'}
コード例 #18
0
def setup(request, account_id):
    if not request.user.is_authenticated: return redirect(login)
    if request.user.account != account_id: raise PermissionDenied
    db = database.builder('foosbot')
    account = db.table('accounts').where('id', request.user.account).first()
    slack_connection = db.table('slack_connections').where(
        'account_id', account_id).first()
    slack_connection = dict(slack_connection) if slack_connection else {}
    if account:
        return render(request,
                      'foosbot/setup.html',
                      context={
                          'account_name': account.name,
                          'account_id': account_id,
                          'slack_config_url':
                          slack_connection.get('config_url'),
                          'slack_channel': slack_connection.get('channel')
                      })
    else:
        return HttpResponseNotFound()
コード例 #19
0
def verify_token(request, request_account_id=None):
    r = request.GET
    token = r.get('token')

    db = database.builder('foosbot')

    #Authentication reader by its token
    reader = db.table('readers').where('token', token).first()
    if not reader: return HttpResponse('Reader not configured: ' + str(token))
    game = db.table('game_types').where('id', reader['game_type']).first()
    if not game: game = {'id': 0}
    account = db.table('accounts').where('id', reader['account']).first()
    if not account: return HttpResponse('Reader not assigned: ' + str(token))

    #Looks good. Authenticate them and redirect to input page.
    request.session['account_id'] = account['id']
    request.session['game_id'] = game['id']
    request.session['reader_id'] = reader['id']
    request.session.set_expiry(360000000)

    return redirect(input, account_id=account['id'])
コード例 #20
0
ファイル: slack.py プロジェクト: aurelion314/foosbot
    def clear_match(match):
        db = database.builder('foosbot')
        #Is there a record to clear?
        slack_record = db.table('slack_records').where('match',
                                                       match['id']).first()
        if not slack_record: return True
        #Get slack connection info
        slack_connection = db.table('slack_connections').where(
            'id', slack_record['slack_connection']).first()
        if not slack_connection: return False

        #format slack data
        data = json.loads(slack_record["data"])
        data['ts'] = slack_record['timestamp']
        data["attachments"] = json.dumps([
            {
                "text": "Match Cleared!",
                "color": "yellow"
            },
        ])
        #update
        r = Slack.updateMessage(slack_connection, data)
コード例 #21
0
ファイル: leaderboard.py プロジェクト: aurelion314/foosbot
def get_match_history(account_id):
    db = database.builder('foosbot')
    matches = db.table('matches')\
        .join(db.raw('users u'), 'u.id', '=', 'matches.player1')\
        .join(db.raw('users u2'), 'u2.id', '=', 'matches.player2')\
        .select('matches.player1', 'matches.player2', 'matches.winner','matches.points', 'matches.created_at', db.raw('u.fname as player1_name, u2.fname as player2_name'))\
        .where('matches.account_id', account_id).where('matches.status', 'complete').order_by('matches.created_at', 'desc')\
        .limit(10).get()

    for match in matches:
        match['points'] = f"{float(match['points']):2.0f}"
        match['created_at'] = parser.parse(str(match['created_at'])[:11])
        match['date'] = match['created_at'].strftime("%b %d")
        match.pop('created_at')
        if match['player1'] == match['winner']:
            match['winner_name'] = match['player1_name']
            match['loser_name'] = match['player2_name']
        else:
            match['winner_name'] = match['player2_name']
            match['loser_name'] = match['player1_name']

    return matches
コード例 #22
0
def slack(request):
    r = request.GET
    print(r)

    data = {}
    data['code'] = r['code']
    data['client_id'] = '624952400887.615198951842'
    data['client_secret'] = 'd91d4794d106de4db1957c2f274346ae'
    # data['redirect_uri'] = 'https://www.employeearcade.com/slack/'

    import requests
    res = requests.get('https://slack.com/api/oauth.access', data)
    res = res.json()

    print(res)
    account_id = request.user.account

    slack_connection = {}
    slack_connection['account_id'] = account_id
    slack_connection['channel'] = res['incoming_webhook']['channel']
    slack_connection['channel_id'] = res['incoming_webhook']['channel_id']
    slack_connection['url'] = res['incoming_webhook']['url']
    slack_connection['config_url'] = res['incoming_webhook'][
        'configuration_url']
    slack_connection['token'] = res['access_token']
    slack_connection['scope'] = res.get('scope')
    slack_connection['team_name'] = res.get('team_name')

    db = database.builder('foosbot')
    #This is the old way of saving webhook.
    # db.table('accounts').where('id', account_id).update({'slack_url':slack_url, 'slack_config_url': slack_config_url, 'slack_channel': slack_channel})

    #save slack connection
    db.table('slack_connections').where('account_id', account_id).delete()
    db.table('slack_connections').insert(slack_connection)

    #return custom page with link to setup, or redirect to setup
    return redirect(setup, account_id=int(account_id))
コード例 #23
0
def initialize_elo(player, player2_elo, win=True):
    db = database.builder('foosbot')
    players = db.table('users').where(
        'account_id', player['account_id']).where_null(
            'deleted_at').where_not_null('elo').get()

    #is this the first player?
    if not players or len(players) < 2:
        return 1500

    #do some math
    import statistics
    elos = [p['elo'] for p in players]
    std = float(statistics.stdev(elos))

    player2_win_prob = float(calculate_win_probability(player2_elo, 1500))
    if win:
        bonus = -0.25 + 0.5 * player2_win_prob
    else:
        bonus = -0.75 + 0.5 * player2_win_prob
    bonus = bonus * std

    return 1500 + bonus
コード例 #24
0
def rfid(data, account_id):
    import foosbot.database as database
    from datetime import datetime, timedelta

    db = database.builder('foosbot')

    rfid = data['rfid']
    #look up rfid 
    # db.table('users').insert({'username': '******', 'fname':'Proth', 'rfid':2, 'points':1500})
    player = db.table('users').where('account_id', account_id).where_null('deleted_at').where('rfid', rfid).first()
    if not player: 
        return {'status':'not found'}
    if not player['elo']:
        player['elo'] = 0

    games = db.table('matches').where('created_at', '>', str(datetime.now() - timedelta(days=1))).where(
        db.query().where('player1', player['id']).or_where('player2', player['id'])
    ).where('status', 'complete').count()
    
    wins = db.table('matches').where('created_at', '>', str(datetime.now() - timedelta(days=1))).where('winner', player['id']).where('status', 'complete').count()
    
    #return results
    return {'status':'success', 'result':{'id':player['id'], 'name':player['fname'], 'games_today': games, 'wins_today': wins, 'points': int(player['elo'])}}
コード例 #25
0
ファイル: slack.py プロジェクト: aurelion314/foosbot
    def new_match(match):
        db = database.builder('foosbot')
        #first see if they have slack configured.
        slack_connection = db.table('slack_connections').where(
            'account_id', match['account_id']).first()
        if not slack_connection: return False

        #get player names
        player1 = db.table('users').where(
            'id', match['player1']).select('fname').first()['fname']
        player2 = db.table('users').where(
            'id', match['player2']).select('fname').first()['fname']

        data = {
            "text":
            "*" + player1 + " vs " + player2 + "*",
            "attachments":
            json.dumps([{
                "text": "Match Started! ",
                "color": "warning"
            }]),
        }

        r = Slack.post_message(slack_connection, data)
        if r:
            record = {
                'account_id': slack_connection['account_id'],
                'slack_connection': slack_connection['id'],
                'match': match['id']
            }
            record['timestamp'] = r['ts']
            record['data'] = json.dumps({
                'text': data['text'],
                'attachments': data.get('attachments')
            })
            db.table('slack_records').insert(record)
コード例 #26
0
def player(request, account_id):
    if not request.user.is_authenticated or request.user.account != account_id:
        raise PermissionDenied
    db = database.builder('foosbot')

    #Patch to modify players
    if request.method == 'PATCH':
        r = loads(request.body)
        #Patch means update or insert
        if r['action'] == 'patch':
            player = r['player']
            player_data = {
                'account_id': account_id,
                'fname': player['fname'].strip(),
                'lname': player['lname'].strip(),
                'rfid': player['rfid'],
                'photo': player['photo'].strip()
            }

            #First make sure this rfid isn't taken.
            if player['rfid']:
                player_id = [player.get('id')]
                taken = db.table('users').where(
                    'account_id',
                    account_id).where('rfid', player['rfid']).where_not_in(
                        'id', player_id).exists()
                if taken:
                    return HttpResponse(
                        dumps({'status': 'rfid taken or invalid'}))

            #Check if this is an update or new player
            if player.get('id'):
                existing = db.table('users').where('account_id',
                                                   account_id).where(
                                                       'id',
                                                       player['id']).first()
                db.table('users').where('id',
                                        existing['id']).update(player_data)
            else:  #player not in DB. insert it.
                from foosbot.modules.player import create_player
                create_player(player_data)

        #Delete
        elif r['action'] == 'delete':
            player = r['player']
            db.table('users').where('account_id',
                                    account_id).where('id',
                                                      player['id']).update({
                                                          'deleted_at':
                                                          datetime.now(),
                                                          'rfid':
                                                          None
                                                      })

        #no action? FAILURE
        else:
            return HttpResponse(dumps({'status': 'failed'}))

        return HttpResponse(dumps({'status': 'success'}))

    #if it wasn't a patch job, then its a query for player list
    players = db.table('users').where(
        'account_id', request.user.account).where_null('deleted_at').order_by(
            'fname', 'asc').get()

    data = [{
        'id': p.id,
        'fname': p.fname,
        'lname': p.lname,
        'photo': p.photo,
        'rfid': p.rfid
    } for p in players]
    return HttpResponse(dumps({'status': 'success', 'result': data}))
コード例 #27
0
def end(data, account_id, reader_id):
    db = database.builder('foosbot')

    #validate
    if 'winner' not in data: return {'status': 'no winner given'}
    winner = data['winner']
    loser = data['player1'] if winner != data['player1'] else data['player2']

    #load the players
    winner = db.table('users').where('id', winner).first()
    loser = db.table('users').where('id', loser).first()

    #ensure there is a match in progress
    match = db.table('matches').select('id').where(
        'account_id', account_id).where('reader_id', reader_id).where(
            'player1',
            data['player1']).where('player2', data['player2']).where(
                'status', 'in_progress').lock_for_update().first()
    if not match: return {'status': 'no match found'}

    #find winning player streak
    streak = 1
    games = db.table('matches').where(
        db.query().where('player1', winner['id']).or_where('player2', winner['id'])
    ) \
    .where('status', 'complete').order_by('created_at', 'desc').get()

    for game in games:
        if game['winner'] != winner['id']: break
        streak += 1

    #check if winner is unranked
    if not winner['elo'] and not loser['elo']:
        winner['elo'] = 1500
        loser['elo'] = 1500
    elif not winner['elo']:
        winner['elo'] = initialize_elo(winner, loser['elo'], True)
    elif not loser['elo']:
        loser['elo'] = initialize_elo(loser, winner['elo'], False)

    #calculate the ELO change
    elo_change = calculate_elo_change(winner['elo'], loser['elo'])
    elo_won, elo_lost = get_real_elo_change(elo_change, account_id)
    # points_won, points_lost = get_points_change(winner, loser, elo_won, elo_lost)

    #update the match
    update_data = {
        'status': 'complete',
        'winner': data['winner'],
        'updated_at': str(datetime.now()),
        'points': elo_change
    }
    db.table('matches').where('id', match['id']).update(update_data)

    db.table('users').where('id', winner['id']).update({
        'elo':
        float(winner['elo']) + elo_won
    })  #'points':winner['points'] + points_won
    db.table('users').where('id', loser['id']).update({
        'elo':
        float(loser['elo']) - elo_lost
    })  #'points':loser['points'] - points_lost

    #update slack if applicable
    Slack.end_match(match['id'], winner, loser, streak, int(round(elo_change)))

    #return results
    return {
        'status': 'success',
        'streak': streak,
        'points': int(round(elo_change))
    }