Skip to content

Commit 9b40f39

Browse files
authored
Use extract_js_vars in inv info
1 parent 387ef08 commit 9b40f39

File tree

1 file changed

+7
-142
lines changed

1 file changed

+7
-142
lines changed

steam/http.py

Lines changed: 7 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -369,14 +369,14 @@ async def get_user_wishlist(self, user_id64: ID64) -> AsyncGenerator[tuple[AppID
369369

370370
async def get_user_inventory_info(self, user_id64: ID64) -> ValuesView[user.InventoryInfo]:
371371
resp = await self.get(URL.COMMUNITY / f"profiles/{user_id64}/inventory")
372-
soup = BeautifulSoup(resp, "html.parser")
372+
soup = BeautifulSoup(resp, "html.parser") # needs to be html
373373
for script in soup.find_all("script", type="text/javascript"):
374-
if match := re.search(r"var\s+g_rgAppContextData\s*=\s*(?P<json>{.*?});\s*", script.text):
375-
break
376-
else:
377-
raise ValueError("Could not find inventory info")
378-
379-
return JSON_LOADS(match["json"]).values()
374+
try:
375+
(info,) = extract_js_variables(script.text, "g_rgAppContextData")
376+
return info.values()
377+
except NameError:
378+
pass
379+
raise ValueError("Could not find inventory info")
380380

381381
async def send_user_gift(
382382
self, user_id: ID32, asset_id: AssetID, name: str, message: str, closing_note: str, signature: str
@@ -554,141 +554,6 @@ def invite_user_to_clan(self, user_id64: ID64, clan_id64: ID64) -> Coro[None]:
554554
}
555555
return self.post(URL.COMMUNITY / "actions/GroupInvite", data=payload)
556556

557-
async def get_user_clans(self, user_id64: ID64) -> list[ID64]:
558-
params = {"steamid": user_id64}
559-
data: user.GetUserGroupList = await self.get(api_route("ISteamUser/GetUserGroupList"), params=params)
560-
return [parse_id64(group["gid"], type=Type.Clan) for group in data["response"]["groups"]]
561-
562-
async def get_user_bans(self, *user_id64s: ID64) -> list[user.UserBan]:
563-
params = {"steamids": ",".join(str(id64) for id64 in user_id64s)}
564-
data: user.GetPlayerBans = await self.get(api_route("ISteamUser/GetPlayerBans"), params=params)
565-
return [
566-
{
567-
"steamid": ID64(int(ban["SteamId"])),
568-
"community_banned": ban["CommunityBanned"],
569-
"vac_banned": ban["VACBanned"],
570-
"number_of_vac_bans": ban["NumberOfVACBans"],
571-
"days_since_last_ban": ban["DaysSinceLastBan"],
572-
"number_of_game_bans": ban["NumberOfGameBans"],
573-
"economy_ban": ban["EconomyBan"],
574-
}
575-
for ban in data["players"]
576-
]
577-
578-
async def get_user_level(self, user_id64: ID64) -> int:
579-
params = {"steamid": user_id64}
580-
resp: user.GetSteamLevel = await self.get(api_route("IPlayerService/GetSteamLevel"), params=params)
581-
return resp["response"]["player_level"]
582-
583-
async def get_user_badges(self, user_id64: ID64) -> user.UserBadges:
584-
params = {"steamid": user_id64}
585-
data: ResponseDict[user.UserBadges] = await self.get(api_route("IPlayerService/GetBadges"), params=params)
586-
return data["response"]
587-
588-
async def get_user_community_badge_progress(
589-
self, user_id64: ID64, badge_id: int
590-
) -> list[user.CommunityBadgeProgressQuest]:
591-
params = {
592-
"steamid": user_id64,
593-
"badgeid": badge_id,
594-
}
595-
data: ResponseDict[dict[Literal["quests"], list[user.CommunityBadgeProgressQuest]]] = await self.get(
596-
api_route("IPlayerService/GetCommunityBadgeProgress"), params=params
597-
)
598-
return data["response"]["quests"]
599-
600-
async def get_user_recently_played_apps(self, user_id64: ID64) -> list[app.UserRecentlyPlayedApp]:
601-
params = {"steamid": user_id64}
602-
data: ResponseDict[dict[Literal["games"], list[app.UserRecentlyPlayedApp]]] = await self.get(
603-
api_route("IPlayerService/GetRecentlyPlayedGames"), params=params
604-
)
605-
return data["response"]["games"]
606-
607-
async def get_user_inventory_info(self, user_id64: ID64) -> ValuesView[user.InventoryInfo]:
608-
resp = await self.get(URL.COMMUNITY / f"profiles/{user_id64}/inventory")
609-
soup = BeautifulSoup(resp, "html.parser") # needs to be html
610-
for script in soup.find_all("script", type="text/javascript"):
611-
try:
612-
(info,) = extract_js_variables(script.text, "g_rgAppContextData")
613-
return info.values()
614-
except NameError:
615-
pass
616-
raise ValueError("Could not find inventory info")
617-
618-
async def send_user_gift(
619-
self, user_id: ID32, asset_id: AssetID, name: str, message: str, closing_note: str, signature: str
620-
) -> None:
621-
payload = {
622-
"GifteeAccountID": user_id,
623-
"GifteeEmail": "",
624-
"GifteeName": name,
625-
"GiftMessage": message,
626-
"GiftSentiment": closing_note,
627-
"GiftSignature": signature,
628-
"GiftGID": asset_id,
629-
"SessionID": self.session_id,
630-
}
631-
headers = {"Referer": f"{URL.STORE}/checkout/sendgift/{asset_id}"}
632-
data: EResultSuccess = await self.post(URL.STORE / "checkout/sendgiftsubmit", data=payload, headers=headers)
633-
if data["success"] != Result.OK:
634-
raise RuntimeError("Failed to send gift")
635-
636-
def clear_nickname_history(self) -> Coro[None]:
637-
payload = {"sessionid": self.session_id}
638-
return self.post(URL.COMMUNITY / "my/ajaxclearaliashistory", data=payload)
639-
640-
async def get_user_wishlist(self, user_id64: ID64) -> AsyncGenerator[tuple[AppID, app.WishlistApp], None]:
641-
params = {"p": 0}
642-
while True:
643-
resp: dict[AppID, app.WishlistApp] = await self.get(
644-
URL.STORE / f"wishlist/profiles/{user_id64}/wishlistdata", params=params
645-
)
646-
if not resp: # it's an empty list sometimes lol
647-
return
648-
for app_id, data in resp.items():
649-
yield app_id, data
650-
params["p"] += 1
651-
652-
def get_app(self, app_id: AppID, language: Language | None) -> Coro[dict[str, Any]]:
653-
params = {
654-
"appids": app_id,
655-
"l": (language or self.language).api_name,
656-
}
657-
return self.get(URL.STORE / "api/appdetails", params=params)
658-
659-
def get_app_dlc(self, app_id: AppID, language: Language | None) -> Coro[dict[str, Any]]:
660-
params = {
661-
"appid": app_id,
662-
"l": (language or self.language).api_name,
663-
}
664-
return self.get(URL.STORE / "api/dlcforapp", params=params)
665-
666-
async def get_app_asset_prices(self, app_id: AppID, currency: Currency | None = None) -> app.AssetPrices:
667-
params = {"appid": app_id, "currency": (currency or self.currency).name}
668-
669-
data: dict[Literal["result"], app.AssetPrices] = await self.get(
670-
api_route("ISteamEconomy/GetAssetPrices"), params=params
671-
)
672-
return data["result"]
673-
674-
async def get_clan_members(self, clan_id64: ID64) -> AsyncGenerator[ID32, None]:
675-
url = f"{ID(clan_id64).community_url}/members"
676-
page = 1
677-
number_of_pages = None
678-
679-
while number_of_pages is None or page <= number_of_pages:
680-
resp = await self.get(url, params={"p": page, "content_only": "true"})
681-
soup = BeautifulSoup(resp, HTML_PARSER)
682-
if not number_of_pages:
683-
page_select = soup.find("div", class_="group_paging")
684-
assert page_select is not None
685-
number_of_pages = int(re.findall(r"\d* - (\d*)", page_select.text)[0])
686-
687-
for s in soup.find_all("div", id="memberList"):
688-
for user in s.find_all("div", class_="member_block"):
689-
yield int(user["data-miniprofile"]) # type: ignore
690-
page += 1
691-
692557
async def get_clan_invitees(
693558
self,
694559
) -> dict[ID64, ID64]: # TODO what about the case where you've been invited by multiple peopl

0 commit comments

Comments
 (0)