예제 #1
0
    def getSuperTriviaCorrectAnswerReveal(
        self,
        question: AbsTriviaQuestion,
        newCuteness: CutenessResult,
        multiplier: int,
        points: int,
        userName: str,
        delimiter: str = '; '
    ) -> str:
        if question is None:
            raise ValueError(f'question argument is malformed: \"{question}\"')
        elif newCuteness is None:
            raise ValueError(f'newCuteness argument is malformed: \"{newCuteness}\"')
        elif not utils.isValidNum(multiplier):
            raise ValueError(f'multiplier argument is malformed: \"{multiplier}\"')
        elif not utils.isValidNum(points):
            raise ValueError(f'points argument is malformed: \"{points}\"')
        elif not utils.isValidStr(userName):
            raise ValueError(f'userName argument is malformed: \"{userName}\"')
        elif delimiter is None:
            raise ValueError(f'delimiter argument is malformed: \"{delimiter}\"')

        pointsStr = locale.format_string("%d", points, grouping = True)
        multiplierStr = locale.format_string("%d", multiplier, grouping = True)
        prefix = f'{question.getEmote()} CONGRATULATIONS @{userName}, that\'s correct!'
        infix = f'You earned {pointsStr} cuteness ({multiplierStr}x multiplier), so your new cuteness is {newCuteness.getCutenessStr()}.'

        correctAnswers = question.getCorrectAnswers()

        if len(correctAnswers) == 1:
            return f'{prefix} 🎉 {infix} ✨ The correct answer was: {correctAnswers[0]}'
        else:
            correctAnswersStr = delimiter.join(correctAnswers)
            return f'{prefix} 🎉 {infix} ✨ The correct answers were: {correctAnswersStr}'
예제 #2
0
    def __init__(self, airQuality: int, humidity: int, pressure: int,
                 temperature: float, tomorrowsHighTemperature: float,
                 tomorrowsLowTemperature: float, alerts: List[str],
                 conditions: List[str], tomorrowsConditions: List[str]):
        if not utils.isValidNum(humidity):
            raise ValueError(f'humidity argument is malformed: \"{humidity}\"')
        elif not utils.isValidNum(pressure):
            raise ValueError(f'pressure argument is malformed: \"{pressure}\"')
        elif not utils.isValidNum(temperature):
            raise ValueError(
                f'temperature argument is malformed: \"{temperature}\"')
        elif not utils.isValidNum(tomorrowsHighTemperature):
            raise ValueError(
                f'tomorrowsHighTemperature argument is malformed: \"{tomorrowsHighTemperature}\"'
            )
        elif not utils.isValidNum(tomorrowsLowTemperature):
            raise ValueError(
                f'tomorrowsLowTemperature argument is malformed: \"{tomorrowsLowTemperature}\"'
            )

        self.__airQuality = airQuality
        self.__humidity = humidity
        self.__pressure = pressure
        self.__temperature = temperature
        self.__tomorrowsHighTemperature = tomorrowsHighTemperature
        self.__tomorrowsLowTemperature = tomorrowsLowTemperature
        self.__alerts = alerts
        self.__conditions = conditions
        self.__tomorrowsConditions = tomorrowsConditions
예제 #3
0
async def safeSend(
    messageable: Messageable,
    message: str,
    perMessageMaxSize: int = 450,
    maxMessages: int = 3
):
    if messageable is None:
        raise ValueError(f'messageable argument is malformed: \"{messageable}\"')
    elif not utils.isValidNum(perMessageMaxSize):
        raise ValueError(f'perMessageMaxSize argument is malformed: \"{perMessageMaxSize}\"')
    elif perMessageMaxSize < 300:
        raise ValueError(f'perMessageMaxSize is too small: {perMessageMaxSize}')
    elif perMessageMaxSize >= getMaxMessageSize():
        raise ValueError(f'perMessageMaxSize is too big: {perMessageMaxSize} (max size is {getMaxMessageSize()})')
    elif not utils.isValidNum(maxMessages):
        raise ValueError(f'maxMessages argument is malformed: \"{maxMessages}\"')
    elif maxMessages < 1 or maxMessages > 5:
        raise ValueError(f'maxMessages is out of bounds: {maxMessages}')

    if not utils.isValidStr(message):
        return

    if len(message) < getMaxMessageSize():
        await messageable.send(message)
        return

    messages: List[str] = list()
    messages.append(message)

    index: int = 0

    while index < len(messages):
        m: str = messages[index]

        if len(m) >= getMaxMessageSize():
            spaceIndex = m.rfind(' ')

            while spaceIndex >= perMessageMaxSize:
                spaceIndex = m[0:spaceIndex].rfind(' ')

            if spaceIndex == -1:
                raise RuntimeError(f'This message is insane and can\'t be sent (len is {len(message)}):\n{message}')

            messages[index] = m[0:spaceIndex].strip()
            messages.append(m[spaceIndex:len(m)].strip())

        index = index + 1

    if len(messages) > maxMessages:
        raise RuntimeError(f'This message is too long and won\'t be sent (len is {len(message)}):\n{message}')

    for m in messages:
        await messageable.send(m)
