Ejemplo n.º 1
0
 def test_import_header(self):
     line = 'h1,h2,h3,h4'
     importer = Importer(None)
     importer.import_line(line)
     self.assertEqual('h1', importer.headers[0])
     self.assertEqual('h2', importer.headers[1])
     self.assertEqual('h3', importer.headers[2])
     self.assertEqual('h4', importer.headers[3])
    def test_basic_import(self):
        inf = StringIO(testImport)
        i = Importer(self.u1)
        i.readModelsFromFile(inf)
        self.assertEqual(len(i.books), 3)
        self.assertEqual(len(i.bookshelfs), 2)
        self.assertEqual(i.bookshelfs[2], self.bs)

        self.assertEqual(i.bookshelfs[1].bc_name, "Schrank")
        self.assertEqual(i.bookshelfs[1].user, self.u1)
    def get_importer(self, options: dict) -> Tuple[Importer, Body]:
        if options.get("body"):
            body = Body.objects.get(oparl_id=options["body"])
        else:
            body = Body.objects.get(id=settings.SITE_DEFAULT_BODY)
        loader = get_loader_from_body(body.oparl_id)
        importer = Importer(loader,
                            body,
                            ignore_modified=options["ignore_modified"])
        importer.force_singlethread = options["force_singlethread"]

        return importer, body
Ejemplo n.º 4
0
 def test_import_valid_line(self):
     header = 'h1,h2,h3,h4'
     line = '0.2,3,76,-48'
     importer = Importer(self.db)
     importer.import_line(header)
     importer.import_line(line)
     result = self.db.report.find_one({'h1': 0.2})
     self.assertIsNotNone(result)
     self.assertEqual(result['h1'], 0.2)
     self.assertEqual(result['h2'], 3)
     self.assertEqual(result['h3'], 76)
     self.assertEqual(result['h4'], -48)
Ejemplo n.º 5
0
    def import_body_and_metadata(
        self,
        body_id: str,
        importer: Importer,
        userinput: str,
        ags: Optional[str],
        skip_body_extra: bool = False,
    ) -> Tuple[JSON, str]:
        logger.info(f"Fetching the body {body_id}")
        [body_data] = importer.load_bodies(body_id)
        logger.info("Importing the body")
        [body] = importer.import_bodies()
        importer.converter.default_body = body
        logger.info("Looking up the Amtliche Gemeindeschlüssel")
        if ags:
            if len(ags) != 5 and len(ags) != 8:
                logger.warning(
                    "Your Amtlicher Gemeindeschlüssel has {} digits instead of 5 or 8"
                    .format(len(ags)))
            body.ags = ags
        else:
            ags, match_name = self.get_ags(body, importer.loader.system,
                                           userinput)
            body.ags = ags
            # Sometimes there's a bad short name (e.g. "Rat" for Erkelenz),
            # so we use the name that's in wikidata instead
            body.short_name = match_name
        body.save()
        logger.info("Using {} as Amtliche Gemeindeschlüssel for '{}'".format(
            body.ags, body.short_name))
        dotenv = ""
        if body.id != settings.SITE_DEFAULT_BODY:
            dotenv += f"SITE_DEFAULT_BODY={body.id}\n"
        if dotenv:
            logger.info(
                "Found the oparl endpoint. Please add the following line to your dotenv file "
                "(you'll be reminded again after the import finished): \n\n" +
                dotenv)

        if not skip_body_extra:
            logger.info("Importing the shape of the city")
            import_outline(body)
            logger.info("Importing the streets")
            import_streets(body)
            logger.info(
                f"Body {body.short_name} import with geo data successful.")
        else:
            logger.info(
                f"Body {body.short_name} import successful. "
                f"Don't forget to run import_streets, import_amenities and import_outline"
            )
        return body_data.data, dotenv
 def check_update(self):
     self.new_timestamp = (self.base_timestamp +
                           relativedelta(years=10)).isoformat()
     self.init_mock_loader()
     importer = Importer(self.loader, force_singlethread=True)
     importer.update(self.body_id)
     for table, count in self.tables.items():
         self.assertEqual(
             table.objects.count(),
             count,
             "{}: {} vs. {}".format(table, count, table.objects.all()),
         )
     self.assertEqual(File.objects.count(), 6)
