Example #1
0
def test_integrate_sources_with_crecord(dclient, admin_user, example_crecord):
    """
    User can post source records and an empty crecord to the server and receive a 
    crecord with the cases from the source record incorporated.
    """
    dclient.force_authenticate(user=admin_user)
    docket = os.listdir("tests/data/dockets/")[0]
    with open(f"tests/data/dockets/{docket}", "rb") as d:
        doc_1 = SourceRecord.objects.create(
            caption="Hello v. World",
            docket_num="MC-1234",
            court=SourceRecord.Courts.CP,
            url="https://abc.def",
            record_type=SourceRecord.RecTypes.DOCKET_PDF,
            file=File(d),
            owner=admin_user,
        )
    summary = os.listdir("tests/data/summaries")[0]
    with open(f"tests/data/summaries/{summary}", "rb") as s:
        doc_2 = SourceRecord.objects.create(
            caption="Hello v. Goodbye",
            docket_num="MC-1235",
            court=SourceRecord.Courts.MDJ,
            url="https://def.ghi",
            record_type=SourceRecord.RecTypes.SUMMARY_PDF,
            file=File(s),
            owner=admin_user,
        )

    # when sent to api, serialized document data won't have a file included.
    # The request is asking to do stuff using the file that is on the server.
    doc_1_data = SourceRecordSerializer(doc_1).data
    # doc_1_data.pop("file")

    doc_2_data = SourceRecordSerializer(doc_2).data
    # doc_2_data.pop("file")
    source_records = [doc_1_data, doc_2_data]
    data = {
        "crecord": CRecordSerializer(example_crecord).data,
        "source_records": source_records,
    }

    resp = dclient.put("/api/record/cases/", data=data)
    assert resp.status_code == 200
    assert "crecord" in resp.data
    assert "source_records" in resp.data
    # the response source_records list might include new source records, so will be at
    # least as long as the original source records list.
    assert len(resp.data["source_records"]) >= len(source_records)
    try:

        CRecord.from_dict(resp.data["crecord"])
    except Exception as err:
        pytest.fail(err)
Example #2
0
    def post(self, request):
        """ Analyze a Criminal Record for expungeable and sealable cases and charges.
        
        POST body should be json-endoded CRecord object. 

        Return, if not an error, will be a json-encoded Decision that explains the expungements
        and sealings that can be generated for this record.

        """
        try:
            serializer = CRecordSerializer(data=request.data)
            if serializer.is_valid():
                rec = CRecord.from_dict(serializer.validated_data)
                analysis = (Analysis(rec).rule(expunge_deceased).rule(
                    expunge_over_70).rule(expunge_nonconvictions).rule(
                        expunge_summary_convictions).rule(seal_convictions))
                return Response(to_serializable(analysis))
            return Response(
                {"validation_errors": serializer.errors},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
            )
        except Exception as err:
            logger.error(err)
            return Response("Something went wrong",
                            status=status.HTTP_400_BAD_REQUEST)
Example #3
0
def test_integrate_sources_with_crecord(dclient, admin_user, example_crecord):
    dclient.force_authenticate(user=admin_user)
    docket = os.listdir("tests/data/dockets/")[0]
    with open(f"tests/data/dockets/{docket}", "rb") as d:
        doc_1 = SourceRecord.objects.create(
            caption="Hello v. World",
            docket_num="MC-1234",
            court=SourceRecord.Courts.CP,
            url="https://abc.def",
            record_type=SourceRecord.RecTypes.DOCKET_PDF,
            file=File(d),
            owner=admin_user,
        )
    summary = os.listdir("tests/data/summaries")[0]
    with open(f"tests/data/summaries/{summary}", "rb") as s:
        doc_2 = SourceRecord.objects.create(
            caption="Hello v. Goodbye",
            docket_num="MC-1235",
            court=SourceRecord.Courts.MDJ,
            url="https://def.ghi",
            record_type=SourceRecord.RecTypes.SUMMARY_PDF,
            file=File(s),
            owner=admin_user,
        )

    # when sent to api, serialized document data won't have a file included.
    # The request is asking to do stuff using the file that is on the server.
    doc_1_data = SourceRecordSerializer(doc_1).data
    doc_1_data.pop("file")

    doc_2_data = SourceRecordSerializer(doc_2).data
    doc_2_data.pop("file")
    data = {
        "crecord": CRecordSerializer(example_crecord).data,
        "source_records": [doc_1_data, doc_2_data]
    }

    resp = dclient.put("/record/sources/", data=data)
    assert resp.status_code == 200
    assert "crecord" in resp.data
    try:
        CRecord.from_dict(resp.data["crecord"])
    except Exception as err:
        pytest.fail(err)
