Exemple #1
0
    def _plays_to_games(self, data):
        def after_players_hook(_, status):
            return status["name"] if "name" in status else "Unknown"

        plays_processor = xml.dictionary("plays", [
            xml.array(
                xml.dictionary('play', [
                    xml.integer(".", attribute="id", alias="playid"),
                    xml.dictionary('item', [
                        xml.string(".", attribute="name", alias="gamename"),
                        xml.integer(".", attribute="objectid", alias="gameid")
                    ],
                                   alias='game'),
                    xml.array(
                        xml.dictionary(
                            'players/player', [
                                xml.string(".",
                                           attribute="name",
                                           required=False,
                                           default="Unknown")
                            ],
                            required=False,
                            alias='players',
                            hooks=xml.Hooks(after_parse=after_players_hook)))
                ],
                               required=False,
                               alias="plays"))
        ])

        plays = xml.parse_from_string(plays_processor, data)
        plays = plays["plays"]
        return plays
def test_processor_locations_parsing():
    """Get processor location in hooks callback."""
    expected_locations = [
        xml.ProcessorLocation(element_path='data', array_index=None),
        xml.ProcessorLocation(element_path='value', array_index=None)
    ]

    def trace(state, _):
        assert isinstance(state, xml.ProcessorStateView)
        assert expected_locations == list(state.locations)

    hooks = xml.Hooks(
        after_parse=trace,
        before_serialize=trace,
    )

    processor = xml.dictionary('data', [
        xml.integer('value', hooks=hooks),
    ])

    xml_string = strip_xml("""
    <data>
        <value>1</value>
    </data>
    """)

    value = {'value': 1}

    xml.parse_from_string(processor, xml_string)
    xml.serialize_to_string(processor, value)
def test_primitive_transform_array_element():
    """Transform a primitive value that is an array element"""
    xml_string = strip_xml("""
    <data>
        <value>3</value>
        <value>7</value>
        <value>16</value>
    </data>
    """)

    value = [
        6,
        14,
        32,
    ]

    def _after_parse(_, x):
        return int(x * 2)

    def _before_serialize(_, x):
        return int(x / 2)

    hooks = xml.Hooks(after_parse=_after_parse,
                      before_serialize=_before_serialize)

    processor = xml.array(xml.integer('value', hooks=hooks), nested='data')

    _transform_test_case_run(processor, value, xml_string)
def test_primitive_transform_attribute():
    """Transform a primitive value that is an attribute"""
    xml_string = strip_xml("""
    <data>
        <element value="3" />
    </data>
    """)

    value = {
        'value': 6,
    }

    def _after_parse(_, x):
        return int(x * 2)

    def _before_serialize(_, x):
        return int(x / 2)

    hooks = xml.Hooks(after_parse=_after_parse,
                      before_serialize=_before_serialize)

    processor = xml.dictionary(
        'data', [xml.integer('element', attribute='value', hooks=hooks)])

    _transform_test_case_run(processor, value, xml_string)
def test_named_tuple_transform():
    """Transform a named tuple value"""
    Person = namedtuple('Person', ['name', 'age'])

    xml_string = strip_xml("""
    <person>
        <name>John</name>
        <age>24</age>
    </person>
    """)

    value = {
        'name': 'John',
        'age': 24,
    }

    def _after_parse(_, tuple_value):
        return {
            'name': tuple_value.name,
            'age': tuple_value.age,
        }

    def _before_serialize(_, dict_value):
        return Person(name=dict_value['name'], age=dict_value['age'])

    processor = xml.named_tuple('person',
                                Person, [
                                    xml.string('name'),
                                    xml.integer('age'),
                                ],
                                hooks=xml.Hooks(
                                    after_parse=_after_parse,
                                    before_serialize=_before_serialize))

    _transform_test_case_run(processor, value, xml_string)
def test_boolean_transform():
    """Transform boolean values"""
    xml_string = strip_xml("""
        <data>
            <value>True</value>
        </data>
    """)

    value = {'value': 'It is true'}

    def _after_parse(_, x):
        if x:
            return 'It is true'
        else:
            return 'It is false'

    def _before_serialize(_, x):
        if x == 'It is true':
            return True
        else:
            return False

    hooks = xml.Hooks(after_parse=_after_parse,
                      before_serialize=_before_serialize)

    processor = xml.dictionary('data', [xml.boolean('value', hooks=hooks)])

    _transform_test_case_run(processor, value, xml_string)