Ejemplo n.º 7
0
    def from_userinput(
        self,
        userinput: str,
        mirror: bool,
        ags: Optional[str],
        skip_body_extra: bool = False,
        skip_files: bool = False,
    ) -> None:
        body_id, entrypoint = self.get_entrypoint_and_body(userinput, mirror)
        importer = Importer(get_loader_from_system(entrypoint))
        body_data, dotenv = self.import_body_and_metadata(
            body_id, importer, userinput, ags, skip_body_extra)

        logger.info("Loading the bulk data from the oparl api")
        importer.fetch_lists_initial([body_data])

        # Also avoid "MySQL server has gone away" errors due to timeouts
        # https://stackoverflow.com/a/32720475/3549270
        db.close_old_connections()

        logger.info("Loading the data into the database")
        importer.import_objects()

        if not skip_files:
            logger.info("Loading the files")
            importer.load_files(fallback_city=userinput)

        if dotenv:
            logger.info(
                f"Done! Please add the following line to your dotenv file: \n\n{dotenv}\n"
            )
Ejemplo n.º 8
0
    def check_deletion(self):
        self.new_timestamp = (self.base_timestamp +
                              relativedelta(years=200)).isoformat()
        self.delete = True
        self.init_mock_loader()
        importer = Importer(self.loader, force_singlethread=True)
        importer.update(self.body_id)
        for table, count in self.tables.items():
            # It doesn't make sense if our Body was deleted
            if table == Body:
                continue

            # We use minus one because we only deleted the top level objects
            self.assertEqual(table.objects.count(), count - 1,
                             f"{table} {table.objects.all()}")
 def handle(self, *args, **options):
     cli = Cli()
     userinput = options["cityname"]
     body_id, entrypoint = cli.get_entrypoint_and_body(
         userinput, options["mirror"])
     importer = Importer(get_loader_from_system(entrypoint))
     if options["manual"]:
         logger.info("Fetching the body")
         importer.load_bodies(body_id)
         logger.info("Importing the body")
         [body] = importer.import_bodies()
         logger.info("The body id is {}".format(body.id))
     else:
         cli.import_body_and_metadata(body_id, importer, userinput,
                                      options["ags"])
 def check_ignoring_unmodified(self):
     """ Check that not-modified objects are ignored """
     tables_with_modified = [
         Body,
         Organization,
         Person,
         Meeting,
         Paper,
         File,
     ]  # must have modified and File for #41
     newer_now = timezone.now()
     importer = Importer(self.loader, force_singlethread=True)
     importer.update(self.body_id)
     for table in tables_with_modified:
         logger.debug(table.__name__)
         self.assertLess(table.objects.first().modified, newer_now)
    def test_file_analysis(self):
        loader = MockLoader()
        with open(filename, "rb") as fp:
            loader.files[download_url] = (fp.read(), "application/pdf")

        importer = Importer(loader, force_singlethread=True)

        [body] = Body.objects.all()

        importer.load_files(fallback_city=body.short_name)

        [file] = File.objects.all()

        self.assertEqual(file.mime_type, "application/pdf")
        self.assertEqual(file.page_count, 3)
        self.assertEqual(len(file.parsed_text), 10019)
        self.assertEqual(file.coordinates(), [{"lat": 11.35, "lon": 142.2}])
        self.assertEqual(file.person_ids(), [1])
