Beispiel #1
0
 def action_history() -> ActionHistoryResponse:
     """
     Return list of action event records for a given ID.
     """
     if content_id := bottle.request.query.content_id or None:
         return ActionHistoryResponse(
             ActionEvent.get_from_content_id(dynamodb_table,
                                             f"{content_id}"))
Beispiel #2
0
    def test_query_action_event(self):
        """
        Test ActionEvent write table with get_from_content_id query
        """

        event = self.get_example_action_event()
        event.write_to_table(self.get_table())

        query_event = ActionEvent.get_from_content_id(
            self.get_table(), TestContentModels.TEST_CONTENT_ID)[0]

        assert event == query_event
Beispiel #3
0
    def pipeline_progress() -> ContentPipelineProgress:
        """
        WARNING: UNOPTIMIZED. DO NOT CALL FROM AUTOMATED SYSTEMS.

        Build a history of the stages that this piece of content has gone
        through and what their results were. Do not call this from anything but
        a UI. This is not optimized for performance.
        """
        content_id = bottle.request.query.content_id or None

        if not content_id:
            return bottle.abort(400, "content_id must be provided.")
        content_id = t.cast(str, content_id)

        content_object = ContentObject.get_from_content_id(
            dynamodb_table, content_id)
        if not content_object:
            return bottle.abort(400,
                                f"Content with id '{content_id}' not found.")
        content_object = t.cast(ContentObject, content_object)

        preview_url = get_preview_url(content_id, content_object)

        # The result object will be gradually built up as records are retrieved.
        result = ContentPipelineProgress(
            content_id=content_id,
            content_type=content_object.content_type,
            content_preview_url=preview_url,
            submitted_at=content_object.updated_at,
            submission_additional_fields=list(
                content_object.additional_fields),
        )

        hash_records = PipelineHashRecord.get_from_content_id(
            dynamodb_table, content_id)
        if len(hash_records) != 0:
            result.hashed_at = max(hash_records,
                                   key=lambda r: r.updated_at).updated_at
            for hash_record in hash_records:
                # Assume that each signal type has a single hash
                if hash_record.signal_type.get_name() in result.hash_results:
                    return bottle.abort(
                        500,
                        f"Content with id '{content_id}' has multiple hash records for signal-type: '{hash_record.signal_type.get_name()}'.",
                    )

                result.hash_results[hash_record.signal_type.get_name(
                )] = hash_record.content_hash

        match_records = MatchRecord.get_from_content_id(
            dynamodb_table, content_id)
        if len(match_records) != 0:
            result.matched_at = max(match_records,
                                    key=lambda r: r.updated_at).updated_at

            # TODO #751 Until we resolve type agnostic storage of signal data,
            # we can't populate match details.
            # actually populate result.match_results.

        # TODO: ActionEvaluation does not yet leave a trail. Either record
        # action evaluation or remove the evaluation stage from the
        # pipeline-progress indicator.

        action_records = ActionEvent.get_from_content_id(
            dynamodb_table, content_id)
        if len(action_records) != 0:
            result.action_performed_at = max(
                action_records, key=lambda r: r.performed_at).performed_at
            result.action_perform_results = [
                r.action_label for r in action_records
            ]

        return result