scratchattach 2.1.14__py3-none-any.whl → 3.0.0b0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. scratchattach/__init__.py +14 -6
  2. scratchattach/__main__.py +93 -0
  3. {scratchattach-2.1.14.dist-info → scratchattach-3.0.0b0.dist-info}/METADATA +7 -11
  4. scratchattach-3.0.0b0.dist-info/RECORD +8 -0
  5. {scratchattach-2.1.14.dist-info → scratchattach-3.0.0b0.dist-info}/WHEEL +1 -1
  6. scratchattach-3.0.0b0.dist-info/entry_points.txt +2 -0
  7. scratchattach/cloud/__init__.py +0 -2
  8. scratchattach/cloud/_base.py +0 -458
  9. scratchattach/cloud/cloud.py +0 -183
  10. scratchattach/editor/__init__.py +0 -21
  11. scratchattach/editor/asset.py +0 -253
  12. scratchattach/editor/backpack_json.py +0 -117
  13. scratchattach/editor/base.py +0 -193
  14. scratchattach/editor/block.py +0 -579
  15. scratchattach/editor/blockshape.py +0 -357
  16. scratchattach/editor/build_defaulting.py +0 -51
  17. scratchattach/editor/code_translation/__init__.py +0 -0
  18. scratchattach/editor/code_translation/parse.py +0 -177
  19. scratchattach/editor/comment.py +0 -80
  20. scratchattach/editor/commons.py +0 -306
  21. scratchattach/editor/extension.py +0 -50
  22. scratchattach/editor/field.py +0 -99
  23. scratchattach/editor/inputs.py +0 -135
  24. scratchattach/editor/meta.py +0 -114
  25. scratchattach/editor/monitor.py +0 -183
  26. scratchattach/editor/mutation.py +0 -324
  27. scratchattach/editor/pallete.py +0 -90
  28. scratchattach/editor/prim.py +0 -170
  29. scratchattach/editor/project.py +0 -279
  30. scratchattach/editor/sprite.py +0 -599
  31. scratchattach/editor/twconfig.py +0 -114
  32. scratchattach/editor/vlb.py +0 -134
  33. scratchattach/eventhandlers/__init__.py +0 -0
  34. scratchattach/eventhandlers/_base.py +0 -100
  35. scratchattach/eventhandlers/cloud_events.py +0 -110
  36. scratchattach/eventhandlers/cloud_recorder.py +0 -26
  37. scratchattach/eventhandlers/cloud_requests.py +0 -459
  38. scratchattach/eventhandlers/cloud_server.py +0 -246
  39. scratchattach/eventhandlers/cloud_storage.py +0 -136
  40. scratchattach/eventhandlers/combine.py +0 -30
  41. scratchattach/eventhandlers/filterbot.py +0 -161
  42. scratchattach/eventhandlers/message_events.py +0 -42
  43. scratchattach/other/__init__.py +0 -0
  44. scratchattach/other/other_apis.py +0 -284
  45. scratchattach/other/project_json_capabilities.py +0 -475
  46. scratchattach/site/__init__.py +0 -0
  47. scratchattach/site/_base.py +0 -66
  48. scratchattach/site/activity.py +0 -382
  49. scratchattach/site/alert.py +0 -227
  50. scratchattach/site/backpack_asset.py +0 -118
  51. scratchattach/site/browser_cookie3_stub.py +0 -17
  52. scratchattach/site/browser_cookies.py +0 -61
  53. scratchattach/site/classroom.py +0 -447
  54. scratchattach/site/cloud_activity.py +0 -107
  55. scratchattach/site/comment.py +0 -242
  56. scratchattach/site/forum.py +0 -432
  57. scratchattach/site/project.py +0 -825
  58. scratchattach/site/session.py +0 -1238
  59. scratchattach/site/studio.py +0 -611
  60. scratchattach/site/user.py +0 -956
  61. scratchattach/utils/__init__.py +0 -0
  62. scratchattach/utils/commons.py +0 -255
  63. scratchattach/utils/encoder.py +0 -158
  64. scratchattach/utils/enums.py +0 -236
  65. scratchattach/utils/exceptions.py +0 -243
  66. scratchattach/utils/requests.py +0 -93
  67. scratchattach-2.1.14.dist-info/RECORD +0 -66
  68. {scratchattach-2.1.14.dist-info → scratchattach-3.0.0b0.dist-info}/licenses/LICENSE +0 -0
  69. {scratchattach-2.1.14.dist-info → scratchattach-3.0.0b0.dist-info}/top_level.txt +0 -0