Ejemplo n.º 12
0
    def handle(self, *args, **options):
        cli = Cli()
        userinput = options["cityname"]
        body_id, entrypoint = cli.get_entrypoint_and_body(
            userinput, options["mirror"])
        importer = Importer(get_loader_from_system(entrypoint))
        if options["manual"]:
            if CachedObject.objects.filter(url=body_id).exists():
                logger.info("Using fetched body")

            else:
                logger.info("Fetching the body")
                importer.load_bodies(body_id)
            logger.info("Importing the body")
            [body] = importer.import_bodies()
            logger.info(f"The body id is {body.id}")
        else:
            cli.import_body_and_metadata(body_id, importer, userinput,
                                         options["ags"])
def test_file_404(pytestconfig, caplog):
    """Check that after a file has been manually deleted, it can't get re-imported and it's gone from minio"""
    url = "https://example.org/file/1"
    file_id = 1
    make_sample_file(file_id, url)

    with responses.RequestsMock() as requests_mock:
        requests_mock.add(responses.GET,
                          url,
                          status=404,
                          content_type="text/plain")
        importer = Importer(BaseLoader({}), force_singlethread=True)
        [successful, failed] = importer.load_files(sample_city.name,
                                                   update=True)
        assert successful == 0 and failed == 1

    assert caplog.messages == [
        f"File 1: Failed to download {url}",
        "1 files failed to download",
    ]
    def handle(self, *args, **options):
        input_file: Path = options["input"]

        logger.info("Loading the data")
        with input_file.open() as fp:
            json_data = json.load(fp)
            if json_data["format_version"] != format_version:
                raise CommandError(
                    f"This version of {settings.PRODUCT_NAME} can only import json format version {format_version}, "
                    f"but the json file you provided is version {json_data['format_version']}"
                )
            ris_data: RisData = converter.structure(json_data, RisData)

        body = models.Body.objects.filter(name=ris_data.meta.name).first()
        if not body:
            logger.info("Building the body")

            if options["ags"] or ris_data.meta.ags:
                ags = options["ags"] or ris_data.meta.ags
            else:
                ags = city_to_ags(ris_data.meta.name, False)
                if not ags:
                    raise RuntimeError(
                        f"Failed to determine the Amtliche Gemeindeschlüssel for '{ris_data.meta.name}'. "
                        f"Please look it up yourself and specify it with `--ags`"
                    )
                logger.info(f"The Amtliche Gemeindeschlüssel is {ags}")
            body = models.Body(
                name=ris_data.meta.name, short_name=ris_data.meta.name, ags=ags
            )
            body.save()
            if not options["skip_body_extra"]:
                import_outline(body)
                import_streets(body)
        else:
            logging.info("Using existing body")

        # TODO: Re-enable this after some more thorough testing
        # handle_counts(ris_data, options["allow_shrinkage"])

        import_data(body, ris_data)

        fix_sort_date(datetime.datetime.now(tz=tz.tzlocal()))

        if not options["skip_download"]:
            Importer(BaseLoader(dict()), force_singlethread=True).load_files(
                fallback_city=body.short_name
            )

        if not options["no_notify_users"]:
            logger.info("Sending notifications")
            NotifyUsers().notify_all()
    def handle(self, *args, **options):
        prefix = options["prefix"]

        body = Body.objects.get(oparl_id__startswith=prefix)
        loader = get_loader_from_body(body.oparl_id)
        importer = Importer(loader, body)
        importer.force_singlethread = options["force_singlethread"]

        import_plan = [File, Paper, Consultation, AgendaItem]

        for class_object in import_plan:
            name = class_object.__name__
            stats = class_object.objects.filter(
                oparl_id__startswith=prefix).delete()
            logger.info("{}: {}".format(name, stats))

            CachedObject.objects.filter(
                url__startswith=prefix,
                oparl_type=class_object.__name__).update(to_import=True)

        for type_class in import_plan:
            importer.import_type(type_class)
    def check_basic_import(self):
        self.new_timestamp = (self.base_timestamp +
                              relativedelta(years=-100)).isoformat()
        self.init_mock_loader()
        importer = Importer(self.loader, force_singlethread=True)
        importer.run(self.body_id)
        now = timezone.now()

        for table, count in self.tables.items():
            self.assertEqual(
                table.objects.count(),
                count,
                "{}: {} vs. {}".format(table, count, table.objects.all()),
            )
            self.assertLess(table.objects.first().modified, now)
        self.assertEqual(File.objects.count(), 6)
        # Test for #56
        self.assertEqual(
            Meeting.by_oparl_id(
                "https://oparl.example.org/meeting/281").organizations.count(),
            1,
        )