예제 #4
0
async def waitThenSend(
    messageable: Messageable,
    delaySeconds: int,
    message: str,
    heartbeat = lambda: True,
    beforeSend = lambda: None,
    afterSend = lambda: None
):
    if messageable is None:
        raise ValueError(f'messageable argument is malformed: \"{messageable}\"')
    elif not utils.isValidNum(delaySeconds):
        raise ValueError(f'delaySeconds argument is malformed: \"{delaySeconds}\"')
    elif delaySeconds < 1:
        raise ValueError(f'delaySeconds argument is out of bounds: \"{delaySeconds}\"')
    elif not utils.isValidStr(message):
        return
    elif heartbeat is None:
        raise ValueError(f'heartbeat argument is malformed: \"{heartbeat}\"')

    await asyncio.sleep(delaySeconds)

    if heartbeat():
        beforeSend()
        await safeSend(messageable, message)
        afterSend()
예제 #5
0
    def __init__(self, definitionsMaxSize: int = 3):
        if not utils.isValidNum(definitionsMaxSize) or definitionsMaxSize < 1:
            raise ValueError(
                f'definitionsMaxSize argument is malformed: \"{definitionsMaxSize}\"'
            )

        self.__definitionsMaxSize = definitionsMaxSize
예제 #6
0
    def __init__(self,
                 eventLoop: AbstractEventLoop,
                 client: Client,
                 port: int,
                 webhookSecret: str,
                 timber: Timber,
                 callbackRoute: str = '/callback'):
        if eventLoop is None:
            raise ValueError(
                f'eventLoop argument is malformed: \"{eventLoop}\"')
        elif client is None:
            raise ValueError(f'client argument is malformed: \"{client}\"')
        elif not utils.isValidNum(port):
            raise ValueError(f'port argument is malformed: \"{port}\"')
        elif port <= 100:
            raise ValueError(f'port argument is out of bounds: {port}')
        elif not utils.isValidStr(webhookSecret):
            raise ValueError(
                f'webhookSecret argument is malformed: \"{webhookSecret}\"')
        elif timber is None:
            raise ValueError(f'timber argument is malformed: \"{timber}\"')
        elif not utils.isValidStr(callbackRoute):
            raise ValueError(
                f'callbackRoute argument is malformed: \"{callbackRoute}\"')

        self.__eventLoop: AbstractEventLoop = eventLoop
        self.__port: int = port
        self.__timber: Timber = timber

        self.__isStarted: bool = False
        self.__eventSubClient: EventSubClient = EventSubClient(
            client=client,
            webhook_secret=webhookSecret,
            callback_route=callbackRoute)
예제 #7
0
    def __init__(self, latitude: float, longitude: float, locationId: str,
                 name: str, timeZone: tzinfo):
        if not utils.isValidNum(latitude):
            raise ValueError(f'latitude argument is malformed: \"{latitude}\"')
        elif not utils.isValidNum(longitude):
            raise ValueError(
                f'longitude argument is malformed: \"{longitude}\"')
        elif not utils.isValidStr(locationId):
            raise ValueError(f'id_ argument is malformed: \"{locationId}\"')
        elif not utils.isValidStr(name):
            raise ValueError(f'name argument is malformed: \"{name}\"')
        elif timeZone is None:
            raise ValueError(f'timeZone argument is malformed: \"{timeZone}\"')

        self.__latitude = latitude
        self.__longitude = longitude
        self.__locationId = locationId
        self.__name = name
        self.__timeZone = timeZone
예제 #8
0
    def __init__(self, userId: int, userName: str, topic: Topic):
        if not utils.isValidNum(userId):
            raise ValueError(f'userId argument is malformed: \"{userId}\"')
        elif not utils.isValidStr(userName):
            raise ValueError(f'userName argument is malformed: \"{userName}\"')
        elif topic is None:
            raise ValueError(f'topic argument is malformed: \"{topic}\"')

        self.__userId: int = userId
        self.__userName: str = userName
        self.__topic: Topic = topic
