예제 #1
0
    def findGameID(self, gameName):
        """
        Searches for the ID of a given game by searching through a .json file containing every steam game with their
        respective ID and game name.
        Once the game is found within the .json file, the games ID is returned.
        If the game isn't found, False is returned
        Uses a simple linear search due to the data being unordered - Likely be improved in future

        :param gameName: str - name of steam game
        :return: steamID of given game as a string or False if the ID was not found
        """
        # Retrieves the steam game list
        with open(self.gameList, "r") as jsonFile:
            gameListData = json.load(jsonFile)

        searchingForIDs = True
        gameIDs = []
        gameName = alphanumericString(gameName)
        # As some games have the same name, searching only concludes until all games of a given name are found
        while searchingForIDs:
            # Sets key variables such as the higher and lower index
            amountOfRows = len(gameListData)
            lowerIndex = 0
            higherIndex = amountOfRows - 1
            searchingForIDs = False
            # Repeats until the game is found within the list or until the entire list has been searched
            while lowerIndex <= higherIndex:
                currentGameIndex = (higherIndex + lowerIndex) // 2
                currentGameName = alphanumericString(
                    gameListData[currentGameIndex]["name"])
                # Game has been found and the game's ID is returned
                if currentGameName == gameName:
                    gameIDs.append(gameListData[currentGameIndex]["appid"])
                    gameListData.pop(currentGameIndex)
                    searchingForIDs = True
                    break
                # Game to be found is above the current game
                elif currentGameName > gameName:
                    higherIndex = currentGameIndex - 1
                # Game to be found is below the current game
                elif currentGameName < gameName:
                    lowerIndex = currentGameIndex + 1
        # If multiple games have the same name, the game with the highest player count has it's ID returned
        highestIndex = 0
        # Returns the games ID if it was found, returns false otherwise
        if len(gameIDs) == 0:
            return False
        elif len(gameIDs) != 1:
            # Compares the popularity of each game to decide which to return
            highestCount = self.gamePlayerCount(gameIDs[0])
            for i in range(1, len(gameIDs)):
                currentCount = self.gamePlayerCount(gameIDs[i])
                if currentCount > highestCount:
                    highestCount = currentCount
                    highestIndex = i
        return gameIDs[highestIndex]