Ejemplo n.º 17
0
 def test_import_invalid_line(self):
     header = 'h1,h2,h3,h4'
     line1 = '0.2,3,76'
     line2 = '34,2342,-98,111,223'
     importer = Importer(self.db)
     importer.import_line(header)
     importer.import_line(line1)
     result = self.db.report.find_one({'h1': 0.2})
     self.assertIsNone(result)
     importer.import_line(line2)
     result = self.db.report.find_one({'h1': 34})
     self.assertIsNone(result)
Ejemplo n.º 18
0
    def test_update_without_change_is_ignored(self):
        loader = build_mock_loader()
        importer = Importer(loader, force_singlethread=True)
        importer.run(self.body["id"])
        [paper] = Paper.objects.all()
        self.assertEqual(paper.history.count(), 1)

        # The "updated" list still contains the same paper object
        importer.update(self.body["id"])
        [paper] = Paper.objects.all()
        self.assertEqual(paper.history.count(), 1)

        # Consistency check: The count is increased if there is actual change
        update(loader)
        importer.update(self.body["id"])
        [paper] = Paper.objects.all()
        self.assertEqual(paper.history.count(), 2)
def test_fetch_list_update():
    loader = MockLoader()
    loader.api_data["https://oparl.wuppertal.de/oparl/bodies/0001/papers"] = {
        "data": [],
        "links": {},
        "pagination": {},
    }
    importer = Importer(loader)
    importer.fetch_list_initial("https://oparl.wuppertal.de/oparl/bodies/0001/papers")
    importer.fetch_list_update("https://oparl.wuppertal.de/oparl/bodies/0001/papers")
def import_update(body_id: Optional[str] = None,
                  ignore_modified: bool = False) -> None:
    from importer.importer import Importer

    if body_id:
        bodies = Body.objects.filter(oparl_id=body_id).all()
    else:
        bodies = Body.objects.filter(oparl_id__isnull=False).all()
    for body in bodies:
        logger.info("Updating body {}: {}".format(body, body.oparl_id))
        loader = get_loader_from_body(body.oparl_id)
        importer = Importer(loader, body, ignore_modified=ignore_modified)
        importer.update(body.oparl_id)
        importer.force_singlethread = True
        importer.load_files(body.short_name)
def test_manual_deletion(pytestconfig):
    """Check that after a file has been manually deleted, it can't get re-imported and it's gone from minio"""
    url = "https://example.org/file/1"
    file_id = 1
    sample_file = File(
        name="Bad File",
        original_id=file_id,
        url=url,
        claimed_size=None,
        paper_original_id=sample_paper.original_id,
    )
    data = RisData(sample_city, None, [], [], [sample_paper], [sample_file],
                   [], [], [], 2)
    body = Body(name=data.meta.name,
                short_name=data.meta.name,
                ags=data.meta.ags)
    body.save()
    import_data(body, data)

    with responses.RequestsMock() as requests_mock:
        requests_mock.add(
            responses.GET,
            url,
            body=Path(pytestconfig.rootdir).joinpath(
                "testdata/media/file.txt").read_bytes(),
            status=200,
            content_type="text/plain",
        )
        importer = Importer(BaseLoader({}), force_singlethread=True)
        [successful, failed] = importer.load_files(sample_city.name)
        assert successful == 1 and failed == 0

    # Ensure that the file is there
    assert minio_client().get_object(minio_file_bucket, str(file_id))
    assert models.File.objects.filter(pk=file_id).first()

    # This is what we test
    models.File.objects.get(pk=file_id).manually_delete()

    with pytest.raises(MinioException):
        minio_client().get_object(minio_file_bucket, str(file_id))

    # Another import, to ensure that manually delete is respected
    import_data(body, data)

    assert not models.File.objects.filter(pk=file_id).first()
    with responses.RequestsMock():
        importer = Importer(BaseLoader({}), force_singlethread=True)
        [successful, failed] = importer.load_files(sample_city.name)
        assert successful == 0 and failed == 0

    with pytest.raises(MinioException):
        minio_client().get_object(minio_file_bucket, str(file_id))
