Esempio n. 1
0
    async def __updatePubSubSubscriptions(self):
        if self.__isManagingPubSub:
            self.__timber(
                'PubSubUtils',
                f'Unable to update PubSub subscriptions because it is currently working!'
            )
            return

        self.__isManagingPubSub = True

        pubSubTopicsToAdd: List[Topic] = list()
        pubSubTopicsToRemove: List[Topic] = list()
        newPubSubEntries = await self.__getSubscribeReadyPubSubEntries()

        if utils.hasItems(newPubSubEntries):
            for newPubSubEntry in newPubSubEntries:
                pubSubTopicsToAdd.append(newPubSubEntry.getTopic())
                self.__pubSubEntries[newPubSubEntry.getUserName()].put(
                    newPubSubEntry.getTopic())

        if utils.hasItems(self.__pubSubEntries):
            for topicQueue in self.__pubSubEntries.values():
                if topicQueue.qsize() > self.__maxConnectionsPerTwitchChannel:
                    pubSubTopicsToRemove.append(
                        topicQueue.get(block=True, timeout=3))

        if utils.hasItems(pubSubTopicsToAdd):
            self.__timber.log(
                'PubSubUtils',
                f'Subscribing to {len(newPubSubEntries)} PubSub user(s)...')
            await self.__pubSubPool.subscribe_topics(pubSubTopicsToAdd)
            self.__timber.log(
                'PubSubUtils',
                f'Finished subscribing to {len(newPubSubEntries)} PubSub user(s)'
            )

        if utils.hasItems(pubSubTopicsToRemove):
            self.__timber.log(
                'PubSubUtils',
                f'Unsubscribing from {len(pubSubTopicsToRemove)} PubSub user(s)...'
            )
            await self.__pubSubPool.unsubscribe_topics(pubSubTopicsToRemove)
            self.__timber.log(
                'PubSubUtils',
                f'Finished unsubscribing from {len(pubSubTopicsToRemove)} PubSub user(s)'
            )

        self.__isManagingPubSub = False
    def getTimeZones(self, timeZones: List[str]):
        if not utils.hasItems(timeZones):
            return None

        newTimeZones = list()

        for timeZone in timeZones:
            newTimeZone = self.getTimeZone(timeZone)

            if newTimeZone is not None:
                newTimeZones.append(newTimeZone)

        if utils.hasItems(newTimeZones):
            return newTimeZones
        else:
            return None
Esempio n. 3
0
    async def event_raw_usernotice(self, channel: Channel, tags: Dict):
        if not utils.hasItems(tags):
            return

        msgId = tags.get('msg-id')

        if not utils.isValidStr(msgId):
            return

        twitchUser = await self.__usersRepository.getUserAsync(channel.name)
        generalSettings = await self.__generalSettingsRepository.getAllAsync()

        if msgId == 'raid':
            await self.__raidLogEvent.handleEvent(
                twitchChannel = channel,
                twitchUser = twitchUser,
                tags = tags
            )

            await self.__raidThankEvent.handleEvent(
                twitchChannel = channel,
                twitchUser = twitchUser,
                tags = tags
            )
        elif msgId == 'subgift' or msgId == 'anonsubgift':
            await self.__subGiftThankingEvent.handleEvent(
                twitchChannel = channel,
                twitchUser = twitchUser,
                tags = tags
            )
        elif generalSettings.isDebugLoggingEnabled():
            self.__timber.log('CynanBot', f'event_raw_usernotice(): {tags}')
Esempio n. 4
0
    def __createUsers(self, jsonContents: Dict[str, Any]) -> List[User]:
        if not utils.hasItems(jsonContents):
            raise ValueError(
                f'jsonContents argument is malformed: \"{jsonContents}\"')

        users: List[User] = list()
        for key in jsonContents:
            user = self.__createUser(key, jsonContents[key])
            users.append(user)

        if not utils.hasItems(users):
            raise RuntimeError(
                f'Unable to read in any users from users repository file: \"{self.__usersFile}\"'
            )

        users.sort(key=lambda user: user.getHandle().lower())
        return users
    def __init__(self, definitions: List[str], word: str):
        if not utils.hasItems(definitions):
            raise ValueError(
                f'definitions argument is malformed: \"{definitions}\"')
        elif not utils.isValidStr(word):
            raise ValueError(f'word argument is malformed: \"{word}\"')

        self.__definitions = definitions
        self.__word = word
