Example #1
0
def get_sorted_levels(domain, filters) -> Tuple[list, dict, dict, dict]:
    """
    Returns dictionaries of location levels, keyed on the ID of their
    parent level. (e.g. {'MA': ['Boston', 'Cambridge']}) The user's
    filters are applied.
    """
    l3s_by_l2 = {}
    l4s_by_l3 = {}
    data_types_by_tag = get_data_types_by_tag(domain)
    level_1s = get_fixture_dicts(
        domain,
        data_types_by_tag["level_1_eco"]._id,
        filter_in={
            'id': [filters['level_1']] if filters['level_1'] else None
        },
        filter_out={'other': '1'},
    )
    l2s_by_l1 = get_fixture_dicts_by_key(
        domain,
        data_type_id=data_types_by_tag["level_2_eco"]._id,
        key='level_1_eco',
        filter_in={
            'level_1_eco': [l['id'] for l in level_1s],
            'id': [filters['level_2']] if filters['level_2'] else None
        },
        filter_out={'other': '1'},
    )
    l3_data_items = get_fixture_items_for_data_type(
        domain, data_type_id=data_types_by_tag["level_3_eco"]._id,
    )
    country_has_level_3 = len(l3_data_items) > 1
    if country_has_level_3:
        l3s_by_l2 = get_fixture_dicts_by_key(
            domain,
            data_type_id=data_types_by_tag["level_3_eco"]._id,
            key='level_2_eco',
            filter_in={
                'level_2_eco': [l2['id'] for l2s in l2s_by_l1.values() for l2 in l2s],
                'id': [filters['level_3']] if filters['level_3'] else None
            },
            filter_out={'other': '1'},
        )
        l4_data_items = get_fixture_items_for_data_type(
            domain, data_type_id=data_types_by_tag["level_4_eco"]._id,
        )
        country_has_level_4 = len(l4_data_items) > 1
        if country_has_level_4:
            l4s_by_l3 = get_fixture_dicts_by_key(
                domain,
                data_type_id=data_types_by_tag["level_4_eco"]._id,
                key='level_3_eco',
                filter_in={
                    'level_3_eco': [l3['id'] for l3s in l3s_by_l2.values() for l3 in l3s],
                    'id': [filters['level_4']] if filters['level_4'] else None
                },
                filter_out={'other': '1'},
            )
    return level_1s, l2s_by_l1, l3s_by_l2, l4s_by_l3
Example #2
0
def get_fixture_dicts(
    domain: str,
    data_type_id: str,
    filter_in: Optional[Dict[str, Optional[Iterable]]] = None,
    filter_out: Optional[Dict[str, Any]] = None,
) -> List[Dict]:
    """
    Returns a list of fixture data items as dictionaries.

    They can be filtered using ``filter_in``, where if the item has a
    key that is in ``filter_in``, then the value of ``item[key]`` must
    be in the (set/tuple/list) value of ``filter_in[key]``.
    """
    data_items = get_fixture_items_for_data_type(domain, data_type_id)
    dicts = (fixture_data_item_to_dict(di) for di in data_items)
    return [d for d in dicts
            if dict_values_in(d, filter_in)
            and dict_value_not(d, filter_out)]
Example #3
0
def get_fixture_dicts_by_key(
    domain: str,
    data_type_id: str,
    key: str,
    filter_in: Optional[Dict[str, list]] = None,
    filter_out: Optional[Dict[str, Any]] = None,
) -> dict:
    """
    Returns a dictionary of fixture data items, keyed on ``key``, and
    fixture data items are dictionaries.

    They can be filtered using ``filter_in``, where if the item has a
    key that is in ``filter_in``, then the value of ``item[key]`` must
    be in the (set/tuple/list) value of ``filter_in[key]``.
    """
    dicts_by_key = defaultdict(list)
    for data_item in get_fixture_items_for_data_type(domain, data_type_id):
        dict_ = fixture_data_item_to_dict(data_item)
        if (dict_values_in(dict_, filter_in)
                and dict_value_not(dict_, filter_out)):
            dicts_by_key[dict_[key]].append(dict_)
    return dicts_by_key
Example #4
0
 def by_data_type(cls, domain, data_type, bypass_cache=False):
     return get_fixture_items_for_data_type(domain, _id_from_doc(data_type),
                                            bypass_cache)