def test_manual_deletion(pytestconfig, caplog):
    """Check that after a file has been manually deleted, it can't get re-imported and it's gone from minio"""
    url = "https://example.org/file/1"
    file_id = 1
    body, data = make_sample_file(file_id, url)

    with responses.RequestsMock() as requests_mock:
        requests_mock.add(
            responses.GET,
            url,
            body=pytestconfig.rootpath.joinpath(
                "testdata/media/file.txt").read_bytes(),
            status=200,
            content_type="text/plain",
        )
        importer = Importer(BaseLoader({}), force_singlethread=True)
        [successful, failed] = importer.load_files(sample_city.name)
        assert successful == 1 and failed == 0

    # Ensure that the file is there
    assert minio_client().get_object(minio_file_bucket, str(file_id))
    assert models.File.objects.filter(pk=file_id).first()

    # This is what we test
    models.File.objects.get(pk=file_id).manually_delete()

    with pytest.raises(MinioException):
        minio_client().get_object(minio_file_bucket, str(file_id))

    # Another import, to ensure that manually delete is respected
    import_data(body, data)

    assert not models.File.objects.filter(pk=file_id).first()
    with responses.RequestsMock():
        importer = Importer(BaseLoader({}), force_singlethread=True)
        [successful, failed] = importer.load_files(sample_city.name)
        assert successful == 0 and failed == 0

    with pytest.raises(MinioException):
        minio_client().get_object(minio_file_bucket, str(file_id))

    assert caplog.messages == [
        "File 1 has an unknown mime type: 'text/plain'",
        "File 1: Couldn't get any text",
    ]
Ejemplo n.º 23
0
    def get_importer(self, options: Dict[str, Any]) -> Tuple[Importer, Body]:
        if options.get("body"):
            body = Body.objects.get(oparl_id=options["body"])
        else:
            body = Body.objects.get(id=settings.SITE_DEFAULT_BODY)

        if body.oparl_id is not None:
            loader = get_loader_from_body(body.oparl_id)
            importer = Importer(
                loader, body, ignore_modified=options["ignore_modified"]
            )
        else:
            importer = Importer(
                BaseLoader(dict()), ignore_modified=options["ignore_modified"]
            )
        importer.force_singlethread = options["force_singlethread"]
        importer.download_files = not options["skip_download"]

        return importer, body
Ejemplo n.º 24
0
    def test_embedded_update(self):
        loader = build_mock_loader()
        importer = Importer(loader, force_singlethread=True)
        importer.run(self.body["id"])
        paper_id = make_paper([])["id"]
        self.assertEqual(Paper.objects.count(), 1)
        file_ids = Paper.by_oparl_id(paper_id).files.values_list("oparl_id",
                                                                 flat=True)
        self.assertEqual(
            sorted(file_ids),
            [make_file(0)["id"], make_file(1)["id"]])
        self.assertEqual(File.objects.count(), 2)

        update(loader)
        importer.update(self.body["id"])
        self.assertEqual(Paper.objects.count(), 1)
        self.assertEqual(File.objects.count(), 2)
        file_ids = Paper.by_oparl_id(paper_id).files.values_list("oparl_id",
                                                                 flat=True)
        self.assertEqual(
            sorted(file_ids),
            [make_file(1)["id"], make_file(2)["id"]])
        self.assertEqual(File.objects_with_deleted.count(), 3)
