# 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__)
# 
# Path: stoq/plugins/base.py
# class BasePlugin(ABC):
#     def __init__(self, config: StoqConfigParser) -> None:
#         self.config = config
#         self.plugin_name = config.get('Core', 'Name', fallback=self.__class__.__name__)
#         self.__author__ = config.get('Documentation', 'Author', fallback='')
#         self.__version__ = config.get('Documentation', 'Version', fallback='')
#         self.__website__ = config.get('Documentation', 'Website', fallback='')
#         self.__description__ = config.get('Documentation', 'Description', fallback='')
#         self.log = logging.getLogger(f'stoq.{self.plugin_name}')


from typing import Optional
from abc import abstractmethod, ABC
from stoq.data_classes import StoqResponse, DecoratorResponse
from stoq.plugins import BasePlugin

    ::

        from typing import Dict, Optional

        from stoq.plugins import DecoratorPlugin
        from stoq.helpers import StoqConfigParser
        from stoq.data_classes import StoqResponse, DecoratorResponse


        class ExampleDecorator(DecoratorPlugin):
            def __init__(self, config: StoqConfigParser) -> None:
                super().__init__(config)
                self.msg = config.get('options', 'msg', fallback='do_more msg')

            async def decorate(self, response: StoqResponse) -> Optional[DecoratorResponse]:
                do_more = False
                if 'yara' in response.results[0].plugins_run:
                    do_more = True
                dr = DecoratorResponse({'do_more': do_more, 'msg': self.msg})
                return dr

    API
    ===

"""





# 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__)
# 
# Path: stoq/plugins/base.py
# class BasePlugin(ABC):
#     def __init__(self, config: StoqConfigParser) -> None:
#         self.config = config
#         self.plugin_name = config.get('Core', 'Name', fallback=self.__class__.__name__)
#         self.__author__ = config.get('Documentation', 'Author', fallback='')
#         self.__version__ = config.get('Documentation', 'Version', fallback='')
#         self.__website__ = config.get('Documentation', 'Website', fallback='')
#         self.__description__ = config.get('Documentation', 'Description', fallback='')
#         self.log = logging.getLogger(f'stoq.{self.plugin_name}')


# Path: stoq/plugins/decorator.py
from typing import Optional
from abc import abstractmethod, ABC
from stoq.data_classes import StoqResponse, DecoratorResponse
from stoq.plugins import BasePlugin


    ::

        from typing import Dict, Optional

        from stoq.plugins import DecoratorPlugin
        from stoq.helpers import StoqConfigParser
        from stoq.data_classes import StoqResponse, DecoratorResponse


        class ExampleDecorator(DecoratorPlugin):
            def __init__(self, config: StoqConfigParser) -> None:
                super().__init__(config)
                self.msg = config.get('options', 'msg', fallback='do_more msg')

            async def decorate(self, response: StoqResponse) -> Optional[DecoratorResponse]:
                do_more = False
                if 'yara' in response.results[0].plugins_run:
                    do_more = True
                dr = DecoratorResponse({'do_more': do_more, 'msg': self.msg})
                return dr

    API
    ===

"""





class DecoratorPlugin(BasePlugin, ABC):