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.
- scratchattach/__init__.py +14 -6
- scratchattach/__main__.py +93 -0
- {scratchattach-2.1.14.dist-info → scratchattach-3.0.0b0.dist-info}/METADATA +7 -11
- scratchattach-3.0.0b0.dist-info/RECORD +8 -0
- {scratchattach-2.1.14.dist-info → scratchattach-3.0.0b0.dist-info}/WHEEL +1 -1
- scratchattach-3.0.0b0.dist-info/entry_points.txt +2 -0
- scratchattach/cloud/__init__.py +0 -2
- scratchattach/cloud/_base.py +0 -458
- scratchattach/cloud/cloud.py +0 -183
- scratchattach/editor/__init__.py +0 -21
- scratchattach/editor/asset.py +0 -253
- scratchattach/editor/backpack_json.py +0 -117
- scratchattach/editor/base.py +0 -193
- scratchattach/editor/block.py +0 -579
- scratchattach/editor/blockshape.py +0 -357
- scratchattach/editor/build_defaulting.py +0 -51
- scratchattach/editor/code_translation/__init__.py +0 -0
- scratchattach/editor/code_translation/parse.py +0 -177
- scratchattach/editor/comment.py +0 -80
- scratchattach/editor/commons.py +0 -306
- scratchattach/editor/extension.py +0 -50
- scratchattach/editor/field.py +0 -99
- scratchattach/editor/inputs.py +0 -135
- scratchattach/editor/meta.py +0 -114
- scratchattach/editor/monitor.py +0 -183
- scratchattach/editor/mutation.py +0 -324
- scratchattach/editor/pallete.py +0 -90
- scratchattach/editor/prim.py +0 -170
- scratchattach/editor/project.py +0 -279
- scratchattach/editor/sprite.py +0 -599
- scratchattach/editor/twconfig.py +0 -114
- scratchattach/editor/vlb.py +0 -134
- scratchattach/eventhandlers/__init__.py +0 -0
- scratchattach/eventhandlers/_base.py +0 -100
- scratchattach/eventhandlers/cloud_events.py +0 -110
- scratchattach/eventhandlers/cloud_recorder.py +0 -26
- scratchattach/eventhandlers/cloud_requests.py +0 -459
- scratchattach/eventhandlers/cloud_server.py +0 -246
- scratchattach/eventhandlers/cloud_storage.py +0 -136
- scratchattach/eventhandlers/combine.py +0 -30
- scratchattach/eventhandlers/filterbot.py +0 -161
- scratchattach/eventhandlers/message_events.py +0 -42
- scratchattach/other/__init__.py +0 -0
- scratchattach/other/other_apis.py +0 -284
- scratchattach/other/project_json_capabilities.py +0 -475
- scratchattach/site/__init__.py +0 -0
- scratchattach/site/_base.py +0 -66
- scratchattach/site/activity.py +0 -382
- scratchattach/site/alert.py +0 -227
- scratchattach/site/backpack_asset.py +0 -118
- scratchattach/site/browser_cookie3_stub.py +0 -17
- scratchattach/site/browser_cookies.py +0 -61
- scratchattach/site/classroom.py +0 -447
- scratchattach/site/cloud_activity.py +0 -107
- scratchattach/site/comment.py +0 -242
- scratchattach/site/forum.py +0 -432
- scratchattach/site/project.py +0 -825
- scratchattach/site/session.py +0 -1238
- scratchattach/site/studio.py +0 -611
- scratchattach/site/user.py +0 -956
- scratchattach/utils/__init__.py +0 -0
- scratchattach/utils/commons.py +0 -255
- scratchattach/utils/encoder.py +0 -158
- scratchattach/utils/enums.py +0 -236
- scratchattach/utils/exceptions.py +0 -243
- scratchattach/utils/requests.py +0 -93
- scratchattach-2.1.14.dist-info/RECORD +0 -66
- {scratchattach-2.1.14.dist-info → scratchattach-3.0.0b0.dist-info}/licenses/LICENSE +0 -0
- {scratchattach-2.1.14.dist-info → scratchattach-3.0.0b0.dist-info}/top_level.txt +0 -0
scratchattach/site/studio.py
DELETED
|
@@ -1,611 +0,0 @@
|
|
|
1
|
-
"""Studio class"""
|
|
2
|
-
from __future__ import annotations
|
|
3
|
-
|
|
4
|
-
import json
|
|
5
|
-
import random
|
|
6
|
-
from . import user, comment, project, activity
|
|
7
|
-
from scratchattach.utils import exceptions, commons
|
|
8
|
-
from scratchattach.utils.commons import api_iterative, headers
|
|
9
|
-
from ._base import BaseSiteComponent
|
|
10
|
-
|
|
11
|
-
from scratchattach.utils.requests import requests
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class Studio(BaseSiteComponent):
|
|
15
|
-
"""
|
|
16
|
-
Represents a Scratch studio.
|
|
17
|
-
|
|
18
|
-
Attributes:
|
|
19
|
-
|
|
20
|
-
:.id:
|
|
21
|
-
|
|
22
|
-
:.title:
|
|
23
|
-
|
|
24
|
-
:.description:
|
|
25
|
-
|
|
26
|
-
:.host_id: The user id of the studio host
|
|
27
|
-
|
|
28
|
-
:.open_to_all: Whether everyone is allowed to add projects
|
|
29
|
-
|
|
30
|
-
:.comments_allowed:
|
|
31
|
-
|
|
32
|
-
:.image_url:
|
|
33
|
-
|
|
34
|
-
:.created:
|
|
35
|
-
|
|
36
|
-
:.modified:
|
|
37
|
-
|
|
38
|
-
:.follower_count:
|
|
39
|
-
|
|
40
|
-
:.manager_count:
|
|
41
|
-
|
|
42
|
-
:.project_count:
|
|
43
|
-
|
|
44
|
-
:.update(): Updates the attributes
|
|
45
|
-
|
|
46
|
-
"""
|
|
47
|
-
|
|
48
|
-
def __init__(self, **entries):
|
|
49
|
-
|
|
50
|
-
# Info on how the .update method has to fetch the data:
|
|
51
|
-
self.update_function = requests.get
|
|
52
|
-
self.update_api = f"https://api.scratch.mit.edu/studios/{entries['id']}"
|
|
53
|
-
|
|
54
|
-
# Set attributes every Project object needs to have:
|
|
55
|
-
self._session = None
|
|
56
|
-
self.id = 0
|
|
57
|
-
|
|
58
|
-
# Update attributes from entries dict:
|
|
59
|
-
self.__dict__.update(entries)
|
|
60
|
-
|
|
61
|
-
# Headers and cookies:
|
|
62
|
-
if self._session is None:
|
|
63
|
-
self._headers = headers
|
|
64
|
-
self._cookies = {}
|
|
65
|
-
else:
|
|
66
|
-
self._headers = self._session._headers
|
|
67
|
-
self._cookies = self._session._cookies
|
|
68
|
-
|
|
69
|
-
# Headers for operations that require accept and Content-Type fields:
|
|
70
|
-
self._json_headers = dict(self._headers)
|
|
71
|
-
self._json_headers["accept"] = "application/json"
|
|
72
|
-
self._json_headers["Content-Type"] = "application/json"
|
|
73
|
-
|
|
74
|
-
def _update_from_dict(self, studio):
|
|
75
|
-
try: self.id = int(studio["id"])
|
|
76
|
-
except Exception: pass
|
|
77
|
-
try: self.title = studio["title"]
|
|
78
|
-
except Exception: pass
|
|
79
|
-
try: self.description = studio["description"]
|
|
80
|
-
except Exception: pass
|
|
81
|
-
try: self.host_id = studio["host"]
|
|
82
|
-
except Exception: pass
|
|
83
|
-
try: self.open_to_all = studio["open_to_all"]
|
|
84
|
-
except Exception: pass
|
|
85
|
-
try: self.comments_allowed = studio["comments_allowed"]
|
|
86
|
-
except Exception: pass
|
|
87
|
-
try: self.image_url = studio["image"]
|
|
88
|
-
except Exception: pass
|
|
89
|
-
try: self.created = studio["history"]["created"]
|
|
90
|
-
except Exception: pass
|
|
91
|
-
try: self.modified = studio["history"]["modified"]
|
|
92
|
-
except Exception: pass
|
|
93
|
-
try: self.follower_count = studio["stats"]["followers"]
|
|
94
|
-
except Exception: pass
|
|
95
|
-
try: self.manager_count = studio["stats"]["managers"]
|
|
96
|
-
except Exception: pass
|
|
97
|
-
try: self.project_count = studio["stats"]["projects"]
|
|
98
|
-
except Exception: pass
|
|
99
|
-
return True
|
|
100
|
-
|
|
101
|
-
def follow(self):
|
|
102
|
-
"""
|
|
103
|
-
You can only use this function if this object was created using :meth:`scratchattach.session.Session.connect_studio`
|
|
104
|
-
"""
|
|
105
|
-
self._assert_auth()
|
|
106
|
-
requests.put(
|
|
107
|
-
f"https://scratch.mit.edu/site-api/users/bookmarkers/{self.id}/add/?usernames={self._session._username}",
|
|
108
|
-
headers=headers,
|
|
109
|
-
cookies=self._cookies,
|
|
110
|
-
timeout=10,
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
def unfollow(self):
|
|
114
|
-
"""
|
|
115
|
-
You can only use this function if this object was created using :meth:`scratchattach.session.Session.connect_studio`
|
|
116
|
-
"""
|
|
117
|
-
self._assert_auth()
|
|
118
|
-
requests.put(
|
|
119
|
-
f"https://scratch.mit.edu/site-api/users/bookmarkers/{self.id}/remove/?usernames={self._session._username}",
|
|
120
|
-
headers=headers,
|
|
121
|
-
cookies=self._cookies,
|
|
122
|
-
timeout=10,
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
def comments(self, *, limit=40, offset=0) -> list[comment.Comment]:
|
|
126
|
-
"""
|
|
127
|
-
Returns the comments posted on the studio (except for replies. To get replies use :meth:`scratchattach.studio.Studio.get_comment_replies`).
|
|
128
|
-
|
|
129
|
-
Keyword Arguments:
|
|
130
|
-
page: The page of the comments that should be returned.
|
|
131
|
-
limit: Max. amount of returned comments.
|
|
132
|
-
|
|
133
|
-
Returns:
|
|
134
|
-
list<Comment>: A list containing the requested comments as Comment objects.
|
|
135
|
-
"""
|
|
136
|
-
response = commons.api_iterative(
|
|
137
|
-
f"https://api.scratch.mit.edu/studios/{self.id}/comments/", limit=limit, offset=offset, add_params=f"&cachebust={random.randint(0,9999)}")
|
|
138
|
-
for i in response:
|
|
139
|
-
i["source"] = "studio"
|
|
140
|
-
i["source_id"] = self.id
|
|
141
|
-
return commons.parse_object_list(response, comment.Comment, self._session)
|
|
142
|
-
|
|
143
|
-
def comment_replies(self, *, comment_id, limit=40, offset=0) -> list[comment.Comment]:
|
|
144
|
-
response = commons.api_iterative(
|
|
145
|
-
f"https://api.scratch.mit.edu/studios/{self.id}/comments/{comment_id}/replies", limit=limit, offset=offset, add_params=f"&cachebust={random.randint(0,9999)}")
|
|
146
|
-
for x in response:
|
|
147
|
-
x["parent_id"] = comment_id
|
|
148
|
-
x["source"] = "studio"
|
|
149
|
-
x["source_id"] = self.id
|
|
150
|
-
return commons.parse_object_list(response, comment.Comment, self._session)
|
|
151
|
-
|
|
152
|
-
def comment_by_id(self, comment_id):
|
|
153
|
-
r = requests.get(
|
|
154
|
-
f"https://api.scratch.mit.edu/studios/{self.id}/comments/{comment_id}",
|
|
155
|
-
timeout=10,
|
|
156
|
-
).json()
|
|
157
|
-
if r is None:
|
|
158
|
-
raise exceptions.CommentNotFound()
|
|
159
|
-
_comment = comment.Comment(id=r["id"], _session=self._session, source="studio", source_id=self.id)
|
|
160
|
-
_comment._update_from_dict(r)
|
|
161
|
-
return _comment
|
|
162
|
-
|
|
163
|
-
def post_comment(self, content, *, parent_id="", commentee_id=""):
|
|
164
|
-
"""
|
|
165
|
-
Posts a comment on the studio. You can only use this function if this object was created using :meth:`scratchattach.session.Session.connect_studio`
|
|
166
|
-
|
|
167
|
-
Args:
|
|
168
|
-
content: Content of the comment that should be posted
|
|
169
|
-
|
|
170
|
-
Keyword Arguments:
|
|
171
|
-
parent_id: ID of the comment you want to reply to. If you don't want to mention a user, don't put the argument.
|
|
172
|
-
commentee_id: ID of the user that will be mentioned in your comment and will receive a message about your comment. If you don't want to mention a user, don't put the argument.
|
|
173
|
-
|
|
174
|
-
Returns:
|
|
175
|
-
scratchattach.comment.Comment: The posted comment as Comment object.
|
|
176
|
-
"""
|
|
177
|
-
self._assert_auth()
|
|
178
|
-
data = {
|
|
179
|
-
"commentee_id": commentee_id,
|
|
180
|
-
"content": str(content),
|
|
181
|
-
"parent_id": parent_id,
|
|
182
|
-
}
|
|
183
|
-
headers = dict(self._json_headers)
|
|
184
|
-
headers["referer"] = "https://scratch.mit.edu/projects/" + str(self.id) + "/"
|
|
185
|
-
r = requests.post(
|
|
186
|
-
f"https://api.scratch.mit.edu/proxy/comments/studio/{self.id}/",
|
|
187
|
-
headers=headers,
|
|
188
|
-
cookies=self._cookies,
|
|
189
|
-
data=json.dumps(data),
|
|
190
|
-
timeout=10,
|
|
191
|
-
).json()
|
|
192
|
-
if "id" not in r:
|
|
193
|
-
raise exceptions.CommentPostFailure(r)
|
|
194
|
-
_comment = comment.Comment(id=r["id"], _session=self._session, source="studio", source_id=self.id)
|
|
195
|
-
_comment._update_from_dict(r)
|
|
196
|
-
return _comment
|
|
197
|
-
|
|
198
|
-
def delete_comment(self, *, comment_id):
|
|
199
|
-
# NEEDS TO BE TESTED!
|
|
200
|
-
"""
|
|
201
|
-
Deletes a comment by ID. You can only use this function if this object was created using :meth:`scratchattach.session.Session.connect_project`
|
|
202
|
-
|
|
203
|
-
Args:
|
|
204
|
-
comment_id: The id of the comment that should be deleted
|
|
205
|
-
"""
|
|
206
|
-
self._assert_auth()
|
|
207
|
-
return requests.delete(
|
|
208
|
-
f"https://api.scratch.mit.edu/proxy/comments/studio/{self.id}/comment/{comment_id}/",
|
|
209
|
-
headers=self._headers,
|
|
210
|
-
cookies=self._cookies,
|
|
211
|
-
).headers
|
|
212
|
-
|
|
213
|
-
def report_comment(self, *, comment_id):
|
|
214
|
-
# NEEDS TO BE TESTED!
|
|
215
|
-
"""
|
|
216
|
-
Reports a comment by ID to the Scratch team. You can only use this function if this object was created using :meth:`scratchattach.session.Session.connect_project`
|
|
217
|
-
|
|
218
|
-
Args:
|
|
219
|
-
comment_id: The id of the comment that should be reported
|
|
220
|
-
"""
|
|
221
|
-
self._assert_auth()
|
|
222
|
-
return requests.delete(
|
|
223
|
-
f"https://api.scratch.mit.edu/proxy/comments/studio/{self.id}/comment/{comment_id}/report",
|
|
224
|
-
headers=self._headers,
|
|
225
|
-
cookies=self._cookies,
|
|
226
|
-
)
|
|
227
|
-
|
|
228
|
-
def set_thumbnail(self, *, file):
|
|
229
|
-
"""
|
|
230
|
-
Sets the studio thumbnail. You can only use this function if this object was created using :meth:`scratchattach.session.Session.connect_studio`
|
|
231
|
-
|
|
232
|
-
Keyword Arguments:
|
|
233
|
-
file: The path to the image file
|
|
234
|
-
|
|
235
|
-
Returns:
|
|
236
|
-
str: Scratch cdn link to the set thumbnail
|
|
237
|
-
"""
|
|
238
|
-
self._assert_auth()
|
|
239
|
-
with open(file, "rb") as f:
|
|
240
|
-
thumbnail = f.read()
|
|
241
|
-
|
|
242
|
-
filename = file.replace("\\", "/")
|
|
243
|
-
if filename.endswith("/"):
|
|
244
|
-
filename = filename[:-1]
|
|
245
|
-
filename = filename.split("/").pop()
|
|
246
|
-
|
|
247
|
-
file_type = filename.split(".").pop()
|
|
248
|
-
|
|
249
|
-
payload1 = f'------WebKitFormBoundaryhKZwFjoxAyUTMlSh\r\nContent-Disposition: form-data; name="file"; filename="{filename}"\r\nContent-Type: image/{file_type}\r\n\r\n'
|
|
250
|
-
payload1 = payload1.encode("utf-8")
|
|
251
|
-
payload2 = b"\r\n------WebKitFormBoundaryhKZwFjoxAyUTMlSh--\r\n"
|
|
252
|
-
payload = b"".join([payload1, thumbnail, payload2])
|
|
253
|
-
|
|
254
|
-
r = requests.post(
|
|
255
|
-
f"https://scratch.mit.edu/site-api/galleries/all/{self.id}/",
|
|
256
|
-
headers={
|
|
257
|
-
"accept": "*/",
|
|
258
|
-
"content-type": "multipart/form-data; boundary=----WebKitFormBoundaryhKZwFjoxAyUTMlSh",
|
|
259
|
-
"Referer": "https://scratch.mit.edu/",
|
|
260
|
-
"x-csrftoken": "a",
|
|
261
|
-
"x-requested-with": "XMLHttpRequest",
|
|
262
|
-
},
|
|
263
|
-
data=payload,
|
|
264
|
-
cookies=self._cookies,
|
|
265
|
-
timeout=10,
|
|
266
|
-
).json()
|
|
267
|
-
|
|
268
|
-
if "errors" in r:
|
|
269
|
-
raise (exceptions.BadRequest(", ".join(r["errors"])))
|
|
270
|
-
else:
|
|
271
|
-
return r["thumbnail_url"]
|
|
272
|
-
|
|
273
|
-
def reply_comment(self, content, *, parent_id, commentee_id=""):
|
|
274
|
-
"""
|
|
275
|
-
Posts a reply to a comment on the studio. You can only use this function if this object was created using :meth:`scratchattach.session.Session.connect_studio`
|
|
276
|
-
|
|
277
|
-
Args:
|
|
278
|
-
content: Content of the comment that should be posted
|
|
279
|
-
|
|
280
|
-
Warning:
|
|
281
|
-
Only replies to top-level comments are shown on the Scratch website. Replies to replies are actually replies to the corresponding top-level comment in the API.
|
|
282
|
-
|
|
283
|
-
Therefore, parent_id should be the comment id of a top level comment.
|
|
284
|
-
|
|
285
|
-
Keyword Arguments:
|
|
286
|
-
parent_id: ID of the comment you want to reply to
|
|
287
|
-
commentee_id: ID of the user you are replying to
|
|
288
|
-
"""
|
|
289
|
-
self._assert_auth()
|
|
290
|
-
return self.post_comment(
|
|
291
|
-
content, parent_id=parent_id, commentee_id=commentee_id
|
|
292
|
-
)
|
|
293
|
-
|
|
294
|
-
def projects(self, limit=40, offset=0):
|
|
295
|
-
"""
|
|
296
|
-
Gets the studio projects.
|
|
297
|
-
|
|
298
|
-
Keyword arguments:
|
|
299
|
-
limit (int): Max amount of returned projects.
|
|
300
|
-
offset (int): Offset of the first returned project.
|
|
301
|
-
|
|
302
|
-
Returns:
|
|
303
|
-
list<scratchattach.project.Project>: A list containing the studio projects as Project objects
|
|
304
|
-
"""
|
|
305
|
-
response = commons.api_iterative(
|
|
306
|
-
f"https://api.scratch.mit.edu/studios/{self.id}/projects", limit=limit, offset=offset)
|
|
307
|
-
return commons.parse_object_list(response, project.Project, self._session)
|
|
308
|
-
|
|
309
|
-
def curators(self, limit=40, offset=0):
|
|
310
|
-
"""
|
|
311
|
-
Gets the studio curators.
|
|
312
|
-
|
|
313
|
-
Keyword arguments:
|
|
314
|
-
limit (int): Max amount of returned curators.
|
|
315
|
-
offset (int): Offset of the first returned curator.
|
|
316
|
-
|
|
317
|
-
Returns:
|
|
318
|
-
list<scratchattach.user.User>: A list containing the studio curators as User objects
|
|
319
|
-
"""
|
|
320
|
-
response = commons.api_iterative(
|
|
321
|
-
f"https://api.scratch.mit.edu/studios/{self.id}/curators", limit=limit, offset=offset)
|
|
322
|
-
return commons.parse_object_list(response, user.User, self._session, "username")
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
def invite_curator(self, curator):
|
|
326
|
-
"""
|
|
327
|
-
You can only use this function if this object was created using :meth:`scratchattach.session.Session.connect_studio`
|
|
328
|
-
"""
|
|
329
|
-
self._assert_auth()
|
|
330
|
-
try:
|
|
331
|
-
return requests.put(
|
|
332
|
-
f"https://scratch.mit.edu/site-api/users/curators-in/{self.id}/invite_curator/?usernames={curator}",
|
|
333
|
-
headers=headers,
|
|
334
|
-
cookies=self._cookies,
|
|
335
|
-
timeout=10,
|
|
336
|
-
).json()
|
|
337
|
-
except Exception:
|
|
338
|
-
raise (exceptions.Unauthorized)
|
|
339
|
-
|
|
340
|
-
def promote_curator(self, curator):
|
|
341
|
-
"""
|
|
342
|
-
You can only use this function if this object was created using :meth:`scratchattach.session.Session.connect_studio`
|
|
343
|
-
"""
|
|
344
|
-
self._assert_auth()
|
|
345
|
-
try:
|
|
346
|
-
return requests.put(
|
|
347
|
-
f"https://scratch.mit.edu/site-api/users/curators-in/{self.id}/promote/?usernames={curator}",
|
|
348
|
-
headers=headers,
|
|
349
|
-
cookies=self._cookies,
|
|
350
|
-
timeout=10,
|
|
351
|
-
).json()
|
|
352
|
-
except Exception:
|
|
353
|
-
raise (exceptions.Unauthorized)
|
|
354
|
-
|
|
355
|
-
def remove_curator(self, curator):
|
|
356
|
-
"""
|
|
357
|
-
You can only use this function if this object was created using :meth:`scratchattach.session.Session.connect_studio`
|
|
358
|
-
"""
|
|
359
|
-
self._assert_auth()
|
|
360
|
-
try:
|
|
361
|
-
return requests.put(
|
|
362
|
-
f"https://scratch.mit.edu/site-api/users/curators-in/{self.id}/remove/?usernames={curator}",
|
|
363
|
-
headers=headers,
|
|
364
|
-
cookies=self._cookies,
|
|
365
|
-
timeout=10,
|
|
366
|
-
).json()
|
|
367
|
-
except Exception:
|
|
368
|
-
raise (exceptions.Unauthorized)
|
|
369
|
-
|
|
370
|
-
def transfer_ownership(self, new_owner, *, password):
|
|
371
|
-
"""
|
|
372
|
-
Makes another Scratcher studio host. You need to specify your password to do this.
|
|
373
|
-
|
|
374
|
-
Arguments:
|
|
375
|
-
new_owner (str): Username of new host
|
|
376
|
-
|
|
377
|
-
Keyword arguments:
|
|
378
|
-
password (str): The password of your Scratch account
|
|
379
|
-
|
|
380
|
-
Warning:
|
|
381
|
-
This action is irreversible!
|
|
382
|
-
"""
|
|
383
|
-
self._assert_auth()
|
|
384
|
-
try:
|
|
385
|
-
return requests.put(
|
|
386
|
-
f"https://api.scratch.mit.edu/studios/{self.id}/transfer/{new_owner}",
|
|
387
|
-
headers=self._headers,
|
|
388
|
-
cookies=self._cookies,
|
|
389
|
-
timeout=10,
|
|
390
|
-
json={"password":password}
|
|
391
|
-
).json()
|
|
392
|
-
except Exception:
|
|
393
|
-
raise (exceptions.Unauthorized)
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
def leave(self):
|
|
397
|
-
"""
|
|
398
|
-
Removes yourself from the studio. You can only use this function if this object was created using :meth:`scratchattach.session.Session.connect_studio`
|
|
399
|
-
"""
|
|
400
|
-
self._assert_auth()
|
|
401
|
-
return self.remove_curator(self._session._username)
|
|
402
|
-
|
|
403
|
-
def add_project(self, project_id):
|
|
404
|
-
"""
|
|
405
|
-
Adds a project to the studio. You can only use this function if this object was created using :meth:`scratchattach.session.Session.connect_studio`
|
|
406
|
-
|
|
407
|
-
Args:
|
|
408
|
-
project_id: Project id of the project that should be added
|
|
409
|
-
"""
|
|
410
|
-
self._assert_auth()
|
|
411
|
-
return requests.post(
|
|
412
|
-
f"https://api.scratch.mit.edu/studios/{self.id}/project/{project_id}",
|
|
413
|
-
headers=self._headers,
|
|
414
|
-
timeout=10,
|
|
415
|
-
).json()
|
|
416
|
-
|
|
417
|
-
def remove_project(self, project_id):
|
|
418
|
-
"""
|
|
419
|
-
Removes a project from the studio. You can only use this function if this object was created using :meth:`scratchattach.session.Session.connect_studio`
|
|
420
|
-
|
|
421
|
-
Args:
|
|
422
|
-
project_id: Project id of the project that should be removed
|
|
423
|
-
"""
|
|
424
|
-
self._assert_auth()
|
|
425
|
-
return requests.delete(
|
|
426
|
-
f"https://api.scratch.mit.edu/studios/{self.id}/project/{project_id}",
|
|
427
|
-
headers=self._headers,
|
|
428
|
-
timeout=10,
|
|
429
|
-
).json()
|
|
430
|
-
|
|
431
|
-
def managers(self, limit=40, offset=0):
|
|
432
|
-
"""
|
|
433
|
-
Gets the studio managers.
|
|
434
|
-
|
|
435
|
-
Keyword arguments:
|
|
436
|
-
limit (int): Max amount of returned managers
|
|
437
|
-
offset (int): Offset of the first returned manager.
|
|
438
|
-
|
|
439
|
-
Returns:
|
|
440
|
-
list<scratchattach.user.User>: A list containing the studio managers as user objects
|
|
441
|
-
"""
|
|
442
|
-
response = commons.api_iterative(
|
|
443
|
-
f"https://api.scratch.mit.edu/studios/{self.id}/managers", limit=limit, offset=offset)
|
|
444
|
-
return commons.parse_object_list(response, user.User, self._session, "username")
|
|
445
|
-
|
|
446
|
-
def host(self):
|
|
447
|
-
"""
|
|
448
|
-
Gets the studio host.
|
|
449
|
-
|
|
450
|
-
Returns:
|
|
451
|
-
scratchattach.user.User: An object representing the studio host.
|
|
452
|
-
"""
|
|
453
|
-
managers = self.managers(limit=1, offset=0)
|
|
454
|
-
try:
|
|
455
|
-
return managers[0]
|
|
456
|
-
except Exception:
|
|
457
|
-
return None
|
|
458
|
-
|
|
459
|
-
def set_fields(self, fields_dict):
|
|
460
|
-
"""
|
|
461
|
-
Sets fields. Uses the scratch.mit.edu/site-api PUT API.
|
|
462
|
-
"""
|
|
463
|
-
self._assert_auth()
|
|
464
|
-
requests.put(
|
|
465
|
-
f"https://scratch.mit.edu/site-api/galleries/all/{self.id}/",
|
|
466
|
-
headers=headers,
|
|
467
|
-
cookies=self._cookies,
|
|
468
|
-
data=json.dumps(fields_dict),
|
|
469
|
-
timeout=10,
|
|
470
|
-
)
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
def set_description(self, new):
|
|
474
|
-
"""
|
|
475
|
-
You can only use this function if this object was created using :meth:`scratchattach.session.Session.connect_studio`
|
|
476
|
-
"""
|
|
477
|
-
self.set_fields({"description": new + "\n"})
|
|
478
|
-
|
|
479
|
-
def set_title(self, new):
|
|
480
|
-
"""
|
|
481
|
-
You can only use this function if this object was created using :meth:`scratchattach.session.Session.connect_studio`
|
|
482
|
-
"""
|
|
483
|
-
self.set_fields({"title": new})
|
|
484
|
-
|
|
485
|
-
def open_projects(self):
|
|
486
|
-
"""
|
|
487
|
-
Changes the studio settings so everyone (including non-curators) is able to add projects to the studio. You can only use this function if this object was created using :meth:`scratchattach.session.Session.connect_studio`
|
|
488
|
-
"""
|
|
489
|
-
self._assert_auth()
|
|
490
|
-
requests.put(
|
|
491
|
-
f"https://scratch.mit.edu/site-api/galleries/{self.id}/mark/open/",
|
|
492
|
-
headers=headers,
|
|
493
|
-
cookies=self._cookies,
|
|
494
|
-
timeout=10,
|
|
495
|
-
)
|
|
496
|
-
|
|
497
|
-
def close_projects(self):
|
|
498
|
-
"""
|
|
499
|
-
Changes the studio settings so only curators can add projects to the studio. You can only use this function if this object was created using :meth:`scratchattach.session.Session.connect_studio`
|
|
500
|
-
"""
|
|
501
|
-
self._assert_auth()
|
|
502
|
-
requests.put(
|
|
503
|
-
f"https://scratch.mit.edu/site-api/galleries/{self.id}/mark/closed/",
|
|
504
|
-
headers=headers,
|
|
505
|
-
cookies=self._cookies,
|
|
506
|
-
timeout=10,
|
|
507
|
-
)
|
|
508
|
-
|
|
509
|
-
def turn_off_commenting(self):
|
|
510
|
-
"""
|
|
511
|
-
You can only use this function if this object was created using :meth:`scratchattach.session.Session.connect_studio`
|
|
512
|
-
"""
|
|
513
|
-
self._assert_auth()
|
|
514
|
-
if self.comments_allowed:
|
|
515
|
-
requests.post(
|
|
516
|
-
f"https://scratch.mit.edu/site-api/comments/gallery/{self.id}/toggle-comments/",
|
|
517
|
-
headers=headers,
|
|
518
|
-
cookies=self._cookies,
|
|
519
|
-
timeout=10,
|
|
520
|
-
)
|
|
521
|
-
self.comments_allowed = not self.comments_allowed
|
|
522
|
-
|
|
523
|
-
def turn_on_commenting(self):
|
|
524
|
-
"""
|
|
525
|
-
You can only use this function if this object was created using :meth:`scratchattach.session.Session.connect_studio`
|
|
526
|
-
"""
|
|
527
|
-
self._assert_auth()
|
|
528
|
-
if not self.comments_allowed:
|
|
529
|
-
requests.post(
|
|
530
|
-
f"https://scratch.mit.edu/site-api/comments/gallery/{self.id}/toggle-comments/",
|
|
531
|
-
headers=headers,
|
|
532
|
-
cookies=self._cookies,
|
|
533
|
-
timeout=10,
|
|
534
|
-
)
|
|
535
|
-
self.comments_allowed = not self.comments_allowed
|
|
536
|
-
|
|
537
|
-
def toggle_commenting(self):
|
|
538
|
-
"""
|
|
539
|
-
You can only use this function if this object was created using :meth:`scratchattach.session.Session.connect_studio`
|
|
540
|
-
"""
|
|
541
|
-
self._assert_auth()
|
|
542
|
-
requests.post(
|
|
543
|
-
f"https://scratch.mit.edu/site-api/comments/gallery/{self.id}/toggle-comments/",
|
|
544
|
-
headers=headers,
|
|
545
|
-
cookies=self._cookies,
|
|
546
|
-
timeout=10,
|
|
547
|
-
)
|
|
548
|
-
self.comments_allowed = not self.comments_allowed
|
|
549
|
-
|
|
550
|
-
def activity(self, *, limit=40, offset=0, date_limit=None):
|
|
551
|
-
add_params = ""
|
|
552
|
-
if date_limit is not None:
|
|
553
|
-
add_params = f"&dateLimit={date_limit}"
|
|
554
|
-
response = commons.api_iterative(
|
|
555
|
-
f"https://api.scratch.mit.edu/studios/{self.id}/activity", limit=limit, offset=offset, add_params=add_params)
|
|
556
|
-
return commons.parse_object_list(response, activity.Activity, self._session)
|
|
557
|
-
|
|
558
|
-
def accept_invite(self):
|
|
559
|
-
self._assert_auth()
|
|
560
|
-
return requests.put(
|
|
561
|
-
f"https://scratch.mit.edu/site-api/users/curators-in/{self.id}/add/?usernames={self._session._username}",
|
|
562
|
-
headers=headers,
|
|
563
|
-
cookies=self._cookies,
|
|
564
|
-
timeout=10,
|
|
565
|
-
).json()
|
|
566
|
-
|
|
567
|
-
def your_role(self):
|
|
568
|
-
"""
|
|
569
|
-
Returns a dict with information about your role in the studio (whether you're following, curating, managing it or are invited)
|
|
570
|
-
"""
|
|
571
|
-
self._assert_auth()
|
|
572
|
-
return requests.get(
|
|
573
|
-
f"https://api.scratch.mit.edu/studios/{self.id}/users/{self._session.username}",
|
|
574
|
-
headers=self._headers,
|
|
575
|
-
cookies=self._cookies,
|
|
576
|
-
timeout=10,
|
|
577
|
-
).json()
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
def get_studio(studio_id) -> Studio:
|
|
581
|
-
"""
|
|
582
|
-
Gets a studio without logging in.
|
|
583
|
-
|
|
584
|
-
Args:
|
|
585
|
-
studio_id (int): Studio id of the requested studio
|
|
586
|
-
|
|
587
|
-
Returns:
|
|
588
|
-
scratchattach.studio.Studio: An object representing the requested studio
|
|
589
|
-
|
|
590
|
-
Warning:
|
|
591
|
-
Any methods that authentication (like studio.follow) will not work on the returned object.
|
|
592
|
-
|
|
593
|
-
If you want to use these, get the studio with :meth:`scratchattach.session.Session.connect_studio` instead.
|
|
594
|
-
"""
|
|
595
|
-
print("Warning: For methods that require authentication, use session.connect_studio instead of get_studio")
|
|
596
|
-
return commons._get_object("id", studio_id, Studio, exceptions.StudioNotFound)
|
|
597
|
-
|
|
598
|
-
def search_studios(*, query="", mode="trending", language="en", limit=40, offset=0):
|
|
599
|
-
if not query:
|
|
600
|
-
raise ValueError("The query can't be empty for search")
|
|
601
|
-
response = commons.api_iterative(
|
|
602
|
-
f"https://api.scratch.mit.edu/search/studios", limit=limit, offset=offset, add_params=f"&language={language}&mode={mode}&q={query}")
|
|
603
|
-
return commons.parse_object_list(response, Studio)
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
def explore_studios(*, query="", mode="trending", language="en", limit=40, offset=0):
|
|
607
|
-
if not query:
|
|
608
|
-
raise ValueError("The query can't be empty for explore")
|
|
609
|
-
response = commons.api_iterative(
|
|
610
|
-
f"https://api.scratch.mit.edu/explore/studios", limit=limit, offset=offset, add_params=f"&language={language}&mode={mode}&q={query}")
|
|
611
|
-
return commons.parse_object_list(response, Studio)
|