Ejemplo n.º 25
0
    def handle(self, *args, **options):
        input_file: Path = options["input"]

        logger.info("Loading the data")
        with input_file.open() as fp:
            json_data = json.load(fp)
            if json_data["format_version"] != format_version:
                raise CommandError(
                    f"This version of {settings.PRODUCT_NAME} can only import json format version {format_version}, "
                    f"but the json file you provided is version {json_data['format_version']}"
                )
            ris_data: RisData = converter.structure(json_data, RisData)

        body = models.Body.objects.filter(name=ris_data.meta.name).first()
        if not body:
            logger.info("Building the body")

            if options["ags"] or ris_data.meta.ags:
                ags = options["ags"] or ris_data.meta.ags
            else:
                ags = city_to_ags(ris_data.meta.name, False)
                if not ags:
                    raise RuntimeError(
                        f"Failed to determine the Amtliche Gemeindeschlüssel for '{ris_data.meta.name}'. "
                        f"Please look it up yourself and specify it with `--ags`"
                    )
                logger.info(f"The Amtliche Gemeindeschlüssel is {ags}")
            body = models.Body(name=ris_data.meta.name,
                               short_name=ris_data.meta.name,
                               ags=ags)
            body.save()
            if not options["skip_body_extra"]:
                import_outline(body)
                import_streets(body)
        else:
            logging.info("Using existing body")

        # TODO: Reenable this after some more thorough testing
        # handle_counts(ris_data, options["allow_shrinkage"])

        flush_model(models.Paper)
        self.import_papers(ris_data)
        self.import_files(ris_data)
        paper_id_map = make_id_map(models.Paper.objects)
        file_id_map = make_id_map(models.File.objects)
        flush_model(models.Paper.files.through)
        self.import_paper_files(ris_data, paper_id_map, file_id_map)
        flush_model(models.Organization)
        self.import_organizations(body, ris_data)
        self.import_meeting_locations(ris_data)
        locations = dict(
            models.Location.objects.values_list("description", "id"))
        flush_model(models.Meeting)
        self.import_meetings(ris_data, locations)
        meeting_id_map = make_id_map(
            models.Meeting.objects.filter(oparl_id__isnull=False))
        organization_name_id_map = dict(
            models.Organization.objects.values_list("name", "id"))
        flush_model(models.Meeting.organizations.through)
        self.import_meeting_organization(meeting_id_map,
                                         organization_name_id_map, ris_data)

        flush_model(models.Person)
        self.import_persons(ris_data)
        flush_model(models.Consultation)
        self.import_consultations(ris_data, meeting_id_map, paper_id_map)

        # We don't have original ids for all agenda items (yet?),
        # so we just assume meeting x paper is unique
        consultation_map = {
            (a, b): c
            for a, b, c in models.Consultation.objects.values_list(
                "meeting_id", "paper_id", "id")
        }

        flush_model(models.AgendaItem)
        self.import_agenda_items(ris_data, consultation_map, meeting_id_map,
                                 paper_id_map)
        flush_model(models.Membership)
        self.import_memberships(ris_data)
        fix_sort_date(fallback_date, datetime.datetime.now(tz=tz.tzlocal()))

        # With the current bulk indexing we need to do this manually
        call_command("search_index", action="populate")

        if not options["skip_download"]:
            Importer(BaseLoader(dict()), force_singlethread=True).load_files(
                fallback_city=body.short_name)
