Beispiel #1
0
    def uptime(self):
        """
        Returns a TimeDelta for how long the stream was online, or is online.
        """

        if self.ended is False:
            return utils.now() - self.stream_start

        return self.stream_end - self.stream_start
Beispiel #2
0
    def refresh_stream_status_stage2(self, status: Optional[UserStream]):
        redis = RedisManager.get()
        key_prefix = self.bot.streamer + ":"

        # Default data we want to update in case the stream is offline
        stream_data = {
            f"{key_prefix}online": "False",
            f"{key_prefix}viewers": 0,
        }
        self.num_viewers = 0

        if status:
            # Update stream_data with fresh online data
            stream_data[f"{key_prefix}online"] = "True"
            stream_data[f"{key_prefix}viewers"] = status.viewer_count

            game_info: Optional[
                TwitchGame] = self.bot.twitch_helix_api.get_game_by_game_id(
                    status.game_id)
            game_name: str = ""
            if game_info is not None:
                game_name = game_info.name

            stream_data[f"{key_prefix}game"] = game_name

            self.num_viewers = status.viewer_count
            self.game = game_name
            self.title = status.title

            self.num_offlines = 0
            self.first_offline = None

            # Update stream chunk data
            if self.current_stream is None:
                self.create_stream(status)
            if self.current_stream_chunk is None:
                self.create_stream_chunk(status)
            if self.current_stream_chunk is not None:
                if self.current_stream_chunk.broadcast_id != status.id:
                    log.debug(
                        f"Detected a new chunk! {self.current_stream_chunk.broadcast_id} != {status.id}"
                    )
                    self.create_stream_chunk(status)
        else:
            # stream reported as offline
            if self.online is True:
                # but we have stream marked as online.. begin the countdown
                self.num_offlines += 1
                log.info(f"Offline. {self.num_offlines}")
                if self.first_offline is None:
                    self.first_offline = utils.now()

                if self.num_offlines >= self.NUM_OFFLINES_REQUIRED:
                    log.info("Switching to offline state!")
                    self.go_offline()

        redis.hmset("stream_data", stream_data)
Beispiel #3
0
    def roulette(self, **options):
        if self.settings["only_roulette_after_sub"]:
            if self.last_sub is None:
                return False
            if utils.now() - self.last_sub > datetime.timedelta(
                    seconds=self.settings["after_sub_roulette_time"]):
                return False

        message = options["message"]
        user = options["source"]
        bot = options["bot"]

        if message:
            bot.whisper(
                user.username,
                "The command is only !roulette and it wagers all your points SmileyFace"
            )
            return False

        try:
            bet = pajbot.utils.parse_points_amount(user, "all")
        except pajbot.exc.InvalidPointAmount as e:
            bot.whisper(user.username, str(e))
            return False

        if bet < 500:
            bot.whisper(user.username,
                        "You can only roulette for 500+ points FeelsWeirdMan")
            return False

        # Calculating the result
        result = self.rigged_random_result()

        points = bet if result else -bet
        user.points += points

        with DBManager.create_session_scope() as db_session:
            r = Roulette(user.id, points)
            db_session.add(r)

        arguments = {
            "bet": bet,
            "user": user.username_raw,
            "points": user.points_available()
        }

        if points > 0:
            out_message = self.get_phrase("message_won", **arguments)
        else:
            out_message = self.get_phrase("message_lost", **arguments)

        if user.subscriber:
            bot.me(out_message)
        else:
            bot.whisper(user.username, out_message)

        HandlerManager.trigger("on_roulette_finish", user=user, points=points)
Beispiel #4
0
def _filter_time_until_dt(var: Any, args: List[str]) -> Any:
    try:
        ts = utils.time_since(var.timestamp(), utils.now().timestamp())
        if ts:
            return ts

        return "0 seconds"
    except:
        return "never FeelsBadMan ?"
Beispiel #5
0
    def execute_now(method, args=[], kwargs={}, scheduler=None):
        if scheduler is None:
            scheduler = ScheduleManager.base_scheduler

        if scheduler is None:
            raise ValueError("No scheduler available")

        job = scheduler.add_job(method, "date", run_date=utils.now(), args=args, kwargs=kwargs)
        return ScheduledJob(job)
