tjvr / kurt

Python library for reading/writing MIT's Scratch file format.
https://kurt.tjvr.org
GNU General Public License v3.0
86 stars 24 forks source link

How to use the extract_blocks_20 script #40

Closed raulperula closed 7 years ago

raulperula commented 7 years ago

Hi!

I have been trying to re-generate the "commands_src" file for the "scratch20" plugin but the script file "extract_blocks_20" seems to work with the resulting file from the website "showmycode.com".

That functionality of this website seems to be broken since August 2016 (found in some forum).

Do you know any other way to generate the input file for that script?

Thank you for the help in advance!

tjvr commented 7 years ago

The Scratch 2.0 source code is now available online, so you don't need to use a decompiler.

Have a look at https://github.com/LLK/scratch-flash/blob/96a2a9a7fca2d042da25dc0d4423900163ab4f33/src/Specs.as :-)

raulperula commented 7 years ago

Thank you @tjvr,

I have modified the script to load the source code directly from the URL:

import urllib

# get file from repository (raw url)
target_url = "https://raw.githubusercontent.com/LLK/scratch-flash/96a2a9a7fca2d042da25dc0d4423900163ab4f33/src/Specs.as"
contents = urllib.urlopen(target_url).read()

# split lines
lines = contents.split("\n")

But it seems that this file is quiet different that the file you used from "showmycode" because it throws an error:

Traceback (most recent call last):
  File "extract_blocks_20.py", line 102, in <module>
    add_line_at_index("commands", i, "commands:Array")
  File "extract_blocks_20.py", line 93, in add_line_at_index
    for cmd in eval(line):
  File "<string>", line 1
    [
    ^
SyntaxError: unexpected EOF while parsing

Any help?

tjvr commented 7 years ago

You might have to modify the script then. The main thing we want is the commands array.

raulperula commented 7 years ago

Ok! I have achieved to load the commands array form the URL and re-generate the code but no the extensions.

This is the new code: https://github.com/raulperula/kurt/blob/master/src/extract_blocks_20.py

And the new auto-generated file (there are only little changes): https://github.com/raulperula/kurt/blob/master/kurt/scratch20/commands_src.py

How did you include the extensions? Manually?

I have created (as I commented), an extension that can be loaded in Scratch: https://github.com/JdeRobot/colab-gsoc2017-RaulPerula/blob/master/extension/scratch2robot.s2e

But I do not know exactly how to translate that blocks specification to the plugin. Any idea?

Thank you again for all your help! I really appreciate it.

tjvr commented 7 years ago

You could try adding your custom blocks to commands_src.py, following the format laid out there: [spec, shape, category, selector, ...defaults].

e.g. ["turn robot %m.turnDirection speed %n", " ", 20, "turn/robot/speed", "left", 1]

raulperula commented 7 years ago

Hi @tjvr ,

Now I have the new _commandsrc file generated including my extension:

https://github.com/JdeRobot/colab-gsoc2017-RaulPerula/blob/master/extension/scratch2robot.s2e

I have created an example Scratch program using the blocks from the extension loaded:

https://github.com/JdeRobot/colab-gsoc2017-RaulPerula/blob/master/data/move_robot_complex_extension.sb2

But Kurt is raising an Exception telling that is already an UnknownBlock.

Traceback (most recent call last):
  File "scratch2python.py", line 53, in <module>
    p = kurt.Project.load(open_path + sys.argv[1])
  File "/home/raul/workspace/gsoc2017/kurt/kurt/__init__.py", line 275, in load
    project = plugin.load(fp)
  File "/home/raul/workspace/gsoc2017/kurt/kurt/scratch20/__init__.py", line 624, in load
    zl = ZipReader(fp)
  File "/home/raul/workspace/gsoc2017/kurt/kurt/scratch20/__init__.py", line 108, in __init__
    sprite = self.load_scriptable(cd)
  File "/home/raul/workspace/gsoc2017/kurt/kurt/scratch20/__init__.py", line 217, in load_scriptable
    scriptable.scripts.append(self.load_script(script_array))
  File "/home/raul/workspace/gsoc2017/kurt/kurt/scratch20/__init__.py", line 313, in load_script
    blocks = map(self.load_block, blocks)
  File "/home/raul/workspace/gsoc2017/kurt/kurt/scratch20/__init__.py", line 292, in load_block
    arg = map(self.load_block, arg)
  File "/home/raul/workspace/gsoc2017/kurt/kurt/scratch20/__init__.py", line 281, in load_block
    block_type = kurt.BlockType.get(command)
  File "/home/raul/workspace/gsoc2017/kurt/kurt/__init__.py", line 1737, in get
    raise UnknownBlock, repr(block_type)
kurt.UnknownBlock: u'Scratch2Robot\x1fmove'

As you can see, the block has the name "Scratch2Robot\x1fmove". I do not know if that is the problem, but I have debugged the code and I cannot find why there is not a coincidence.

raulperula commented 7 years ago

Solved!

In the pull request you can see the solution to load extensions.

Thanks for all your help!

tjvr commented 7 years ago

Thanks so much :-)