예제 #2
0
    def _gameListMergeSort(self, unsortedGL):
        """
        Method used to sort the list of all steam games by name.

        :param unsortedGL: unsorted game list as a list containing dictionaries of which contain individual game data
        :return: List of all sorted steam games, ascending
        """
        startingSize = len(unsortedGL)

        # Converts names into their alphanumeric equivalent so they are easier for user to specify
        for i in range(0, len(unsortedGL)):
            unsortedGL[i]["name"] = alphanumericString(unsortedGL[i]["name"])

        # Sorts every pair to be in order
        for i in range(0, len(unsortedGL) - 1, 2):
            if unsortedGL[i + 1]["name"] < unsortedGL[i]["name"]:
                unsortedGL[i], unsortedGL[i + 1] = unsortedGL[i +
                                                              1], unsortedGL[i]

        # Combines every pair into a small list
        for i in range(0, len(unsortedGL) // 2, 1):
            unsortedGL[i:i + 2] = [[unsortedGL[i], unsortedGL[i + 1]]]

        # If there's an odd number of elements, the final element replaced with a list containing only itself
        if startingSize % 2 != 0:
            unsortedGL[-1:] = [unsortedGL[-1:]]

        # Sorts all the pairs into a single sorted list
        # Repeats until only a single list remains
        while len(unsortedGL) != 1:
            # Combines every pair of lists into a single sorted list until only a single sorted list remains
            for i in range(0, len(unsortedGL) // 2, 1):
                sortedList = []
                # Assigns pointers to mark out the two lists being combined
                leftPointer = 0
                leftMax = len(unsortedGL[i])
                rightPointer = 0
                rightMax = len(unsortedGL[i + 1])
                # Repeat until a pair of the two lists is a subset of the sorted list
                while rightPointer != rightMax and leftPointer != leftMax:
                    if unsortedGL[i][leftPointer]["name"] < unsortedGL[
                            i + 1][rightPointer]["name"]:
                        sortedList.append(unsortedGL[i][leftPointer])
                        leftPointer += 1
                    else:
                        sortedList.append(unsortedGL[i + 1][rightPointer])
                        rightPointer += 1
                # Appends the remaining elements to the sorted list
                if leftPointer != leftMax:
                    while leftPointer != leftMax:
                        sortedList.append(unsortedGL[i][leftPointer])
                        leftPointer += 1
                elif rightPointer != rightMax:
                    while rightPointer != rightMax:
                        sortedList.append(unsortedGL[i + 1][rightPointer])
                        rightPointer += 1
                unsortedGL[i:i + 2] = [sortedList]
        # Returns the sorted list
        return unsortedGL[0]
예제 #3
0
def setPreference(userID, preferenceID, preferenceType):
    """
    Used to set a given user preference.

    :param userID: int - Discord ID of user
    :param preferenceID: str - ID for the data to be stored
    :param preferenceType: str - Name of preference to be set
    :return: str - Error or success message response to the user
    """
    # Validates the passed ID by calling the necessary function with the require arguments
    if preferenceType in ["favourite_games", "tracked_game"]:
        validationResponse = validationOfID(preferenceID, "steam_game")
    elif preferenceType in ["favourite_streamers", "tracked_streamer", "blacklisted_streamers"]:
        validationResponse = validationOfID(preferenceID, "twitch_user")
    elif preferenceType in ["steam_id"]:
        validationResponse = validationOfID(preferenceID, "steam_user")
    # Stores data of which cannot be validated (No API for all steam game genres available)
    elif preferenceType in ["favourite_genre"]:
        storageHandler.writeUserDetails(userID, preferenceType, preferenceID)
        return ["Preference set successfully!"]
    # Raise an error to inform a fellow programmer using the function of their invalid arguments passed
    else:
        raise Exception("You must pass a valid 'preferenceType', please refer to documentation")
    # Returns error message if the validation fails
    if not str(validationResponse).isdigit():
        return validationResponse
    # Retrieves the string name corresponding to the given ID
    if preferenceType in ["favourite_games", "tracked_game"]:
        preferenceData = steamHandler.getGameName(validationResponse)
    elif preferenceType in ["favourite_streamers", "tracked_streamer", "blacklisted_streamers"]:
        preferenceData = twitchHandler.getStreamerName(validationResponse)
    elif preferenceType in ["steam_id"]:
        storageHandler.writeUserDetails(userID, preferenceType, validationResponse)
        return ["Steam ID set"]
    # Converts the string to only contain lowercase alphanumeric character
    preferenceData = alphanumericString(preferenceData)
    # Writes the user preference to storage
    storageHandler.writeUserDetails(userID, preferenceType, preferenceData)
    return ["Preference set successfully!"]
예제 #4
0
def requestProcessing(userRequest, userID):
    if userRequest[0] in ["#"]:
        return ""
    argumentList = []
    possibleFunctions = copy.deepcopy(availableFunctions)
    rawRequest = userRequest.split(" ")
    originalRequest = rawRequest[:]
    for i in range(0, len(rawRequest)):
        rawRequest[i] = alphanumericString(rawRequest[i])
        originalRequest[i] = rawRequest[i]
        rawRequest[i] = lem.lemmatize(rawRequest[i], 'v')
    for i in range(1, len(possibleFunctions)):
        for expectedWord in possibleFunctions[i][0]:
            if lem.lemmatize(expectedWord, 'v') in rawRequest:
                possibleFunctions[i][2] += 1

    largestIndexList = []
    largestIndex = 0
    largestValue = 0
    for i in range(1, len(possibleFunctions)):
        if possibleFunctions[i][2] > largestValue:
            largestValue = possibleFunctions[i][2]
            largestIndexList = [i]
        elif possibleFunctions[i][2] == largestValue:
            largestIndexList.append(i)

    if len(largestIndexList) > 1:
        newIndex = largestIndex
        highestPriority = possibleFunctions[largestIndex][4]
        for checkIndex in largestIndexList:
            if possibleFunctions[checkIndex][4] < highestPriority:
                highestPriority = possibleFunctions[checkIndex][4]
                newIndex = checkIndex
        largestIndex = newIndex
    else:
        if largestIndexList:
            largestIndex = largestIndexList[0]

    referenceType = ""
    if {"stream", "streamer", "streamers"} & set(rawRequest):
        referenceType = "twitch"
    else:
        referenceType = "steam"

    for loopCounter in range(len(possibleFunctions[largestIndex][3])):
        if not argumentList and "userID" in possibleFunctions[largestIndex][3]:
            argumentList.append(userID)

        elif {"preference", "set", "delete", "remove"} & set(rawRequest):
            if {"steam", "id"} & set(rawRequest) == {"steam", "id"}:
                steamIndex = rawRequest.index("steam")
                rawRequest[steamIndex] = "steamid"
                originalRequest[steamIndex] = "steamid"
                rawRequest.pop(steamIndex + 1)
                originalRequest.pop(steamIndex + 1)
            addPreference = True
            preferenceFirst = True
            indicatorTuple = ("set", "remove", "delete")
            connectTuple = ("a", "my", "from")
            dividerTuple = ("as", "to")
            for possibleIndicator in indicatorTuple:
                if possibleIndicator in rawRequest:
                    indicatorIndex = rawRequest.index(possibleIndicator)
                    if not possibleIndicator == "set":
                        addPreference = False
                    break

            for possibleConnect in connectTuple:
                if possibleConnect in rawRequest:
                    connectIndex = rawRequest.index(possibleConnect)
                    break

            dividerIndex = connectIndex
            for possibleDivider in dividerTuple:
                if possibleDivider in rawRequest:
                    dividerIndex = rawRequest.index(possibleDivider)
                    break

            if indicatorIndex + 1 in [connectIndex]:
                preferenceFirst = False
                indicatorIndex += 1
                connectIndex = dividerIndex
            referencedObject = ""
            for gameSectionIndex in range(indicatorIndex + 1, dividerIndex):
                referencedObject += f"{originalRequest[gameSectionIndex]} "

            argumentList.append(referencedObject[:-1])

            referencedObject = ""
            for gameSectionIndex in range(connectIndex + 1, len(rawRequest)):
                referencedObject += f"{originalRequest[gameSectionIndex]} "

            referencedObject = referencedObject[:-1]
            argumentList.append(referencedObject)

            if not preferenceFirst:
                argumentList[1], argumentList[2] = argumentList[
                    2], argumentList[1]
            argumentList[2] = argumentList[2].replace(" ", "_")
            if argumentList[2] in [
                    "favourite_streamer", "favourite_game",
                    "blacklisted_streamer"
            ]:
                argumentList[2] += "s"
            if argumentList[2] == "steamid":
                argumentList[2] = "steam_id"

            if addPreference:
                return setPreference(argumentList[0], argumentList[1],
                                     argumentList[2])
            else:
                argumentList[1] = argumentList[1].replace(" ", "")
                return deletePreference(argumentList[0], argumentList[1],
                                        argumentList[2])
        else:
            if "play" in rawRequest or ("for" in rawRequest
                                        and "and" not in rawRequest
                                        and "vs" not in rawRequest):
                indicatorTuple = ("play", "for")
                for possibleIndicator in indicatorTuple:
                    if possibleIndicator in rawRequest:
                        indicatorIndex = rawRequest.index(possibleIndicator)
                        break

                referencedGame = ""
                for gameSectionIndex in range(indicatorIndex + 1,
                                              len(rawRequest)):
                    referencedGame += f"{originalRequest[gameSectionIndex]} "
                if referencedGame:
                    referencedGame = referencedGame[:-1]
                    referencedGame = aliasesCheck(referencedGame)
                    argumentList.append(referencedGame)
                    break
            elif "graph" in rawRequest or "compare" in rawRequest:
                indicatorIndex = ""
                connectIndex = ""
                indicatorTuple = ("for", "compare")
                connectTuple = ("and", "vs")
                for possibleIndicator in indicatorTuple:
                    if possibleIndicator in rawRequest:
                        indicatorIndex = rawRequest.index(possibleIndicator)

                for possibleConnect in connectTuple:
                    if possibleConnect in rawRequest:
                        connectIndex = rawRequest.index(possibleConnect)
                        break

                if str(indicatorIndex) and str(connectIndex):
                    referencedObject = ""
                    for gameSectionIndex in range(indicatorIndex + 1,
                                                  connectIndex):
                        referencedObject += f"{originalRequest[gameSectionIndex]} "
                    referencedObject = referencedObject[:-1]
                    referencedObject = aliasesCheck(referencedObject)
                    argumentList.append(referencedObject)

                    referencedObject = ""
                    for gameSectionIndex in range(connectIndex + 1,
                                                  len(rawRequest)):
                        referencedObject += f"{originalRequest[gameSectionIndex]} "
                    referencedObject = referencedObject[:-1]
                    referencedObject = aliasesCheck(referencedObject)
                    argumentList.append(referencedObject)

                    break
            for verb in linkingVerbs:
                if verb in rawRequest:
                    linkingVerb = rawRequest.index(verb)
                    extractedArgument = originalRequest[linkingVerb + 1]
                    extractedArgument = aliasesCheck(extractedArgument)
                    argumentList.append(extractedArgument)

    if "referenceType" in possibleFunctions[largestIndex][3]:
        argumentList.append(referenceType)
    if not argumentList:
        return possibleFunctions[largestIndex][1]()
    elif len(argumentList) == 1:
        return possibleFunctions[largestIndex][1](argumentList[0])
    elif len(argumentList) == 2:
        return possibleFunctions[largestIndex][1](argumentList[0],
                                                  argumentList[1])
    elif len(argumentList) == 3:
        return possibleFunctions[largestIndex][1](argumentList[0],
                                                  argumentList[1],
                                                  argumentList[2])
    else:
        raise Exception("Redundant arguments extracted from request")
예제 #5
0
    def _friendQuickSort(self, playingFriends):
        """
        Used to sort a list of sub lists containing a user and the game they are currently playing

        :param playingFriends: list - list of sub lists containing a user and the game they are currently playing
        :return: list - the given list but sorted by game
        """
        # Implementation of quicksort
        # Key variables
        pivot = alphanumericString(playingFriends[-1:][0][1])
        pivotData = playingFriends[-1:][0]
        toSort = playingFriends[:-1]
        marker1 = 0
        marker2 = len(toSort) - 1
        marker1Stopped = False
        marker2Stopped = False
        # Whilst the markers are not adjacent
        while marker1 < marker2 - 1:
            if not marker1Stopped:
                # Stops marker as an out of place element has been found
                if alphanumericString(toSort[marker1][1]) > pivot:
                    marker1Stopped = True
                # Moves maker as the element was in place
                else:
                    marker1 += 1
            # Marker1 has priority so this is only ran when marker1 has stopped
            if marker1Stopped and not marker2Stopped:
                # Stops marker as an out of place element has been found
                if toSort[marker2][1].lower() < pivot:
                    marker2Stopped = True
                # Moves maker as the element was in place
                else:
                    marker2 -= 1
            # Run when both markers have stopped as hey have both encountered an out of place element
            if marker1Stopped and marker2Stopped:
                # Swaps out of place elements and sets the markers as being mobile
                toSort[marker1], toSort[marker2] = toSort[marker2], toSort[
                    marker1]
                marker1Stopped, marker2Stopped = False, False
                marker1 += 1
                if marker1 < marker2 - 1:
                    marker2 -= 1
        # Ensures the element at marker2 is sorted as the previous while loop may end with unsorted data due to
        # marker1 being given priority
        if alphanumericString(toSort[marker2][1]) < pivot:
            toSort[marker1], toSort[marker2] = toSort[marker2], toSort[marker1]
        # If the element at marker1 is larger than the pivot, the pivot is below that element
        if alphanumericString(toSort[marker1][1]) > pivot:
            toSort.append(pivot)
            toSort[marker1], toSort[len(toSort) -
                                    1] = toSort[len(toSort) -
                                                1], toSort[marker1]
            lowerSection = toSort[0:marker1]
            higherSection = toSort[marker1 + 1:]
        # If the element at marker2 is larger than the pivot, the pivot is below that element
        elif alphanumericString(toSort[marker2][1]) > pivot:
            toSort.append(pivot)
            toSort[marker2], toSort[len(toSort) -
                                    1] = toSort[len(toSort) -
                                                1], toSort[marker2]
            lowerSection = toSort[0:marker2]
            higherSection = toSort[marker2 + 1:]
        # If the element at marker2+1 is larger than the pivot, the pivot is below that element
        elif marker2 + 1 < len(toSort) and toSort[marker2 + 1][0] > pivot:
            toSort.append(pivot)
            toSort[marker2 + 1], toSort[len(toSort) -
                                        1] = toSort[len(toSort) -
                                                    1], toSort[marker2 + 1]
            lowerSection = toSort[0:marker2 + 1]
            higherSection = toSort[marker2 + 2:]
        # The pivot is larger than all elements in the list
        else:
            lowerSection = toSort[:]
            higherSection = []
        # Recursive calls to sort each section
        if len(lowerSection) > 1:
            lowerSection = self._friendQuickSort(lowerSection)
        if len(higherSection) > 1:
            higherSection = self._friendQuickSort(higherSection)
        # Prepares the list in a suitable format for returning
        passResult = []
        for i in lowerSection:
            passResult.append(i)
        passResult.append(pivotData)
        for i in higherSection:
            passResult.append(i)
        return passResult