Esempio n. 6
0
    async def handlePointRedemption(self, twitchChannel: Channel,
                                    twitchUser: User, redemptionMessage: str,
                                    rewardId: str, userIdThatRedeemed: str,
                                    userNameThatRedeemed: str) -> bool:
        if twitchChannel is None:
            raise ValueError(
                f'twitchChannel argument is malformed: \"{twitchChannel}\"')
        elif twitchUser is None:
            raise ValueError(
                f'twitchUser argument is malformed: \"{twitchUser}\"')
        elif not utils.isValidStr(rewardId):
            raise ValueError(f'rewardId argument is malformed: \"{rewardId}\"')
        elif not utils.isValidStr(userIdThatRedeemed):
            raise ValueError(
                f'userIdThatRedeemed argument is malformed: \"{userIdThatRedeemed}\"'
            )
        elif not utils.isValidStr(userNameThatRedeemed):
            raise ValueError(
                f'userNameThatRedeemed argument is malformed: \"{userNameThatRedeemed}\"'
            )

        if not twitchUser.isPkmnEnabled():
            return False

        splits = utils.getCleanedSplits(redemptionMessage)
        if not utils.hasItems(splits):
            await twitchUtils.safeSend(
                twitchChannel,
                f'⚠ Sorry @{userNameThatRedeemed}, you must specify the exact user name of the person you want to fight'
            )
            return False

        opponentUserName = utils.removePreceedingAt(splits[0])
        generalSettings = await self.__generalSettingsRepository.getAllAsync()
        actionCompleted = False

        if generalSettings.isFuntoonApiEnabled():
            if await self.__funtoonRepository.pkmnBattle(
                    userThatRedeemed=userNameThatRedeemed,
                    userToBattle=opponentUserName,
                    twitchChannel=twitchUser.getHandle()):
                actionCompleted = True

        if not actionCompleted and generalSettings.isFuntoonTwitchChatFallbackEnabled(
        ):
            await twitchUtils.safeSend(
                twitchChannel,
                f'!battle {userNameThatRedeemed} {opponentUserName}')
            actionCompleted = True

        self.__timber.log(
            'PkmnBattleRedemption',
            f'Redeemed pkmn battle for {userNameThatRedeemed}:{userIdThatRedeemed} in {twitchUser.getHandle()}'
        )
        return actionCompleted
Esempio n. 7
0
    def __init__(self, jsonContents: Dict[str, Any], generalSettingsFile: str):
        if not utils.hasItems(jsonContents):
            raise ValueError(
                f'jsonContents argument is malformed: \"{jsonContents}\"')
        elif not utils.isValidStr(generalSettingsFile):
            raise ValueError(
                f'generalSettingsFile argument is malformed: \"{generalSettingsFile}\"'
            )

        self.__jsonContents: Dict[str, Any] = jsonContents
        self.__generalSettingsFile: str = generalSettingsFile
    def __init__(self, jsonContents: Dict[str, Any], authRepositoryFile: str):
        if not utils.hasItems(jsonContents):
            raise ValueError(
                f'jsonContents argument is malformed: \"{jsonContents}\"')
        elif not utils.isValidStr(authRepositoryFile):
            raise ValueError(
                f'authRepositoryFile argument is malformed: \"{authRepositoryFile}\"'
            )

        self.__jsonContents: Dict[str, Any] = jsonContents
        self.__authRepositoryFile: str = authRepositoryFile
    def __init__(
        self,
        commandNames: List[str],
        apiName: str
    ):
        if not utils.hasItems(commandNames):
            raise ValueError(f'commandNames argument is malformed: \"{commandNames}\"')
        elif not utils.isValidStr(apiName):
            raise ValueError(f'apiName argument is malformed: \"{apiName}\"')

        self.__commandNames = commandNames
        self.__apiName = apiName
