Beispiel #1
0
async def getLeagueTable(competition: Competition) -> str:
    """
    Creates a nicely structured league table for a given competition. Competition needs to be
    valid, no further check on that object is done
    :param competition: Competition for which you are looking for
    :return: string containing the league in a nicely formatted way
    """
    try:
        data = makeMiddlewareCall(DataCalls.standings + f"/{competition.id}")
    except JSONDecodeError:
        return ""
    table = Texttable()
    tableData = [["Rk", "Team", "M", "W", "L", "D", "Pts"]]

    for i in data['competitionsStanding'][0]['listStandings']:
        tableData.append([
            i['rank'], i['teamName'], i['matches'], i['matchesWon'],
            i['matchesLost'], i['matchesDrawn'], i['points']
        ])

    table.set_deco(Texttable.VLINES | Texttable.HEADER | Texttable.BORDER)
    table.set_cols_width([2, 20, 2, 2, 2, 2, 3])
    table.add_rows(tableData, True)
    logger.info(table.draw())

    return "```" + table.draw() + "```"
Beispiel #2
0
    async def beautifyEvent(event, match):
        data = makeMiddlewareCall(DataCalls.liveData + f"/{match.id}")['match']
        homeTeam = data['teamHomeName']
        awayTeam = data['teamAwayName']

        if event.event == MatchEvents.goal:
            if event.team == homeTeam:
                goalString = LiveMatch.styleSheetEvents(
                    MatchEvents.goalTallyHomeScore.value)
            else:
                goalString = LiveMatch.styleSheetEvents(
                    MatchEvents.goalTallyAwayScore.value)
        else:
            goalString = LiveMatch.styleSheetEvents(
                MatchEvents.goalTally.value)

        title = LiveMatch.styleSheetEvents(MatchEvents.title.value)

        replaceDict = OrderedDict()
        replaceDict["$tally$"] = goalString
        replaceDict["$homeScore$"] = data['scoreHome']
        replaceDict["$awayScore$"] = data['scoreAway']
        replaceDict["$homeTeam$"] = homeTeam
        replaceDict["$awayTeam$"] = awayTeam
        for key, val in replaceDict.items():
            title = title.replace(str(key), str(val))

        replaceDict = {
            "$minute$": event.minute,
            "$player$": event.player,
            "$playerTo$": event.playerTo,
            "$team$": event.team,
        }

        content = LiveMatch.styleSheetEvents(event.event.value)

        foundEmojis = re.findall(r':[\w\d_-]+:', content)

        logger.debug(f"found emojis : {foundEmojis}")

        for i in foundEmojis:
            if i.replace(":", "") in LiveMatch.emojiSet.keys():
                logger.debug(
                    f"Replacing {i} for {LiveMatch.emojiSet[i.replace('':'','')]}"
                )
                content.replace(i, LiveMatch.emojiSet[i.replace(":", "")])
            else:
                logger.debug(
                    f"{i} not in emojilist, replacing it with nothing")
                content.replace(i, "")

        for key, val in replaceDict.items():
            content = content.replace(key, str(val))

        goalListing = ""
        if event.event == MatchEvents.goal:
            goalListing = content + f" {event.player}"

        return title, content, goalListing
