# Path: stoq/data_classes.py
# class StoqResponse:
#     def __init__(
#         self,
#         request: Request,
#         time: Optional[str] = None,
#         decorators: Optional[Dict[str, Dict]] = None,
#         scan_id: Optional[str] = None,
#     ) -> None:
#         """
# 
#         Response object of a completed scan
# 
#         :param results: ``PayloadResults`` object of scanned payload
#         :param request_meta: ``RequetMeta`` object pertaining to original scan request
#         :param time: ISO Formatted timestamp of scan
#         :param decorators: Decorator plugin results
# 
#         """
#         self.results = [p.results for p in request.payloads]
#         self.request_meta = request.request_meta
#         self.errors = request.errors
#         self.time: str = datetime.now().isoformat() if time is None else time
#         self.decorators = {} if decorators is None else decorators
#         self.scan_id = str(uuid.uuid4()) if scan_id is None else scan_id
# 
#     def split(self) -> List[Dict]:
#         """
#         Split worker results individually
# 
#         """
#         split_results = []
#         for result in self.results:
#             for k, v in result.workers.items():
#                 rcopy = deepcopy(self.__dict__)
#                 rcopy['results'] = [deepcopy(result.__dict__)]
#                 rcopy['results'][0]['workers'] = {k: v}
#                 split_results.append(rcopy)
#         return split_results
# 
#     def __str__(self) -> str:
#         return helpers.dumps(self)
# 
#     def __repr__(self):
#         return repr(self.__dict__)
# 
# class DecoratorResponse:
#     def __init__(
#         self, results: Optional[Dict] = None, errors: Optional[List[Error]] = None
#     ) -> None:
#         """
# 
#          Object containing response from decorator plugins
# 
#         :param results: Results from decorator plugin
#         :param errors: Errors that occurred
# 
#         >>> from stoq import DecoratorResponse
#         >>> results = {'decorator_key': 'decorator_value'}
#         >>> errors = ['This plugin failed for a reason']
#         >>> response = DecoratorResponse(results=results, errors=errors)
# 
#         """
#         self.results = results
#         self.errors = errors or []
# 
#     def __str__(self) -> str:
#         return helpers.dumps(self)
# 
#     def __repr__(self):
#         return repr(self.__dict__)
# 
# class Error:
#     def __init__(
#         self,
#         error: str,
#         plugin_name: Optional[str] = None,
#         payload_id: Optional[str] = None,
#     ) -> None:
#         """
# 
#         Object for errors collected from plugins
# 
#         :param error: Error message to add to results
#         :param plugin_name: The name of the plugin producing the error
#         :param payload_id: The ``payload_id`` of the ``Payload`` that the error occurred on
# 
#         >>> from stoq import Error, Payload
#         >>> errors: List[Error] = []
#         >>> payload = Payload(b'test bytes')
#         >>> err = Error(
#         ...     error='This is our error message',
#         ...     plugin_name='test_plugin', 
#         ...     payload_id=payload.results.payload_id
#         ... )
#         >>> errors.append(err)
# 
#         """
#         self.error = error
#         self.plugin_name = plugin_name
#         self.payload_id = payload_id
# 
#     def __str__(self) -> str:
#         return helpers.dumps(self)
# 
#     def __repr__(self):
#         return repr(self.__dict__)
# 
# Path: stoq/plugins/decorator.py
# class DecoratorPlugin(BasePlugin, ABC):
#     @abstractmethod
#     async def decorate(self, response: StoqResponse) -> Optional[DecoratorResponse]:
#         pass


from typing import Optional
from stoq.data_classes import StoqResponse, DecoratorResponse, Error
from stoq.plugins import DecoratorPlugin
#!/usr/bin/env python3

#   Copyright 2014-2018 PUNCH Cyber Analytics Group
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.




