def chrome_manifest(script_host_url, bouncer_url, browser): # Chrome is strict about the format of the version string if '+' in h.__version__: tag, detail = h.__version__.split('+') distance, commit = detail.split('.', 1) version = '{}.{}'.format(tag, distance) version_name = commit else: version = h.__version__ version_name = 'Official Build' # If a bouncer URL was supplied, allow connections from the whole domain bouncer = urlparse.urljoin(bouncer_url, '*') if bouncer_url else None context = { 'version': version, 'version_name': version_name, 'bouncer': bouncer, 'browser': browser, } if script_host_url: context['script_src'] = script_host_url template = jinja_env.get_template('browser/chrome/manifest.json.jinja2') return template.render(context)
def chrome_manifest(request): # Chrome is strict about the format of the version string if '+' in h.__version__: tag, detail = h.__version__.split('+') distance, commit = detail.split('.', 1) version = '{}.{}'.format(tag, distance) version_name = commit else: version = h.__version__ version_name = 'Official Build' src = request.resource_url(request.context) # We need to use only the host and port for the CSP script-src when # developing. If we provide a path such as /assets the CSP check fails. # See: # # https://developer.chrome.com/extensions/contentSecurityPolicy#relaxing-remote-script if urlparse.urlparse(src).hostname not in ('localhost', '127.0.0.1'): src = urlparse.urljoin(src, request.webassets_env.url) value = { 'src': src, 'version': version, 'version_name': version_name } return render('h:browser/chrome/manifest.json.jinja2', value, request=request)
def incontext_link(request, annotation): """Generate a link to an annotation on the page where it was made.""" bouncer_url = request.registry.settings.get('h.bouncer_url') if not bouncer_url: via_url = request.registry.settings.get('h.via_url') if not via_url: return None link = via_url + '/' + annotation.target_uri return link link = urlparse.urljoin(bouncer_url, annotation.thread_root_id) return link # skip this part to short URIs uri = annotation.target_uri if uri.startswith(('http://', 'https://')): # We can't use urljoin here, because if it detects the second argument # is a URL it will discard the base URL, breaking the link entirely. link += '/' + uri[uri.index('://') + 3:] elif uri.startswith('urn:x-pdf:') and annotation.document: for docuri in annotation.document.document_uris: uri = docuri.uri if uri.startswith(('http://', 'https://')): link += '/' + uri[uri.index('://') + 3:] break return link
def get_env(config_uri, base_url): """ Return a preconfigured paste environment object. Sets up the WSGI application and ensures that webassets knows to load files from ``h:static`` regardless of the ``webassets.base_dir`` setting. """ request = Request.blank('', base_url=base_url) env = paster.bootstrap(config_uri, request) request.root = env['root'] # Ensure that the webassets URL is absolute request.webassets_env.url = urlparse.urljoin(base_url, request.webassets_env.url) # Disable webassets caching and manifest generation request.webassets_env.cache = False request.webassets_env.manifest = False # By default, webassets will use its base_dir setting as its search path. # When building extensions, we change base_dir so as to build assets # directly into the extension directories. As a result, we have to add # back the correct search path. request.webassets_env.append_path(resolve('h:static').abspath(), request.webassets_env.url) return env
def chrome_manifest(request): # Chrome is strict about the format of the version string if '+' in h.__version__: tag, detail = h.__version__.split('+') distance, commit = detail.split('.', 1) version = '{}.{}'.format(tag, distance) version_name = commit else: version = h.__version__ version_name = 'Official Build' src = request.resource_url(request.context) # We need to use only the host and port for the CSP script-src when # developing. If we provide a path such as /assets the CSP check fails. # See: # # https://developer.chrome.com/extensions/contentSecurityPolicy#relaxing-remote-script if urlparse.urlparse(src).hostname not in ('localhost', '127.0.0.1'): src = urlparse.urljoin(src, request.webassets_env.url) value = {'src': src, 'version': version, 'version_name': version_name} return render('h:browser/chrome/manifest.json.jinja2', value, request=request)
def get_env(config_uri, base_url): """ Return a preconfigured paste environment object. Sets up the WSGI application and ensures that webassets knows to load files from ``h:static`` regardless of the ``webassets.base_dir`` setting. """ request = Request.blank('', base_url=base_url) env = paster.bootstrap(config_uri, request) request.root = env['root'] # Ensure that the webassets URL is absolute request.webassets_env.url = urlparse.urljoin(base_url, request.webassets_env.url) # Disable webassets caching and manifest generation request.webassets_env.cache = False request.webassets_env.manifest = False # By default, webassets will use its base_dir setting as its search path. # When building extensions, we change base_dir so as to build assets # directly into the extension directories. As a result, we have to add # back the correct search path. request.webassets_env.append_path( resolve('h:static').abspath(), request.webassets_env.url) return env
def incontext_link(request, annotation): """Generate a link to an annotation on the page where it was made.""" is_reply = bool(annotation.references) if not request.feature('direct_linking') or is_reply: return None bouncer_url = request.registry.settings.get('h.bouncer_url') if not bouncer_url: return None link = urlparse.urljoin(bouncer_url, annotation.id) uri = annotation.target_uri if uri and uri.startswith(('http://', 'https://')): # We can't use urljoin here, because if it detects the second argument # is a URL it will discard the base URL, breaking the link entirely. link += '/' + uri[uri.index('://') + 3:] return link
def includeme(config): config.scan(__name__) # Add a static (i.e. external) route for the bouncer service if we have a # URL for a bouncer service set. bouncer_url = config.registry.settings.get('h.bouncer_url') if bouncer_url: bouncer_route = urlparse.urljoin(bouncer_url, '{id}') config.add_route('annotation.incontext', bouncer_route, static=True) # Add an annotation link generator for the `annotation` view -- this adds a # named link called "html" to API rendered views of annotations. See # :py:mod:`h.api.presenters` for details. config.add_annotation_link_generator('html', _html_link) # Add an annotation link generator for viewing annotations in context on # the page on which they were made. config.add_annotation_link_generator('incontext', _incontext_link)
def incontext_link(request, annotation): """Generate a link to an annotation on the page where it was made.""" bouncer_url = request.registry.settings.get('h.bouncer_url') if not bouncer_url: return None link = urlparse.urljoin(bouncer_url, annotation.thread_root_id) uri = annotation.target_uri if uri.startswith(('http://', 'https://')): # We can't use urljoin here, because if it detects the second argument # is a URL it will discard the base URL, breaking the link entirely. link += '/' + uri[uri.index('://')+3:] elif uri.startswith('urn:x-pdf:') and annotation.document: for docuri in annotation.document.document_uris: uri = docuri.uri if uri.startswith(('http://', 'https://')): link += '/' + uri[uri.index('://')+3:] break return link
def incontext_link(request, annotation): """Generate a link to an annotation on the page where it was made.""" bouncer_url = request.registry.settings.get("h.bouncer_url") if not bouncer_url: return None link = urlparse.urljoin(bouncer_url, annotation.thread_root_id) uri = annotation.target_uri if uri.startswith(("http://", "https://")): # We can't use urljoin here, because if it detects the second argument # is a URL it will discard the base URL, breaking the link entirely. link += "/" + uri[uri.index("://") + 3:] elif uri.startswith("urn:x-pdf:") and annotation.document: for docuri in annotation.document.document_uris: uri = docuri.uri if uri.startswith(("http://", "https://")): link += "/" + uri[uri.index("://") + 3:] break return link
def scope(self): """Return a URL composed from the origin and path attrs""" return urlparse.urljoin(self._origin, self._path)
def absolute_asset_urls(bundle_name): return [urlparse.urljoin(base_url, url) for url in assets_env.urls(bundle_name)]
def absolute_asset_urls(bundle_name): return [ urlparse.urljoin(base_url, url) for url in assets_env.urls(bundle_name) ]