Beispiel #6
0
def _filter_time_since_dt(var, args):
    try:
        ts = utils.time_since(utils.now().timestamp(), var.timestamp())
        if ts:
            return ts

        return "0 seconds"
    except:
        return "never FeelsBadMan ?"
Beispiel #7
0
 def _seek(self, _time, current_song_webjsonify):
     self.bot.songrequest_websocket_manager.emit(
         "play", {
             "current_song": current_song_webjsonify,
             "current_timestamp": str(utils.now().timestamp())
         })
     self.bot.websocket_manager.emit("songrequest_seek", WIDGET_ID,
                                     {"seek_time": _time})
     self.module_state["paused"] = True
     self._module_state()
Beispiel #8
0
    def on_tick(self, **rest):
        if self.output_buffer == "":
            return

        if self.last_add is None:
            return

        diff = utils.now() - self.last_add

        if diff.seconds > 3:
            self.flush_output_buffer()
Beispiel #9
0
    def execute_delayed(delay, method, args=[], kwargs={}, scheduler=None):
        if scheduler is None:
            scheduler = ScheduleManager.base_scheduler

        if scheduler is None:
            raise ValueError("No scheduler available")

        job = scheduler.add_job(
            method, "date", run_date=utils.now() + datetime.timedelta(seconds=delay), args=args, kwargs=kwargs
        )
        return ScheduledJob(job)
Beispiel #10
0
    def on_message(self, source, message, whisper, **rest):
        sendMessage = ""
        if message is None or whisper or source.ignored:
            return

        if self.question:
            right_answer = self.question["answer"].lower()
            user_answer = message.lower()
            if len(right_answer) <= 5:
                correct = right_answer == user_answer
            else:
                ratio = Levenshtein.ratio(right_answer, user_answer)
                correct = ratio >= 0.86

            if correct:
                if self.point_bounty > 0:
                    sendMessage = "{} got the answer right! The answer was {} FeelsGoodMan They get {} points! PogChamp".format(
                        source.username_raw, self.question["answer"],
                        self.point_bounty)
                    source.points += self.point_bounty
                else:
                    sendMessage = "{} got the answer right! The answer was {} FeelsGoodMan".format(
                        source.username_raw, self.question["answer"])

                self.question = None
                self.step = 0
                self.last_question = utils.now()
                self.correct_dict[source.username_raw] = self.correct_dict.get(
                    source.username_raw, 0) + 1

                if "strep" in source.username_raw:
                    self.streptocuckus += 1
                    if self.streptocuckus == 6:
                        self.bot.say(
                            "streptocarcus you gotta stop. you've been answering trivia almost every hour for the past "
                            "few weeks. i know it's hard waiting for the next question but this trivia addiction is going "
                            "to destroy you. please, streptocarcus. its for your own good."
                        )
                        self.streptocuckus = 0

                # record winstreak of correct answers for user

                if source.username_raw != self.winstreak[0]:
                    self.winstreak = [source.username_raw, 1]
                else:
                    self.winstreak[1] += 1
                    if self.winstreak[1] >= 7:
                        sendMessage += " {} is on a {} question streak. Get a life FeelsWeirdMan".format(
                            *self.winstreak)
                    elif self.winstreak[1] >= self.min_streak:
                        sendMessage += " {} is on a streak of {} correct answers Pog".format(
                            *self.winstreak)

                self.bot.safe_me(sendMessage)
Beispiel #11
0
    def lost(self, points_lost):
        self.duels_total += 1
        self.points_lost += points_lost
        self.last_duel = utils.now()

        if self.current_streak < 0:
            self.current_streak -= 1
        else:
            self.current_streak = -1
        if abs(self.current_streak) > self.longest_losestreak:
            self.longest_losestreak = self.current_streak
