From 3e2c2846d09bb703e1694e603b94613d491a07d2 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Sun, 8 Nov 2020 19:16:09 +0100 Subject: [PATCH] Creating coordinator logics, reworking the main function --- autopipe/__init__.py | 42 +++++++++++++++++++++++-- autopipe/__main__.py | 12 +------ autopipe/autopipe.py | 7 +++-- autopipe/coordinators/__init__.py | 3 ++ autopipe/coordinators/notify_example.py | 7 +++++ autopipe/exceptions/ArgumentError.py | 7 +++++ autopipe/exceptions/__init__.py | 1 + autopipe/input/__init__.py | 1 + autopipe/models.py | 14 +++++++-- autopipe/pipe/__init__.py | 2 ++ bin/autopipe | 12 ++++++- 11 files changed, 89 insertions(+), 19 deletions(-) create mode 100644 autopipe/coordinators/__init__.py create mode 100644 autopipe/coordinators/notify_example.py create mode 100644 autopipe/exceptions/ArgumentError.py create mode 100644 autopipe/exceptions/__init__.py mode change 120000 => 100755 bin/autopipe diff --git a/autopipe/__init__.py b/autopipe/__init__.py index 5119759..531965c 100644 --- a/autopipe/__init__.py +++ b/autopipe/__init__.py @@ -1,4 +1,40 @@ +__all__ = ["Autopipe", "main", "available_coordinators" + "Coordinator", "Pipe", "Input", "APData", + "ArgumentError", + "input", "output", "pipe", "coordinators"] + +from .exceptions import ArgumentError +from .models import Coordinator, Pipe, Input, APData +from .coordinators import * from .autopipe import Autopipe -from input import * -from output import * -from pipe import * + +version = 1.0 + + +def main(argv=None): + import sys + from autopipe import Autopipe, ArgumentError, coordinators + import logging + from argparse import ArgumentParser + + parser = ArgumentParser(description="Easily run advanced pipelines in a daemon or in one run sessions.") + parser.add_argument("coordinator", help="The name of your pipeline coordinator.", nargs="+") + parser.add_argument("-V", "--version", action="version", version=f"%(prog)s {version}") + parser.add_argument("-v", "--verbose", choices=["debug", "info", "warn", "error"], nargs="?", const="info", + default="warn", dest="log_level", metavar="loglevel", + help="Set the logging level.", type=str.lower) + args = parser.parse_args(argv if argv is not None else sys.argv[1:]) + + try: + Autopipe(args.coordinator[0], args.coordinator[1:], log_level=getattr(logging, args.log_level.upper())) + return 0 + except ArgumentError as e: + logging.error(str(e)) + if e.flag == "coordinator": + logging.error("Available coordinators:") + for coordinator in available_coordinators: + logging.error(f" - {coordinator.name()}") + return 2 + except Exception as ex: + logging.error(ex, exc_info=logging.getLogger().getEffectiveLevel() <= logging.INFO) + return 1 diff --git a/autopipe/__main__.py b/autopipe/__main__.py index 87d6e54..d7e5398 100755 --- a/autopipe/__main__.py +++ b/autopipe/__main__.py @@ -1,15 +1,5 @@ #!/usr/bin/env python3 import autopipe -import logging -from argparse import ArgumentParser - if __name__ == "__main__": - parser = ArgumentParser(description="Easily run advanced pipelines in a daemon or in one run sessions.") - parser.add_argument("coordinator", help="The name of your pipeline coordinator.") - parser.add_argument("-v", "--verbose", choices=["debug", "info", "warn", "error"], nargs="?", const="info", - default="warn", dest="log_level", metavar="loglevel", - help="Set the logging level.", type=str.lower) - args = parser.parse_args() - - autopipe.Autopipe(args.coordinator, log_level=getattr(logging, args.log_level.upper())) + exit(autopipe.main()) diff --git a/autopipe/autopipe.py b/autopipe/autopipe.py index 99e87bb..c73da84 100644 --- a/autopipe/autopipe.py +++ b/autopipe/autopipe.py @@ -1,7 +1,10 @@ import logging +from autopipe import available_coordinators, ArgumentError class Autopipe: - def __init__(self, coordinator, log_level=logging.WARNING): + def __init__(self, coordinator, coordinator_args, log_level=logging.WARNING): logging.basicConfig(format="%(levelname)s: %(message)s", level=log_level) - logging.info(f"Using coordinator: {coordinator}") + if coordinator not in available_coordinators: + raise ArgumentError(f"Invalid coordinator: {coordinator}", "coordinator") + self.coordinator = available_coordinators[coordinator](*coordinator_args) diff --git a/autopipe/coordinators/__init__.py b/autopipe/coordinators/__init__.py new file mode 100644 index 0000000..75af45e --- /dev/null +++ b/autopipe/coordinators/__init__.py @@ -0,0 +1,3 @@ +from .notify_example import NotifyExample + +available_coordinators = [NotifyExample] diff --git a/autopipe/coordinators/notify_example.py b/autopipe/coordinators/notify_example.py new file mode 100644 index 0000000..5590735 --- /dev/null +++ b/autopipe/coordinators/notify_example.py @@ -0,0 +1,7 @@ +from autopipe import Coordinator + + +class NotifyExample(Coordinator): + @classmethod + def name(cls): + return "NotifyExample" diff --git a/autopipe/exceptions/ArgumentError.py b/autopipe/exceptions/ArgumentError.py new file mode 100644 index 0000000..250fdb9 --- /dev/null +++ b/autopipe/exceptions/ArgumentError.py @@ -0,0 +1,7 @@ +class ArgumentError(Exception): + def __init__(self, msg, flag=None): + self.msg = msg + self.flag = flag + + def __str__(self): + return self.msg diff --git a/autopipe/exceptions/__init__.py b/autopipe/exceptions/__init__.py new file mode 100644 index 0000000..a4c5303 --- /dev/null +++ b/autopipe/exceptions/__init__.py @@ -0,0 +1 @@ +from .ArgumentError import ArgumentError diff --git a/autopipe/input/__init__.py b/autopipe/input/__init__.py index e69de29..a08083f 100644 --- a/autopipe/input/__init__.py +++ b/autopipe/input/__init__.py @@ -0,0 +1 @@ +from .rss import RssInput diff --git a/autopipe/models.py b/autopipe/models.py index 0c0cfb8..d850bfe 100644 --- a/autopipe/models.py +++ b/autopipe/models.py @@ -33,14 +33,24 @@ class Input(ABC): raise NotImplementedError @abstractmethod - def generate(self) -> Generator[APData]: + def generate(self) -> Generator[APData, None, None]: raise NotImplementedError - @abstractmethod @property + @abstractmethod def loop_cooldown(self) -> int: """ If negative or 0, the input can't be chained and once the generator return the program will exit. If grater then 0, the generator will be called again after a sleep of x seconds where x is the return of this. """ raise NotImplementedError + + +class Coordinator(ABC): + def __init__(self): + logging.info(f"Using coordinator: {self.name()}") + + @classmethod + @abstractmethod + def name(cls): + raise NotImplementedError diff --git a/autopipe/pipe/__init__.py b/autopipe/pipe/__init__.py index e69de29..5d86fab 100644 --- a/autopipe/pipe/__init__.py +++ b/autopipe/pipe/__init__.py @@ -0,0 +1,2 @@ +from .tee import TeePipe +from .filter_pipe import FilterPipe diff --git a/bin/autopipe b/bin/autopipe deleted file mode 120000 index 372fa57..0000000 --- a/bin/autopipe +++ /dev/null @@ -1 +0,0 @@ -../autopipe/__main__.py \ No newline at end of file diff --git a/bin/autopipe b/bin/autopipe new file mode 100755 index 0000000..521eabe --- /dev/null +++ b/bin/autopipe @@ -0,0 +1,11 @@ +#!/usr/bin/env python3 +try: + import autopipe +except ModuleNotFoundError: + import sys + import os + sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__), ".."))) + import autopipe + +if __name__ == "__main__": + exit(autopipe.main()) \ No newline at end of file