예제 #1
0
 def test_slugify_use_given_join_sign(self):
     self.assertEqual(slugify('Slugify this string please!', '-'),
                      'slugify-this-string-please')
     self.assertEqual(slugify('Slugify this string please!', '_'),
                      'slugify_this_string_please')
     self.assertEqual(slugify('Slugify this string please!', '.'),
                      'slugify.this.string.please')
예제 #2
0
    def test_cannot_handle_non_string_objects(self):
        with self.assertRaises(TypeError) as raised:
            # noinspection PyTypeChecker
            slugify(None)

        self.assertEqual(str(raised.exception),
                         'Expected "str", received "NoneType"')

        with self.assertRaises(TypeError) as raised:
            # noinspection PyTypeChecker
            slugify(False)

        self.assertEqual(str(raised.exception),
                         'Expected "str", received "bool"')

        with self.assertRaises(TypeError) as raised:
            # noinspection PyTypeChecker
            slugify(0)

        self.assertEqual(str(raised.exception),
                         'Expected "str", received "int"')

        with self.assertRaises(TypeError) as raised:
            # noinspection PyTypeChecker
            slugify([])

        self.assertEqual(str(raised.exception),
                         'Expected "str", received "list"')

        with self.assertRaises(TypeError) as raised:
            # noinspection PyTypeChecker
            slugify({'a': 1})

        self.assertEqual(str(raised.exception),
                         'Expected "str", received "dict"')
예제 #3
0
 def test_slugify_trim_strings_and_extra_white_spaces(self):
     self.assertEqual(slugify('hello '), 'hello')
     self.assertEqual(slugify(' hello'), 'hello')
     self.assertEqual(slugify(' hello '), 'hello')
     self.assertEqual(slugify(' hello world '), 'hello-world')
     self.assertEqual(
         slugify('''
         \n\t
         hello \n\t world
         \n\t
     '''), 'hello-world')
예제 #4
0
    def create_for_schema(
        cls, dataset: Dataset, table: DatasetTableSchema
    ) -> DatasetTable:
        """Create a DatasetTable object based on the Amsterdam Schema table spec.

        (The table spec contains a JSON-schema for all fields).
        """
        enable_geosearch = True
        if dataset.name in settings.AMSTERDAM_SCHEMA["geosearch_disabled_datasets"]:
            enable_geosearch = False

        claims = table.get("auth", [])
        if isinstance(claims, str):
            claims = [claims]

        instance = cls.objects.create(
            dataset=dataset,
            name=slugify(table.id, sign="_"),
            db_table=get_db_table_name(table),
            auth=" ".join(claims),
            enable_geosearch=enable_geosearch,
            **cls._get_field_values(table),
        )

        for field in table.fields:
            DatasetField.create_for_schema(instance, field)

        return instance
예제 #5
0
def to_snake_case(name):
    """
    Convert field/column/dataset name from Space separated/Snake Case/Camel case
    to snake_case.
    """
    # Convert to field name, avoiding snake_case to snake_case issues.
    name = toCamelCase(name)
    return slugify(re_camel_case.sub(r" \1", name).strip().lower(),
                   separator="_")
예제 #6
0
    def create_for_schema(
        cls, table: DatasetTableSchema, field: DatasetFieldSchema
    ) -> DatasetField:
        """Create a DatasetField object based on the Amsterdam Schema field spec.

        """
        claims = field.get("auth", [])
        if isinstance(claims, str):
            claims = [claims]

        return cls.objects.create(
            table=table, name=slugify(field.name, sign="_"), auth=" ".join(claims)
        )
예제 #7
0
    def save_schema_tables(self):
        """Expose the schema data to the DatasetTable.
        This allows other projects (e.g. geosearch) to process our dynamic tables.
        """
        if not self.schema_data:
            # no schema stored -> no tables
            if self._old_schema_data:
                self.tables.all().delete()
            return

        new_definitions = {slugify(t.id, sign="_"): t for t in self.schema.tables}
        new_names = set(new_definitions.keys())
        existing_models = {t.name: t for t in self.tables.all()}
        existing_names = set(existing_models.keys())

        # Create models for newly added tables
        for added_name in new_names - existing_names:
            table = new_definitions[added_name]
            DatasetTable.create_for_schema(self, table)

        # Remove tables that are no longer part of the schema.
        for removed_name in existing_names - new_names:
            existing_models[removed_name].delete()