Esempio n. 10
0
    def getLocalLeaderboard(self, entries: List[CutenessEntry],
                            delimiter: str) -> str:
        if not utils.hasItems(entries):
            raise ValueError(f'entries argument is malformed: \"{entries}\"')
        elif delimiter is None:
            raise ValueError(
                f'delimiter argument is malformed: \"{delimiter}\"')

        entryStrings: List[str] = list()
        for entry in entries:
            entryStrings.append(self.getLocalLeaderboardPlacement(entry))

        return delimiter.join(entryStrings)
    def __getEnName(jsonResponse: Dict) -> str:
        if jsonResponse is None:
            raise ValueError(f'jsonResponse argument is malformed: \"{jsonResponse}\"')

        names = jsonResponse['names']
        if not utils.hasItems(names):
            raise ValueError(f'\"names\" field in JSON response is empty: {jsonResponse}')

        for name in names:
            if name['language']['name'] == 'en':
                return name['name'].capitalize()

        raise RuntimeError(f'can\'t find \"en\" language name in \"names\" field: {names}')
Esempio n. 12
0
    def __init__(self, definitions: List[str], furigana: str, url: str,
                 word: str):
        if not utils.hasItems(definitions):
            raise ValueError(
                f'definitions argument is malformed: \"{definitions}\"')
        elif not utils.isValidUrl(url):
            raise ValueError(f'url argument is malformed: \"{url}\"')
        elif not utils.isValidStr(word):
            raise ValueError(f'word argument is malformed: \"{word}\"')

        self.__definitions = definitions
        self.__furigana = furigana
        self.__url = url
        self.__word = word
Esempio n. 13
0
    def getGlobalSuperTriviaGameControllers(self) -> List[str]:
        gameControllersJson: List[str] = self.__jsonContents.get(
            'superTriviaGameControllers')

        if not utils.hasItems(gameControllersJson):
            return None

        gameControllers: List[str] = list()

        for gameController in gameControllersJson:
            if utils.isValidStr(gameController):
                gameControllers.append(gameController)

        gameControllers.sort(key=lambda gameController: gameController.lower())
        return gameControllers
    def __init__(
        self,
        pokedexId: int,
        pokepediaTypes: Dict[PokepediaGeneration, PokepediaType],
        name: str
    ):
        if not utils.isValidNum(pokedexId):
            raise ValueError(f'pokedexId argument is malformed: \"{pokedexId}\"')
        if not utils.hasItems(pokepediaTypes):
            raise ValueError(f'pokepediaTypes argument is malformed: \"{pokepediaTypes}\"')
        elif not utils.isValidStr(name):
            raise ValueError(f'name argument is malformed: \"{name}\"')

        self.__pokedexId = pokedexId
        self.__pokepediaTypes = pokepediaTypes
        self.__name = name
    def __fetchWotd(self, languageEntry: LanguageEntry) -> Wotd:
        if languageEntry is None:
            raise ValueError(f'languageEntry argument is malformed: \"{languageEntry}\"')

        cacheValue = self.__cache[languageEntry]

        if cacheValue is not None:
            return cacheValue

        print(f'Refreshing Word Of The Day for \"{languageEntry.getApiName()}\"... ({utils.getNowTimeText()})')

        ##############################################################################
        # retrieve word of the day from https://www.transparent.com/word-of-the-day/ #
        ##############################################################################

        rawResponse = None
        try:
            rawResponse = requests.get(
                url = f'https://wotd.transparent.com/rss/{languageEntry.getApiName()}-widget.xml?t=0',
                timeout = utils.getDefaultTimeout()
            )
        except (ConnectionError, HTTPError, MaxRetryError, NewConnectionError, Timeout) as e:
            print(f'Exception occurred when attempting to fetch Word Of The Day for \"{languageEntry.getApiName()}\": {e}')
            raise RuntimeError(f'Exception occurred when attempting to fetch Word Of The Day for \"{languageEntry.getApiName()}\": {e}')

        xmlTree = xmltodict.parse(rawResponse.content)
        if not utils.hasItems(xmlTree):
            print(f'xmlTree for \"{languageEntry.getApiName()}\" is malformed: {xmlTree}')
            raise RuntimeError(f'xmlTree for \"{languageEntry.getApiName()}\" is malformed: {xmlTree}')

        wordsTree = xmlTree['xml']['words']
        word = wordsTree['word']
        definition = wordsTree['translation']
        englishExample = wordsTree.get('enphrase')
        foreignExample = wordsTree.get('fnphrase')
        languageName = wordsTree['langname']
        transliteration = wordsTree.get('wotd:transliteratedWord')

        return Wotd(
            languageEntry = languageEntry,
            word = word,
            definition = definition,
            englishExample = englishExample,
            languageName = languageName,
            foreignExample = foreignExample,
            transliteration = transliteration
        )