Beispiel #12
0
    def shared_end_predict(bot, source, type):
        with DBManager.create_session_scope() as db_session:
            # Check if there is a non-ended, but closed prediction run we can end
            predictions = db_session.query(PredictionRun).filter_by(ended=None, open=False, type=type).all()
            if len(predictions) == 0:
                bot.say(f"{source}, There is no closed prediction runs we can end right now.")
                return True

            for prediction in predictions:
                prediction.ended = utils.now()
            bot.say(f"Closed predictions with IDs {', '.join([str(p.id) for p in predictions])}")
Beispiel #13
0
 def request(self, method, endpoint, params, headers, authorization=None, json=None):
     try:
         return super().request(method, endpoint, params, headers, authorization, json)
     except HTTPError as e:
         if e.response.status_code == 429:
             # retry once after rate limit resets...
             rate_limit_reset = datetime.fromtimestamp(int(e.response.headers["Ratelimit-Reset"]), tz=timezone.utc)
             time_to_wait = rate_limit_reset - utils.now()
             time.sleep(math.ceil(time_to_wait.total_seconds()))
             return super().request(method, endpoint, params, headers, authorization, json)
         else:
             raise e
Beispiel #14
0
 def step_end(self):
     if self.question is not None:
         self.winstreak = [None, None]
         self.bot.safe_me(
             'MingLee No one could answer the trivia! The answer was "{}" MingLee Since you\'re all useless, DatGuy gets one point.'
             .format(self.question["answer"]))
         self.question = None
         self.step = 0
         self.last_question = utils.now()
         with DBManager.create_session_scope() as db_session:
             user = self.bot.users.find("datguy1", db_session=db_session)
             user.points += 1
Beispiel #15
0
    def won(self, points_won):
        self.duels_won += 1
        self.duels_total += 1
        self.points_won += points_won
        self.last_duel = utils.now()

        if self.current_streak > 0:
            self.current_streak += 1
        else:
            self.current_streak = 1
        if self.current_streak > self.longest_winstreak:
            self.longest_winstreak = self.current_streak
Beispiel #16
0
 def _create(db_session, stream_id, video_id, requested_by_id,
             skipped_by_id, skip_after):
     songrequesthistory = SongrequestHistory(
         stream_id=stream_id,
         video_id=video_id,
         date_finished=utils.now(),
         requested_by_id=requested_by_id,
         skipped_by_id=skipped_by_id,
         skip_after=skip_after,
     )
     db_session.add(songrequesthistory)
     return songrequesthistory
Beispiel #17
0
    def __init__(self, stream_id, youtube_id, **options):
        self.id = None
        self.stream_id = stream_id
        self.user_id = options.get("user_id", None)
        self.youtube_id = youtube_id
        self.date_added = utils.now()
        self.date_played = None
        self.skip_after = options.get("skip_after", None)

        if self.skip_after is not None and self.skip_after < 0:
            # Make sure skip_after cannot be a negative number
            self.skip_after = None
Beispiel #18
0
 def _play(self, video_id, current_song_webjsonify):
     self.bot.songrequest_websocket_manager.emit(
         "play", {
             "current_song": current_song_webjsonify,
             "current_timestamp": str(utils.now().timestamp())
         })
     self.bot.websocket_manager.emit("songrequest_play", WIDGET_ID,
                                     {"video_id": video_id})
     self.module_state["paused"] = True
     self._module_state()
     if self.module_state["video_showing"]:
         self._show()
Beispiel #19
0
 def step_end(self):
     if self.question is not None:
         self.winstreak = 0
         self.bot.safe_me(
             f'MingLee No one could answer the trivia! The answer was "{self.question["answer"]}" MingLee'
         )
         self.question = None
         self.step = 0
         self.last_question = utils.now()
         with DBManager.create_session_scope() as db_session:
             user = User.find_by_user_input(db_session, "datguy1")
             user.points = user.points + 1
Beispiel #20
0
 def __init__(
         self,
         user_id,
         timeout_start,
         timeout_end,
         timeout_author,
         timeout_recent_end=(utils.now() + datetime.timedelta(days=14)),
 ):
     self.user_id = user_id
     self.timeout_start = timeout_start
     self.timeout_recent_end = timeout_recent_end
     self.timeout_end = timeout_end
     self.timeout_author = timeout_author
