From ced63d7c360c8b0d84b73a13c32af4844eb9a00e Mon Sep 17 00:00:00 2001 From: TheCommCraft <79996518+TheCommCraft@users.noreply.github.com> Date: Sat, 29 Nov 2025 23:24:00 +0100 Subject: [PATCH] partial activity dict and datetime attribute for activity --- scratchattach/site/activity.py | 16 ++++++++++----- scratchattach/site/classroom.py | 6 +++--- scratchattach/site/typed_dicts.py | 33 +++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/scratchattach/site/activity.py b/scratchattach/site/activity.py index 5ea0bc03..9701a300 100644 --- a/scratchattach/site/activity.py +++ b/scratchattach/site/activity.py @@ -7,10 +7,12 @@ from dataclasses import dataclass from typing import Optional, Any from enum import Enum +from datetime import datetime from bs4 import Tag from . import user, project, studio, session, forum +from .typed_dicts import ActivityDict from ._base import BaseSiteComponent from scratchattach.utils import exceptions @@ -72,7 +74,8 @@ class Activity(BaseSiteComponent): changed_fields: Optional[dict[str, str]] = None is_reshare: Optional[bool] = None - datetime_created: Optional[str] = None + datetime_created: Optional[datetime] = None + datetime_created_raw: Optional[str] = None time: Any = None type: Optional[ActivityTypes] = None @@ -180,7 +183,7 @@ def update(self): print("Warning: Activity objects can't be updated") return False # Objects of this type cannot be updated - def _update_from_dict(self, data): + def _update_from_dict(self, data: ActivityDict): self.raw = data self._session = data.get("_session", self._session) @@ -214,7 +217,8 @@ def _update_from_dict(self, data): self.changed_fields = data.get("changed_fields", self.changed_fields) self.is_reshare = data.get("is_reshare", self.is_reshare) - self.datetime_created = data.get("datetime_created", self.datetime_created) + self.datetime_created_raw = data.get("datetime_created", self.datetime_created_raw) + self.datetime_created = datetime.fromisoformat(self.datetime_created_raw) self.time = data.get("time", self.time) _type = data.get("type", self.type) @@ -252,7 +256,8 @@ def _update_from_json(self, data: dict): self.actor_username = username self.username = username self.raw = data - self.datetime_created = _time + self.datetime_created_raw = _time + self.datetime_created = datetime.fromisoformat(self.datetime_created_raw) if activity_type == 0: self.type = ActivityTypes.followuser self.followed_username = data["followed_username"] @@ -339,7 +344,8 @@ def _update_from_html(self, data: Tag): while '\xa0' in _time: _time = _time.replace('\xa0', ' ') - self.datetime_created = _time + self.datetime_created_raw = _time + self.datetime_created = datetime.fromisoformat(self.datetime_created_raw) self.actor_username = data.find('div').find('span').text self.target_name = data.find('div').find('span').find_next().text diff --git a/scratchattach/site/classroom.py b/scratchattach/site/classroom.py index 4eacac89..8e5dedef 100644 --- a/scratchattach/site/classroom.py +++ b/scratchattach/site/classroom.py @@ -51,8 +51,8 @@ def __post_init__(self): self._headers = commons.headers self._cookies = {} else: - self._headers = self._session._headers - self._cookies = self._session._cookies + self._headers = self._session.get_headers() + self._cookies = self._session.get_cookies() # Headers for operations that require accept and Content-Type fields: self._json_headers = {**self._headers, @@ -98,7 +98,7 @@ def update(self): "educator": {}, "status": status, "is_closed": True - } + } if educator_username: ret["educator"]["username"] = educator_username diff --git a/scratchattach/site/typed_dicts.py b/scratchattach/site/typed_dicts.py index e94be4cc..23ba66d3 100644 --- a/scratchattach/site/typed_dicts.py +++ b/scratchattach/site/typed_dicts.py @@ -147,3 +147,36 @@ class PlaceholderProjectDataDict(TypedDict): metadata: PlaceholderProjectDataMetadataDict md5extsToSha256: OrderedDict[str, str] adminOwnershipToken: Optional[str] + +class ActivityDict(TypedDict): + id: int + datetime_created: str + actor_username: str + actor_id: int + type: str + + # addcomment + comment_type: NotRequired[int] + comment_obj_id: NotRequired[int] + comment_id: NotRequired[int] + comment_fragment: NotRequired[str] + comment_obj_title: NotRequired[str] + commentee_username: NotRequired[Optional[str]] + + # forumpost + topic_id: NotRequired[int] + topic_title: NotRequired[str] + + # followuser + followed_user_id: NotRequired[int] + followed_username: NotRequired[str] + + # loveproject + project_id: NotRequired[int] + title: NotRequired[str] + + # favoriteproject + project_title: NotRequired[str] + + # curatorinvite & studioactivity + gallery_id: NotRequired[int]