scratchattach 2.1.13__py3-none-any.whl → 2.1.15b0__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/cloud/_base.py +12 -8
- scratchattach/cloud/cloud.py +19 -7
- scratchattach/editor/asset.py +59 -5
- scratchattach/editor/base.py +82 -31
- scratchattach/editor/block.py +86 -15
- scratchattach/editor/blockshape.py +10 -6
- scratchattach/editor/build_defaulting.py +6 -2
- scratchattach/editor/code_translation/__init__.py +0 -0
- scratchattach/editor/code_translation/parse.py +177 -0
- scratchattach/editor/comment.py +6 -0
- scratchattach/editor/commons.py +49 -19
- scratchattach/editor/extension.py +10 -3
- scratchattach/editor/field.py +9 -0
- scratchattach/editor/inputs.py +4 -1
- scratchattach/editor/meta.py +11 -3
- scratchattach/editor/monitor.py +46 -38
- scratchattach/editor/mutation.py +11 -4
- scratchattach/editor/pallete.py +24 -25
- scratchattach/editor/prim.py +2 -2
- scratchattach/editor/project.py +9 -3
- scratchattach/editor/sprite.py +19 -6
- scratchattach/editor/twconfig.py +2 -1
- scratchattach/editor/vlb.py +1 -1
- scratchattach/eventhandlers/_base.py +2 -2
- scratchattach/eventhandlers/cloud_events.py +2 -2
- scratchattach/eventhandlers/cloud_requests.py +3 -3
- scratchattach/eventhandlers/cloud_server.py +3 -3
- scratchattach/eventhandlers/message_events.py +1 -1
- scratchattach/other/other_apis.py +4 -4
- scratchattach/other/project_json_capabilities.py +3 -3
- scratchattach/site/_base.py +13 -12
- scratchattach/site/activity.py +11 -43
- scratchattach/site/alert.py +227 -0
- scratchattach/site/backpack_asset.py +2 -2
- scratchattach/site/browser_cookie3_stub.py +17 -0
- scratchattach/site/browser_cookies.py +27 -21
- scratchattach/site/classroom.py +51 -34
- scratchattach/site/cloud_activity.py +4 -4
- scratchattach/site/comment.py +30 -8
- scratchattach/site/forum.py +101 -69
- scratchattach/site/project.py +42 -21
- scratchattach/site/session.py +170 -80
- scratchattach/site/studio.py +4 -4
- scratchattach/site/user.py +179 -64
- scratchattach/utils/commons.py +35 -23
- scratchattach/utils/enums.py +44 -5
- scratchattach/utils/exceptions.py +10 -0
- scratchattach/utils/requests.py +57 -31
- {scratchattach-2.1.13.dist-info → scratchattach-2.1.15b0.dist-info}/METADATA +8 -3
- scratchattach-2.1.15b0.dist-info/RECORD +66 -0
- {scratchattach-2.1.13.dist-info → scratchattach-2.1.15b0.dist-info}/WHEEL +1 -1
- scratchattach/editor/sbuild.py +0 -2837
- scratchattach-2.1.13.dist-info/RECORD +0 -63
- {scratchattach-2.1.13.dist-info → scratchattach-2.1.15b0.dist-info}/licenses/LICENSE +0 -0
- {scratchattach-2.1.13.dist-info → scratchattach-2.1.15b0.dist-info}/top_level.txt +0 -0
|
@@ -1,14 +1,21 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Enum & dataclass representing extension categories
|
|
3
|
+
"""
|
|
4
|
+
|
|
1
5
|
from __future__ import annotations
|
|
2
6
|
|
|
3
7
|
|
|
4
8
|
from dataclasses import dataclass
|
|
5
9
|
|
|
6
10
|
from . import base
|
|
7
|
-
from
|
|
11
|
+
from scratchattach.utils import enums
|
|
8
12
|
|
|
9
13
|
|
|
10
|
-
@dataclass
|
|
14
|
+
@dataclass
|
|
11
15
|
class Extension(base.JSONSerializable):
|
|
16
|
+
"""
|
|
17
|
+
Represents an extension in the Scratch block pallete - e.g. video sensing
|
|
18
|
+
"""
|
|
12
19
|
code: str
|
|
13
20
|
name: str = None
|
|
14
21
|
|
|
@@ -40,4 +47,4 @@ class Extensions(enums._EnumWrapper):
|
|
|
40
47
|
TRANSLATE = Extension("translate", "Translate Extension")
|
|
41
48
|
VIDEOSENSING = Extension("videoSensing", "Video Sensing Extension")
|
|
42
49
|
WEDO2 = Extension("wedo2", "LEGO Education WeDo 2.0 Extension")
|
|
43
|
-
COREEXAMPLE = Extension("coreExample", "CoreEx Extension")
|
|
50
|
+
COREEXAMPLE = Extension("coreExample", "CoreEx Extension") # hidden extension!
|
scratchattach/editor/field.py
CHANGED
|
@@ -38,6 +38,9 @@ class Field(base.BlockSubComponent):
|
|
|
38
38
|
|
|
39
39
|
@property
|
|
40
40
|
def value_id(self):
|
|
41
|
+
"""
|
|
42
|
+
Get the id of the value associated with this field (if applicable) - when value is var/list/broadcast
|
|
43
|
+
"""
|
|
41
44
|
if self.id is not None:
|
|
42
45
|
return self.id
|
|
43
46
|
else:
|
|
@@ -48,6 +51,9 @@ class Field(base.BlockSubComponent):
|
|
|
48
51
|
|
|
49
52
|
@property
|
|
50
53
|
def value_str(self):
|
|
54
|
+
"""
|
|
55
|
+
Convert the associated value to a string - if this is a VLB, return the VLB name
|
|
56
|
+
"""
|
|
51
57
|
if not isinstance(self.value, base.NamedIDComponent):
|
|
52
58
|
return self.value
|
|
53
59
|
else:
|
|
@@ -55,6 +61,9 @@ class Field(base.BlockSubComponent):
|
|
|
55
61
|
|
|
56
62
|
@property
|
|
57
63
|
def name(self) -> str:
|
|
64
|
+
"""
|
|
65
|
+
Fetch the name of this field using the associated block
|
|
66
|
+
"""
|
|
58
67
|
for _name, _field in self.block.fields.items():
|
|
59
68
|
if _field is self:
|
|
60
69
|
return _name
|
scratchattach/editor/inputs.py
CHANGED
scratchattach/editor/meta.py
CHANGED
|
@@ -7,7 +7,7 @@ from . import base, commons
|
|
|
7
7
|
from typing import Optional
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
@dataclass
|
|
10
|
+
@dataclass
|
|
11
11
|
class PlatformMeta(base.JSONSerializable):
|
|
12
12
|
name: str = None
|
|
13
13
|
url: str = field(repr=True, default=None)
|
|
@@ -36,8 +36,13 @@ EDIT_META = True
|
|
|
36
36
|
META_SET_PLATFORM = False
|
|
37
37
|
|
|
38
38
|
|
|
39
|
-
def set_meta_platform(true_false: bool =
|
|
39
|
+
def set_meta_platform(true_false: bool = None):
|
|
40
|
+
"""
|
|
41
|
+
toggle whether to set the meta platform by default (or specify a value)
|
|
42
|
+
"""
|
|
40
43
|
global META_SET_PLATFORM
|
|
44
|
+
if true_false is None:
|
|
45
|
+
true_false = bool(1 - true_false)
|
|
41
46
|
META_SET_PLATFORM = true_false
|
|
42
47
|
|
|
43
48
|
|
|
@@ -69,7 +74,10 @@ class Meta(base.JSONSerializable):
|
|
|
69
74
|
|
|
70
75
|
@property
|
|
71
76
|
def vm_is_valid(self):
|
|
72
|
-
|
|
77
|
+
"""
|
|
78
|
+
Check whether the vm value is valid using a regex
|
|
79
|
+
Thanks to TurboWarp for this pattern ↓↓↓↓, I just copied it
|
|
80
|
+
"""
|
|
73
81
|
return re.match("^([0-9]+\\.[0-9]+\\.[0-9]+)($|-)", self.vm) is not None
|
|
74
82
|
|
|
75
83
|
def to_json(self):
|
scratchattach/editor/monitor.py
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import warnings
|
|
3
4
|
from typing import Optional, TYPE_CHECKING
|
|
4
5
|
|
|
6
|
+
from typing_extensions import deprecated
|
|
7
|
+
|
|
5
8
|
if TYPE_CHECKING:
|
|
9
|
+
from .block import Block
|
|
6
10
|
from . import project
|
|
7
11
|
|
|
8
12
|
from . import base
|
|
@@ -26,6 +30,8 @@ class Monitor(base.ProjectSubcomponent):
|
|
|
26
30
|
"""
|
|
27
31
|
Represents a variable/list monitor
|
|
28
32
|
https://en.scratch-wiki.info/wiki/Scratch_File_Format#Monitors
|
|
33
|
+
|
|
34
|
+
Instantiating these yourself and attaching these to projects can lead to interesting results!
|
|
29
35
|
"""
|
|
30
36
|
assert isinstance(reporter, base.SpriteSubComponent) or reporter is None
|
|
31
37
|
|
|
@@ -135,41 +141,43 @@ class Monitor(base.ProjectSubcomponent):
|
|
|
135
141
|
self.reporter = new_vlb
|
|
136
142
|
self.reporter_id = None
|
|
137
143
|
|
|
138
|
-
#
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
144
|
+
# todo: consider reimplementing this
|
|
145
|
+
@deprecated("This method does not work correctly (This may be fixed in the future)")
|
|
146
|
+
@staticmethod
|
|
147
|
+
def from_reporter(reporter: "Block", _id: str = None, mode: str = "default",
|
|
148
|
+
opcode: str = None, sprite_name: str = None, value=0, width: int | float = 0,
|
|
149
|
+
height: int | float = 0,
|
|
150
|
+
x: int | float = 5, y: int | float = 5, visible: bool = False, slider_min: int | float = 0,
|
|
151
|
+
slider_max: int | float = 100, is_discrete: bool = True, params: dict = None):
|
|
152
|
+
if "reporter" not in reporter.stack_type:
|
|
153
|
+
warnings.warn(f"{reporter} is not a reporter block; the monitor will return '0'")
|
|
154
|
+
elif "(menu)" in reporter.stack_type:
|
|
155
|
+
warnings.warn(f"{reporter} is a menu block; the monitor will return '0'")
|
|
156
|
+
# Maybe add note that length of list doesn't work fsr?? idk
|
|
157
|
+
if _id is None:
|
|
158
|
+
_id = reporter.opcode
|
|
159
|
+
if opcode is None:
|
|
160
|
+
opcode = reporter.opcode # .replace('_', ' ')
|
|
161
|
+
|
|
162
|
+
if params is None:
|
|
163
|
+
params = {}
|
|
164
|
+
for field in reporter.fields:
|
|
165
|
+
if field.value_id is None:
|
|
166
|
+
params[field.id] = field.value
|
|
167
|
+
else:
|
|
168
|
+
params[field.id] = field.value, field.value_id
|
|
169
|
+
|
|
170
|
+
return Monitor(
|
|
171
|
+
_id,
|
|
172
|
+
mode,
|
|
173
|
+
opcode,
|
|
174
|
+
|
|
175
|
+
params,
|
|
176
|
+
sprite_name,
|
|
177
|
+
value,
|
|
178
|
+
|
|
179
|
+
width, height,
|
|
180
|
+
x, y,
|
|
181
|
+
visible,
|
|
182
|
+
slider_min, slider_max, is_discrete
|
|
183
|
+
)
|
scratchattach/editor/mutation.py
CHANGED
|
@@ -6,13 +6,13 @@ from dataclasses import dataclass
|
|
|
6
6
|
from typing import Optional, TYPE_CHECKING, Iterable, Any
|
|
7
7
|
|
|
8
8
|
from . import base, commons
|
|
9
|
-
from
|
|
9
|
+
from scratchattach.utils import enums
|
|
10
10
|
|
|
11
11
|
if TYPE_CHECKING:
|
|
12
12
|
from . import block
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
@dataclass
|
|
15
|
+
@dataclass
|
|
16
16
|
class ArgumentType(base.Base):
|
|
17
17
|
type: str
|
|
18
18
|
proc_str: str
|
|
@@ -38,7 +38,7 @@ class ArgumentType(base.Base):
|
|
|
38
38
|
return None
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
@dataclass
|
|
41
|
+
@dataclass
|
|
42
42
|
class ArgSettings(base.Base):
|
|
43
43
|
ids: bool
|
|
44
44
|
names: bool
|
|
@@ -61,7 +61,7 @@ class ArgSettings(base.Base):
|
|
|
61
61
|
return int(self) > int(other)
|
|
62
62
|
|
|
63
63
|
|
|
64
|
-
@dataclass
|
|
64
|
+
@dataclass
|
|
65
65
|
class Argument(base.MutationSubComponent):
|
|
66
66
|
name: str
|
|
67
67
|
default: str = ''
|
|
@@ -103,6 +103,10 @@ class ArgTypes(enums._EnumWrapper):
|
|
|
103
103
|
|
|
104
104
|
|
|
105
105
|
def parse_proc_code(_proc_code: str) -> list[str, ArgumentType] | None:
|
|
106
|
+
"""
|
|
107
|
+
Parse a proccode (part of a mutation) into argument types and strings
|
|
108
|
+
"""
|
|
109
|
+
|
|
106
110
|
if _proc_code is None:
|
|
107
111
|
return None
|
|
108
112
|
token = ''
|
|
@@ -209,6 +213,9 @@ class Mutation(base.BlockSubComponent):
|
|
|
209
213
|
|
|
210
214
|
@property
|
|
211
215
|
def parsed_proc_code(self) -> list[str, ArgumentType] | None:
|
|
216
|
+
"""
|
|
217
|
+
Parse the proc code into arguments & strings
|
|
218
|
+
"""
|
|
212
219
|
return parse_proc_code(self.proc_code)
|
|
213
220
|
|
|
214
221
|
@staticmethod
|
scratchattach/editor/pallete.py
CHANGED
|
@@ -6,43 +6,42 @@ May want to completely change this later
|
|
|
6
6
|
"""
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
-
from dataclasses import dataclass
|
|
9
|
+
from dataclasses import dataclass, field
|
|
10
|
+
from typing import Optional
|
|
10
11
|
|
|
11
12
|
from . import prim
|
|
12
|
-
from
|
|
13
|
+
from scratchattach.utils.enums import _EnumWrapper
|
|
13
14
|
|
|
14
15
|
|
|
15
|
-
@dataclass
|
|
16
|
+
@dataclass
|
|
16
17
|
class FieldUsage:
|
|
17
18
|
name: str
|
|
18
|
-
value_type: prim.PrimTypes = None
|
|
19
|
+
value_type: Optional[prim.PrimTypes] = None
|
|
19
20
|
|
|
20
21
|
|
|
21
|
-
@dataclass
|
|
22
|
+
@dataclass
|
|
22
23
|
class SpecialFieldUsage(FieldUsage):
|
|
23
24
|
name: str
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
attrs = []
|
|
25
|
+
value_type: None = None # Order cannot be changed
|
|
26
|
+
attrs: list[str] = field(default_factory=list)
|
|
27
27
|
|
|
28
|
-
value_type: None = None
|
|
29
28
|
|
|
30
29
|
|
|
31
|
-
@dataclass
|
|
30
|
+
@dataclass
|
|
32
31
|
class InputUsage:
|
|
33
32
|
name: str
|
|
34
|
-
value_type: prim.PrimTypes = None
|
|
35
|
-
default_obscurer: BlockUsage = None
|
|
33
|
+
value_type: Optional[prim.PrimTypes] = None
|
|
34
|
+
default_obscurer: Optional[BlockUsage] = None
|
|
36
35
|
|
|
37
36
|
|
|
38
|
-
@dataclass
|
|
37
|
+
@dataclass
|
|
39
38
|
class BlockUsage:
|
|
40
39
|
opcode: str
|
|
41
|
-
fields: list[FieldUsage] = None
|
|
40
|
+
fields: Optional[list[FieldUsage]] = None
|
|
42
41
|
if fields is None:
|
|
43
42
|
fields = []
|
|
44
43
|
|
|
45
|
-
inputs: list[InputUsage] = None
|
|
44
|
+
inputs: Optional[list[InputUsage]] = None
|
|
46
45
|
if inputs is None:
|
|
47
46
|
inputs = []
|
|
48
47
|
|
|
@@ -51,41 +50,41 @@ class BlockUsages(_EnumWrapper):
|
|
|
51
50
|
# Special Enum blocks
|
|
52
51
|
MATH_NUMBER = BlockUsage(
|
|
53
52
|
"math_number",
|
|
54
|
-
[SpecialFieldUsage("NUM", ["name", "value"])]
|
|
53
|
+
[SpecialFieldUsage("NUM", attrs=["name", "value"])]
|
|
55
54
|
)
|
|
56
55
|
MATH_POSITIVE_NUMBER = BlockUsage(
|
|
57
56
|
"math_positive_number",
|
|
58
|
-
[SpecialFieldUsage("NUM", ["name", "value"])]
|
|
57
|
+
[SpecialFieldUsage("NUM", attrs=["name", "value"])]
|
|
59
58
|
)
|
|
60
59
|
MATH_WHOLE_NUMBER = BlockUsage(
|
|
61
60
|
"math_whole_number",
|
|
62
|
-
[SpecialFieldUsage("NUM", ["name", "value"])]
|
|
61
|
+
[SpecialFieldUsage("NUM", attrs=["name", "value"])]
|
|
63
62
|
)
|
|
64
63
|
MATH_INTEGER = BlockUsage(
|
|
65
64
|
"math_integer",
|
|
66
|
-
[SpecialFieldUsage("NUM", ["name", "value"])]
|
|
65
|
+
[SpecialFieldUsage("NUM", attrs=["name", "value"])]
|
|
67
66
|
)
|
|
68
67
|
MATH_ANGLE = BlockUsage(
|
|
69
68
|
"math_angle",
|
|
70
|
-
[SpecialFieldUsage("NUM", ["name", "value"])]
|
|
69
|
+
[SpecialFieldUsage("NUM", attrs=["name", "value"])]
|
|
71
70
|
)
|
|
72
71
|
COLOUR_PICKER = BlockUsage(
|
|
73
72
|
"colour_picker",
|
|
74
|
-
[SpecialFieldUsage("COLOUR", ["name", "value"])]
|
|
73
|
+
[SpecialFieldUsage("COLOUR", attrs=["name", "value"])]
|
|
75
74
|
)
|
|
76
75
|
TEXT = BlockUsage(
|
|
77
76
|
"text",
|
|
78
|
-
[SpecialFieldUsage("TEXT", ["name", "value"])]
|
|
77
|
+
[SpecialFieldUsage("TEXT", attrs=["name", "value"])]
|
|
79
78
|
)
|
|
80
79
|
EVENT_BROADCAST_MENU = BlockUsage(
|
|
81
80
|
"event_broadcast_menu",
|
|
82
|
-
[SpecialFieldUsage("BROADCAST_OPTION", ["name", "id", "value", "variableType"])]
|
|
81
|
+
[SpecialFieldUsage("BROADCAST_OPTION", attrs=["name", "id", "value", "variableType"])]
|
|
83
82
|
)
|
|
84
83
|
DATA_VARIABLE = BlockUsage(
|
|
85
84
|
"data_variable",
|
|
86
|
-
[SpecialFieldUsage("VARIABLE", ["name", "id", "value", "variableType"])]
|
|
85
|
+
[SpecialFieldUsage("VARIABLE", attrs=["name", "id", "value", "variableType"])]
|
|
87
86
|
)
|
|
88
87
|
DATA_LISTCONTENTS = BlockUsage(
|
|
89
88
|
"data_listcontents",
|
|
90
|
-
[SpecialFieldUsage("LIST", ["name", "id", "value", "variableType"])]
|
|
89
|
+
[SpecialFieldUsage("LIST", attrs=["name", "id", "value", "variableType"])]
|
|
91
90
|
)
|
scratchattach/editor/prim.py
CHANGED
|
@@ -5,10 +5,10 @@ from dataclasses import dataclass
|
|
|
5
5
|
from typing import Optional, Callable, Final
|
|
6
6
|
|
|
7
7
|
from . import base, sprite, vlb, commons, build_defaulting
|
|
8
|
-
from
|
|
8
|
+
from scratchattach.utils import enums, exceptions
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
@dataclass
|
|
11
|
+
@dataclass
|
|
12
12
|
class PrimType(base.JSONSerializable):
|
|
13
13
|
code: int
|
|
14
14
|
name: str
|
scratchattach/editor/project.py
CHANGED
|
@@ -8,12 +8,15 @@ from typing import Optional, Iterable, Generator, BinaryIO
|
|
|
8
8
|
from zipfile import ZipFile
|
|
9
9
|
|
|
10
10
|
from . import base, meta, extension, monitor, sprite, asset, vlb, twconfig, comment, commons
|
|
11
|
-
from
|
|
12
|
-
from
|
|
13
|
-
from
|
|
11
|
+
from scratchattach.site import session
|
|
12
|
+
from scratchattach.site.project import get_project
|
|
13
|
+
from scratchattach.utils import exceptions
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class Project(base.JSONExtractable):
|
|
17
|
+
"""
|
|
18
|
+
sa.editor's equivalent of the ProjectBody. Represents the editor contents of a scratch project
|
|
19
|
+
"""
|
|
17
20
|
def __init__(self, _name: Optional[str] = None, _meta: Optional[meta.Meta] = None, _extensions: Iterable[extension.Extension] = (),
|
|
18
21
|
_monitors: Iterable[monitor.Monitor] = (), _sprites: Iterable[sprite.Sprite] = (), *,
|
|
19
22
|
_asset_data: Optional[list[asset.AssetFile]] = None, _session: Optional[session.Session] = None):
|
|
@@ -268,6 +271,9 @@ class Project(base.JSONExtractable):
|
|
|
268
271
|
os.system(f"explorer.exe \"{fp}\"")
|
|
269
272
|
|
|
270
273
|
def add_monitor(self, _monitor: monitor.Monitor) -> monitor.Monitor:
|
|
274
|
+
"""
|
|
275
|
+
Bind a monitor to this project. Doing these manually can lead to interesting results.
|
|
276
|
+
"""
|
|
271
277
|
_monitor.project = self
|
|
272
278
|
_monitor.reporter_id = self.new_id
|
|
273
279
|
self.monitors.append(_monitor)
|
scratchattach/editor/sprite.py
CHANGED
|
@@ -11,6 +11,8 @@ if TYPE_CHECKING:
|
|
|
11
11
|
from . import asset
|
|
12
12
|
|
|
13
13
|
class Sprite(base.ProjectSubcomponent, base.JSONExtractable):
|
|
14
|
+
_local_globals: list[base.NamedIDComponent]
|
|
15
|
+
asset_data: list[asset.AssetFile]
|
|
14
16
|
def __init__(self, is_stage: bool = False, name: str = '', _current_costume: int = 1, _layer_order: Optional[int] = None,
|
|
15
17
|
_volume: int = 100,
|
|
16
18
|
_broadcasts: Optional[list[vlb.Broadcast]] = None,
|
|
@@ -120,6 +122,9 @@ class Sprite(base.ProjectSubcomponent, base.JSONExtractable):
|
|
|
120
122
|
_comment.link_using_sprite()
|
|
121
123
|
|
|
122
124
|
def add_local_global(self, _vlb: base.NamedIDComponent):
|
|
125
|
+
"""
|
|
126
|
+
Add a global variable/list to this sprite (for when an overarching project/stage is not available)
|
|
127
|
+
"""
|
|
123
128
|
self._local_globals.append(_vlb)
|
|
124
129
|
_vlb.sprite = self
|
|
125
130
|
|
|
@@ -128,11 +133,11 @@ class Sprite(base.ProjectSubcomponent, base.JSONExtractable):
|
|
|
128
133
|
_variable.sprite = self
|
|
129
134
|
|
|
130
135
|
def add_list(self, _list: vlb.List):
|
|
131
|
-
self.
|
|
136
|
+
self.lists.append(_list)
|
|
132
137
|
_list.sprite = self
|
|
133
138
|
|
|
134
139
|
def add_broadcast(self, _broadcast: vlb.Broadcast):
|
|
135
|
-
self.
|
|
140
|
+
self.broadcasts.append(_broadcast)
|
|
136
141
|
_broadcast.sprite = self
|
|
137
142
|
|
|
138
143
|
def add_vlb(self, _vlb: base.NamedIDComponent):
|
|
@@ -151,18 +156,20 @@ class Sprite(base.ProjectSubcomponent, base.JSONExtractable):
|
|
|
151
156
|
return _block
|
|
152
157
|
|
|
153
158
|
_block.sprite = self
|
|
159
|
+
new_id = self.new_id
|
|
154
160
|
|
|
155
161
|
if isinstance(_block, block.Block):
|
|
156
|
-
self.blocks[
|
|
162
|
+
self.blocks[new_id] = _block
|
|
163
|
+
_block.id = new_id
|
|
157
164
|
_block.link_using_sprite()
|
|
158
165
|
|
|
159
166
|
elif isinstance(_block, prim.Prim):
|
|
160
|
-
self.prims[
|
|
167
|
+
self.prims[new_id] = _block
|
|
161
168
|
_block.link_using_sprite()
|
|
162
169
|
|
|
163
170
|
return _block
|
|
164
171
|
|
|
165
|
-
def add_chain(self, *chain:
|
|
172
|
+
def add_chain(self, *chain: block.Block | prim.Prim) -> block.Block | prim.Prim:
|
|
166
173
|
"""
|
|
167
174
|
Adds a list of blocks to the sprite **AND RETURNS THE FIRST BLOCK**
|
|
168
175
|
:param chain:
|
|
@@ -173,6 +180,8 @@ class Sprite(base.ProjectSubcomponent, base.JSONExtractable):
|
|
|
173
180
|
_prev = self.add_block(chain[0])
|
|
174
181
|
|
|
175
182
|
for _block in chain[1:]:
|
|
183
|
+
if not isinstance(_prev, block.Block) or not isinstance(_block, block.Block):
|
|
184
|
+
continue
|
|
176
185
|
_prev = _prev.attach_block(_block)
|
|
177
186
|
|
|
178
187
|
return chain[0]
|
|
@@ -206,7 +215,11 @@ class Sprite(base.ProjectSubcomponent, base.JSONExtractable):
|
|
|
206
215
|
"""
|
|
207
216
|
:return: All vlbs associated with the sprite. No local globals are added
|
|
208
217
|
"""
|
|
209
|
-
|
|
218
|
+
vlbs: list[base.NamedIDComponent] = []
|
|
219
|
+
vlbs.extend(self.variables)
|
|
220
|
+
vlbs.extend(self.lists)
|
|
221
|
+
vlbs.extend(self.broadcasts)
|
|
222
|
+
return vlbs
|
|
210
223
|
|
|
211
224
|
@property
|
|
212
225
|
def assets(self) -> list[asset.Costume | asset.Sound]:
|
scratchattach/editor/twconfig.py
CHANGED
|
@@ -17,7 +17,7 @@ You can move, resize, and minimize this comment, but don't edit it by hand. This
|
|
|
17
17
|
_END = " // _twconfig_"
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
@dataclass
|
|
20
|
+
@dataclass
|
|
21
21
|
class TWConfig(base.JSONSerializable):
|
|
22
22
|
framerate: int = None,
|
|
23
23
|
interpolation: bool = False,
|
|
@@ -100,6 +100,7 @@ def get_twconfig_data(string: str) -> dict | None:
|
|
|
100
100
|
return None
|
|
101
101
|
|
|
102
102
|
|
|
103
|
+
# todo: move this to commons.py?
|
|
103
104
|
def none_if_eq(data, compare) -> Any | None:
|
|
104
105
|
"""
|
|
105
106
|
Returns None if data and compare are the same
|
scratchattach/editor/vlb.py
CHANGED
|
@@ -5,8 +5,8 @@ from collections import defaultdict
|
|
|
5
5
|
from threading import Thread
|
|
6
6
|
from collections.abc import Callable
|
|
7
7
|
import traceback
|
|
8
|
-
from
|
|
9
|
-
from
|
|
8
|
+
from scratchattach.utils.requests import requests
|
|
9
|
+
from scratchattach.utils import exceptions
|
|
10
10
|
|
|
11
11
|
class BaseEventHandler(ABC):
|
|
12
12
|
_events: defaultdict[str, list[Callable]]
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"""CloudEvents class"""
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
|
-
from
|
|
4
|
+
from scratchattach.cloud import _base
|
|
5
5
|
from ._base import BaseEventHandler
|
|
6
|
-
from
|
|
6
|
+
from scratchattach.site import cloud_activity
|
|
7
7
|
import time
|
|
8
8
|
import json
|
|
9
9
|
from collections.abc import Iterator
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
4
|
from .cloud_events import CloudEvents
|
|
5
|
-
from
|
|
5
|
+
from scratchattach.site import project
|
|
6
6
|
from threading import Thread, Event, current_thread
|
|
7
7
|
import time
|
|
8
8
|
import random
|
|
9
9
|
import traceback
|
|
10
|
-
from
|
|
11
|
-
from
|
|
10
|
+
from scratchattach.utils.encoder import Encoding
|
|
11
|
+
from scratchattach.utils import exceptions
|
|
12
12
|
|
|
13
13
|
class Request:
|
|
14
14
|
|
|
@@ -2,11 +2,11 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from SimpleWebSocketServer import SimpleWebSocketServer, WebSocket
|
|
4
4
|
from threading import Thread
|
|
5
|
-
from
|
|
5
|
+
from scratchattach.utils import exceptions
|
|
6
6
|
import json
|
|
7
7
|
import time
|
|
8
|
-
from
|
|
9
|
-
from
|
|
8
|
+
from scratchattach.site import cloud_activity
|
|
9
|
+
from scratchattach.site.user import User
|
|
10
10
|
from ._base import BaseEventHandler
|
|
11
11
|
|
|
12
12
|
class TwCloudSocket(WebSocket):
|
|
@@ -4,10 +4,10 @@ from __future__ import annotations
|
|
|
4
4
|
import json
|
|
5
5
|
from dataclasses import dataclass, field
|
|
6
6
|
|
|
7
|
-
from
|
|
8
|
-
from
|
|
9
|
-
from
|
|
10
|
-
from
|
|
7
|
+
from scratchattach.utils import commons
|
|
8
|
+
from scratchattach.utils.enums import Languages, Language, TTSVoices, TTSVoice
|
|
9
|
+
from scratchattach.utils.exceptions import BadRequest, InvalidLanguage, InvalidTTSGender
|
|
10
|
+
from scratchattach.utils.requests import requests
|
|
11
11
|
from typing import Optional
|
|
12
12
|
|
|
13
13
|
|
|
@@ -10,9 +10,9 @@ import random
|
|
|
10
10
|
import string
|
|
11
11
|
import zipfile
|
|
12
12
|
from abc import ABC, abstractmethod
|
|
13
|
-
from
|
|
14
|
-
from
|
|
15
|
-
from
|
|
13
|
+
from scratchattach.utils import exceptions
|
|
14
|
+
from scratchattach.utils.commons import empty_project_json
|
|
15
|
+
from scratchattach.utils.requests import requests
|
|
16
16
|
# noinspection PyPep8Naming
|
|
17
17
|
def load_components(json_data: list, ComponentClass: type, target_list: list):
|
|
18
18
|
for element in json_data:
|