sugarlabs / memorize-activity

A memory game, not only to play but also to create you own games, for the Sugar learning environment
GNU General Public License v2.0
1 stars 15 forks source link

Editing the game doesn't work, activity gets stuck #29

Closed shaansubbaiah closed 3 years ago

shaansubbaiah commented 3 years ago

Tested on: Sugar 0.117-3, Debian Bullseye Sugar 0.117, Sugar Live Build

Reproduce:

Click 'Edit Game' -> Click 'Match Identical Tiles' and/or Click 'Mixed Tiles Game' and/or 3.Edit the cards and Click update-> Click 'Play Game' Sometimes, Sugar freezes completely, cannot recover without rebooting. Most times, closing the activity fixes it.

Traceback:

1594050507.412289 ERROR root: Error saving activity object to datastore
Traceback (most recent call last):
  File "/usr/lib/python3.8/xml/etree/ElementTree.py", line 1076, in _escape_attrib
    if "&" in text:
TypeError: argument of type 'bool' is not iterable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/sugar3/activity/activity.py", line 1277, in _prepare_close
    self.save()
  File "/usr/lib/python3/dist-packages/sugar3/activity/activity.py", line 978, in save
    self.write_file(file_path)
  File "/usr/share/sugar/activities/Memorize.activity/activity.py", line 409, in write_file
    self.game.model.write()
  File "/usr/share/sugar/activities/Memorize.activity/model.py", line 357, in write
    xml_file.write(tostring(root))
  File "/usr/lib/python3.8/xml/etree/ElementTree.py", line 1133, in tostring
    ElementTree(element).write(stream, encoding,
  File "/usr/lib/python3.8/xml/etree/ElementTree.py", line 772, in write
    serialize(write, self._root, qnames, namespaces,
  File "/usr/lib/python3.8/xml/etree/ElementTree.py", line 937, in _serialize_xml
    _serialize_xml(write, e, qnames, None,
  File "/usr/lib/python3.8/xml/etree/ElementTree.py", line 930, in _serialize_xml
    v = _escape_attrib(v)
  File "/usr/lib/python3.8/xml/etree/ElementTree.py", line 1099, in _escape_attrib
    _raise_serialization_error(text)
  File "/usr/lib/python3.8/xml/etree/ElementTree.py", line 1053, in _raise_serialization_error
    raise TypeError(
TypeError: cannot serialize False (type bool)
1594050582.942545 ERROR dbus.connection: Exception in handler for D-Bus signal:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/dbus/connection.py", line 232, in maybe_handle_message
    self._handler(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/sugar3/presence/connectionmanager.py", line 99, in
__status_changed_cb
    self._connections_per_account[account_path].connected = False
KeyError: dbus.ObjectPath('/org/freedesktop/Telepathy/Account/salut/local_xmpp/account0')
quozl commented 3 years ago

Some of the errors may not be relevant to the problem. This one may be explained away;

1594050582.942545 ERROR dbus.connection: Exception in handler for D-Bus signal:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/dbus/connection.py", line 232, in maybe_handle_message
    self._handler(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/sugar3/presence/connectionmanager.py", line 99, in
__status_changed_cb
    self._connections_per_account[account_path].connected = False
KeyError: dbus.ObjectPath('/org/freedesktop/Telepathy/Account/salut/local_xmpp/account0')

It may occur if the system is momentarily not connected to a network, as can happen if the network cable, wireless network, or virtual network is interrupted. This in turn may occur due to suspend and resume during a lid close, carry, lid open sequence.

As I've reproduced it independently of Memorize, I've moved it to https://github.com/sugarlabs/sugar-toolkit-gtk3/issues/450.

shaansubbaiah commented 3 years ago

Investigating I've found that some of the dictionary values used to store the card's data have Boolean values instead of String. Skipping those values entirely somewhat fixes saving in the Datastore, I'll try converting them to String and check.

shaansubbaiah commented 3 years ago

Changing the Boolean False values to empty strings before writing to an .XML file

    for key in self.pairs:
            pair_props = {}
            if self.pairs[key].props.aimg is not None:
                pair_props["aimg"] = self.pairs[key].props.aimg
            if self.pairs[key].props.asnd is not None:
                pair_props["asnd"] = self.pairs[key].props.asnd
            if self.pairs[key].props.achar is not None:
                pair_props["achar"] = self.pairs[key].props.achar
            if self.pairs[key].props.bimg is not None:
                pair_props["bimg"] = self.pairs[key].props.bimg
            if self.pairs[key].props.bsnd is not None:
                pair_props["bsnd"] = self.pairs[key].props.bsnd
            if self.pairs[key].props.bchar is not None:
                pair_props["bchar"] = self.pairs[key].props.bchar
            if self.pairs[key].props.aspeak is not None:
                pair_props["aspeak"] = self.pairs[key].props.aspeak
            if self.pairs[key].props.bspeak is not None:
                pair_props["bspeak"] = self.pairs[key].props.bspeak
            SubElement(root, 'pair', pair_props)

to

    arr = ["aimg", "asnd", "achar", "bimg", "bsnd", "bchar", "aspeak", "bspeak"]

    for key in self.pairs:
        pair_props = {}
        for e in arr:
            if self.pairs[key].get_property(e) is not None:
                if self.pairs[key].get_property(e) is False:
                    pair_props[e] = ""
                else:
                    pair_props[e] = self.pairs[key].get_property(e)
        SubElement(root, 'pair', pair_props)

This fixes the error and allows instances of the activity with modified cards to be saved to the Journal.

shaansubbaiah commented 3 years ago

@quozl if this is fine, I'll make a PR with the changes? The extra array created can be used to shorten the other if statements in the other functions or a function set_property_for_XML() can be created, which will convert False to empty strings and allow maintaining the current structure.

quozl commented 3 years ago

I guess so, but not sure. I'd like to see it described in a pull request with a clear commit message.