From 859ee9529ea41f54cd589d66c8f4ec01388f17f6 Mon Sep 17 00:00:00 2001 From: Mykyta Holubakha Date: Sun, 4 Jun 2017 02:41:21 +0300 Subject: Implement package source dispatch --- pomu/source/__init__.py | 3 +++ pomu/source/manager.py | 72 ++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 pomu/source/__init__.py diff --git a/pomu/source/__init__.py b/pomu/source/__init__.py new file mode 100644 index 0000000..a86679f --- /dev/null +++ b/pomu/source/__init__.py @@ -0,0 +1,3 @@ +from pomu.source.manager import PackageDispatcher + +dispatcher = PackageDispatcher() diff --git a/pomu/source/manager.py b/pomu/source/manager.py index a15a427..93c05c0 100644 --- a/pomu/source/manager.py +++ b/pomu/source/manager.py @@ -1,8 +1,68 @@ -def register_package_handler(source, handler, priority): - pass +""" +Package source manager is responsible for selecting the correct source +for a requested package, by a provided string. -def get_package_source(uri): - pass +Package sources can provide several handlers with different priorities. +A handler is a String -> Result function, which tries to parse the passed +value and return Ok(value). -def get_package(uri): - pass +The package would be handled by the handler with the lowest priority, which +was added the first. + +Example: + @dispatcher.source + class BgoSource(): + @dispatcher.handler(priority=5) + def parse_int(uri): + if uri.is_decimal(): + return Result.Ok(int(uri)) + elif uri[0] == '#' and uri[1:].is_decimal(): + return Result.Ok(int(uri[1:])) + return Result.Err('NaN') + + @dispatcher.handler(priority=1) + def parse_url(uri): + if uri.startswith('http://bugs.gentoo.org/'): + ... +""" +#TODO: efficient sorted insertion +#import bisect +import inspect + +class PackageDispatcher(): + def __init__(self): + self.handlers = [] + + def source(self, cls): + for m, obj in inspect.getmembers(cls): + if isinstance(obj, self.handler._handler): + self.register_package_handler(cls, obj.handler, obj.priority) + return cls + + class handler(): + class _handler(): + def __init__(self, handler): + self.handler = handler + def __call__(self, *args): + return self.handler(*args) + + def __init__(self, priority=1000, *args, **kwargs): + self.priority = priority + + def __call__(self, func, *args, **kwargs): + x = self._handler(func) + x.priority = self.priority + return x + + def register_package_handler(self, source, handler, priority): + i = 0 + for i in range(len(self.handlers)): + if self.handlers[0] > priority: + break + self.handlers.insert(i, (priority, source, handler)) + + def get_package_source(self, uri): + for priority, source, handler in self.handlers: + if handler(uri).is_ok(): + return source + return None -- cgit v1.2.3-65-gdbad