예제 #8
0
 def test_slugify_removes_dash_duplicates(self):
     self.assertEqual(slugify('-hello world too--much --dashes---here--'),
                      'hello-world-too-much-dashes-here')
예제 #9
0
 def test_slugify_preserves_numbers(self):
     self.assertEqual(slugify('12 eggs, 1 gallon of milk, 4 bananas'),
                      '12-eggs-1-gallon-of-milk-4-bananas')
예제 #10
0
 def test_slugify_converts_non_ascii_letters(self):
     self.assertEqual(slugify('Mönstér Mägnët'), 'monster-magnet')
예제 #11
0
 def test_slugify_removes_signs(self):
     self.assertEqual(slugify('(this is a "test")'), 'this-is-a-test')
     self.assertEqual(slugify('<<wow>> :: [yeah]'), 'wow-yeah')
     self.assertEqual(slugify('c++'), 'c')
     self.assertEqual(slugify('?#foo+bar+baz!'), 'foo-bar-baz')
예제 #12
0
 def test_slugify_lowercase_strings(self):
     self.assertEqual(slugify('BANANA'), 'banana')
예제 #13
0
def get_db_table_name(table: DatasetTableSchema) -> str:
    """Generate the table name for a database schema."""
    dataset = table._parent_schema
    app_label = dataset.id
    table_id = table.id
    return slugify(f"{app_label}_{table_id}", sign="_")
예제 #14
0
def model_factory(table: DatasetTableSchema,
                  base_app_name=None) -> Type[DynamicModel]:
    """Generate a Django model class from a JSON Schema definition."""
    dataset = table._parent_schema
    app_label = dataset.id
    base_app_name = base_app_name or "dso_api.dynamic_api"
    module_name = f"{base_app_name}.{app_label}.models"
    model_name = f"{table.id.capitalize()}"

    # Generate fields
    fields = {}
    display_field = None
    for field in table.fields:
        type_ = field.type
        # skip schema field for now
        if type_.endswith("definitions/schema"):
            continue
        # reduce amsterdam schema refs to their fragment
        if type_.startswith(settings.SCHEMA_DEFS_URL):
            type_ = urlparse(type_).fragment
        base_class, init_kwargs = JSON_TYPE_TO_DJANGO[type_]
        if init_kwargs is None:
            init_kwargs = {}

        # Generate field object
        kls, args, kwargs = FieldMaker(base_class, **init_kwargs)(field,
                                                                  dataset)
        if kls is None:
            # Some fields are not mapped into classes
            continue
        model_field = kls(*args, **kwargs)

        # Generate name, fix if needed.
        field_name = slugify(field.name, sign="_")
        model_field.name = field_name
        fields[field_name] = model_field

        if not display_field and is_possible_display_field(field):
            display_field = field.name

    # Generate Meta part
    meta_cls = type(
        "Meta",
        (),
        {
            "managed": False,
            "db_table": get_db_table_name(table),
            "app_label": app_label,
            "verbose_name": table.id.title(),
            "ordering": ("id", ),
        },
    )

    # Generate the model
    return ModelBase(
        model_name,
        (DynamicModel, ),
        {
            **fields,
            "_dataset_schema": dataset,
            "_table_schema": table,
            "_display_field": "",
            "__module__": module_name,
            "Meta": meta_cls,
        },
    )
예제 #15
0
 def get_table_id(cls) -> str:
     """Give access to the table name"""
     return slugify(cls._table_schema.id, sign="_")
예제 #16
0
 def get_dataset_id(cls) -> str:
     return slugify(cls._table_schema._parent_schema.id, sign="_")