Пример #1
0
def test_login():
    kickbase = Kickbase()
    assert not kickbase._is_token_valid()
    user, leagues = kickbase.login(os.environ["KKBS_TEST_USERNAME"],
                                   os.environ["KKBS_TEST_PASSWORD"])
    assert kickbase._is_token_valid()
    assert user is not None
    assert leagues is not None
Пример #2
0
 def __init__(self, **kwargs):
     self.kickbase_api = Kickbase(
         google_identity_toolkit_api_key=kwargs.get('google_identity_toolkit_api_key', None))
     self.persistence = _Persistence(
         mongo_host=kwargs.get('mongodb_host', 'localhost'),
         mongo_user=kwargs.get('mongodb_user', ''),
         mongo_pwd=kwargs.get('mongodb_password', ''),
         mongo_db=kwargs.get('mongodb_db', 'kkbs_bot'),
         auth_mechanism=kwargs.get('mongodb_auth_mechanism', 'SCRAM-SHA-256')
     )
     
     self._periodic_feed_interval = kwargs.get("periodic_feed_interval", 15)
     self._periodic_chat_interval = kwargs.get("periodic_chat_interval", 5)
     self._periodic_market_interval = kwargs.get("periodic_market_interval", 60)
from kickbase_api.kickbase import Kickbase
from kickbase_api.models.player import Player
import time
import requests

headers = {
    'Content-Type': 'application/json',
}

EXPIRY_VALUE = 1800
SLEEP_TIMER = 600
DISCOUNT_FACTOR = 0.9902

kickbase = Kickbase()
user, leagues = kickbase.login("<LOGIN-MAIL-ADRESSE>", "LOGIN-PASSWORD>")


def notify_market_offer(player: Player):
    #Telegram notification
    subject = "Making offer for " + player.first_name + " " + player.last_name
    offer = "Offer: " + str(int(player.market_value * DISCOUNT_FACTOR))
    telegram_request = '{"chat_id": "<CHAT-ID>", "text": "%s %s", "disable_notification": false}' % (
        subject, offer)
    requests.post('https://api.telegram.org/bot<API-TOKEN>/sendMessage',
                  headers=headers,
                  data=telegram_request)


while (True):
    market = kickbase.market(leagues[0].id)
    my_info = kickbase.league_me(leagues[0].id)
Пример #4
0
 def logout(self):
     self.kickbase = Kickbase()
     self.isLoggedIn = False