Example #4
0
    def put(self, request, *args, **kwargs):
        """
        Accept a CRecord and a set of SourceRecords. Incorporate the information that the SourceRecords contain into the CRecord.

        TODO this should replace FileUpload view. 
        """
        try:
            serializer = IntegrateSourcesSerializer(data=request.data)
            if serializer.is_valid():
                crecord = CRecord.from_dict(
                    serializer.validated_data["crecord"])
                for source_record_data in serializer.validated_data[
                        "source_records"]:
                    source_record = SourceRecord.objects.get(
                        id=source_record_data["id"])
                    if source_record.record_type == SourceRecord.RecTypes.SUMMARY_PDF:
                        summary = parse_pdf(source_record.file.path)
                        crecord.add_summary(
                            summary,
                            case_merge_strategy="overwrite_old",
                            override_person=True)
                    elif source_record.record_type == SourceRecord.RecTypes.DOCKET_PDF:
                        docket, errs = Docket.from_pdf(source_record.file.path)
                        crecord.add_docket(docket)
                    else:
                        logger.error(
                            f"Cannot parse a source record with type {source_record.record_type}"
                        )
                return Response({'crecord': CRecordSerializer(crecord).data},
                                status=status.HTTP_200_OK)
            else:
                return Response({"errors": serializer.errors},
                                status=status.HTTP_400_BAD_REQUEST)
        except Exception as err:
            return Response({"errors": [str(err)]},
                            status=status.HTTP_500_INTERNAL_SERVER_ERROR)
Example #5
0
def test_from_dict(example_crecord):
    serialized = to_serializable(example_crecord)
    crec2 = CRecord.from_dict(serialized)
    assert example_crecord.person.last_name == crec2.person.last_name
Example #6
0
    def put(self, request):
        """
        Accept a CRecord and a set of SourceRecords.
        
        Parse the SourceRecords, and incorporate the information that the SourceRecords
        contain into the CRecord.

        Two api endpoints of the Django app interact with RecordLib. This one
        accepts a serialzed crecord and a list of sourcerecords. It attempts
        to parse each source_record, and then integrate the sourcerecords into the crecord.

        TODO IntegrateCRecordWithSources should communicate failures better.

        """
        try:
            serializer = IntegrateSourcesSerializer(data=request.data)
            if serializer.is_valid():
                nonfatal_errors = []
                crecord = CRecord.from_dict(
                    serializer.validated_data["crecord"])
                source_records = []
                # Find the SourceRecords in the database that have been sent in this request,
                # or if these are new source records, download the files they point to.
                # TODO this probably doesn't handle a request with a new SoureRecord missing a URL.
                for source_record_data in serializer.validated_data[
                        "source_records"]:
                    try:
                        source_records.append(
                            SourceRecord.objects.get(
                                id=source_record_data["id"]))
                    except Exception:
                        # create this source record in the database, if it is new.
                        source_rec = SourceRecord(**source_record_data,
                                                  owner=request.user)
                        source_rec.save()
                        # also download it to the server.
                        download_service.source_records([source_rec])
                        source_records.append(source_rec)
                # Parse the uploaded source records, collecting RecordLib.SourceRecord objects.
                # These objects are parsing the records and figuring out case information in the SourceRecords.
                # For any source records that are summaries, find out if the summary describes cases that aren't also
                # docket source records. Search CPCMS for those, add the missing dockets to the list of source records.

                # First, parse the dockets.
                # Then we'll parse the summaries to find out if there are cases the summaries mention which the dockets do not.
                docket_source_records = [
                    sr for sr in source_records
                    if sr.record_type == SourceRecord.RecTypes.DOCKET_PDF
                ]
                crecord, nonfatal_errors = integrate_dockets(
                    crecord, docket_source_records, nonfatal_errors)
                # Now attempt to parse summary records. Check the cases in each summary record to see if we have a docket for this case yet.
                # If we dont yet have a docket for this case, fetch it, parse it, integrate it into the CRecord.
                summary_source_records = [
                    sr for sr in source_records
                    if sr.record_type == SourceRecord.RecTypes.SUMMARY_PDF
                ]
                crecord, new_source_records, nonfatal_errors = integrate_summaries(
                    crecord,
                    summary_source_records,
                    docket_source_records,
                    nonfatal_errors,
                    owner=request.user,
                )
                source_records += new_source_records
                return Response(
                    {
                        "crecord":
                        CRecordSerializer(crecord).data,
                        "source_records":
                        SourceRecordSerializer(source_records, many=True).data,
                        "errors":
                        nonfatal_errors,
                    },
                    status=status.HTTP_200_OK,
                )
            return Response({"errors": serializer.errors},
                            status=status.HTTP_400_BAD_REQUEST)
        except Exception as err:
            return Response({"errors": [str(err)]},
                            status=status.HTTP_500_INTERNAL_SERVER_ERROR)