From c46a6918165cb2a3851105a679c5567418c15e50 Mon Sep 17 00:00:00 2001 From: YuviPanda Date: Fri, 2 Aug 2024 19:00:28 -0700 Subject: [PATCH] Add OpenGraph social card support --- binderhub/app.py | 19 +++++++++++++++---- binderhub/main.py | 33 +++++++++++++++++++++++++++++++-- binderhub/templates/page.html | 4 ++-- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/binderhub/app.py b/binderhub/app.py index 50816a59f..2b5e34484 100644 --- a/binderhub/app.py +++ b/binderhub/app.py @@ -50,7 +50,7 @@ from .health import HealthHandler, KubernetesHealthHandler from .launcher import Launcher from .log import log_request -from .main import LegacyRedirectHandler, MainHandler +from .main import LegacyRedirectHandler, RepoLaunchUIHandler, UIHandler from .metrics import MetricsHandler from .quota import KubernetesLaunchQuota, LaunchQuota from .ratelimit import RateLimiter @@ -989,14 +989,24 @@ def initialize(self, *args, **kwargs): (r"/versions", VersionHandler), (r"/build/([^/]+)/(.+)", BuildHandler), (r"/health", self.health_handler_class, {"hub_url": self.hub_url_local}), + (r"/api/repoproviders", RepoProvidersHandlers), ] if not self.enable_api_only_mode: # In API only mode the endpoints in the list below - # are unregistered as they don't make sense in a API only scenario + # are not registered since they are primarily about providing UI + + for provider_id in self.repo_providers: + # Register launchable URLs for all our repo providers + # These render social previews, but otherwise redirect to UIHandler + handlers += [ + ( + rf"/v2/({provider_id})/(.+)", + RepoLaunchUIHandler, + {"repo_provider": self.repo_providers[provider_id]}, + ) + ] handlers += [ - (r"/(?:v2/.*|about)?", MainHandler), (r"/repo/([^/]+)/([^/]+)(/.*)?", LegacyRedirectHandler), - (r"/api/repoproviders", RepoProvidersHandlers), # for backward-compatible mybinder.org badge URLs # /assets/images/badge.svg ( @@ -1062,6 +1072,7 @@ def initialize(self, *args, **kwargs): ) }, ), + (r"/.*", UIHandler), ] # This needs to be the last handler in the list, because it needs to match "everything else" handlers.append((r".*", Custom404)) diff --git a/binderhub/main.py b/binderhub/main.py index e42ee8c2d..7d66c5303 100644 --- a/binderhub/main.py +++ b/binderhub/main.py @@ -9,8 +9,14 @@ from .base import BaseHandler -class MainHandler(BaseHandler): - """Main handler for requests""" +class UIHandler(BaseHandler): + """ + Responds to most UI Page Requests + """ + + def initialize(self): + self.opengraph_title = "The Binder Project" + return super().initialize() @authenticated def get(self): @@ -32,7 +38,30 @@ def get(self): "page.html", page_config=page_config, extra_footer_scripts=self.settings["extra_footer_scripts"], + opengraph_title=self.opengraph_title, + ) + + +class RepoLaunchUIHandler(UIHandler): + """ + Responds to /v2/ launch URLs only + + Forwards to UIHandler, but puts out an opengraph_title for social previews + """ + + def initialize(self, repo_provider): + self.repo_provider = repo_provider + return super().initialize() + + @authenticated + def get(self, provider_id, _escaped_spec): + prefix = "/v2/" + provider_id + spec = self.get_spec_from_request(prefix).rstrip("/") + + self.opengraph_title = ( + f"{self.repo_provider.display_config['displayName']}: {spec}" ) + return super().get() class LegacyRedirectHandler(BaseHandler): diff --git a/binderhub/templates/page.html b/binderhub/templates/page.html index 212d61ef5..6b6780d27 100644 --- a/binderhub/templates/page.html +++ b/binderhub/templates/page.html @@ -5,8 +5,8 @@ {% block title %}Binder{% endblock %} {% block meta_social %} {# Social media previews #} - - + +