Skip to content

Commit

Permalink
Speed up app loading by fetching inventory images concurrently
Browse files Browse the repository at this point in the history
  • Loading branch information
DevilXD committed Jul 16, 2024
1 parent aad27ba commit f32c8f2
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 25 deletions.
35 changes: 19 additions & 16 deletions gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -1302,6 +1302,18 @@ def _on_tab_switched(self, event: tk.Event[ttk.Notebook]) -> None:
# refresh only if we're switching to the tab
self.refresh()

def get_status(self, campaign: DropsCampaign) -> tuple[str, str]:
if campaign.active:
status_text: str = _("gui", "inventory", "status", "active")
status_color: str = "green"
elif campaign.upcoming:
status_text = _("gui", "inventory", "status", "upcoming")
status_color = "goldenrod"
else:
status_text = _("gui", "inventory", "status", "expired")
status_color = "red"
return (status_text, status_color)

def refresh(self):
for campaign in self._campaigns:
# status
Expand Down Expand Up @@ -1341,6 +1353,13 @@ async def add_campaign(self, campaign: DropsCampaign) -> None:
campaign_frame, text=status_text, takefocus=False, foreground=status_color
)
status_label.grid(column=1, row=1, sticky="w", padx=4)
# NOTE: We have to save the campaign's frame and status before any awaits happen,
# otherwise the len(self._campaigns) call may overwrite an existing frame,
# if the campaigns are added concurrently.
self._campaigns[campaign] = {
"frame": campaign_frame,
"status": status_label,
}
# Starts / Ends
MouseOverLabel(
campaign_frame,
Expand Down Expand Up @@ -1415,10 +1434,6 @@ async def add_campaign(self, campaign: DropsCampaign) -> None:
self._drops[drop.id] = label = MouseOverLabel(drop_frame)
self.update_progress(drop, label)
label.grid(column=0, row=1)
self._campaigns[campaign] = {
"frame": campaign_frame,
"status": status_label,
}
if self._manager.tabs.current_tab() == 1:
self._update_visibility(campaign)
self._canvas_update()
Expand All @@ -1429,18 +1444,6 @@ def clear(self) -> None:
self._drops.clear()
self._campaigns.clear()

def get_status(self, campaign: DropsCampaign) -> tuple[str, str]:
if campaign.active:
status_text: str = _("gui", "inventory", "status", "active")
status_color: str = "green"
elif campaign.upcoming:
status_text = _("gui", "inventory", "status", "upcoming")
status_color = "goldenrod"
else:
status_text = _("gui", "inventory", "status", "expired")
status_color = "red"
return (status_text, status_color)

def update_progress(self, drop: TimedDrop, label: MouseOverLabel) -> None:
# Returns: main text, alt text, text color
alt_text: str = ''
Expand Down
30 changes: 21 additions & 9 deletions twitch.py
Original file line number Diff line number Diff line change
Expand Up @@ -1462,25 +1462,37 @@ async def fetch_inventory(self) -> None:
campaigns.sort(key=lambda c: c.active, reverse=True)
campaigns.sort(key=lambda c: c.upcoming and c.starts_at or c.ends_at)
campaigns.sort(key=lambda c: c.linked, reverse=True)

self._drops.clear()
self.gui.inv.clear()
self.inventory.clear()
self._mnt_triggers.clear()
switch_triggers: set[datetime] = set()
next_hour = datetime.now(timezone.utc) + timedelta(hours=1)
for i, campaign in enumerate(campaigns, start=1):
status_update(
_("gui", "status", "adding_campaigns").format(counter=f"({i}/{len(campaigns)})")
)
# add the campaigns to the internal inventory
for campaign in campaigns:
self._drops.update({drop.id: drop for drop in campaign.drops})
if campaign.can_earn_within(next_hour):
switch_triggers.update(campaign.time_triggers)
# NOTE: this fetches pictures from the CDN, so might be slow without a cache
await self.gui.inv.add_campaign(campaign)
# this is needed here explicitly, because images aren't always fetched
self.inventory.append(campaign)
# concurrently add the campaigns into the GUI
# NOTE: this fetches pictures from the CDN, so might be slow without a cache
for i, coro in enumerate(
asyncio.as_completed(
[
asyncio.create_task(self.gui.inv.add_campaign(campaign))
for campaign in campaigns
]
),
start=1,
):
status_update(
_("gui", "status", "adding_campaigns").format(counter=f"({i}/{len(campaigns)})")
)
await coro
# this is needed here explicitly, because cache reads from disk don't raise this
if self.gui.close_requested:
raise ExitRequest()
self.inventory.append(campaign)
self._mnt_triggers.clear()
self._mnt_triggers.extend(sorted(switch_triggers))
# trim out all triggers that we're already past
now = datetime.now(timezone.utc)
Expand Down

0 comments on commit f32c8f2

Please sign in to comment.