from flask import request, url_for, make_response, current_app, \
                  _app_ctx_stack as stack
from werkzeug.routing import BuildError
from jinja2 import Markup

import functools

__all__ = ('init_publisher', 'publisher',)

HEADER_VALUE = '<%s>; rel="self", <%s>; rel="hub"'
SELF_LINK = '<link rel="self" href="%s" />'
HUB_LINK = '<link rel="hub" href="%s" />'


def init_publisher(app):
    @app.context_processor
    def inject_links():
        return {
            'websub_self_url': stack.top.websub_self_url,
            'websub_hub_url': stack.top.websub_hub_url,
            'websub_self_link': stack.top.websub_self_link,
            'websub_hub_link': stack.top.websub_hub_link,
        }


def publisher(self_url=None, hub_url=None):
    def decorator(topic_view):
        @functools.wraps(topic_view)
        def wrapper(*args, **kwargs):
            nonlocal hub_url, self_url

            if not self_url:
                self_url = request.url
            if not hub_url:
                # If hub_url is not set, the hub and publisher need to share
                # their application for the url to be auto-discovered
                try:
                    hub_url = url_for('websub_hub.endpoint', _external=True)
                except BuildError:
                    hub_url = current_app.config['HUB_URL']

            stack.top.websub_self_url = self_url
            stack.top.websub_hub_url = hub_url
            stack.top.websub_self_link = Markup(SELF_LINK % self_url)
            stack.top.websub_hub_link = Markup(HUB_LINK % hub_url)

            resp = make_response(topic_view(*args, **kwargs))
            resp.headers.add('Link', HEADER_VALUE % (self_url, hub_url))
            return resp
        return wrapper
    return decorator

@@ -394,16 +394,130 @@
 r(app):%0A
+    %22%22%22Calling this with your flask app as argument is required for the%0A    publisher decorator to work.%0A%0A    %22%22%22%0A
     @app
@@ -535,16 +535,16 @@
 ocessor%0A
-
     def 
@@ -864,16 +864,885 @@
 =None):%0A
+    %22%22%22This decorator makes it easier to implement a websub publisher. You use%0A    it on an endpoint, and Link headers will automatically be added. To also%0A    include these links in your template html/atom/rss (and you should!) you%0A    can use the following to get the raw links:%0A%0A    - %7B%7B websub_self_url %7D%7D%0A    - %7B%7B websub_hub_url %7D%7D%0A%0A    And the following to get them wrapped in %3Clink tags%3E:%0A%0A    - %7B%7B websub_self_link %7D%7D%0A    - %7B%7B websub_hub_link %7D%7D%0A%0A    If hub_url is not given, the hub needs to be a flask_websub one and the%0A    hub and publisher need to share their application for the url to be%0A    auto-discovered. If that is not the case, you need to set%0A    config%5B'HUB_URL'%5D.%0A%0A    If self_url is not given, the url of the current request will be used. Note%0A    that this includes url query arguments. If this is not what you want,%0A    override it.%0A%0A    %22%22%22%0A
     def 
@@ -1943,24 +1943,24 @@
 request.url%0A
+
             
@@ -1979,155 +1979,8 @@
 rl:%0A
-                # If hub_url is not set, the hub and publisher need to share%0A                # their application for the url to be auto-discovered%0A
     

Document publisher