mirror of
https://github.com/rangermix/TwitchDropsMiner.git
synced 2026-05-29 16:39:37 +00:00
A bunch of naming and consistency changes
This commit is contained in:
14
channel.py
14
channel.py
@@ -76,7 +76,7 @@ class Channel:
|
||||
id: SupportsInt,
|
||||
login: str,
|
||||
display_name: str | None = None,
|
||||
priority: bool = False,
|
||||
acl_based: bool = False,
|
||||
):
|
||||
self._twitch: Twitch = twitch
|
||||
self._gui_channels: ChannelList = twitch.gui.channels
|
||||
@@ -87,11 +87,11 @@ class Channel:
|
||||
self.points: int | None = None
|
||||
self._stream: Stream | None = None
|
||||
self._pending_stream_up: asyncio.Task[Any] | None = None
|
||||
# Priority channels are:
|
||||
# ACL-based channels are:
|
||||
# • considered first when switching channels
|
||||
# • if we're watching a non-priority channel, a priority channel going up triggers a switch
|
||||
# • if we're watching a non-based channel, a based channel going up triggers a switch
|
||||
# • not cleaned up unless they're streaming a game we haven't selected
|
||||
self.priority: bool = priority
|
||||
self.acl_based: bool = acl_based
|
||||
|
||||
@classmethod
|
||||
def from_acl(cls, twitch: Twitch, data: JsonType) -> Channel:
|
||||
@@ -100,7 +100,7 @@ class Channel:
|
||||
id=data["id"],
|
||||
login=data["name"],
|
||||
display_name=data.get("displayName"),
|
||||
priority=True,
|
||||
acl_based=True,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -114,9 +114,9 @@ class Channel:
|
||||
|
||||
@classmethod
|
||||
async def from_name(
|
||||
cls, twitch: Twitch, channel_login: str, *, priority: bool = False
|
||||
cls, twitch: Twitch, channel_login: str, *, acl_based: bool = False
|
||||
) -> Channel:
|
||||
self = cls(twitch, id=0, login=channel_login, priority=priority)
|
||||
self = cls(twitch, id=0, login=channel_login, acl_based=acl_based)
|
||||
# id and display name to be filled/overwritten by get_stream
|
||||
stream = await self.get_stream()
|
||||
if stream is not None:
|
||||
|
||||
12
gui.py
12
gui.py
@@ -865,7 +865,7 @@ class ChannelList:
|
||||
self._add_column(
|
||||
"points", _("gui", "channels", "headings", "points"), width_template="1234567"
|
||||
)
|
||||
self._add_column("priority", "❗", width_template="✔")
|
||||
self._add_column("acl_base", "📋", width_template="✔")
|
||||
self._channel_map: dict[str, Channel] = {}
|
||||
|
||||
def _add_column(
|
||||
@@ -999,8 +999,8 @@ class ChannelList:
|
||||
self.shrink()
|
||||
|
||||
def display(self, channel: Channel, *, add: bool = False):
|
||||
# priority
|
||||
priority = "✔" if channel.priority else "❌"
|
||||
# ACL-based
|
||||
acl_based = "✔" if channel.acl_based else "❌"
|
||||
# status
|
||||
if channel.online:
|
||||
status = _("gui", "channels", "online")
|
||||
@@ -1026,7 +1026,7 @@ class ChannelList:
|
||||
self._set(iid, "drops", drops)
|
||||
self._set(iid, "status", status)
|
||||
self._set(iid, "viewers", viewers)
|
||||
self._set(iid, "priority", priority)
|
||||
self._set(iid, "acl_base", acl_based)
|
||||
if points != '': # we still want to display 0
|
||||
self._set(iid, "points", points)
|
||||
elif add:
|
||||
@@ -1039,7 +1039,7 @@ class ChannelList:
|
||||
"points": points,
|
||||
"status": status,
|
||||
"viewers": viewers,
|
||||
"priority": priority,
|
||||
"acl_base": acl_based,
|
||||
"channel": channel.name,
|
||||
},
|
||||
)
|
||||
@@ -1613,7 +1613,7 @@ class SettingsPanel:
|
||||
# NOTE: we shift the indexes so that 0 can be used as the default one
|
||||
size = self._priority_list.size()
|
||||
return {
|
||||
game_name: i - size for i, game_name in enumerate(self._priority_list.get(0, "end"))
|
||||
game_name: size - i for i, game_name in enumerate(self._priority_list.get(0, "end"))
|
||||
}
|
||||
|
||||
def priority_add(self) -> None:
|
||||
|
||||
72
twitch.py
72
twitch.py
@@ -229,7 +229,7 @@ class Twitch:
|
||||
# State management
|
||||
self._state: State = State.IDLE
|
||||
self._state_change = asyncio.Event()
|
||||
self.games: dict[Game, int] = {}
|
||||
self.wanted_games: dict[Game, int] = {}
|
||||
self.inventory: list[DropsCampaign] = []
|
||||
self._drops: dict[str, TimedDrop] = {}
|
||||
# Session and auth
|
||||
@@ -280,11 +280,11 @@ class Twitch:
|
||||
await self._session.close()
|
||||
self._session = None
|
||||
self._drop_update = None
|
||||
self.games.clear()
|
||||
self._drops.clear()
|
||||
self.channels.clear()
|
||||
self.inventory.clear()
|
||||
self._auth_state.clear()
|
||||
self.wanted_games.clear()
|
||||
# wait at least half a second + whatever it takes to complete the closing
|
||||
# this allows aiohttp to safely close the session
|
||||
await asyncio.sleep(start_time + 0.5 - time())
|
||||
@@ -330,21 +330,27 @@ class Twitch:
|
||||
self.gui.save(force=force)
|
||||
self.settings.save(force=force)
|
||||
|
||||
def get_priority(self, channel: Channel) -> int:
|
||||
"""
|
||||
Return a priority number for a given channel.
|
||||
|
||||
Higher number, higher priority.
|
||||
Priority 0 is given to channels streaming a game not on the priority list.
|
||||
Priority -1 is given to OFFLINE channels, or channels streaming no particular games.
|
||||
"""
|
||||
if (game := channel.game) is None:
|
||||
# None when OFFLINE or no game set
|
||||
return -1
|
||||
elif game not in self.wanted_games:
|
||||
return 0
|
||||
return self.wanted_games[game]
|
||||
|
||||
@staticmethod
|
||||
def _viewers_key(channel: Channel) -> int:
|
||||
if (viewers := channel.viewers) is not None:
|
||||
return viewers
|
||||
return -1
|
||||
|
||||
def _game_key(self, channel: Channel) -> int:
|
||||
if (game := channel.game) is None:
|
||||
return 1
|
||||
elif game not in self.games:
|
||||
# in case a channel is gathered from an ACL and doesn't play the expected game,
|
||||
# we use the same priority as for non-prioritized games
|
||||
return 0
|
||||
return self.games[game]
|
||||
|
||||
async def run(self):
|
||||
while True:
|
||||
try:
|
||||
@@ -400,36 +406,35 @@ class Twitch:
|
||||
self.save()
|
||||
self.change_state(State.GAMES_UPDATE)
|
||||
elif self._state is State.GAMES_UPDATE:
|
||||
# Figure out which games to watch, and claim the drops we can
|
||||
self.games.clear()
|
||||
priorities = self.gui.settings.priorities()
|
||||
# claim drops from expired and active campaigns
|
||||
for campaign in self.inventory:
|
||||
if not campaign.upcoming:
|
||||
for drop in campaign.drops:
|
||||
if drop.can_claim:
|
||||
await drop.claim()
|
||||
# collect games from active campaigns
|
||||
# figure out which games we want
|
||||
self.wanted_games.clear()
|
||||
priorities = self.gui.settings.priorities()
|
||||
exclude = self.settings.exclude
|
||||
priority = self.settings.priority
|
||||
priority_only = self.settings.priority_only
|
||||
for campaign in self.inventory:
|
||||
game = campaign.game
|
||||
if (
|
||||
game not in self.games # isn't already there
|
||||
game not in self.wanted_games # isn't already there
|
||||
and game.name not in exclude # and isn't excluded
|
||||
# and isn't excluded by priority_only
|
||||
and (not priority_only or game.name in priority)
|
||||
and campaign.can_earn() # and can be progressed (active required)
|
||||
):
|
||||
# non-excluded games with no priority, are placed last, below priority ones
|
||||
self.games[game] = priorities.get(game.name, 0)
|
||||
# non-excluded games with no priority are placed last, below priority ones
|
||||
self.wanted_games[game] = priorities.get(game.name, 0)
|
||||
full_cleanup = True
|
||||
self.restart_watching()
|
||||
self.change_state(State.CHANNELS_CLEANUP)
|
||||
elif self._state is State.CHANNELS_CLEANUP:
|
||||
self.gui.status.update(_("gui", "status", "cleanup"))
|
||||
if not self.games or full_cleanup:
|
||||
if not self.wanted_games or full_cleanup:
|
||||
# no games selected or we're doing full cleanup: remove everything
|
||||
to_remove: list[Channel] = list(channels.values())
|
||||
else:
|
||||
@@ -438,11 +443,11 @@ class Twitch:
|
||||
channel
|
||||
for channel in channels.values()
|
||||
if (
|
||||
not channel.priority # aren't prioritized
|
||||
not channel.acl_based # aren't ACL-based
|
||||
and (
|
||||
channel.offline # and are offline
|
||||
# or online but aren't streaming the game we want anymore
|
||||
or (channel.game is None or channel.game not in self.games)
|
||||
or (channel.game is None or channel.game not in self.wanted_games)
|
||||
)
|
||||
)
|
||||
]
|
||||
@@ -456,7 +461,7 @@ class Twitch:
|
||||
del channels[channel.id]
|
||||
channel.remove()
|
||||
del to_remove
|
||||
if self.games:
|
||||
if self.wanted_games:
|
||||
self.change_state(State.CHANNELS_FETCH)
|
||||
else:
|
||||
# with no games available, we switch to IDLE after cleanup
|
||||
@@ -472,7 +477,7 @@ class Twitch:
|
||||
no_acl: set[Game] = set()
|
||||
acl_channels: OrderedSet[Channel] = OrderedSet()
|
||||
for campaign in self.inventory:
|
||||
if campaign.game in self.games and campaign.can_earn():
|
||||
if campaign.game in self.wanted_games and campaign.can_earn():
|
||||
if campaign.allowed_channels:
|
||||
acl_channels.update(campaign.allowed_channels)
|
||||
else:
|
||||
@@ -493,8 +498,8 @@ class Twitch:
|
||||
ordered_channels: list[Channel] = sorted(
|
||||
new_channels, key=self._viewers_key, reverse=True
|
||||
)
|
||||
ordered_channels.sort(key=lambda ch: ch.priority, reverse=True)
|
||||
ordered_channels.sort(key=self._game_key)
|
||||
ordered_channels.sort(key=lambda ch: ch.acl_based, reverse=True)
|
||||
ordered_channels.sort(key=self.get_priority, reverse=True)
|
||||
# ensure that we won't end up with more channels than we can handle
|
||||
# NOTE: we substract 2 due to the two base topics always being added:
|
||||
# channel points gain and drop update subscriptions
|
||||
@@ -557,7 +562,7 @@ class Twitch:
|
||||
# for a switch (including the watching one)
|
||||
# NOTE: we need to sort the channels every time because one channel
|
||||
# can end up streaming any game - channels aren't game-tied
|
||||
for channel in sorted(channels.values(), key=self._game_key):
|
||||
for channel in sorted(channels.values(), key=self.get_priority, reverse=True):
|
||||
if self.can_watch(channel) and self.should_switch(channel):
|
||||
new_watching = channel
|
||||
break
|
||||
@@ -688,13 +693,13 @@ class Twitch:
|
||||
"""
|
||||
Determines if the given channel qualifies as a watching candidate.
|
||||
"""
|
||||
if not self.games:
|
||||
if not self.wanted_games:
|
||||
return False
|
||||
return (
|
||||
channel.online # stream online
|
||||
and channel.drops_enabled # drops are enabled
|
||||
# it's one of the games we've selected
|
||||
and channel.game is not None and channel.game in self.games
|
||||
and (game := channel.game) is not None and game in self.wanted_games
|
||||
# we can progress any campaign for the selected game
|
||||
and any(campaign.can_earn(channel) for campaign in self.inventory)
|
||||
)
|
||||
@@ -706,15 +711,14 @@ class Twitch:
|
||||
watching_channel = self.watching_channel.get_with_default(None)
|
||||
if watching_channel is None:
|
||||
return True
|
||||
channel_order = self._game_key(channel)
|
||||
watching_order = self._game_key(watching_channel)
|
||||
channel_order = self.get_priority(channel)
|
||||
watching_order = self.get_priority(watching_channel)
|
||||
return (
|
||||
# this channel's game is higher order than the watching one's
|
||||
# NOTE: order is tied to the priority list position, so lower == higher
|
||||
channel_order < watching_order
|
||||
channel_order > watching_order
|
||||
or channel_order == watching_order # or the order is the same
|
||||
# and this channel has priority over the watching channel
|
||||
and channel.priority > watching_channel.priority
|
||||
# and this channel is ACL-based and the watching channel isn't
|
||||
and channel.acl_based > watching_channel.acl_based
|
||||
)
|
||||
|
||||
def watch(self, channel: Channel):
|
||||
|
||||
Reference in New Issue
Block a user