Convenience functions for callable hooks
authorChristopher Allan Webber <cwebber@dustycloud.org>
Sun, 7 Apr 2013 22:46:11 +0000 (17:46 -0500)
committerChristopher Allan Webber <cwebber@dustycloud.org>
Sun, 7 Apr 2013 22:46:11 +0000 (17:46 -0500)
mediagoblin/tools/pluginapi.py

index 784bede948a59c8a35ab84165d848de399caccc6..f233fe51f860399b1bbecd90dafb0c6a1c1469e7 100644 (file)
@@ -272,3 +272,68 @@ def get_hook_templates(hook_name):
       A list of strings representing template paths.
     """
     return PluginManager().get_template_hooks(hook_name)
+
+
+###########################
+# Callable convenience code
+###########################
+
+class CantHandleIt(Exception):
+    """
+    A callable may call this method if they look at the relevant
+    arguments passed and decide it's not possible for them to handle
+    things.
+    """
+    pass
+
+class UnhandledCallable(Exception):
+    """
+    Raise this method if no callables were available to handle the
+    specified hook.  Only used by callable_runone.
+    """
+    pass
+
+
+def callable_runone(hookname, unhandled_okay=False, *args, **kwargs):
+    """
+    Run the callable hook HOOKNAME... run until the first response,
+    then return.
+
+    This function will run stop at the first hook that handles the
+    result.  Hooks raising CantHandleIt will be skipped.
+
+    Unless unhandled_okay is True, this will error out if no hooks
+    have been registered to handle this function.
+    """
+    callables = PluginManager().get_hook_callables(hookname)
+
+    for callable in callables:
+        try:
+            return callable(*args, **kwargs)
+        except CantHandleIt:
+            continue
+
+    if unhandled_okay is False:
+        raise UnhandledCallable(
+            "No hooks registered capable of handling '%s'" % hookname)
+
+
+def callable_runall(hookname, *args, **kwargs):
+    """
+    Run all callables for HOOKNAME.
+
+    This method will run *all* hooks that handle this method (skipping
+    those that raise CantHandleIt), and will return a list of all
+    results.
+    """
+    callables = PluginManager().get_hook_callables(hookname)
+
+    results = []
+
+    for callable in callables:
+        try:
+            results.append(callable(*args, **kwargs))
+        except CantHandleIt:
+            continue
+
+    return results