Пример #5
0
class User():

    kickbase = Kickbase()
    isLoggedIn = False

    user = None
    leagueData = None
    userLeagueData: k_models.league_me = None

    transactions = []
    transactionsDict = {}

    @classmethod
    def login(self, email: str, pw: str) -> bool:
        if self.kickbase._is_token_valid == True or self.isLoggedIn == True:
            print("already logged in")
            return True

        try:
            #"*****@*****.**", "ilovesoccer3"
            user, leagues = self.kickbase.login(email, pw)
            self.user = user
            self.leagueData = leagues[0]
        except:
            print("Something went wrong with the retrieval of login data")
            return False

        if self.getUserStats() != True:
            print("failed at updating player")
            return False

        if self.getTransactions() != True:
            print("failed at getting tranactions")
            return False

        self.updateOwnedPlayer()
        self.isLoggedIn = True
        return True

    @classmethod
    def logout(self):
        self.kickbase = Kickbase()
        self.isLoggedIn = False

    @classmethod
    def getUserStats(self) -> bool:
        if self.userLeagueData is not None:
            print("user stats already retrieved")
            return False

        try:
            self.userLeagueData = self.kickbase.league_me(self.leagueData)
            print("user stats were retrieved")
            return True
        except:
            print("Something went wrong with the retrieval of user stats")
            return False

    @classmethod
    def getTransactions(self) -> bool:
        try:
            meta_feed = self.kickbase.league_feed(0, self.leagueData)
            print("meta data was retrieved")
        except:
            print("Something went wrong while retrieving meta data")
            return False

        # iterate through feed
        for item in meta_feed:

            meta = item.meta
            user_name = self.user.name
            value: int = -1

            if str(item.type.name) == "BUY":
                if meta.buyer_name == user_name:
                    transaction_type = "BUY"
                    value = meta.buy_price
                    traded_player_id = meta.player_id
                    traded_player_name = meta.player_last_name
                else:
                    continue

            if str(item.type.name) == "SALE":
                if meta.seller_name == user_name:
                    transaction_type = "SALE"
                    value = meta.sell_price
                    traded_player_id = meta.player_id
                    traded_player_name = meta.player_last_name
                else:
                    continue

            # if transaction was found: add
            if value > 0:
                t = Transaction.objects.filter(
                    traded_player_id=traded_player_id,
                    value=value,
                    user_name=user_name)
                if len(t) > 0:
                    print("transaction already exists: " + traded_player_name +
                          ", Price: " + str(value))
                else:
                    trans = Transaction(transaction_type=transaction_type,
                                        traded_player_id=traded_player_id,
                                        traded_player_name=traded_player_name,
                                        value=value,
                                        user_name=user_name)
                    trans.save()
                    print("added new transaction: " + traded_player_name +
                          ", Price: " + str(value))

        all_transaction = Transaction.objects.all()
        user_transactions = []
        for t in all_transaction:
            if t.user_name == user_name:
                user_transactions.append(t)
        self.transactions = user_transactions
        return True

    @classmethod
    def updateOwnedPlayer(self):
        # create dictionary with transactions
        self.transactionsDict = {}
        if len(self.transactions) > 0:
            for tran in self.transactions:
                transaction_type = tran.transaction_type
                if str(transaction_type) == "BUY":
                    traded_player_id = tran.traded_player_id
                    value = tran.value
                    self.transactionsDict.update({traded_player_id: value})

        # check if some players were sold ?
        try:
            player = self.kickbase.league_user_players(self.leagueData,
                                                       self.user)
        except:
            print("could not extract player")

        stored_player = OwnedPlayer.objects.all()
        for op in stored_player:
            if op.user_name != self.user.name:
                continue

            id_player_stored = op.traded_player_id
            still_owned = False

            for p in player:
                id_player = p.id
                if id_player == id_player_stored:
                    still_owned = True
                    break

            if still_owned == False:
                op.delete()

        # add player to database (if not existent)
        for p in player:
            id_player = p.id
            market_val = p.market_value

            owned_player = OwnedPlayer.objects.filter(
                traded_player_id=id_player, user_name=self.user.name)
            if len(owned_player) > 0:
                print("player with id " + id_player + " is already stored")
            else:
                if id_player in self.transactionsDict:
                    print("found purchase value in transactions")
                    new_owned_player_val = self.transactionsDict[id_player]
                else:
                    print("didn't find purchase value in transactions")
                    new_owned_player_val = market_val

                new_owned_player = OwnedPlayer(
                    traded_player_id=id_player,
                    market_value_purchased=new_owned_player_val,
                    user_name=self.user.name)
                new_owned_player.save()

    # GETTER
    def tester(self):
        try:
            #allp = kickbase.test_all_player(self.leagueData)
            players = self.kickbase.league_user_players(
                self.leagueData, self.user)
            hist = self.getMarketValueHistoryOfPlayer(players[1])
            return hist
        except:
            print("test failed")
            return

    def buyPlayer(self, player_id: str, offer: int) -> json:
        resp_code = {
            "playerPurchased": False,
            "m": "Something went wrong when trying to purchase player"
        }

        # get player
        try:
            player = self.kickbase.player_info(self.leagueData, player_id)
        except:
            resp_code['m'] = "Player couldn't be found"
            return resp_code

        # make offer
        try:
            self.kickbase.make_offer(offer, player, self.leagueData)
        except:
            return resp_code

        # return if offer was made succesfully
        resp_code['playerPurchased'] = True
        resp_code['m'] = "Offer for player was made"
        return resp_code

    def sellPlayer(self, player_id: str) -> json:
        resp_code = {
            "playerAddedToMarket": False,
            "m": "Something went wrong when trying to purchase player"
        }

        # get player
        try:
            player = self.kickbase.player_info(self.leagueData, player_id)
        except:
            resp_code['m'] = "Player couldn't be found"
            return resp_code

        # get price
        price = int(player.market_value)

        # add to market using kickbase
        try:
            self.kickbase.add_to_market(price, player, self.leagueData)
        except:
            return resp_code

        # return if request was successful
        resp_code['playerAddedToMarket'] = True
        resp_code['m'] = "Player added to TM successfully"
        return resp_code

    def getPredictionBuyML(self):
        predict = PredictBuyML()

        # get list of players from tm
        # needed params for each player: first name, last name, id, price*1.1, stats, market values

        predicted_player = predict.predict(player_tm=[])
        return predicted_player

    def getPredictionBuy(self, buy_params: dict):
        try:
            predict = PredictBuy(buy_params)
        except:
            print("Something was wrong with setting of parameters")
            return []

        prediction = predict.predict(player_tm=self.getPlayerOnTradeMarket())
        return prediction

    def getPredictionSell(self, sell_params: dict):
        try:
            predict = PredictSell(sell_params)
        except:
            print("Something was wrong with setting of parameters")
            return []

        # check if player was added to TM; if yes remove
        players = self.getUserPlayer()['player']
        players_to_predict = []
        try:
            market = self.kickbase.market(self.leagueData)
        except:
            return []

        for p in players:
            addedToTM = False
            for p_market in market.players:
                if p['id_player'] == p_market.id:
                    addedToTM = True
                    break
            if addedToTM == False:
                # add statistics
                try:
                    owned_player = self.kickbase.player_info(
                        self.leagueData, p['id_player'])
                    player_stats = self.getStatsHistoryOfPlayer(owned_player)
                    if player_stats is not None:
                        p['stats'] = player_stats
                    else:
                        print("Stats of player couldn't be retrieved")
                except:
                    pass
                players_to_predict.append(p)

        prediction = predict.predict(player_op=players_to_predict)
        return prediction

    def getPlayerOnTradeMarket(self):
        # get players from market
        try:
            market = self.kickbase.market(self.leagueData)
            print("received market")
        except:
            print("something went wrong witrh tm")
            return

        # retrieve player struct and offers (if existing) from market player
        player_from_market = []
        for m_player in market.players:
            try:
                # ectract player from id
                player = self.kickbase.player_info(self.leagueData,
                                                   str(m_player.id))
            except:
                print("something went wrong with extracting player from id")
                continue

            try:
                # get price
                p_highest_offer: int = 0
                additional_increase: float = 1.1
                offer_already_made = False

                # check if we own player on tm
                if m_player.username == self.user.name:
                    print("player owned by user")
                    continue

                if len(m_player.offers) > 0:
                    for offer in m_player.offers:
                        # check if user name is samsies
                        if self.user.name == offer.user_name:
                            print("offer mady by user already")
                            offer_already_made = True
                            continue

                        # update highest offer
                        if offer.price > p_highest_offer:
                            p_highest_offer = offer.price

                    p_highest_offer = int(additional_increase *
                                          float(p_highest_offer))

                if offer_already_made == True:
                    print(
                        "offer mady by user already; player will not be considered for prediction"
                    )
                    continue

                if p_highest_offer <= 0:
                    p_highest_offer = int(
                        float(player.market_value) * additional_increase)

                # check if user can afford player
                if self.userLeagueData.budget < p_highest_offer:
                    continue

                # get stats of player
                player_stats = self.getStatsHistoryOfPlayer(player)

                if player_stats is None:
                    continue

                if player.status != PlayerStatus.NONE:
                    print("player not added because currently not playing")
                    continue

                optional_player = {
                    'first_name': player.first_name,
                    'last_name': player.last_name,
                    'player_id': player.id,
                    'value': p_highest_offer,
                    'stats': player_stats
                }

                player_from_market.append(optional_player)
            except:
                print("something went wrong with extracting offer from player")
                pass

        return player_from_market

    def getOffers(self):
        try:
            market = self.kickbase.market(self.leagueData)
        except:
            return {"m": "Something went wrong"}

        offers = []
        for p in market.players:
            # get all our players on TM that we get offers for
            if self.user.name == p.username:
                # get highest offer
                p_highest_offer: int = -1
                offer_id = "-"
                offer_exists = (len(p.offers) > 0)
                for offer in p.offers:
                    if offer.price > p_highest_offer:
                        p_highest_offer = offer.price
                        offer_id = offer.id

                active_offer = {
                    "first_name": p.first_name,
                    "last_name": p.last_name,
                    "player_id": p.id,
                }

                if offer_exists is True:
                    active_offer["offer_price"] = p_highest_offer
                    active_offer["offer_id"] = offer_id

                offers.append(active_offer)

        resp = {"offers": offers}

        return resp

    def acceptOffer(self, offer_id: str, player_id: str):
        resp = {"playerSold": False, "m": "Player was sold"}
        try:
            player = self.kickbase.player_info(self.leagueData, player_id)
            self.kickbase.accept_offer(offer_id, player, self.leagueData)
        except:
            resp["m"] = "Something went wrong with accepting the offer"
            return resp

        self.getTransactions()

        resp["playerSold"] = True
        return resp

    def getStatsHistoryOfPlayer(self, player: Player):
        try:
            player_stats = self.kickbase.player_stats(player)
            return player_stats
        except:
            print("Something went wrong with the retrieval of player stats")
            return None

    def getMarketValueHistoryOfPlayer(self, player: Player):
        try:
            player_marketvalue_hist = self.kickbase.league_player_marketvalue_history(
                self.leagueData, player)
            print("player marketvals were retrieved")
            return player_marketvalue_hist
        except:
            print(
                "Something went wrong with the retrieval of player market vals"
            )
            return None

    # return json (!!!)
    def getPlayerFeed(self, player: Player):
        try:
            player_feed = self.kickbase.league_players_feed(
                self.leagueData, player)
            print("player feed was retrieved successfully")
            return player_feed
        except:
            print("Something went wrong with player feed retrieval")
            pass

    def getUser(self):
        if self.user is not None:
            return self.user

    def getLeagueData(self):
        if self.leagueData is not None:
            return self.leagueData

    def getLeagueMe(self):
        if self.userLeagueData is not None:
            return self.userLeagueData

    def getUserPlayer(self):
        try:
            player = self.kickbase.league_user_players(self.leagueData,
                                                       self.user)
        except:
            print("could not extract player")
            pass

        playerArr = []
        for p in player:
            first_name = p.first_name
            last_name = p.last_name
            market_val = p.market_value

            # 2: value trend going down
            # 1: value trend going up
            # 0: no change
            market_value_trend = p.market_value_trend
            if market_value_trend == 0:
                market_value_trend_string = "-"
            elif market_value_trend == 1:
                market_value_trend_string = "UP"
            else:
                market_value_trend_string = "DOWN"

            position = str(p.position.name)
            points = p.totalPoints
            status = str(p.status.name)
            id_player = p.id

            market_value_purchased = "--"
            owned_player = OwnedPlayer.objects.filter(
                traded_player_id=id_player, user_name=self.user.name)
            if len(owned_player) == 1:
                for op in owned_player:
                    market_value_purchased = op.market_value_purchased
            else:
                market_value_purchased = "-"

            playerStruct = {
                "first_name": first_name,
                "last_name": last_name,
                "market_val": market_val,
                "market_val_purchased": market_value_purchased,
                "market_value_trend": market_value_trend_string,
                "position": position,
                "points": points,
                "status": status,
                "id_player": id_player
            }

            try:
                img_path = self.kickbase.player_image_path(
                    self.leagueData, str(id_player))
                playerStruct['img_path'] = img_path
            except:
                pass

            playerArr.append(playerStruct)

        playerJSON = {"player": playerArr}

        return playerJSON

    def getListOfTransactions(self):
        if len(self.transactions) > 0:
            transactionArray = []
            for tran in self.transactions:
                transaction_type = tran.transaction_type
                traded_player_id = tran.traded_player_id
                traded_player_name = tran.traded_player_name
                value = tran.value

                transactionStruct = {
                    "transaction_type": transaction_type,
                    "traded_player_id": traded_player_id,
                    "traded_player_name": traded_player_name,
                    "value": value
                }
                transactionArray.append(transactionStruct)

            transactionJSON = {"transactions": transactionArray}
            return transactionJSON
        else:
            transactionJSON = {"transactions": []}
            return transactionJSON

    def get_player_val(self, ids):
        vals = []
        try:
            player = self.kickbase.player_info(self.leagueData, ids)
            name = player.first_name + " " + player.last_name
            hist = self.getMarketValueHistoryOfPlayer(player)
            val = {"name": str(name), "marketvalue": hist.marketvalues}
            vals.append(val)
        except:
            print("player not found")
            pass
        return vals

    def getStatsForPrediction(self):
        ERR = {"e": "ZOMEZING WENT WRONG"}
        try:
            players = self.kickbase.top_25_players()
        except:
            return ERR

        player_stats = []
        for p in players:
            # market values
            market_hist = self.getMarketValueHistoryOfPlayer(p)
            stats = self.getStatsHistoryOfPlayer(p)

            if market_hist is None:
                print('stopped')
                continue
            if stats is None:
                print('stopped')
                continue

            name = p.first_name + " " + p.last_name

            content = {
                'player': name,
                'market_value': market_hist.marketvalues,
                'stats': stats.stats
            }
            player_stats.append(content)

        return {'data': player_stats}