예제 #9
0
    def __init__(self, merriamWebsterApiKey: str, definitionsMaxSize: int = 3):
        if not utils.isValidStr(merriamWebsterApiKey):
            raise ValueError(
                f'merriamWebsterApiKey argument is malformed: \"{merriamWebsterApiKey}\"'
            )
        elif not utils.isValidNum(
                definitionsMaxSize) or definitionsMaxSize < 1:
            raise ValueError(
                f'definitionsMaxSize argument is malformed: \"{definitionsMaxSize}\"'
            )

        self.__definitionsMaxSize = definitionsMaxSize
        self.__merriamWebsterApiKey = merriamWebsterApiKey
예제 #10
0
    def getTriviaGameQuestionPrompt(
        self,
        triviaQuestion: AbsTriviaQuestion,
        delaySeconds: int,
        points: int,
        userNameThatRedeemed: str,
        delimiter: str = ' '
    ) -> str:
        if triviaQuestion is None:
            raise ValueError(f'triviaQuestion argument is malformed: \"{triviaQuestion}\"')
        elif not utils.isValidNum(delaySeconds):
            raise ValueError(f'delaySeconds argument is malformed: \"{delaySeconds}\"')
        elif delaySeconds < 1:
            raise ValueError(f'delaySeconds argument is out of bounds: {delaySeconds}')
        elif not utils.isValidNum(points):
            raise ValueError(f'points argument is malformed: \"{points}\"')
        elif points < 1:
            raise ValueError(f'points argument is out of bounds: {points}')
        elif delimiter is None:
            raise ValueError(f'delimiter argument is malformed: \"{delimiter}\"')

        triviaEmote = triviaQuestion.getEmote()
        delaySecondsStr = locale.format_string("%d", delaySeconds, grouping = True)
        pointsStr = locale.format_string("%d", points, grouping = True)

        pointsPlurality: str = None
        if points == 1:
            pointsPlurality = 'point'
        else:
            pointsPlurality = 'points'

        questionPrompt: str = None
        if triviaQuestion.getTriviaType() is TriviaType.QUESTION_ANSWER and triviaQuestion.hasCategory():
            questionPrompt = f'(category is \"{triviaQuestion.getCategory()}\") — {triviaQuestion.getQuestion()}'
        else:
            questionPrompt = f'— {triviaQuestion.getPrompt(delimiter)}'

        return f'{triviaEmote} @{userNameThatRedeemed} !answer in {delaySecondsStr}s for {pointsStr} {pointsPlurality} {questionPrompt}'
예제 #11
0
    def getSuperTriviaQuestionPrompt(
        self,
        triviaQuestion: AbsTriviaQuestion,
        delaySeconds: int,
        points: int,
        multiplier: int,
        delimiter: str = ' '
    ) -> str:
        if triviaQuestion is None:
            raise ValueError(f'triviaQuestion argument is malformed: \"{triviaQuestion}\"')
        elif not utils.isValidNum(delaySeconds):
            raise ValueError(f'delaySeconds argument is malformed: \"{delaySeconds}\"')
        elif delaySeconds < 1:
            raise ValueError(f'delaySeconds argument is out of bounds: {delaySeconds}')
        elif not utils.isValidNum(points):
            raise ValueError(f'points argument is malformed: \"{points}\"')
        elif points < 1:
            raise ValueError(f'points argument is out of bounds: {points}')
        elif not utils.isValidNum(multiplier):
            raise ValueError(f'multiplier argument is malformed: \"{multiplier}\"')
        elif multiplier < 1:
            raise ValueError(f'multiplier argument is out of bounds: {multiplier}')
        elif delimiter is None:
            raise ValueError(f'delimiter argument is malformed: \"{delimiter}\"')

        triviaEmote = triviaQuestion.getEmote()
        delaySecondsStr = locale.format_string("%d", delaySeconds, grouping = True)
        pointsStr = locale.format_string("%d", points, grouping = True)
        multiplierStr = locale.format_string("%d", multiplier, grouping = True)

        questionPrompt: str = None
        if triviaQuestion.getTriviaType() is TriviaType.QUESTION_ANSWER and triviaQuestion.hasCategory():
            questionPrompt = f'— category is {triviaQuestion.getCategory()} — {triviaQuestion.getQuestion()}'
        else:
            questionPrompt = f'— {triviaQuestion.getPrompt(delimiter)}'

        return f'{triviaEmote} EVERYONE can play! !superanswer in {delaySecondsStr}s for {pointsStr} points ({multiplierStr}x multiplier ✨) {questionPrompt}'
    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
