redruin1 / factorio-draftsman

A complete, well-tested, and up-to-date module to manipulate Factorio blueprint strings. Compatible with mods.
MIT License
92 stars 17 forks source link

Facilities for loading Blueprints stored as JSON #75

Closed SIGSTACKFAULT closed 1 year ago

SIGSTACKFAULT commented 1 year ago

I'm storing blueprintables as JSON so git can diff and merge them better.

currently, i'm forced to do:

with open(...) as f:
    bp = draftsman.blueprintable.get_blueprintable_from_string(
        draftsman.utils.JSON_to_string(json.load(f))
    )

of course the first thing get_blueprintable_from_string does is string_to_JSON, so we're encoding and decoding for no reason.

Suggetion

redruin1 commented 1 year ago
  1. get_blueprintable_from_JSON() is now added. I've also patched get_blueprintable_from_string() to no longer encode/decode itself twice.
  2. Technically you can already create Blueprintables from JSON dicts:
    # The following should work
    some_dict = {
        "blueprint": {
            "item": "blueprint",
            "description": "Test.",
            "label": "Some Blueprint",
            "version": 281479276920832
        }
    }
    bp = Blueprint(some_dict)
    assert bp.label == "Some Blueprint"
    assert bp.description == "Test."
    assert bp.version == 281479276920832

    Unfortunately, since I don't use this feature nearly as much, it's slightly bugged: you have to pass in the root item dict instead of the outer containing one in order for it to work on the current release:

    # This actually works right now
    some_dict = {
        "blueprint": {
            "item": "blueprint",
            "description": "Test.",
            "label": "Some Blueprint",
            "version": 281479276920832
        }
    }
    bp = Blueprint(some_dict["blueprint"])

    This is unintentional, and will be fixed in 1.0.5.

Note also that you can use the Blueprintable.setup() function to reset the keys all at once why keeping the same blueprint object, if desired:

   some_other_dict = {
        "blueprint": {
            "item": "blueprint",
            "label": "Another Blueprint",
            "version": 281479276920832
        }
    }
    # Unfortunately, due to the way this function takes kwargs you also have to index the item dict instead of the root
    bp.setup(**some_other_dict["blueprint"])
    # This is done so that you can write `bp.setup(label="something", description="something else")`
    assert bp.label == "Another Blueprint"
    assert bp.description == None

Lemme know if you think I should change setup() as well.