Esempio n. 16
0
    def __parseCutenessBoosterPacksFromJson(
            self, jsonList: List[Dict]) -> List[CutenessBoosterPack]:
        if not utils.hasItems(jsonList):
            return None

        cutenessBoosterPacks: List[CutenessBoosterPack] = list()

        for cutenessBoosterPackJson in jsonList:
            cutenessBoosterPacks.append(
                CutenessBoosterPack(
                    amount=utils.getIntFromDict(cutenessBoosterPackJson,
                                                'amount'),
                    rewardId=utils.getStrFromDict(cutenessBoosterPackJson,
                                                  'rewardId')))

        cutenessBoosterPacks.sort(key=lambda pack: pack.getAmount())
        return cutenessBoosterPacks
Esempio n. 17
0
    def __findAndCreateUser(self, handle: str,
                            jsonContents: Dict[str, Any]) -> User:
        if not utils.isValidStr(handle):
            raise ValueError(f'handle argument is malformed: \"{handle}\"')
        elif not utils.hasItems(jsonContents):
            raise ValueError(
                f'jsonContents argument is malformed: \"{jsonContents}\"')

        handle = handle.lower()

        for key in jsonContents:
            if key.lower() == handle:
                return self.__createUser(handle, jsonContents[key])

        raise RuntimeError(
            f'Unable to find user with handle \"{handle}\" in users repository file: \"{self.__usersFile}\"'
        )
Esempio n. 18
0
    def toStr(self,
              includePrices: bool = False,
              inStockProductsOnly: bool = True,
              delimiter: str = ', ') -> str:
        if includePrices is None:
            raise ValueError(
                f'includePrices argument is malformed: \"{includePrices}\"')
        elif inStockProductsOnly is None:
            raise ValueError(
                f'inStockProductsOnly argument is malformed: \"{inStockProductsOnly}\"'
            )
        elif delimiter is None:
            raise ValueError(
                f'delimiter argument is malformed: \"{delimiter}\"')

        if not self.hasProducts():
            return '🍃 Analogue store is empty'

        productStrings = list()
        for product in self.__products:
            if inStockProductsOnly:
                if product.inStock():
                    productStrings.append(
                        product.toStr(includePrice=includePrices,
                                      includeStockInfo=False))
            else:
                productStrings.append(
                    product.toStr(includePrice=includePrices,
                                  includeStockInfo=True))

        if inStockProductsOnly and not utils.hasItems(productStrings):
            return '🍃 Analogue store has nothing in stock'

        productsString = delimiter.join(productStrings)

        if inStockProductsOnly:
            return f'Analogue products in stock: {productsString}'
        else:
            return f'Analogue products: {productsString}'
Esempio n. 19
0
    def __parsePkmnCatchBoosterPacksFromJson(
            self, jsonList: List[Dict]) -> List[PkmnCatchBoosterPack]:
        if not utils.hasItems(jsonList):
            return None

        pkmnCatchBoosterPacks: List[PkmnCatchBoosterPack] = list()

        for pkmnCatchBoosterPackJson in jsonList:
            pkmnCatchTypeStr = utils.getStrFromDict(d=pkmnCatchBoosterPackJson,
                                                    key='catchType',
                                                    fallback='')

            pkmnCatchType: PkmnCatchType = None
            if utils.isValidStr(pkmnCatchTypeStr):
                pkmnCatchType = PkmnCatchType.fromStr(pkmnCatchTypeStr)

            pkmnCatchBoosterPacks.append(
                PkmnCatchBoosterPack(pkmnCatchType=pkmnCatchType,
                                     rewardId=utils.getStrFromDict(
                                         pkmnCatchBoosterPackJson,
                                         'rewardId')))

        return pkmnCatchBoosterPacks