예제 #13
0
    def getSuperTriviaOutOfTimeAnswerReveal(
        self,
        question: AbsTriviaQuestion,
        multiplier: int,
        delimiter: str = '; '
    ) -> str:
        if question is None:
            raise ValueError(f'question argument is malformed: \"{question}\"')
        elif not utils.isValidNum(multiplier):
            raise ValueError(f'multiplier argument is malformed: \"{multiplier}\"')
        elif delimiter is None:
            raise ValueError(f'delimiter argument is malformed: \"{delimiter}\"')

        multiplierStr = locale.format_string("%d", multiplier, grouping = True)
        prefix = f'{question.getEmote()} Sorry everyone, y\'all are out of time… {utils.getRandomSadEmoji()} Goodbye {multiplierStr}x multiplier 👋…'
        correctAnswers = question.getCorrectAnswers()

        if len(correctAnswers) == 1:
            return f'{prefix} The correct answer is: {correctAnswers[0]}'
        else:
            correctAnswersStr = delimiter.join(correctAnswers)
            return f'{prefix} The correct answers are: {correctAnswersStr}'
예제 #14
0
 def hasAirQuality(self) -> bool:
     return utils.isValidNum(self.__airQuality)
예제 #15
0
    def __init__(self,
                 eventLoop: AbstractEventLoop,
                 authRepository: AuthRepository,
                 client: Client,
                 generalSettingsRepository: GeneralSettingsRepository,
                 timber: Timber,
                 twitchTokensRepository: TwitchTokensRepository,
                 userIdsRepository: UserIdsRepository,
                 usersRepository: UsersRepository,
                 maxConnectionsPerTwitchChannel: int = 8):
        if eventLoop is None:
            raise ValueError(
                f'eventLoop argument is malformed: \"{eventLoop}\"')
        elif authRepository is None:
            raise ValueError(
                f'authRepository argument is malformed: \"{authRepository}\"')
        elif client is None:
            raise ValueError(f'client argument is malformed: \"{client}\"')
        elif generalSettingsRepository is None:
            raise ValueError(
                f'generalSettingsRepository argument is malformed: \"{generalSettingsRepository}\"'
            )
        elif timber is None:
            raise ValueError(f'timber argument is malformed: \"{timber}\"')
        elif twitchTokensRepository is None:
            raise ValueError(
                f'twitchTokensRepository argument is malformed: \"{twitchTokensRepository}\"'
            )
        elif userIdsRepository is None:
            raise ValueError(
                f'userIdsRepository argument is malformed: \"{userIdsRepository}\"'
            )
        elif usersRepository is None:
            raise ValueError(
                f'usersRepository argument is malformed: \"{usersRepository}\"'
            )
        elif not utils.isValidNum(maxConnectionsPerTwitchChannel):
            raise ValueError(
                f'maxConnectionsPerTwitchChannel argument is malformed: \"{maxConnectionsPerTwitchChannel}\"'
            )
        elif maxConnectionsPerTwitchChannel < 2 or maxConnectionsPerTwitchChannel > 16:
            raise ValueError(
                f'maxConnectionsPerTwitchChannel argument is out of bounds: {maxConnectionsPerTwitchChannel}'
            )

        self.__eventLoop: AbstractEventLoop = eventLoop
        self.__authRepository: AuthRepository = authRepository
        self.__generalSettingsRepository: GeneralSettingsRepository = generalSettingsRepository
        self.__timber: Timber = timber
        self.__twitchTokensRepository: TwitchTokensRepository = twitchTokensRepository
        self.__userIdsRepository: UserIdsRepository = userIdsRepository
        self.__usersRepository: UsersRepository = usersRepository

        self.__isManagingPubSub: bool = False
        self.__isStarted: bool = False
        self.__pubSubEntries: Dict[str, SimpleQueue[Topic]] = defaultdict(
            lambda: SimpleQueue())
        self.__maxConnectionsPerTwitchChannel: int = maxConnectionsPerTwitchChannel

        self.__pubSubPool: PubSubPool = PubSubPool(
            client=client,
            max_pool_size=max(32, maxConnectionsPerTwitchChannel * 4),
            max_connection_topics=max(128,
                                      maxConnectionsPerTwitchChannel * 16))