Exemple #7
0
    def _collection_to_games(self, data):
        def after_status_hook(_, status):
            return [tag for tag, value in status.items() if value == "1"]

        game_in_collection_processor = xml.dictionary(
            "items", [
                xml.array(
                    xml.dictionary('item', [
                        xml.integer(".", attribute="objectid", alias="id"),
                        xml.string("name"),
                        xml.string("thumbnail", required=False, alias="image"),
                        xml.string("version/item/thumbnail",
                                   required=False,
                                   alias="image_version"),
                        xml.dictionary(
                            "status", [
                                xml.string(".", attribute="fortrade"),
                                xml.string(".", attribute="own"),
                                xml.string(".", attribute="preordered"),
                                xml.string(".", attribute="prevowned"),
                                xml.string(".", attribute="want"),
                                xml.string(".", attribute="wanttobuy"),
                                xml.string(".", attribute="wanttoplay"),
                                xml.string(".", attribute="wishlist"),
                            ],
                            alias='tags',
                            hooks=xml.Hooks(after_parse=after_status_hook)),
                        xml.integer("numplays"),
                    ],
                                   required=False,
                                   alias="items"), )
            ])
        collection = xml.parse_from_string(game_in_collection_processor, data)
        collection = collection["items"]
        return collection
    def _hooks(self):
        def validate(state, _):
            state.raise_error(_ValidationError, 'Invalid value')

        return xml.Hooks(
            after_parse=validate,
            before_serialize=validate,
        )
    def _dict_processor(self):
        hooks = xml.Hooks(after_parse=self._after_parse,
                          before_serialize=self._before_serialize)

        return xml.dictionary('data', [
            xml.integer('a'),
            xml.integer('b'),
            xml.integer('c'),
        ],
                              hooks=hooks)
    def _user_object_processor(self):
        hooks = xml.Hooks(
            after_parse=self._after_parse,
            before_serialize=self._before_serialize,
        )

        return xml.user_object('person',
                               self._Person, [
                                   xml.string('name'),
                                   xml.integer('age'),
                               ],
                               hooks=hooks)
    def _processor(self):
        def validate(state, value):
            if value < 0:
                state.raise_error(_ValidationError)

            return value

        hooks = xml.Hooks(after_parse=validate, before_serialize=validate)

        processor = xml.dictionary('data', [xml.integer('value', hooks=hooks)])

        return processor
    def _processor(self):
        def validate(state, value):
            if len(value) != len(set(value)):
                state.raise_error(_ValidationError)
            return value

        hooks = xml.Hooks(
            after_parse=validate,
            before_serialize=validate,
        )

        processor = xml.array(xml.integer('value'), hooks=hooks, nested='data')

        return processor
def test_primitive_missing_hooks():
    """Process primitive value with missing hooks."""
    hooks = xml.Hooks(after_parse=None, before_serialize=None)

    processor = xml.dictionary('data', [xml.integer('value', hooks=hooks)])

    xml_string = strip_xml("""
    <data>
        <value>1</value>
    </data>
    """)

    value = {'value': 1}

    _assert_valid(processor, value, xml_string)
    def _processor(self):
        def validate(state, value):
            if value.name == 'Bob' and value.age == 24:
                state.raise_error(_ValidationError)
            return value

        hooks = xml.Hooks(
            after_parse=validate,
            before_serialize=validate,
        )

        processor = xml.user_object(
            'user',
            _UserClass,
            [xml.string('name'), xml.integer('age')],
            hooks=hooks)

        return processor
    def _processor(self):
        def validate(state, value):
            if value['a'] == 5 and value['b'] == 6:
                state.raise_error(_ValidationError)
            return value

        hooks = xml.Hooks(
            after_parse=validate,
            before_serialize=validate,
        )

        processor = xml.dictionary('data', [
            xml.integer('a'),
            xml.integer('b'),
        ],
                                   hooks=hooks)

        return processor
def test_aggregate_missing_hooks():
    """Process with missing aggregate hooks."""
    hooks = xml.Hooks(after_parse=None, before_serialize=None)

    processor = xml.dictionary(
        'data', [xml.integer('a'), xml.integer('b')], hooks=hooks)

    xml_string = strip_xml("""
    <data>
        <a>1</a>
        <b>2</b>
    </data>
    """)

    value = {
        'a': 1,
        'b': 2,
    }

    _assert_valid(processor, value, xml_string)
