Improve figuring out if new campaigns are claimed or not
This commit is contained in:
1 parent
d51c3f53bd
commit
9ef0007604
2 files changed
+32
-11
No files matched your search
+24
-8
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from functools import cached_property
|
from functools import cached_property
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from typing import Optional, List, Dict, Set, Iterable, TYPE_CHECKING
|
from typing import Optional, List, Dict, Iterable, TYPE_CHECKING
|
||||||
|
|
||||||
from channel import Channel
|
from channel import Channel
|
||||||
from constants import JsonType, GQL_OPERATIONS
|
from constants import JsonType, GQL_OPERATIONS
|
||||||
@@ -13,7 +13,9 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
|
|
||||||
class BaseDrop:
|
class BaseDrop:
|
||||||
def __init__(self, campaign: DropsCampaign, data: JsonType, claimed_benefits: Set[str]):
|
def __init__(
|
||||||
|
self, campaign: DropsCampaign, data: JsonType, claimed_benefits: Dict[str, datetime]
|
||||||
|
):
|
||||||
self._twitch: Twitch = campaign._twitch
|
self._twitch: Twitch = campaign._twitch
|
||||||
self.id: str = data["id"]
|
self.id: str = data["id"]
|
||||||
self.name: str = data["name"]
|
self.name: str = data["name"]
|
||||||
@@ -26,10 +28,22 @@ class BaseDrop:
|
|||||||
if "self" in data:
|
if "self" in data:
|
||||||
self.claim_id = data["self"]["dropInstanceID"]
|
self.claim_id = data["self"]["dropInstanceID"]
|
||||||
self.is_claimed = data["self"]["isClaimed"]
|
self.is_claimed = data["self"]["isClaimed"]
|
||||||
elif all(b["benefit"]["id"] in claimed_benefits for b in data["benefitEdges"]):
|
elif (
|
||||||
# NOTE: this may erroneously mark drops from an unprogressed campaign as claimed
|
# If there's no self edge available, we can use claimed_benefits to determine
|
||||||
# if the benefits repeat, but shouldn't cause a problem
|
# (with pretty good certainty) if this drop has been claimed or not.
|
||||||
# once the campaign is in-progress
|
# To do this, we check if the benefitEdges appear in claimed_benefits, and then
|
||||||
|
# deref their "lastAwardedAt" timestamps into a list to check against.
|
||||||
|
# If the benefits were claimed while the drop was active,
|
||||||
|
# the drop has been claimed too.
|
||||||
|
(
|
||||||
|
dts := [
|
||||||
|
claimed_benefits[bid]
|
||||||
|
for b in data["benefitEdges"]
|
||||||
|
if (bid := b["benefit"]["id"]) in claimed_benefits
|
||||||
|
]
|
||||||
|
)
|
||||||
|
and all(self.starts_at <= dt < self.ends_at for dt in dts)
|
||||||
|
):
|
||||||
self.is_claimed = True
|
self.is_claimed = True
|
||||||
self._precondition_drops: List[str] = [d["id"] for d in (data["preconditionDrops"] or [])]
|
self._precondition_drops: List[str] = [d["id"] for d in (data["preconditionDrops"] or [])]
|
||||||
|
|
||||||
@@ -109,7 +123,9 @@ class BaseDrop:
|
|||||||
|
|
||||||
|
|
||||||
class TimedDrop(BaseDrop):
|
class TimedDrop(BaseDrop):
|
||||||
def __init__(self, campaign: DropsCampaign, data: JsonType, claimed_benefits: Set[str]):
|
def __init__(
|
||||||
|
self, campaign: DropsCampaign, data: JsonType, claimed_benefits: Dict[str, datetime]
|
||||||
|
):
|
||||||
super().__init__(campaign, data, claimed_benefits)
|
super().__init__(campaign, data, claimed_benefits)
|
||||||
self.current_minutes: int = 0
|
self.current_minutes: int = 0
|
||||||
if "self" in data:
|
if "self" in data:
|
||||||
@@ -164,7 +180,7 @@ class TimedDrop(BaseDrop):
|
|||||||
|
|
||||||
|
|
||||||
class DropsCampaign:
|
class DropsCampaign:
|
||||||
def __init__(self, twitch: Twitch, data: JsonType, claimed_benefits: Set[str]):
|
def __init__(self, twitch: Twitch, data: JsonType, claimed_benefits: Dict[str, datetime]):
|
||||||
self._twitch: Twitch = twitch
|
self._twitch: Twitch = twitch
|
||||||
self.id: str = data["id"]
|
self.id: str = data["id"]
|
||||||
self.name: str = data["name"]
|
self.name: str = data["name"]
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import logging
|
|||||||
from yarl import URL
|
from yarl import URL
|
||||||
from time import time
|
from time import time
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
from datetime import datetime
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
from typing import (
|
from typing import (
|
||||||
@@ -22,7 +23,7 @@ from websocket import WebsocketPool
|
|||||||
from gui import GUIManager, LoginData
|
from gui import GUIManager, LoginData
|
||||||
from inventory import DropsCampaign, TimedDrop
|
from inventory import DropsCampaign, TimedDrop
|
||||||
from exceptions import LoginException, CaptchaRequired
|
from exceptions import LoginException, CaptchaRequired
|
||||||
from utils import Game, AwaitableValue, OrderedSet, task_wrapper
|
from utils import Game, AwaitableValue, OrderedSet, task_wrapper, timestamp
|
||||||
from constants import (
|
from constants import (
|
||||||
State,
|
State,
|
||||||
JsonType,
|
JsonType,
|
||||||
@@ -734,7 +735,9 @@ class Twitch:
|
|||||||
continue
|
continue
|
||||||
raise RuntimeError(f"Ran out of attempts while handling a GQL request: {op}")
|
raise RuntimeError(f"Ran out of attempts while handling a GQL request: {op}")
|
||||||
|
|
||||||
async def fetch_campaign(self, campaign_id: str, claimed_benefits: Set[str]) -> DropsCampaign:
|
async def fetch_campaign(
|
||||||
|
self, campaign_id: str, claimed_benefits: Dict[str, datetime]
|
||||||
|
) -> DropsCampaign:
|
||||||
response = await self.gql_request(
|
response = await self.gql_request(
|
||||||
GQL_OPERATIONS["CampaignDetails"].with_variables(
|
GQL_OPERATIONS["CampaignDetails"].with_variables(
|
||||||
{"channelLogin": str(self._user_id), "dropID": campaign_id}
|
{"channelLogin": str(self._user_id), "dropID": campaign_id}
|
||||||
@@ -756,7 +759,9 @@ class Twitch:
|
|||||||
inventory = response["data"]["currentUser"]["inventory"]
|
inventory = response["data"]["currentUser"]["inventory"]
|
||||||
ongoing_campaigns = inventory["dropCampaignsInProgress"] or []
|
ongoing_campaigns = inventory["dropCampaignsInProgress"] or []
|
||||||
# this contains claimed benefit edge IDs, not drop IDs
|
# this contains claimed benefit edge IDs, not drop IDs
|
||||||
claimed_benefits: Set[str] = set(d["id"] for d in inventory["gameEventDrops"])
|
claimed_benefits: Dict[str, datetime] = {
|
||||||
|
b["id"]: timestamp(b["lastAwardedAt"]) for b in inventory["gameEventDrops"]
|
||||||
|
}
|
||||||
campaigns: List[DropsCampaign] = [
|
campaigns: List[DropsCampaign] = [
|
||||||
DropsCampaign(self, campaign_data, claimed_benefits)
|
DropsCampaign(self, campaign_data, claimed_benefits)
|
||||||
for campaign_data in ongoing_campaigns
|
for campaign_data in ongoing_campaigns
|
||||||
|
|||||||
Reference in new issue
Block a user