@@ -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