Esempio n. 20
0
 def hasAlerts(self) -> bool:
     return utils.hasItems(self.__alerts)
Esempio n. 21
0
    def __refreshStoreStock(self) -> AnalogueStoreStock:
        print(f'Refreshing Analogue store stock... ({utils.getNowTimeText()})')

        rawResponse = None
        try:
            rawResponse = requests.get(url=self.__storeUrl,
                                       timeout=utils.getDefaultTimeout())
        except (ConnectionError, HTTPError, MaxRetryError, NewConnectionError,
                Timeout) as e:
            print(
                f'Exception occurred when attempting to fetch Analogue store stock: {e}'
            )
            raise RuntimeError(
                f'Exception occurred when attempting to fetch Analogue store stock: {e}'
            )

        htmlTree = html.fromstring(rawResponse.content)
        if htmlTree is None:
            print(f'Analogue store\'s htmlTree is malformed: \"{htmlTree}\"')
            raise ValueError(
                f'Analogue store\'s htmlTree is malformed: \"{htmlTree}\"')

        productTrees = htmlTree.find_class('store_product-header__1rLY-')
        if not utils.hasItems(productTrees):
            print(
                f'Analogue store\'s productTrees list is malformed: \"{productTrees}\"'
            )
            raise ValueError(
                f'Analogue store\'s productTrees list is malformed: \"{productTrees}\"'
            )

        products = list()

        for productTree in productTrees:
            productTrees = productTree.find_class('store_title__3eCzb')
            if productTrees is None or len(productTrees) != 1:
                continue

            nameAndPrice = utils.cleanStr(productTrees[0].text_content())
            if len(nameAndPrice) == 0:
                continue
            elif '8BitDo'.lower() in nameAndPrice.lower():
                # don't show 8BitDo products in the final stock listing
                continue

            name = None
            price = None
            indexOfDollar = nameAndPrice.find('$')

            if indexOfDollar == -1:
                name = utils.cleanStr(nameAndPrice)
            else:
                name = utils.cleanStr(nameAndPrice[0:indexOfDollar])
                price = utils.cleanStr(
                    nameAndPrice[indexOfDollar:len(nameAndPrice)])

            if name[len(name) - 1] == '1':
                name = name[0:len(name) - 1]

            productType = AnalogueProductType.fromStr(name)

            inStock = True
            outOfStockElement = productTree.find_class(
                'button_Disabled__2CEbR')
            if utils.hasItems(outOfStockElement):
                inStock = False

            products.append(
                AnalogueStoreEntry(productType=productType,
                                   inStock=inStock,
                                   name=name,
                                   price=price))

        return AnalogueStoreStock(products=products)
Esempio n. 22
0
 def hasProducts(self) -> bool:
     return utils.hasItems(self.__products)
