Get a user's associated classroom, and return it as a `scratchattach.classroom.Classroom` object. If there is no associated classroom, returns `None`
(self)
| 243 | |
| 244 | @property |
| 245 | def classroom(self) -> classroom.Classroom | None: |
| 246 | """ |
| 247 | Get a user's associated classroom, and return it as a `scratchattach.classroom.Classroom` object. |
| 248 | If there is no associated classroom, returns `None` |
| 249 | """ |
| 250 | if not self._classroom[0]: |
| 251 | with requests.no_error_handling(): |
| 252 | resp = requests.get(f"https://scratch.mit.edu/users/{self.username}/") |
| 253 | soup = BeautifulSoup(resp.text, "html.parser") |
| 254 | |
| 255 | details = soup.find("p", {"class": "profile-details"}) |
| 256 | if details is None: |
| 257 | # No details, e.g. if the user is banned |
| 258 | return None |
| 259 | |
| 260 | assert isinstance(details, Tag) |
| 261 | |
| 262 | class_name, class_id, is_closed = None, None, False |
| 263 | for a in details.find_all("a"): |
| 264 | if not isinstance(a, Tag): |
| 265 | continue |
| 266 | href = str(a.get("href")) |
| 267 | if re.match(r"/classes/\d*/", href): |
| 268 | class_name = a.text.strip()[len("Student of: ") :] |
| 269 | is_closed = bool(re.search(r"\n *\(ended\)", class_name)) # as this has a \n, we can be sure |
| 270 | if is_closed: |
| 271 | class_name = re.sub(r"\n *\(ended\)", "", class_name).strip() |
| 272 | |
| 273 | class_id = int(href.split("/")[2]) |
| 274 | break |
| 275 | |
| 276 | if class_name: |
| 277 | self._classroom = ( |
| 278 | True, |
| 279 | classroom.Classroom( |
| 280 | _session=self._session, |
| 281 | id=class_id or 0, |
| 282 | title=class_name, |
| 283 | is_closed=is_closed, |
| 284 | ), |
| 285 | ) |
| 286 | else: |
| 287 | self._classroom = True, None |
| 288 | |
| 289 | return self._classroom[1] |
| 290 | |
| 291 | def does_exist(self) -> Optional[bool]: |
| 292 | """ |
nothing calls this directly
no test coverage detected