def test_integer_transform():
    """Transform integer values"""
    xml_string = strip_xml("""
        <data>
            <value>3</value>
        </data>
    """)

    value = {'value': 6}

    def _after_parse(_, x):
        return int(x * 2)

    def _before_serialize(_, x):
        return int(x / 2)

    hooks = xml.Hooks(after_parse=_after_parse,
                      before_serialize=_before_serialize)

    processor = xml.dictionary('data', [xml.integer('value', hooks=hooks)])

    _transform_test_case_run(processor, value, xml_string)
def test_string_transform():
    """Transform string values"""
    xml_string = strip_xml("""
        <data>
            <value>hello</value>
        </data>
    """)

    value = {'value': 'HELLO'}

    def _after_parse(_, x):
        return x.upper()

    def _before_serialize(_, x):
        return x.lower()

    hooks = xml.Hooks(after_parse=_after_parse,
                      before_serialize=_before_serialize)

    processor = xml.dictionary('data', [xml.string('value', hooks=hooks)])

    _transform_test_case_run(processor, value, xml_string)
def test_floating_point_transform():
    """Transform floating point values"""
    xml_string = strip_xml("""
        <data>
            <value>13.1</value>
        </data>
    """)

    value = {'value': 26.2}

    def _after_parse(_, x):
        return x * 2.0

    def _before_serialize(_, x):
        return x / 2.0

    hooks = xml.Hooks(after_parse=_after_parse,
                      before_serialize=_before_serialize)

    processor = xml.dictionary('data',
                               [xml.floating_point('value', hooks=hooks)])

    _transform_test_case_run(processor, value, xml_string)
 def _hooks(self):
     return xml.Hooks(after_parse=self._after_parse,
                      before_serialize=self._before_serialize)
Exemple #21
0
    def _games_list_to_games(self, data):
        def numplayers_to_result(_, results):
            result = {
                result["value"].lower().replace(" ", "_"):
                int(result["numvotes"])
                for result in results
            }

            if not result:
                result = {'best': 0, 'recommended': 0, 'not_recommended': 0}

            is_recommended = result['best'] + result['recommended'] > result[
                'not_recommended']
            if not is_recommended:
                return "not_recommended"

            is_best = result['best'] > 10 and result['best'] > result[
                'recommended']
            if is_best:
                return "best"

            return "recommended"

        def suggested_numplayers(_, numplayers):
            # Remove not_recommended player counts
            numplayers = [
                players for players in numplayers
                if players["result"] != "not_recommended"
            ]

            # If there's only one player count, that's the best one
            if len(numplayers) == 1:
                numplayers[0]["result"] = "best"

            # Just return the numbers
            return [(players["numplayers"], players["result"])
                    for players in numplayers]

        def log_item(_, item):
            logger.debug("Successfully parsed: {} (id: {}).".format(
                item["name"], item["id"]))
            return item

        game_processor = xml.dictionary("items", [
            xml.array(
                xml.dictionary(
                    "item",
                    [
                        xml.integer(".", attribute="id"),
                        xml.string(".", attribute="type"),
                        xml.string("name[@type='primary']",
                                   attribute="value",
                                   alias="name"),
                        xml.string("description"),
                        xml.array(
                            xml.string("link[@type='boardgamecategory']",
                                       attribute="value",
                                       required=False),
                            alias="categories",
                        ),
                        xml.array(
                            xml.string("link[@type='boardgamemechanic']",
                                       attribute="value",
                                       required=False),
                            alias="mechanics",
                        ),
                        xml.array(
                            xml.dictionary(
                                "link[@type='boardgameexpansion']", [
                                    xml.integer(".", attribute="id"),
                                    xml.boolean(".",
                                                attribute="inbound",
                                                required=False),
                                ],
                                required=False),
                            alias="expansions",
                        ),
                        xml.array(
                            xml.dictionary(
                                "poll[@name='suggested_numplayers']/results", [
                                    xml.string(".", attribute="numplayers"),
                                    xml.array(xml.dictionary("result", [
                                        xml.string(".", attribute="value"),
                                        xml.integer(".", attribute="numvotes"),
                                    ],
                                                             required=False),
                                              hooks=xml.Hooks(
                                                  after_parse=
                                                  numplayers_to_result))
                                ]),
                            alias="suggested_numplayers",
                            hooks=xml.Hooks(after_parse=suggested_numplayers),
                        ),
                        xml.string("statistics/ratings/averageweight",
                                   attribute="value",
                                   alias="weight"),
                        xml.string(
                            "statistics/ratings/ranks/rank[@friendlyname='Board Game Rank']",
                            attribute="value",
                            required=False,
                            alias="rank"),
                        xml.string("statistics/ratings/usersrated",
                                   attribute="value",
                                   alias="usersrated"),
                        xml.string("statistics/ratings/owned",
                                   attribute="value",
                                   alias="numowned"),
                        xml.string("statistics/ratings/bayesaverage",
                                   attribute="value",
                                   alias="rating"),
                        xml.string("playingtime",
                                   attribute="value",
                                   alias="playing_time"),
                    ],
                    required=False,
                    alias="items",
                    hooks=xml.Hooks(after_parse=log_item),
                ))
        ])
        games = xml.parse_from_string(game_processor, data)
        games = games["items"]
        return games