Esempio n. 23
0
    def search(self, query: str) -> JishoResult:
        if not utils.isValidStr(query):
            raise ValueError(f'query argument is malformed: \"{query}\"')

        query = query.strip()
        print(f'Looking up \"{query}\"... ({utils.getNowTimeText()})')

        encodedQuery = urllib.parse.quote(query)
        requestUrl = f'https://jisho.org/search/{encodedQuery}'

        rawResponse = None
        try:
            rawResponse = requests.get(url=requestUrl,
                                       timeout=utils.getDefaultTimeout())
        except (ConnectionError, HTTPError, MaxRetryError, NewConnectionError,
                Timeout) as e:
            print(
                f'Exception occurred when attempting to search Jisho for \"{query}\": {e}'
            )
            raise RuntimeError(
                f'Exception occurred when attempting to search Jisho for \"{query}\": {e}'
            )

        htmlTree = html.fromstring(rawResponse.content)
        if htmlTree is None:
            print(
                f'Exception occurred when attempting to decode Jisho\'s response for \"{query}\" into HTML tree'
            )
            raise RuntimeError(
                f'Exception occurred when attempting to decode Jisho\'s response for \"{query}\" into HTML tree'
            )

        parentElements = htmlTree.find_class('concept_light-representation')
        if not utils.hasItems(parentElements):
            print(
                f'Exception occurred when attempting to find parent elements in Jisho\'s HTML tree in query for \"{query}\"'
            )
            raise ValueError(
                f'Exception occurred when attempting to find parent elements in Jisho\'s HTML tree in query for \"{query}\"'
            )

        textElements = parentElements[0].find_class('text')
        if textElements is None or len(textElements) != 1:
            print(
                f'Exception occurred when attempting to find text elements in Jisho\'s HTML tree in query for \"{query}\"'
            )
            raise ValueError(
                f'Exception occurred when attempting to find text elements in Jisho\'s HTML tree in query for \"{query}\"'
            )

        word = utils.cleanStr(textElements[0].text_content())
        if not utils.isValidStr(word):
            print(
                f'Exception occurred when checking that Jisho\'s word is valid in query for \"{query}\"'
            )
            raise ValueError(
                f'Exception occurred when checking that Jisho\'s word is valid in query for \"{query}\"'
            )

        definitionElements = htmlTree.find_class('meaning-meaning')
        if not utils.hasItems(definitionElements):
            print(
                f'Exception occurred when attempting to find definition elements in Jisho\'s HTML tree in query for \"{query}\"'
            )
            raise ValueError(
                f'Exception occurred when attempting to find definition elements in Jisho\'s HTML tree in query for \"{query}\"'
            )

        definitions = list()

        for definitionElement in definitionElements:
            breakUnitElements = definitionElement.find_class('break-unit')
            if breakUnitElements is None or len(breakUnitElements) != 0:
                continue

            definition = utils.cleanStr(definitionElement.text_content())
            if not utils.isValidStr(definition):
                continue

            number = locale.format_string("%d",
                                          len(definitions) + 1,
                                          grouping=True)
            definitions.append(f'#{number} {definition}')

            if len(definitions) >= self.__definitionsMaxSize:
                # keep from adding tons of definitions
                break

        if not utils.hasItems(definitions):
            print(f'Unable to find any viable definitions for \"{query}\"')
            raise ValueError(
                f'Unable to find any viable definitions for \"{query}\"')

        furigana = None
        furiganaElements = htmlTree.find_class('furigana')
        if utils.hasItems(furiganaElements):
            furigana = utils.cleanStr(furiganaElements[0].text_content())

        return JishoResult(definitions=definitions,
                           furigana=furigana,
                           url=requestUrl,
                           word=word)
    def __init__(self, entries: List[LanguageEntry]):
        if not utils.hasItems(entries):
            raise ValueError(f'entries argument is malformed: \"{entries}\"')

        self.__entries = entries
    def search(self, query: str) -> EnEsDictionaryResult:
        if not utils.isValidStr(query):
            raise ValueError(f'query argument is malformed: \"{query}\"')

        query = query.strip()
        print(f'Looking up \"{query}\"... ({utils.getNowTimeText()})')

        encodedQuery = urllib.parse.quote(query)
        requestUrl = 'https://www.dictionaryapi.com/api/v3/references/spanish/json/{}?key={}'.format(
            encodedQuery, self.__merriamWebsterApiKey)

        rawResponse = None
        try:
            rawResponse = requests.get(url=requestUrl,
                                       timeout=utils.getDefaultTimeout())
        except (ConnectionError, HTTPError, MaxRetryError, NewConnectionError,
                Timeout) as e:
            print(
                f'Exception occurred when attempting to search Merriam Webster for \"{query}\": {e}'
            )
            raise RuntimeError(
                f'Exception occurred when attempting to search Merriam Webster for \"{query}\": {e}'
            )

        jsonResponse = None
        try:
            jsonResponse = rawResponse.json()
        except JSONDecodeError as e:
            print(
                f'Exception occurred when attempting to decode Merriam Webster\'s response into JSON for \"{query}\": {e}'
            )
            raise RuntimeError(
                f'Exception occurred when attempting to decode Merriam Webster\'s response into JSON for \"{query}\": {e}'
            )

        if not utils.hasItems(jsonResponse):
            print(
                f'jsonResponse for \"{query}\" has no definitions: {jsonResponse}'
            )
            raise ValueError(
                f'jsonResponse \"{query}\" has no definitions: {jsonResponse}')

        definitions = list()

        for entry in jsonResponse:
            definition = None

            if isinstance(entry, str):
                definition = entry
            elif not entry['meta'].get('offensive', True) and utils.hasItems(
                    entry['shortdef']):
                definition = entry['shortdef'][0]

            definition = utils.cleanStr(definition)
            if not utils.isValidStr(definition):
                continue

            index = 0
            add = True

            while (index < len(definitions) and add):
                if definitions[index].lower() == definition.lower():
                    add = False

                index = index + 1

            if add:
                number = locale.format_string("%d",
                                              len(definitions) + 1,
                                              grouping=True)
                definitions.append(f'#{number} {definition}')

                if len(definitions) >= self.__definitionsMaxSize:
                    # keep from adding tons of definitions
                    break

        if not utils.hasItems(definitions):
            print(f'Unable to find any viable definitions for \"{query}\"')
            raise ValueError(
                f'Unable to find any viable definitions for \"{query}\"')

        return EnEsDictionaryResult(definitions=definitions, word=query)