Пример #6
0
class KickbaseBot:
    
    _periodic_feed_thread: Thread
    _periodic_chat_thread: Thread
    _periodic_market_thread: Thread

    _leagues: [LeagueData] = []
    selected_league: LeagueData = None
    
    _feed_item_callback: [Callable[[FeedItem, 'KickbaseBot'], None]] = []
    _chat_item_callback: [Callable[[ChatItem, 'KickbaseBot'], None]] = []
    _market_callback: [Callable[[Market, 'KickbaseBot'], None]] = []

    def __init__(self, **kwargs):
        self.kickbase_api = Kickbase(
            google_identity_toolkit_api_key=kwargs.get('google_identity_toolkit_api_key', None))
        self.persistence = _Persistence(
            mongo_host=kwargs.get('mongodb_host', 'localhost'),
            mongo_user=kwargs.get('mongodb_user', ''),
            mongo_pwd=kwargs.get('mongodb_password', ''),
            mongo_db=kwargs.get('mongodb_db', 'kkbs_bot'),
            auth_mechanism=kwargs.get('mongodb_auth_mechanism', 'SCRAM-SHA-256')
        )
        
        self._periodic_feed_interval = kwargs.get("periodic_feed_interval", 15)
        self._periodic_chat_interval = kwargs.get("periodic_chat_interval", 5)
        self._periodic_market_interval = kwargs.get("periodic_market_interval", 60)

    def connect(self, username, password):
        logger.debug("Login using username %s", username)
        me, self._leagues = self.kickbase_api.login(username, password)
        logger.debug("Login succeeded")
        
    def add_feed_item_callback(self, func: Callable[[FeedItem, 'KickbaseBot'], None]):
        self._feed_item_callback.append(func)

    def add_chat_item_callback(self, func: Callable[[ChatItem, 'KickbaseBot'], None]):
        self._chat_item_callback.append(func)

    def add_market_item_callback(self, func: Callable[[Market, 'KickbaseBot'], None]):
        self._market_callback.append(func)
        
    def _periodic_feed(self, silent=False):
        try:
            # Fetch all feed items
            count = 0
            while True:
                logger.debug("Fetching feed items, start: %s", count)
                feed_items = self.kickbase_api.league_feed(count, self.selected_league)
                if len(feed_items) == 0:
                    break
                else:
                    new_feed_item = False
                    for feed_item in feed_items:
                        exists = self.persistence.does_feed_item_exist(feed_item)
                        self.persistence.save_feed_item(feed_item)
                        if not exists:
                            logger.debug("New feed item: %s", feed_item.id)
                            new_feed_item = True
                            for cb in self._feed_item_callback:
                                if not silent:
                                    try:
                                        cp = copy.deepcopy(feed_item)
                                        cb(cp, self)
                                        del cp
                                    except Exception as ex:
                                        logger.error("[{}] Error in feed callback: ".format(feed_item.id) + str(ex))
                                        
                    if not new_feed_item:
                        break
                            
                    count = count + len(feed_items)
                del feed_items
    
            logger.debug("Fetched %s feed items", count)
        except Exception as ex:
            logger.error("Something went wrong fetching feed items: %s", ex)

    def _periodic_chat(self, silent=False):
        try:
            # Fetch chat items
            logger.debug("Fetching chat items")
            count = 0
            next_page_token = None
            while True:
                chat_items, next_page_token = self.kickbase_api.chat_messages(self.selected_league,
                                                                              page_size=100,
                                                                              next_page_token=next_page_token)
                count = count + len(chat_items)
                for chat_item in chat_items:
                    exists = self.persistence.does_chat_item_exist(chat_item)
                    self.persistence.save_chat_item(chat_item)
                    if not exists:
                        logger.debug("New chat item: %s (%s)", chat_item.id, chat_item.message)
                        for cb in self._chat_item_callback:
                            if not silent:
                                try:
                                    cp = copy.deepcopy(chat_item)
                                    cb(cp, self)
                                    del cp
                                except Exception as ex:
                                    logger.error("[{}] Error in chat callback: ".format(chat_item.id) + str(ex))
                                    
                del chat_items
                if next_page_token is None:
                    break

            logger.debug("Fetched %s chat items", count)
        except Exception as ex:
            logger.error("Something went wrong fetching chat items: %s", ex)
            
    def _periodic_market(self, silent=False):
        try:
            logger.debug("Fetching market")
            market = self.kickbase_api.market(self.selected_league)
            market.date = datetime.utcnow()
            self.persistence.save_market(market)
            for cb in self._market_callback:
                if not silent:
                    try:
                        cp = copy.deepcopy(market)
                        cb(cp, self)
                        del cp
                    except Exception as ex:
                        logger.error("Error in market callback: " + str(ex))
            del market
            logger.debug("Fetched market")
        except Exception as ex:
            logger.error("Something went wrong fetching market: %s", ex)
            
    def initialize(self, league_id):
        saved_league_id = self.persistence.get_value("league_id")
        if saved_league_id is not None and saved_league_id != league_id:
            raise Exception("The database is based on a different league_id. Please specify a different database.")
        self.persistence.save_value("league_id", league_id)

        for league in self._leagues:
            if league.id == league_id:
                self.selected_league = league
                logger.debug("Selected league: %s", self.selected_league.name)

        if self.selected_league is None:
            logger.error("League with id %s could not be found", league_id)
            logger.error("Available leagues are:")
            for league in self._leagues:
                logger.error("%s [%s]", league.name, league.id)
            raise Exception("League not found".format(league_id))
        
    def run(self):
        logger.debug("Starting threads...")
        threads = []
        
        logger.debug("Feed update interval was set to %s seconds", self._periodic_feed_interval)
        self._periodic_feed_thread = _start_thread_periodically(self._periodic_feed_interval, self._periodic_feed)
        threads.append(self._periodic_feed_thread)
        
        logger.debug("Chat update interval was set to %s seconds", self._periodic_chat_interval)
        self._periodic_chat_thread = _start_thread_periodically(self._periodic_chat_interval, self._periodic_chat)
        threads.append(self._periodic_chat_thread)
        
        logger.debug("Market update interval was set to %s seconds", self._periodic_market_interval)
        self._periodic_market_thread = _start_thread_periodically(self._periodic_market_interval, self._periodic_market)
        threads.append(self._periodic_market_thread)
        
        logger.debug("All threads started")
        for thread in threads:
            thread.join()
Пример #7
0
def create_logged_in_kickbase():
    kickbase = Kickbase(
        google_identity_toolkit_api_key=os.environ["KKBS_API_KEY"])
    user, leagues = kickbase.login(os.environ["KKBS_TEST_USERNAME"],
                                   os.environ["KKBS_TEST_PASSWORD"])
    return kickbase, user, leagues