kurt
Scratch project files <---> Python <---> Scratchblocks code & images
Kurt is a de/compiler for converting to/from a folder structure of scripts and images. You can decompile a project into its parts, edit the scripts as scratchblocks code (the same syntax as forum blocks) in a text editor, and images in an image editor, then recompile!
It's also a Python library for reading/writing Scratch project (.sb) and sprite (.sprite) files. You can load the files, look at their internal structure — including sprites, scripts, variables, images, etc — make changes, and save them again! You can generate Scratch projects from Python code.
Check it out on Github.
---
a post about working with Kurt
I've reached my long-term goal: to be able to decompile my roads game to text/images, compile it again, and have it (mostly) working. Now I can edit projects as text!
Screenshot:
---
~Many thanks to nXIII for advice on the format.
Thanks to Bobbybee for inspiration.
Last edited by blob8108 (2012-10-24 13:19:36)
Offline
(high-pitched pleas) Could you (greedily) mention that I'm inspiration?
Offline
bobbybee wrote:
(high-pitched pleas) Could you (greedily) mention that I'm inspiration?
Happy?
Offline
blob8108 wrote:
bobbybee wrote:
(high-pitched pleas) Could you (greedily) mention that I'm inspiration?
Happy?
Yeah. Now can we do the mailinator team elite process?
Offline
Yesss! I've been waiting forever for this! Thank you!
Offline
Magnie wrote:
Yesss! I've been waiting forever for this! Thank you!
Pleasure Let me know how you get on!
Offline
blob8108 wrote:
Magnie wrote:
Yesss! I've been waiting forever for this! Thank you!
Pleasure Let me know how you get on!
How...is...Magnie...only...on...when...I'm....not...on....?....
Offline
Also, you might want to change the file test_files.py: the path has your name in it.
Offline
bobbybee wrote:
Also, you might want to change the file test_files.py: the path has your name in it.
That's fine Thanks, though!
Last edited by blob8108 (2012-03-21 17:05:49)
Offline
Also, I can't run the tests. Which test should I run?
Offline
bobbybee wrote:
Also, I can't run the tests. Which test should I run?
The tests are from when I was making inline & fixed objects parse correctly. It all works now, so they're no longer really necessary; though they might be in future, to check I haven't broken anything.
You can run them from the root directory by
from tests import test_objtable
...but as I said, they don't currently work.
Offline
What is the helloworld of kurt, then?
Offline
Thank you.
Offline
Annoying Python Interpreter wrote:
macpro-8:blob8108-kurt-51156df *$ python test.py
Traceback (most recent call last):
File "test.py", line 2, in <module>
project = ScratchProjectFile('tests/game.sb')
File "/Users/*/Downloads/blob8108-kurt-51156df/kurt/files.py", line 19, in __init__
self.load()
File "/Users/*/Downloads/blob8108-kurt-51156df/kurt/files.py", line 25, in load
self._load(bytes)
File "/Users/*/Downloads/blob8108-kurt-51156df/kurt/files.py", line 81, in _load
project = self._construct.parse(bytes)
File "/Users/*/Downloads/blob8108-kurt-51156df/construct/core.py", line 126, in parse
return self.parse_stream(StringIO(data))
File "/Users/*/Downloads/blob8108-kurt-51156df/construct/core.py", line 129, in parse_stream
return self._parse(stream, AttrDict())
File "/Users/*/Downloads/blob8108-kurt-51156df/construct/core.py", line 522, in _parse
subobj = sc._parse(stream, context)
File "/Users/*/Downloads/blob8108-kurt-51156df/construct/core.py", line 166, in _parse
return self.subcon._parse(stream, context)
File "/Users/*/Downloads/blob8108-kurt-51156df/kurt/objtable.py", line 280, in _parse
objtable = self.subcon._parse(stream, context)
File "/Users/*/Downloads/blob8108-kurt-51156df/construct/core.py", line 181, in _parse
return self._decode(self.subcon._parse(stream, context), context)
File "/Users/*/Downloads/blob8108-kurt-51156df/construct/core.py", line 181, in _parse
return self._decode(self.subcon._parse(stream, context), context)
File "/Users/*/Downloads/blob8108-kurt-51156df/construct/core.py", line 522, in _parse
subobj = sc._parse(stream, context)
File "/Users/*/Downloads/blob8108-kurt-51156df/construct/core.py", line 166, in _parse
return self.subcon._parse(stream, context)
File "/Users/*/Downloads/blob8108-kurt-51156df/construct/core.py", line 332, in _parse
obj.append(self.subcon._parse(stream, context))
File "/Users/*/Downloads/blob8108-kurt-51156df/construct/core.py", line 181, in _parse
return self._decode(self.subcon._parse(stream, context), context)
File "/Users/*/Downloads/blob8108-kurt-51156df/construct/core.py", line 181, in _parse
return self._decode(self.subcon._parse(stream, context), context)
File "/Users/*/Downloads/blob8108-kurt-51156df/construct/core.py", line 522, in _parse
subobj = sc._parse(stream, context)
File "/Users/*/Downloads/blob8108-kurt-51156df/construct/core.py", line 700, in _parse
obj = self.cases.get(key, self.default)._parse(stream, context)
File "/Users/*/Downloads/blob8108-kurt-51156df/construct/core.py", line 181, in _parse
return self._decode(self.subcon._parse(stream, context), context)
File "/Users/*/Downloads/blob8108-kurt-51156df/kurt/objtable.py", line 48, in _decode
return cls.from_construct(obj, context)
File "/Users/*/Downloads/blob8108-kurt-51156df/kurt/fixed_objects.py", line 20, in from_construct
return cls.from_value(obj.value)
File "/Users/*/Downloads/blob8108-kurt-51156df/kurt/fixed_objects.py", line 235, in from_value
return cls(**dict(value))
File "/Users/*/Downloads/blob8108-kurt-51156df/construct/lib/container.py", line 41, in __getitem__
return self.__dict__[name]
KeyError: 0
macpro-8:blob8108-kurt-51156df *$
Offline
That's... interesting.
Turns out you're using Construct version 2.00; it appears I sent you an outdated download link. My apologies. Try this.
Offline
kay
Offline
It works great now.
Offline
blob8108 wrote:
I made a Python library for parsing Scratch format project (.sb) and sprite (.sprite) files.
I didn't test it yet if it works but... this is an incredible job! Thanks a lot for investing your time in doing this!
Offline
awesome, just awesome
and you're releasing it under... GPL3? please?
just want to know if we can use it on M30W
Last edited by roijac_test (2012-03-22 14:50:32)
Offline
roijac_test wrote:
awesome, just awesome
and you're releasing it under... GPL3? please?
just want to know if we can use it on M30W
I haven't actually decided yet as permissive as possible, I think -- probably LGPL, or maybe Apache License... what licence would allow you to use it?
Offline
I'd like a GPL...although LGPL might be more appropiate for this particular project. Also, can we talk? (wikispaces...something that might be too ambitious to work)
Offline
As I'm definitely not a Python guy... after having:
- installed python
- installed costruct
what will I do in order to run the commands that I found in the readme?!?!? Do I have to:
- change to a specific dir? how?
- load kurt? how?
- run... what?
Thanks for your help :-)
Offline
s_federici wrote:
As I'm definitely not a Python guy... after having:
- installed python
- installed costruct
what will I do in order to run the commands that I found in the readme?!?!? Do I have to:
- change to a specific dir? how?
- load kurt? how?
- run... what?
Thanks for your help :-)
What platform are you using? You could try copying just the "kurt" folder to Python's "site-packages" directory:
C:\Python26\Lib\site-packages on Windows;
On Mac OS X, either /Library/Python/2.6/site-packages
or /Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages;
/usr/local/lib/python2.6/lib/site-packages or similar on Linux
-- replace 2.6 with the version of Python you're using. (Should be about 2.6 or newer, don't think it works on 3.0)
Then you should be able to run Python/IDLE, and type in the commands from the readme after the interpreter's triple > prompt.
Make sure you supply absolute paths to files (ie. starting with "/" or "C:\"), and it should all work nicely!
Gratuitous screenshot of working example.
Offline
Thanks a lot. Now I can run it. I got the following error when loading the provided game.sb:
>>> project = ScratchProjectFile('tests/game.sb') Traceback (most recent call last): File "<pyshell#5>", line 1, in <module> project = ScratchProjectFile('tests/game.sb') File "C:\Python27\lib\site-packages\kurt\files.py", line 19, in __init__ self.load() File "C:\Python27\lib\site-packages\kurt\files.py", line 25, in load self._load(bytes) File "C:\Python27\lib\site-packages\kurt\files.py", line 81, in _load project = self._construct.parse(bytes) File "C:\Python27\lib\site-packages\construct\core.py", line 181, in parse return self.parse_stream(StringIO(data)) File "C:\Python27\lib\site-packages\construct\core.py", line 191, in parse_stream return self._parse(stream, Container()) File "C:\Python27\lib\site-packages\construct\core.py", line 645, in _parse subobj = sc._parse(stream, context) File "C:\Python27\lib\site-packages\construct\core.py", line 264, in _parse return self.subcon._parse(stream, context) File "C:\Python27\lib\site-packages\kurt\objtable.py", line 280, in _parse objtable = self.subcon._parse(stream, context) File "C:\Python27\lib\site-packages\construct\core.py", line 279, in _parse return self._decode(self.subcon._parse(stream, context), context) File "C:\Python27\lib\site-packages\construct\core.py", line 279, in _parse return self._decode(self.subcon._parse(stream, context), context) File "C:\Python27\lib\site-packages\construct\core.py", line 645, in _parse subobj = sc._parse(stream, context) File "C:\Python27\lib\site-packages\construct\core.py", line 264, in _parse return self.subcon._parse(stream, context) File "C:\Python27\lib\site-packages\construct\core.py", line 432, in _parse raise ArrayError("expected %d, found %d" % (count, c), ex) ArrayError: ('expected 96, found 18', ArrayError('expected 256, found 5', FieldError(FieldError('expected 2, found 1',),)))
Last edited by s_federici (2012-03-24 02:48:45)
Offline