Esempio n. 26
0
 def hasConditions(self) -> bool:
     return utils.hasItems(self.__conditions)
Esempio n. 27
0
 def hasTomorrowsConditions(self) -> bool:
     return utils.hasItems(self.__tomorrowsConditions)
Esempio n. 28
0
    async def __getSubscribeReadyPubSubEntries(self) -> List[PubSubEntry]:
        twitchHandles = await self.__twitchTokensRepository.getExpiringTwitchHandles(
        )
        authSnapshot = await self.__authRepository.getAllAsync()
        users: List[User] = None

        if twitchHandles is None:
            # if twitchHandles is None, then we must do a full validate and refresh
            users = await self.__usersRepository.getUsersAsync()
        elif len(twitchHandles) == 0:
            # if twitchHandles is empty, then there is no need to do a validate or refresh of anyone
            return None
        else:
            # if twitchHandles has entries, then we will validate and refresh those specific users
            users = list()

            for twitchHandle in twitchHandles:
                users.append(await
                             self.__usersRepository.getUserAsync(twitchHandle))

        usersAndTwitchTokens: Dict[User, str] = dict()

        for user in users:
            twitchAccessToken = await self.__twitchTokensRepository.getAccessToken(
                user.getHandle())

            if utils.isValidStr(twitchAccessToken):
                usersAndTwitchTokens[user] = twitchAccessToken

        if not utils.hasItems(usersAndTwitchTokens):
            return None

        usersToRemove: List[User] = list()

        for user in usersAndTwitchTokens:
            try:
                await self.__twitchTokensRepository.validateAndRefreshAccessToken(
                    twitchClientId=authSnapshot.requireTwitchClientId(),
                    twitchClientSecret=authSnapshot.requireTwitchClientSecret(
                    ),
                    twitchHandle=user.getHandle())

                usersAndTwitchTokens[
                    user] = await self.__twitchTokensRepository.getAccessToken(
                        user.getHandle())
            except (TwitchAccessTokenMissingException,
                    TwitchExpiresInMissingException, TwitchJsonException,
                    TwitchNetworkException,
                    TwitchRefreshTokenMissingException) as e:
                # if we run into this error, that most likely means that this user changed
                # their password
                usersToRemove.append(user)
                self.__timber.log(
                    'CynanBot',
                    f'Failed to validate and refresh access Twitch token for {user.getHandle()}: {e}'
                )

        if utils.hasItems(usersToRemove):
            for user in usersToRemove:
                del usersAndTwitchTokens[user]

        pubSubEntries: List[PubSubEntry] = list()

        for user in usersAndTwitchTokens:
            twitchAccessToken = usersAndTwitchTokens[user]

            userId = await self.__userIdsRepository.fetchUserIdAsInt(
                userName=user.getHandle(),
                twitchAccessToken=twitchAccessToken,
                twitchClientId=authSnapshot.requireTwitchClientId())

            pubSubEntries.append(
                PubSubEntry(
                    userId=userId,
                    userName=user.getHandle().lower(),
                    topic=pubsub.channel_points(twitchAccessToken)[userId]))

        return pubSubEntries