@@ -1,107 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import time
4
- from ._base import BaseSiteComponent
5
-
6
-
7
-
8
- class CloudActivity(BaseSiteComponent):
9
- """
10
- Represents a cloud activity (a cloud variable set / creation / deletion).
11
-
12
- Attributes:
13
-
14
- :.username: The user who caused the cloud event (the user who added / set / deleted the cloud variable)
15
-
16
- :.var: The name of the cloud variable that was updated (specified without the cloud emoji)
17
-
18
- :.name: The name of the cloud variable that was updated (specified without the cloud emoji)
19
-
20
- :.type: The activity type
21
-
22
- :.timestamp: Then timestamp of when the action was performed
23
-
24
- :.value: If the cloud variable was set, then this attribute provides the value the cloud variable was set to
25
-
26
- :.cloud: The cloud (as object inheriting from scratchattach.Cloud.BaseCloud) that the cloud activity corresponds to
27
- """
28
-
29
- def __init__(self, **entries):
30
- # Set attributes every CloudActivity object needs to have:
31
- self._session = None
32
- self.cloud = None
33
- self.user = None
34
- self.username = None
35
- self.type = None
36
- self.timestamp = time.time()
37
-
38
- # Update attributes from entries dict:
39
- self.__dict__.update(entries)
40
-
41
- def update(self):
42
- print("Warning: CloudActivity objects can't be updated")
43
- return False # Objects of this type cannot be updated
44
-
45
- def __eq__(self, activity2):
46
- # CloudLogEvents needs to check if two activites are equal (to finde new ones), therefore CloudActivity objects need to be comparable
47
- return self.user == activity2.user and self.type == activity2.type and self.timestamp == activity2.timestamp and self.value == activity2.value and self.name == activity2.name
48
-
49
- def _update_from_dict(self, data) -> bool:
50
- try: self.name = data["name"]
51
- except Exception: pass
52
- try: self.var = data["name"]
53
- except Exception: pass
54
- try: self.value = data["value"]
55
- except Exception: pass
56
- try: self.user = data["user"]
57
- except Exception: pass
58
- try: self.username = data["user"]
59
- except Exception: pass
60
- try: self.timestamp = data["timestamp"]
61
- except Exception: pass
62
- try: self.type = data["verb"].replace("_var","")
63
- except Exception: pass
64
- try: self.type = data["method"]
65
- except Exception: pass
66
- try: self.cloud = data["cloud"]
67
- except Exception: pass
68
- return True
69
-
70
- def load_log_data(self):
71
- if self.cloud is None:
72
- print("Warning: There aren't cloud logs available for this cloud, therefore the user and exact timestamp can't be loaded")
73
- else:
74
- if hasattr(self.cloud, "logs"):
75
- logs = self.cloud.logs(filter_by_var_named=self.var, limit=100)
76
- matching = list(filter(lambda x: x.value == self.value and x.timestamp <= self.timestamp, logs))
77
- if matching == []:
78
- return False
79
- activity = matching[0]
80
- self.username = activity.username
81
- self.user = activity.username
82
- self.timestamp = activity.timestamp
83
- return True
84
- else:
85
- print("Warning: There aren't cloud logs available for this cloud, therefore the user and exact timestamp can't be loaded")
86
- return False
87
-
88
- def actor(self):
89
- """
90
- Returns the user that performed the cloud activity as scratchattach.user.User object
91
- """
92
- if self.username is None:
93
- return None
94
- from scratchattach.site import user
95
- from scratchattach.utils import exceptions
96
- return self._make_linked_object("username", self.username, user.User, exceptions.UserNotFound)
97
-
98
- def project(self):
99
- """
100
- Returns the project where the cloud activity was performed as scratchattach.project.Project object
101
- """
102
- if self.cloud is None:
103
- return None
104
- from scratchattach.site import project
105
- from scratchattach.utils import exceptions
106
- return self._make_linked_object("id", self.cloud.project_id, project.Project, exceptions.ProjectNotFound)
107
-
@@ -1,242 +0,0 @@
1
- """Comment class"""
2
- from __future__ import annotations
3
-
4
- import html
5
- from typing import Union, Optional, Any
6
- from typing_extensions import assert_never # importing from typing caused me errors
7
- from enum import Enum, auto
8
-
9
- from . import user, project, studio
10
- from ._base import BaseSiteComponent
11
- from scratchattach.utils import exceptions
12
-
13
- class Comment(BaseSiteComponent):
14
- """
15
- Represents a Scratch comment (on a profile, studio or project)
16
- """
17
- id: Union[int, str]
18
- source: str
19
- source_id: Union[int, str]
20
- cached_replies: Optional[list[Comment]]
21
- parent_id: Optional[Union[int, str]]
22
- cached_parent_comment: Optional[Comment]
23
- commentee_id: Optional[int]
24
- content: Any
25
-
26
- def __str__(self):
27
- return str(self.content)
28
-
29
- def __init__(self, **entries):
30
-
31
- # Set attributes every Comment object needs to have:
32
- self.id = None
33
- self._session = None
34
- self.source = None
35
- self.source_id = None
36
- self.cached_replies = None
37
- self.parent_id = None
38
- self.cached_parent_comment = None
39
-
40
- # Update attributes from entries dict:
41
- self.__dict__.update(entries)
42
-
43
- if "source" not in entries:
44
- self.source = "Unknown"
45
-
46
- def update(self):
47
- print("Warning: Comment objects can't be updated")
48
- return False # Objects of this type cannot be updated
49
-
50
- def _update_from_dict(self, data):
51
- try:
52
- self.id = data["id"]
53
- except Exception:
54
- pass
55
- try:
56
- self.parent_id = data["parent_id"]
57
- except Exception:
58
- pass
59
- try:
60
- self.commentee_id = data["commentee_id"]
61
- except Exception:
62
- pass
63
- try:
64
- self.content = data["content"]
65
- except Exception:
66
- pass
67
- try:
68
- self.datetime_created = data["datetime_created"]
69
- except Exception:
70
- pass
71
- try:
72
- self.author_name = data["author"]["username"]
73
- except Exception:
74
- pass
75
- try:
76
- self.author_id = data["author"]["id"]
77
- except Exception:
78
- pass
79
- try:
80
- self.written_by_scratchteam = data["author"]["scratchteam"]
81
- except Exception:
82
- pass
83
- try:
84
- self.reply_count = data["reply_count"]
85
- except Exception:
86
- pass
87
- try:
88
- self.source = data["source"]
89
- except Exception:
90
- pass
91
- try:
92
- self.source_id = data["source_id"]
93
- except Exception:
94
- pass
95
- return True
96
-
97
- @property
98
- def text(self) -> str:
99
- if self.source == "profile":
100
- return self.content
101
- return str(html.unescape(self.content))
102
-
103
- # Methods for getting related entities
104
-
105
- def author(self) -> user.User:
106
- return self._make_linked_object("username", self.author_name, user.User, exceptions.UserNotFound)
107
-
108
- def place(self) -> user.User | studio.Studio | project.Project:
109
- """
110
- Returns the place (the project, profile or studio) where the comment was posted as Project, User, or Studio object.
111
-
112
- If the place can't be traced back, None is returned.
113
- """
114
- if self.source == "profile":
115
- return self._make_linked_object("username", self.source_id, user.User, exceptions.UserNotFound)
116
- elif self.source == "studio":
117
- return self._make_linked_object("id", self.source_id, studio.Studio, exceptions.UserNotFound)
118
- elif self.source == "project":
119
- return self._make_linked_object("id", self.source_id, project.Project, exceptions.UserNotFound)
120
- else:
121
- raise ValueError("Unknown source.")
122
-
123
- def parent_comment(self) -> Comment | None:
124
- if self.parent_id is None:
125
- return None
126
-
127
- if self.cached_parent_comment is not None:
128
- return self.cached_parent_comment
129
-
130
- if self.source == "profile":
131
- self.cached_parent_comment = user.User(username=self.source_id, _session=self._session).comment_by_id(
132
- self.parent_id)
133
-
134
- elif self.source == "project":
135
- p = project.Project(id=self.source_id, _session=self._session)
136
- p.update()
137
- self.cached_parent_comment = p.comment_by_id(self.parent_id)
138
-
139
- elif self.source == "studio":
140
- self.cached_parent_comment = studio.Studio(id=self.source_id, _session=self._session).comment_by_id(
141
- self.parent_id)
142
-
143
- return self.cached_parent_comment
144
-
145
- def replies(self, *, use_cache: bool = True, limit=40, offset=0):
146
- """
147
- Keyword Arguments:
148
- use_cache (bool): Returns the replies cached on the first reply fetch. This makes it SIGNIFICANTLY faster for profile comments. Warning: For profile comments, the replies are retrieved and cached on object creation.
149
- """
150
- if (self.cached_replies is None) or (not use_cache):
151
- if self.source == "profile":
152
- _cached_replies = user.User(username=self.source_id, _session=self._session).comment_by_id(
153
- self.id).cached_replies
154
- if _cached_replies is not None:
155
- self.cached_replies = _cached_replies[offset:offset + limit]
156
-
157
- elif self.source == "project":
158
- p = project.Project(id=self.source_id, _session=self._session)
159
- p.update()
160
- self.cached_replies = p.comment_replies(comment_id=self.id, limit=limit, offset=offset)
161
-
162
- elif self.source == "studio":
163
- self.cached_replies = studio.Studio(id=self.source_id, _session=self._session).comment_replies(
164
- comment_id=self.id, limit=limit, offset=offset)
165
-
166
- return self.cached_replies
167
-
168
- # Methods for dealing with the comment
169
-
170
- def reply(self, content, *, commentee_id=None):
171
- """
172
- Posts a reply comment to the comment.
173
-
174
- Warning:
175
- Scratch only shows comments replying to top-level comments, and all replies to replies are actually replies to top-level comments in the API.
176
-
177
- Therefore, if this comment is a reply, this method will not reply to the comment itself but to the corresponding top-level comment.
178
-
179
- Args:
180
- content (str): Comment content to post.
181
-
182
- Keyword args:
183
- commentee_id (None or str): If set to None (default), it will automatically fill out the commentee ID with the user ID of the parent comment author. Set it to "" to mention no user.
184
-
185
-
186
- Returns:
187
- scratchattach.Comment: The created comment.
188
- """
189
-
190
- self._assert_auth()
191
- parent_id = str(self.id)
192
- if self.parent_id is not None:
193
- parent_id = str(self.parent_id)
194
- if commentee_id is None:
195
- if "author_id" in self.__dict__:
196
- commentee_id = self.author_id
197
- else:
198
- commentee_id = ""
199
- if self.source == "profile":
200
- return user.User(username=self.source_id, _session=self._session).reply_comment(content,
201
- parent_id=str(parent_id),
202
- commentee_id=commentee_id)
203
- if self.source == "project":
204
- p = project.Project(id=self.source_id, _session=self._session)
205
- p.update()
206
- return p.reply_comment(content, parent_id=str(parent_id), commentee_id=commentee_id)
207
- if self.source == "studio":
208
- return studio.Studio(id=self.source_id, _session=self._session).reply_comment(content,
209
- parent_id=str(parent_id),
210
- commentee_id=commentee_id)
211
-
212
- def delete(self):
213
- """
214
- Deletes the comment.
215
- """
216
- self._assert_auth()
217
- if self.source == "profile":
218
- user.User(username=self.source_id, _session=self._session).delete_comment(comment_id=self.id)
219
-
220
- elif self.source == "project":
221
- p = project.Project(id=self.source_id, _session=self._session)
222
- p.update()
223
- p.delete_comment(comment_id=self.id)
224
-
225
- elif self.source == "studio":
226
- studio.Studio(id=self.source_id, _session=self._session).delete_comment(comment_id=self.id)
227
-
228
- def report(self):
229
- """
230
- Reports the comment to the Scratch team.
231
- """
232
- self._assert_auth()
233
- if self.source == "profile":
234
- user.User(username=self.source_id, _session=self._session).report_comment(comment_id=self.id)
235
-
236
- elif self.source == "project":
237
- p = project.Project(id=self.source_id, _session=self._session)
238
- p.update()
239
- p.report_comment(comment_id=self.id)
240
-
241
- elif self.source == "studio":
242
- studio.Studio(id=self.source_id, _session=self._session).report_comment(comment_id=self.id)