Ejemplo n.º 26
0
def test_missing_organization(caplog):
    with RequestsMock() as requests_mock:
        requests_mock.add(
            requests_mock.GET,
            "http://oparl.wuppertal.de/oparl/bodies/0001/organizations/gr/230",
            json={"error": "not found"},
            status=404,
        )
        # Add another one to test for uniqueness constraints
        requests_mock.add(
            requests_mock.GET,
            "http://oparl.wuppertal.de/oparl/bodies/0001/organizations/gr/231",
            json={"error": "not found"},
            status=404,
        )

        requests_mock.add(
            requests_mock.GET,
            "http://oparl.wuppertal.de/oparl/bodies",
            json={
                "data": [
                    json.loads(
                        Path("testdata/oparl-missing/body.json").read_text())
                ],
                "links": {},
                "pagination": {},
            },
        )
        requests_mock.add(
            requests_mock.GET,
            "http://oparl.wuppertal.de/oparl/bodies/0001/organizations",
            json=empty_page,
        )
        requests_mock.add(
            requests_mock.GET,
            "http://oparl.wuppertal.de/oparl/bodies/0001/people",
            json=empty_page,
        )
        requests_mock.add(
            requests_mock.GET,
            "http://oparl.wuppertal.de/oparl/bodies/0001/papers",
            json=empty_page,
        )
        requests_mock.add(
            requests_mock.GET,
            "http://oparl.wuppertal.de/oparl/bodies/0001/meetings",
            json={
                "data": [
                    json.loads(
                        Path(
                            "testdata/oparl-missing/meeting.json").read_text())
                ],
                "links": {},
                "pagination": {},
            },
        )
        requests_mock.add(
            requests_mock.GET,
            "http://oparl.wuppertal.de/oparl/bodies/0001/people/292",
            status=404,
        )

        body_id = "http://oparl.wuppertal.de/oparl/bodies/0001"
        importer = Importer(
            BaseLoader(
                json.loads(
                    Path("testdata/oparl-missing/system.json").read_text())),
            force_singlethread=True,
        )
        [body_data] = importer.load_bodies(body_id)
        [body] = importer.import_bodies()
        importer.converter.default_body = body
        body.ags = "05124000"
        importer.fetch_lists_initial([body_data.data])
        importer.import_objects()

        assert set(i.oparl_id for i in Organization.objects.all()) == {
            "http://oparl.wuppertal.de/oparl/bodies/0001/organizations/gr/230",
            "http://oparl.wuppertal.de/oparl/bodies/0001/organizations/gr/231",
        }

        assert list(i.short_name for i in Organization.objects.all()) == [
            "Missing",
            "Missing",
        ]

    assert Person.objects.first().name == "Missing Person"

    assert caplog.messages == [
        "The Person http://oparl.wuppertal.de/oparl/bodies/0001/people/292 linked "
        "from http://oparl.wuppertal.de/oparl/bodies/0001/meetings/19160 was supposed "
        "to be a part of the external lists, but was not. This is a bug in the OParl "
        "implementation.",
        "Failed to load http://oparl.wuppertal.de/oparl/bodies/0001/people/292: 404 "
        "Client Error: Not Found for url: "
        "http://oparl.wuppertal.de/oparl/bodies/0001/people/292",
        "Using a dummy for http://oparl.wuppertal.de/oparl/bodies/0001/people/292. "
        "THIS IS BAD.",
        "The Organization "
        "http://oparl.wuppertal.de/oparl/bodies/0001/organizations/gr/230 linked from "
        "http://oparl.wuppertal.de/oparl/bodies/0001/meetings/19160 was supposed to "
        "be a part of the external lists, but was not. This is a bug in the OParl "
        "implementation.",
        "Failed to load "
        "http://oparl.wuppertal.de/oparl/bodies/0001/organizations/gr/230: 404 Client "
        "Error: Not Found for url: "
        "http://oparl.wuppertal.de/oparl/bodies/0001/organizations/gr/230",
        "Using a dummy for "
        "http://oparl.wuppertal.de/oparl/bodies/0001/organizations/gr/230. THIS IS "
        "BAD.",
        "The Organization "
        "http://oparl.wuppertal.de/oparl/bodies/0001/organizations/gr/231 linked from "
        "http://oparl.wuppertal.de/oparl/bodies/0001/meetings/19160 was supposed to "
        "be a part of the external lists, but was not. This is a bug in the OParl "
        "implementation.",
        "Failed to load "
        "http://oparl.wuppertal.de/oparl/bodies/0001/organizations/gr/231: 404 Client "
        "Error: Not Found for url: "
        "http://oparl.wuppertal.de/oparl/bodies/0001/organizations/gr/231",
        "Using a dummy for "
        "http://oparl.wuppertal.de/oparl/bodies/0001/organizations/gr/231. THIS IS "
        "BAD.",
    ]
