@@ -93,6 +93,8 @@ class User(BaseSiteComponent[typed_dicts.UserDict]):
9393 icon_url : str = field (kw_only = True , default = "" )
9494 id : int = field (kw_only = True , default = 0 )
9595 scratchteam : bool = field (kw_only = True , repr = False , default = False )
96+ is_member : bool = field (kw_only = True , repr = False , default = False )
97+ has_ears : bool = field (kw_only = True , repr = False , default = False )
9698 _classroom : tuple [bool , Optional [classroom .Classroom ]] = field (init = False , default = (False , None ))
9799 _headers : dict [str , str ] = field (init = False , default_factory = headers .copy )
98100 _cookies : dict [str , str ] = field (init = False , default_factory = dict )
@@ -141,14 +143,20 @@ def __post_init__(self):
141143
142144 def _update_from_dict (self , data : Union [dict , typed_dicts .UserDict ]):
143145 data = cast (typed_dicts .UserDict , data )
144- self .id = data ["id" ]
145- self .username = data ["username" ]
146- self .scratchteam = data ["scratchteam" ]
147- self .join_date = data ["history" ]["joined" ]
148- self .about_me = data ["profile" ]["bio" ]
149- self .wiwo = data ["profile" ]["status" ]
150- self .country = data ["profile" ]["country" ]
151- self .icon_url = data ["profile" ]["images" ]["90x90" ]
146+
147+ self .id = data .get ("id" , self .id )
148+ self .username = data .get ("username" , self .username )
149+ self .scratchteam = data .get ("scratchteam" , self .scratchteam )
150+ if history := data .get ("history" ):
151+ self .join_date = history ["joined" ]
152+
153+ if profile := data .get ("profile" ):
154+ self .about_me = profile ["bio" ]
155+ self .wiwo = profile ["status" ]
156+ self .country = profile ["country" ]
157+ self .icon_url = profile ["images" ]["90x90" ]
158+ self .is_member = bool (profile .get ("membership_label" , False ))
159+ self .has_ears = bool (profile .get ("membership_avatar_badge" , False ))
152160 return True
153161
154162 def _assert_permission (self ):
@@ -612,6 +620,25 @@ def favorites_count(self):
612620 ).text
613621 return commons .webscrape_count (text , "Favorites (" , ")" )
614622
623+ def has_badge (self ) -> bool :
624+ """
625+ Returns:
626+ bool: Whether the user has a scratch membership badge on their profile (located next to the follow button)
627+ """
628+ with requests .no_error_handling ():
629+ resp = requests .get (self .url )
630+ soup = BeautifulSoup (resp .text , "html.parser" )
631+ head = soup .find ("div" , {"class" : "box-head" })
632+ if not head :
633+ return False
634+ for child in head .children :
635+ if child .name == "img" :
636+ if child ["src" ] == "//cdn.scratch.mit.edu/scratchr2/static/__ff7229f036c458728e45c39b0751aa44__/membership/membership-badge.svg" :
637+ return True
638+ return False
639+
640+
641+
615642 def toggle_commenting (self ):
616643 """
617644 You can only use this function if this object was created using :meth:`scratchattach.session.Session.connect_user`
0 commit comments