Beispiel #21
0
    def execute_now(method, args=[], kwargs={}, scheduler=None):
        if scheduler is None:
            scheduler = ScheduleManager.base_scheduler

        if scheduler is None:
            return ScheduledJob(None)

        job = scheduler.add_job(method,
                                "date",
                                run_date=utils.now(),
                                args=args,
                                kwargs=kwargs)
        return ScheduledJob(job)
Beispiel #22
0
    def command_close(self, **options):
        bot = options["bot"]

        self.last_game_start = utils.now() - datetime.timedelta(seconds=10)

        for username in self.bets:
            _, points = self.bets[username]
            user = self.bot.users[username]
            user.remove_debt(points)
            bot.whisper(
                username,
                "Your HS bet of {} points has been refunded because the bet has been cancelled.".format(points),
            )
        self.bets = {}
Beispiel #23
0
    def refresh_video_url_stage2(self, data):
        if self.online is False:
            return

        if self.current_stream_chunk is None or self.current_stream is None:
            return

        log.info(
            f"Attempting to fetch video url for broadcast {self.current_stream_chunk.broadcast_id}"
        )
        video_url, video_preview_image_url, video_recorded_at = self.fetch_video_url_stage2(
            data)

        if video_url is None:
            log.info("No video for broadcast found")
            return

        log.info(f"Successfully fetched a video url: {video_url}")
        if self.current_stream_chunk is None or self.current_stream_chunk.video_url is None:
            with DBManager.create_session_scope(
                    expire_on_commit=False) as db_session:
                self.current_stream_chunk.video_url = video_url
                self.current_stream_chunk.video_preview_image_url = video_preview_image_url

                db_session.add(self.current_stream_chunk)

                db_session.commit()

                db_session.expunge_all()
            log.info("Successfully commited video url data.")
        elif self.current_stream_chunk.video_url != video_url:
            # End current stream chunk
            self.current_stream_chunk.chunk_end = utils.now()
            DBManager.session_add_expunge(self.current_stream_chunk)

            with DBManager.create_session_scope(
                    expire_on_commit=False) as db_session:
                stream_chunk = StreamChunk(
                    self.current_stream,
                    self.current_stream_chunk.broadcast_id, video_recorded_at)
                self.current_stream_chunk = stream_chunk
                self.current_stream_chunk.video_url = video_url
                self.current_stream_chunk.video_preview_image_url = video_preview_image_url

                db_session.add(self.current_stream_chunk)

                db_session.commit()

                db_session.expunge_all()
            log.info("Successfully commited video url data in a new chunk.")
Beispiel #24
0
    def on_user_sub_or_resub(self, **rest):
        now = utils.now()

        # True if we already announced the alert_message_after_sub within the last 5 seconds. Prevents
        # spam after bulk sub gifts.
        skip_message = self.last_sub is not None and now - self.last_sub < datetime.timedelta(
            seconds=5)

        self.last_sub = now
        if (self.settings["only_roulette_after_sub"]
                and self.settings["alert_message_after_sub"] != ""
                and not skip_message):
            self.bot.say(self.settings["alert_message_after_sub"].format(
                seconds=self.settings["after_sub_roulette_time"]))
Beispiel #25
0
    def poll_trivia(self):
        if self.question is None and (self.last_question is None
                                      or utils.now() - self.last_question >=
                                      datetime.timedelta(seconds=12)):
            url = "http://jservice.io/api/random"
            r = requests.get(url)
            self.question = r.json()[0]
            self.question["answer"] = (self.question["answer"].replace(
                "<i>", "").replace("</i>", "").replace("\\", "").replace(
                    "(", "").replace(")", "").strip('"').strip("."))

            if (len(self.question["answer"]) == 0
                    or len(self.question["question"]) <= 1
                    or "href=" in self.question["answer"]):
                self.question = None
                return

            self.step = 0
            self.last_step = None

        # Is it time for the next step?
        condition = self.last_question is None or utils.now(
        ) - self.last_question >= datetime.timedelta(
            seconds=self.settings["question_delay"])
        if (self.last_step is None and condition) or (
                self.last_step is not None and utils.now() - self.last_step >=
                datetime.timedelta(seconds=self.settings["step_delay"])):
            self.last_step = utils.now()
            self.step += 1

            if self.step == 1:
                self.step_announce()
            elif self.step < self.settings["hint_count"] + 2:
                self.step_hint()
            else:
                self.step_end()