Exemple #22
0
    def __init__(self, group_name="Imported", group_desc=""):

        self.group_name = group_name
        self.group_desc = group_desc
        self.scenario_group = None

        def dict_to_scenario(state, value):
            session = Session()
            value['id'] = Scenario.scenario_hash(value['acq_time'],
                                                 value['scen_materials'],
                                                 value['scen_bckg_materials'],
                                                 value['influences'])
            q = session.query(Scenario).filter_by(id=value['id']).first()
            if q:
                if self.scenario_group:
                    self.scenario_group.scenarios.append(q)
                return q
            else:
                scenario = Scenario(value['acq_time'], value['replication'],
                                    value['scen_materials'],
                                    value['scen_bckg_materials'],
                                    value['influences'], [self.scenario_group])

            return scenario

        def scenario_to_dict(state, value):
            return value.__dict__

        def material_validate(state, value):
            session = Session()
            q = session.query(Material).filter_by(name=value.name).first()
            if q:
                return q
            else:
                session.add(value)
                return value

        def trace(state, value):
            print('Got {} at {}'.format(value, state))
            print(value.__dict__)
            return value

        def influence_validate(state, value):
            session = Session()
            q = session.query(Influence).filter_by(name=value.name).first()
            if q:
                return q
            else:
                session.add(value)
                return value

        self.scenario_hooks = xml.Hooks(
            after_parse=dict_to_scenario,
            before_serialize=scenario_to_dict,
        )

        self.material_hooks = xml.Hooks(
            after_parse=material_validate,
            before_serialize=lambda _, x: x,
        )

        self.influence_hooks = xml.Hooks(
            after_parse=influence_validate,
            before_serialize=lambda _, x: x,
        )

        self.material_processor = xml.user_object(
            'Material',
            Material, [xml.string('BaseMaterialName', alias='name')],
            alias='material',
            hooks=self.material_hooks)

        self.sourcematerials_processor = xml.user_object(
            'ScenarioMaterial',
            ScenarioMaterial, [
                self.material_processor,
                xml.string('fd_mode'),
                xml.floating_point('dose'),
            ],
            alias='scen_materials')

        self.bkgmaterial_processor = xml.user_object(
            'ScenarioBackgroundMaterial',
            ScenarioBackgroundMaterial, [
                self.material_processor,
                xml.string('fd_mode'),
                xml.floating_point('dose'),
            ],
            alias='scen_bckg_materials',
            required=False)

        self.influence_processor = xml.user_object(
            'Influence',
            Influence, [xml.string('InfluenceName', alias='name')],
            alias='influences',
            hooks=self.influence_hooks,
            required=False)

        self.scenario_processor = xml.dictionary('Scenario', [
            xml.string("id", required=False),
            xml.floating_point("acq_time"),
            xml.integer("replication"),
            xml.array(self.sourcematerials_processor),
            xml.array(self.bkgmaterial_processor),
            xml.array(self.influence_processor)
        ],
                                                 hooks=self.scenario_hooks)

        self.scenarios_processor = xml.dictionary(
            'Scenarios', [xml.array(self.scenario_processor)])