Ejemplo n.º 27
0
 def test_empty_header_values_renamed_to_unknown(self):
     header = 'h1,h2,,,\n'
     importer = Importer(self.db)
     importer.import_line(header)
     self.assertListEqual(importer.headers, ['h1', 'h2', 'Unknown0','Unknown1', 'Unknown2'])
Ejemplo n.º 28
0
 def test_datetime_valid(self):
     i = Importer(None)
     s ="2015-10-04 17:19:47"
     self.assertEqual(i._dt(s), datetime.datetime(2015,10,04,17,19,47))
Ejemplo n.º 29
0
 def _dateParseDateTest(self, s, r):
     i = Importer(None)
     self.assertEqual(i._parseDate(s), r)
Ejemplo n.º 30
0
 def test_datetime_garbage(self):
     i = Importer(None)
     self.assertEqual(i._dt("asdfer"), None)
Ejemplo n.º 31
0
    def test_membeship_get_or_load(self):
        """ Sometimes main objects are not in the external lists.

        Also check that cycles (between Membership and Person are resolved) """
        membership = {
            "id": "https://oparl.example.org/membership/0",
            "type": "https://schema.oparl.org/1.1/Membership",
            "person": "https://oparl.example.org/person/1",
            "organization": "https://oparl.example.org/organization/1",
            "created": "2011-11-11T11:11:00+01:00",
            "modified": "2012-08-16T14:05:27+02:00",
        }
        data = [
            membership,
            {
                "id": "https://oparl.example.org/body/1",
                "type": "https://schema.oparl.org/1.1/Body",
                "system": "https://oparl.example.org/",
                "shortName": "Köln",
                "name": "Stadt Köln, kreisfreie Stadt",
                "created": "2014-01-08T14:28:31+01:00",
                "modified": "2014-01-08T14:28:31+01:00",
            },
            {
                "id": "https://oparl.example.org/organization/1",
                "type": "https://schema.oparl.org/1.1/Organization",
                "body": "https://oparl.example.org/body/1",
                "name": "Ausschuss für Haushalt und Finanzen",
                "shortName": "Finanzausschuss",
                "membership": ["https://oparl.example.org/membership/1"],
                "created": "2012-07-16T00:00:00+02:00",
                "modified": "2012-08-16T12:34:56+02:00",
            },
            {
                "id": "https://oparl.example.org/person/1",
                "type": "https://schema.oparl.org/1.1/Person",
                "body": "https://oparl.example.org/body/1",
                "name": "Prof. Dr. Max Mustermann",
                "familyName": "Mustermann",
                "givenName": "Max",
                "membership": [
                    {
                        "id": "https://oparl.example.org/membership/1",
                        "type": "https://schema.oparl.org/1.1/Membership",
                        "organization": "https://oparl.example.org/organization/1",
                        "role": "Vorsitzende",
                        "votingRight": True,
                        "startDate": "2013-12-03",
                    }
                ],
                "created": "2011-11-11T11:11:00+01:00",
                "modified": "2012-08-16T14:05:27+02:00",
            },
        ]

        loader = MockLoader()
        for oparl_object in data:
            loader.api_data[oparl_object["id"]] = oparl_object

        importer = Importer(loader)
        importer.converter.warn_missing = False
        # We need to have a body to load an organization
        importer.import_anything("https://oparl.example.org/body/1")
        importer.import_anything("https://oparl.example.org/membership/0")
        self.assertEqual(
            Membership.objects.filter(oparl_id=membership["id"]).count(), 1
        )
        self.assertEqual(Person.objects.count(), 1)
        self.assertEqual(Organization.objects.count(), 1)