diff --git a/channel.py b/channel.py index c3d993e..0985de1 100644 --- a/channel.py +++ b/channel.py @@ -58,9 +58,10 @@ class Channel: self.points: Optional[int] = None self._stream: Optional[Stream] = None self._pending_stream_up: Optional[asyncio.Task[Any]] = None - # Priority channels are considered first when switching channels, - # and if we're watching a non-priority channel, - # a priority channel going up triggers a switch + # Priority channels are: + # • considered first when switching channels + # • if we're watching a non-priority channel, a priority channel going up triggers a switch + # • not cleaned up unless they're streaming a game we haven't selected self.priority: bool = priority @classmethod @@ -120,6 +121,13 @@ class Channel: """ return self._stream is not None + @property + def offline(self) -> bool: + """ + Returns True if the streamer is offline and isn't about to come online, False otherwise. + """ + return self._stream is None and self._pending_stream_up is None + @property def pending_online(self) -> bool: """ @@ -210,35 +218,34 @@ class Channel: The 'stream-up' event is sent before the stream actually goes online, so just wait a bit and check if it's actually online by then. """ - self.display() await asyncio.sleep(ONLINE_DELAY.total_seconds()) online = await self.check_online() - self._pending_stream_up = None + self._pending_stream_up = None # for 'display' to work properly self.display() if online: self._twitch.on_online(self) def set_online(self): """ - Sets the channel status to OFFLINE. + Sets the channel status to PENDING_ONLINE, where after ONLINE_DELAY, + it's going to be set to ONLINE. This is called externally, if we receive an event about this happening. """ - if self.online or self.pending_online: - # we're already online, or about to be - return - self._pending_stream_up = asyncio.create_task(self._online_delay()) - # display is called from within the task + if self.offline: + self._pending_stream_up = asyncio.create_task(self._online_delay()) + self.display() def set_offline(self): """ - Sets the channel status to OFFLINE. + Sets the channel status to OFFLINE. Cancels PENDING_ONLINE if applicable. This is called externally, if we receive an event about this happening. """ if self._pending_stream_up is not None: self._pending_stream_up.cancel() self._pending_stream_up = None + self.display() if self.online: self._stream = None self.display() diff --git a/twitch.py b/twitch.py index b1e4fd4..a64e84f 100644 --- a/twitch.py +++ b/twitch.py @@ -204,25 +204,28 @@ class Twitch: self.restart_watching() self.change_state(State.CHANNELS_CLEANUP) elif self._state is State.CHANNELS_CLEANUP: - # remove all channels that are offline, - # or aren't streaming the game we want anymore if self.game is None: # remove everything to_remove: List[Channel] = list(self.channels.values()) else: + # remove all channels that: to_remove = [ - channel for channel in self.channels.values() - if not (channel.online or channel.pending_online) + channel + for channel in self.channels.values() + if channel.offline # are offline + or not channel.priority # aren't prioritized + # aren't streaming the game we want anymore or channel.game is None or channel.game != self.game ] self.websocket.remove_topics( WebsocketTopic.as_str("Channel", "VideoPlayback", channel.id) for channel in to_remove ) + watching_channel = self.watching_channel.get_with_default(None) + if watching_channel is not None and watching_channel in to_remove: + # we're removing a channel we're watching + self.stop_watching() for channel in to_remove: - if self.is_watching(channel): - # we're removing a channel we're watching - self.stop_watching() del self.channels[channel.id] channel.remove() self.gui.channels.shrink()