Beispiel #3
0
async def cdoScores(msg : Message,**kwargs):
    """
    Returns the scores for a given competition/matchday/team
    :param kwargs:
    :return:
    """
    channel = msg.channel

    if "parameter0" not in kwargs.keys():
        if not "live-" in channel.name:
            return CDOInteralResponseData(f"This command with no argument can only be called within matchday channels")

        comp,md = Scheduler.findCompetitionMatchdayByChannel(channel.name)

        matchList = Scheduler.getScores(comp,md)

        resp = CDOInteralResponseData("Current scores:")
        addInfo = InfoObj()
        for matchString,goalList in matchList.items():
            addInfo[matchString] = ""
            for goals in goalList[0]:
                if goals != '':
                    addInfo[matchString] += goals+"\n"

            if addInfo[matchString] == "":
                del addInfo[matchString]

            if addInfo == InfoObj():
                addInfo[matchString] = f"{goalList[1]}: 0-0"

        if addInfo == InfoObj():
            resp.response = "Currently no running matches"
        else:
            resp.response = "Current scores:"
        resp.additionalInfo = addInfo
        return resp
    else:
        searchString = kwargs['parameter0']
        query = Competition.objects.filter(clear_name = searchString)

        if len(query) == 0:
            teamList = getTeamsSearchedByName(searchString)
            if len(teamList) == 0:
                return CDOInteralResponseData(f"Can't find team {searchString}")
            matchObj = teamList[0]['Name'][0]['Description']
            matchList = getLiveMatches(teamID=int(teamList[0]["IdTeam"]))

        else:
            comp = query.first()
            matchObj = comp.clear_name
            matchList = getLiveMatches(competitionID=comp.id)

        if len(matchList) == 0:
            return CDOInteralResponseData(f"No current matches for {matchObj}")

        addInfo = InfoObj()
        for matchID in matchList:
            try:
                data = makeMiddlewareCall(DataCalls.liveData + f"/{matchID}")
            except JSONDecodeError:
                logger.error(f"Failed to do a middleware call for {matchID}")
                continue

            newEvents, _ = LiveMatch.parseEvents(data["match"]["events"], [])

            class Match:
                id = matchID

            for event in newEvents:
                title,_,goalListing = await LiveMatch.beautifyEvent(event,Match)

                if goalListing != "":
                    try:
                        addInfo[title]+=goalListing + "\n"
                    except KeyError:
                        addInfo[title] = goalListing + "\n"

        if addInfo == InfoObj():
            return CDOInteralResponseData(f"No goals currently for {matchObj}")

        resp = CDOInteralResponseData(f"Current scores for {matchObj}")
        resp.additionalInfo = addInfo
        return resp
Beispiel #4
0
    async def runMatchThread(self):
        """
        Start a match threader for a given match. Will read the live data from the middleWare API (data.fifa.com) every
        20 seconds and post the events to the channel that corresponds to the match. This channel has to be created
        previously.
        :param match: Match object.  Will  post to discord channels if the object is a database.models.Match object
        """
        if self.runningStarted:
            logger.warning(f"Match {self.title} already started!")
            return
        else:
            logger.info(f"Starting match {self.title}")
        self.runningStarted = True
        pastEvents = []
        eventList = []
        sleepTime = 600
        endCycles = 10

        matchid = self.match.id
        channelName = toDiscordChannelName(
            f"{self.match.competition.clear_name} Matchday {self.match.matchday}"
        )

        lineupsPosted = False
        while True:
            try:
                data = makeMiddlewareCall(DataCalls.liveData + f"/{matchid}")
            except JSONDecodeError:
                break

            if data["match"]["isFinished"] and not self.running:
                logger.info(f"Match {self.match} allready passed")
                break

            self.running = True
            if data["match"]["isLive"]:
                self.started = True
            else:
                self.started = False

            if not self.lock.is_set():
                self.lock.set()

            if not lineupsPosted and data["match"]["hasLineup"]:
                logger.info(f"Posting lineups for {self.title}")
                await asyncio.sleep(5)
                try:
                    for channel in client.get_all_channels():
                        if channel.name == channelName:
                            await LiveMatch.postLineups(
                                channel, self.match, data["match"])
                            lineupsPosted = True
                            sleepTime = 20
                except RuntimeError:
                    lineupsPosted = False
                    logger.warning("Size of channels has changed")
            else:
                if not lineupsPosted:
                    logger.info(f"Lineups not yet available for {self.title}")

            newEvents, pastEvents = LiveMatch.parseEvents(
                data["match"]["events"], pastEvents)
            eventList += newEvents

            for i in eventList:
                try:
                    for channel in client.get_all_channels():
                        if channel.name == channelName:
                            self.started = True
                            self.title, goalString = await LiveMatch.sendMatchEvent(
                                channel, self.match, i)
                            self.goalList.append(goalString)
                            try:
                                eventList.remove(i)
                            except ValueError:
                                pass
                            logger.info(f"Posting event: {i}")
                except RuntimeError:
                    logger.warning("Size of channels has changed!")
                    break

            if self.lock.is_set():
                self.lock.clear()

            if data["match"]["isFinished"]:
                if endCycles <= 0:
                    logger.info(f"Match {match} finished!")
                    break
                endCycles -= 1

            await asyncio.sleep(sleepTime)

        now = datetime.utcnow().replace(tzinfo=UTC)
        if now < (self.match.date + timedelta(hours=3)).replace(tzinfo=UTC):
            self.passed = True
        self.running = False
        self.started = False
        self.runningStarted = False
        self.lock.set()
        logger.info(f"Ending match {self.title}")