Beispiel #26
0
 def _create(db_session,
             video_id,
             skip_after,
             requested_by_id,
             queue=None,
             backup=False):
     songrequestqueue = SongrequestQueue(video_id=video_id,
                                         date_added=utils.now(),
                                         skip_after=skip_after,
                                         requested_by_id=requested_by_id)
     db_session.add(songrequestqueue)
     db_session.commit()
     SongRequestQueueManager.inset_song(
         songrequestqueue.id,
         "backup-song-queue" if backup else "song-queue", queue)
     return songrequestqueue
Beispiel #27
0
    def check_follow_age(self, bot, source, username, streamer, event):
        streamer = bot.streamer if streamer is None else streamer.lower()
        age = bot.twitchapi.get_follow_relationship(username, streamer)
        is_self = source.username == username
        message = ""
        streamer = streamer.replace('admiralbulldog', 'Buldog')

        if age:
            # Following
            human_age = time_since(utils.now().timestamp() - age.timestamp(), 0)
            message = "{} has been following {} for {}".format(username, streamer, human_age)
        else:
            # Not following
            message = "{} is not following {}".format(username, streamer)

        bot.send_message_to_user(source, message, event, method=self.settings["action_followage"])
Beispiel #28
0
    def pause_function(self):
        if not self.module_state["enabled"] or not self.current_song_id:
            return False
        if not self.module_state["paused"]:
            self.module_state["paused"] = True
            self._module_state()
            self._pause()
            self.remove_schedule()
            with DBManager.create_session_scope() as db_session:
                song = SongrequestQueue._from_id(db_session,
                                                 self.current_song_id)
                song.played_for = (utils.now() -
                                   song.date_resumed).total_seconds()
                song.date_resumed = None
            return True

        return False
Beispiel #29
0
    def command_restart(self, bot, message, **rest):
        reason = message if message else "No reason given EleGiggle"
        with DBManager.create_session_scope() as db_session:
            current_game = self.get_current_game(db_session, with_bets=True, with_users=True)
            for bet in current_game.bets:
                bet.user.points = User.points + bet.points
                bot.whisper(
                    bet.user, f"Your {bet.points} points bet has been refunded. The reason given is: '{reason}'"
                )

                db_session.delete(bet)

            current_game.timestamp = utils.now()

        self.spectating = False

        bot.me("All your bets have been refunded and betting has been restarted.")
Beispiel #30
0
    def refresh_video_url_stage2(self, data) -> None:
        if self.online is False:
            return

        if self.current_stream_chunk is None or self.current_stream is None:
            return

        video: Optional[TwitchVideo] = self.fetch_video_url_stage2(data)

        if video is None:
            return

        log.info(f"Successfully fetched a video url: {video.url}")
        if self.current_stream_chunk is None or self.current_stream_chunk.video_url is None:
            with DBManager.create_session_scope(
                    expire_on_commit=False) as db_session:
                self.current_stream_chunk.video_url = video.url
                self.current_stream_chunk.video_preview_image_url = video.thumbnail_url

                db_session.add(self.current_stream_chunk)

                db_session.commit()

                db_session.expunge_all()
            log.info("Successfully commited video url data.")
        elif self.current_stream_chunk.video_url != video.url:
            # End current stream chunk
            self.current_stream_chunk.chunk_end = utils.now()
            DBManager.session_add_expunge(self.current_stream_chunk)

            with DBManager.create_session_scope(
                    expire_on_commit=False) as db_session:
                stream_chunk = StreamChunk(
                    self.current_stream,
                    self.current_stream_chunk.broadcast_id, video.created_at)
                self.current_stream_chunk = stream_chunk
                self.current_stream_chunk.video_url = video.url
                self.current_stream_chunk.video_preview_image_url = video.thumbnail_url

                db_session.add(self.current_stream_chunk)

                db_session.commit()

                db_session.expunge_all()
            log.info("Successfully commited video url data in a new chunk.")