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

Is not JSON Serializable #28

Closed towerofnix closed 9 years ago

towerofnix commented 9 years ago

I get this error..

Traceback (most recent call last):
  File "/Users/towerofnix/Documents/Python/Kurt/dqiv.py", line 117, in <module>
    p.save('test.sb2')
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/kurt/__init__.py", line 399, in save
    result = p._save(fp)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/kurt/__init__.py", line 405, in _save
    return self._plugin.save(fp, self)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/kurt/scratch20/__init__.py", line 594, in save
    zw = ZipWriter(fp, project)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/kurt/scratch20/__init__.py", line 343, in __init__
    self.write_file("project.json", json.dumps(self.json))
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 243, in dumps
    return _default_encoder.encode(obj)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 207, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 270, in iterencode
    return _iterencode(o, 0)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 184, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: kurt.Script([
    kurt.Block('doIf', 
        kurt.Block('keyPressed:', 'rightArrow'),
    kurt.Script([
        kurt.Block('show')]))]) is not JSON serializable

.. when running this code:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from sys import argv
import os
import kurt
import dqivdata
import re

if (len(argv) > 1):
    if argv[1][-1] == "/":
        path = argv[1]
    else:
        path = argv[1] + "/"
else:
    path = "import-images/"

path = os.path.abspath(path) + "/"

# COSTUMES ===================================================================

def get_costume_name(name):
    return name.lower(
    ).replace(" ", "_").replace("'", "").replace(
        "é", "e"
    ).replace("-", "_")

costumes = []
for i in dqivdata.get_dqiv_data():
    costume_name = get_costume_name(i['name'])
    costumes.append(
        kurt.Costume(costume_name, kurt.Image.load(
            path + costume_name + ".png")
        )
    )

p = kurt.Project()
s = kurt.Sprite(p, "Sprite")

for i in costumes:
    print "appending costume", i.name
    s.costumes.append(i)

# DATA ========================================================================

def strip_accents(x):
    # This works but only because the only accent in the entire
    # bestiary is é.
    return x.replace("é", "e")

namelist = kurt.List()
goldlist = kurt.List()
hplist = kurt.List()
commentslist = kurt.List()
itemlist = kurt.List()
mplist = kurt.List()
explist = kurt.List()
locationlist = kurt.List()
for i in dqivdata.get_dqiv_data():
    namelist.items.append(i['name'])
    goldlist.items.append(i['gold'])
    hplist.items.append(i['hp'])
    commentslist.items.append(i['comments'])
    itemlist.items.append(i['item'])
    mplist.items.append(i['mp'])
    explist.items.append(i['exp'])
    locationlist.items.append(i['location'])
s.lists['name'] = namelist
s.lists['gold'] = goldlist
s.lists['hp'] = hplist
s.lists['comments'] = commentslist
s.lists['item'] = itemlist
s.lists['mp'] = mplist
s.lists['exp'] = explist
s.lists['location'] = locationlist
for i in s.lists.items():
    i[1].items = map(strip_accents, i[1].items)

# SCRIPTS =====================================================================

s.scripts = [
    kurt.Script(
        blocks=[
            kurt.Block(
                "when green flag clicked"
            ),
            kurt.Block(
                "forever",
                kurt.Script(blocks=[
                    kurt.Block(
                        "if then",
                        kurt.Block(
                            "key pressed",
                            "rightArrow"
                        ),
                        kurt.Script(blocks=[
                            kurt.Block(
                                "show"
                            )
                        ])
                    )
                ])
            )
        ],
        pos=(30, 30)
    )
]

# COMPILE =====================================================================

print "adding sprite to project"
p.sprites.append(s)

print "saving project"
p.save('test.sb2')

It seems to be that the error is in the script section. Any idea what this is?

I'm on Mac OS X 10.10 (Yosemite) running Python 2.7.8.

tjvr commented 9 years ago

The mouth of a C block has to be a list, not a Script.

(Scripts are just lists of blocks together with a position; and you can't position the contents of a C block mouth independently of the parent script!)

In [4]: s.parse("""
when green flag clicked
forever
  if (key right arrow pressed?) then
    show
  end
end
""")

In [6]: s.scripts[0]
Out[6]: 
kurt.Script([
    kurt.Block('whenGreenFlag'),
    kurt.Block('doForever',  [
        kurt.Block('doIf', 
            kurt.Block('keyPressed:', 'right arrow'),
            [
            kurt.Block('show'),
            ]),
        ])])

Hope that helps :)

towerofnix commented 9 years ago

Ahh okay. Thanks! :)