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,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)