Example #5
0
def get_locations(domain, filters) -> List[LocationTuple]:
    """
    Returns a list of level-four locations, or level-three locations if
    the country does not have level-four locations.

    The return value respects the filters applied by the user.
    """
    data_types_by_tag = get_data_types_by_tag(domain)
    level_1s = get_fixture_dicts(
        domain,
        data_types_by_tag["level_1_dcv"]._id,
        filter_in={'id': [filters['level_1']] if filters['level_1'] else None},
        filter_out={'other': '1'},
    )
    l2s_by_l1 = get_fixture_dicts_by_key(
        domain,
        data_type_id=data_types_by_tag["level_2_dcv"]._id,
        key='level_1_dcv',
        filter_in={
            'level_1_dcv': [l['id'] for l in level_1s],
            'id': [filters['level_2']] if filters['level_2'] else None
        },
        filter_out={'other': '1'},
    )
    l3s_by_l2 = get_fixture_dicts_by_key(
        domain,
        data_type_id=data_types_by_tag["level_3_dcv"]._id,
        key='level_2_dcv',
        filter_in={
            'level_2_dcv':
            [l2['id'] for l2s in l2s_by_l1.values() for l2 in l2s],
            'id': [filters['level_3']] if filters['level_3'] else None
        },
        filter_out={'other': '1'},
    )
    l4_data_items = get_fixture_items_for_data_type(
        domain, data_types_by_tag["level_4_dcv"]._id)
    country_has_level_4 = len(l4_data_items) > 1
    if country_has_level_4:
        l4s_by_l3 = get_fixture_dicts_by_key(
            domain,
            data_type_id=data_types_by_tag["level_4_dcv"]._id,
            key='level_3_dcv',
            filter_in={
                'level_3_dcv':
                [l3['id'] for l3s in l3s_by_l2.values() for l3 in l3s],
                'id': [filters['level_4']] if filters['level_4'] else None
            },
            filter_out={'other': '1'},
        )
    else:
        l4s_by_l3 = {}

    locations = []
    for level_1 in level_1s:
        for level_2 in l2s_by_l1[level_1['id']]:
            for level_3 in l3s_by_l2[level_2['id']]:
                if country_has_level_4:
                    for level_4 in l4s_by_l3[level_3['id']]:
                        locations.append(
                            LocationTuple(
                                id=level_4['id'],
                                name=level_4['name'],
                                country=level_1['country'],
                                level_1=level_1['name'],
                                level_2=level_2['name'],
                                level_3=level_3['name'],
                                level_4=level_4['name'],
                            ))
                else:
                    locations.append(
                        LocationTuple(
                            id=level_3['id'],
                            name=level_3['name'],
                            country=level_1['country'],
                            level_1=level_1['name'],
                            level_2=level_2['name'],
                            level_3=level_3['name'],
                            level_4=None,
                        ))
    return locations
Example #6
0
def get_fixture(domain, tag):
    data_type = get_fixture_data_type_by_tag(domain, tag)
    return {
        "data_type": data_type,
        "data_items": get_fixture_items_for_data_type(domain, data_type._id),
    }
    def test_update_fixture(self):
        self.assertEqual([], get_fixture_data_types(self.linked_domain))

        # Update linked domain
        update_fixture(self.domain_link, self.table.tag)

        # Linked domain should now have master domain's table and rows
        linked_types = get_fixture_data_types(self.linked_domain)
        self.assertEqual({'moons'}, {t.tag for t in linked_types})
        self.assertEqual({self.linked_domain},
                         {t.domain
                          for t in linked_types})
        items = get_fixture_items_for_data_type(self.linked_domain,
                                                linked_types[0]._id)
        self.assertEqual({self.linked_domain}, {i.domain for i in items})
        self.assertEqual({linked_types[0]._id},
                         {i.data_type_id
                          for i in items})
        self.assertEqual([
            'Callisto',
            'Europa',
            'Io',
            'Jupiter',
            'Jupiter',
            'Jupiter',
        ],
                         sorted([
                             i.fields[field_name].field_list[0].field_value
                             for i in items for field_name in i.fields.keys()
                         ]))

        # Master domain's table and rows should be untouched
        master_types = get_fixture_data_types(self.domain)
        self.assertEqual({'moons'}, {t.tag for t in master_types})
        self.assertEqual({self.domain}, {t.domain for t in master_types})
        master_items = get_fixture_items_for_data_type(self.domain,
                                                       master_types[0]._id)
        self.assertEqual([
            'Callisto',
            'Europa',
            'Io',
            'Jupiter',
            'Jupiter',
            'Jupiter',
        ],
                         sorted([
                             i.fields[field_name].field_list[0].field_value
                             for i in master_items
                             for field_name in i.fields.keys()
                         ]))

        # Update rows in master table and re-update linked domain
        master_items[-1].delete()  # Callisto
        FixtureDataItem(
            domain=self.domain,
            data_type_id=self.table._id,
            fields={
                'name':
                FieldList(
                    field_list=[FixtureItemField(field_value='Thalassa')]),
                'planet':
                FieldList(field_list=[FixtureItemField(
                    field_value='Neptune')]),
            },
        ).save()
        FixtureDataItem(
            domain=self.domain,
            data_type_id=self.table._id,
            fields={
                'name':
                FieldList(field_list=[FixtureItemField(field_value='Naiad')]),
                'planet':
                FieldList(field_list=[FixtureItemField(
                    field_value='Neptune')]),
            },
        ).save()
        clear_fixture_quickcache(self.domain,
                                 get_fixture_data_types(self.domain))
        clear_fixture_cache(self.domain)
        update_fixture(self.domain_link, self.table.tag)

        # Linked domain should still have one table, with the new rows
        linked_types = get_fixture_data_types(self.linked_domain)
        self.assertEqual(1, len(linked_types))
        self.assertEqual('moons', linked_types[0].tag)
        items = get_fixture_items_for_data_type(self.linked_domain,
                                                linked_types[0]._id)
        self.assertEqual(4, len(items))
        self.assertEqual([
            'Europa',
            'Io',
            'Jupiter',
            'Jupiter',
            'Naiad',
            'Neptune',
            'Neptune',
            'Thalassa',
        ],
                         sorted([
                             i.fields[field_name].field_list[0].field_value
                             for i in items for field_name in i.fields.keys()
                         ]))