class SimpleDecorator(DecoratorPlugin):
    RAISE_EXCEPTION = False
    RETURN_ERRORS = False

    async def decorate(self, response: StoqResponse) -> Optional[DecoratorResponse]:
        if self.RAISE_EXCEPTION:
            raise Exception('Test exception please ignore')
        dr = DecoratorResponse({'simple_decoration': 123})
        if self.RETURN_ERRORS:
            dr.errors.append(

# Path: stoq/data_classes.py
# class StoqResponse:
#     def __init__(
#         self,
#         request: Request,
#         time: Optional[str] = None,
#         decorators: Optional[Dict[str, Dict]] = None,
#         scan_id: Optional[str] = None,
#     ) -> None:
#         """
# 
#         Response object of a completed scan
# 
#         :param results: ``PayloadResults`` object of scanned payload
#         :param request_meta: ``RequetMeta`` object pertaining to original scan request
#         :param time: ISO Formatted timestamp of scan
#         :param decorators: Decorator plugin results
# 
#         """
#         self.results = [p.results for p in request.payloads]
#         self.request_meta = request.request_meta
#         self.errors = request.errors
#         self.time: str = datetime.now().isoformat() if time is None else time
#         self.decorators = {} if decorators is None else decorators
#         self.scan_id = str(uuid.uuid4()) if scan_id is None else scan_id
# 
#     def split(self) -> List[Dict]:
#         """
#         Split worker results individually
# 
#         """
#         split_results = []
#         for result in self.results:
#             for k, v in result.workers.items():
#                 rcopy = deepcopy(self.__dict__)
#                 rcopy['results'] = [deepcopy(result.__dict__)]
#                 rcopy['results'][0]['workers'] = {k: v}
#                 split_results.append(rcopy)
#         return split_results
# 
#     def __str__(self) -> str:
#         return helpers.dumps(self)
# 
#     def __repr__(self):
#         return repr(self.__dict__)
# 
# class DecoratorResponse:
#     def __init__(
#         self, results: Optional[Dict] = None, errors: Optional[List[Error]] = None
#     ) -> None:
#         """
# 
#          Object containing response from decorator plugins
# 
#         :param results: Results from decorator plugin
#         :param errors: Errors that occurred
# 
#         >>> from stoq import DecoratorResponse
#         >>> results = {'decorator_key': 'decorator_value'}
#         >>> errors = ['This plugin failed for a reason']
#         >>> response = DecoratorResponse(results=results, errors=errors)
# 
#         """
#         self.results = results
#         self.errors = errors or []
# 
#     def __str__(self) -> str:
#         return helpers.dumps(self)
# 
#     def __repr__(self):
#         return repr(self.__dict__)
# 
# class Error:
#     def __init__(
#         self,
#         error: str,
#         plugin_name: Optional[str] = None,
#         payload_id: Optional[str] = None,
#     ) -> None:
#         """
# 
#         Object for errors collected from plugins
# 
#         :param error: Error message to add to results
#         :param plugin_name: The name of the plugin producing the error
#         :param payload_id: The ``payload_id`` of the ``Payload`` that the error occurred on
# 
#         >>> from stoq import Error, Payload
#         >>> errors: List[Error] = []
#         >>> payload = Payload(b'test bytes')
#         >>> err = Error(
#         ...     error='This is our error message',
#         ...     plugin_name='test_plugin', 
#         ...     payload_id=payload.results.payload_id
#         ... )
#         >>> errors.append(err)
# 
#         """
#         self.error = error
#         self.plugin_name = plugin_name
#         self.payload_id = payload_id
# 
#     def __str__(self) -> str:
#         return helpers.dumps(self)
# 
#     def __repr__(self):
#         return repr(self.__dict__)
# 
# Path: stoq/plugins/decorator.py
# class DecoratorPlugin(BasePlugin, ABC):
#     @abstractmethod
#     async def decorate(self, response: StoqResponse) -> Optional[DecoratorResponse]:
#         pass


# Path: stoq/tests/data/plugins/decorator/simple_decorator/simple_decorator.py
from typing import Optional
from stoq.data_classes import StoqResponse, DecoratorResponse, Error
from stoq.plugins import DecoratorPlugin

#!/usr/bin/env python3

#   Copyright 2014-2018 PUNCH Cyber Analytics Group
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.




class SimpleDecorator(DecoratorPlugin):
    RAISE_EXCEPTION = False
    RETURN_ERRORS = False

    async def decorate(self, response: StoqResponse) -> Optional[DecoratorResponse]:
        if self.RAISE_EXCEPTION:
            raise Exception('Test exception please ignore')
        dr = DecoratorResponse({'simple_decoration': 123})
        if self.RETURN_ERRORS:
            dr.errors.append(

                Error(plugin_name='simple_decorator', error='Test error please ignore')