4242)
4343from traitlets .config import Application
4444
45- from .base import AboutHandler , Custom404 , VersionHandler
45+ from .base import VersionHandler
4646from .build import BuildExecutor , KubernetesBuildExecutor , KubernetesCleaner
4747from .builder import BuildHandler
48- from .config import ConfigHandler
4948from .events import EventLog
49+ from .handlers .repoproviders import RepoProvidersHandlers
5050from .health import HealthHandler , KubernetesHealthHandler
5151from .launcher import Launcher
5252from .log import log_request
53- from .main import LegacyRedirectHandler , MainHandler , ParameterizedMainHandler
53+ from .main import LegacyRedirectHandler , RepoLaunchUIHandler , UIHandler
5454from .metrics import MetricsHandler
5555from .quota import KubernetesLaunchQuota , LaunchQuota
5656from .ratelimit import RateLimiter
@@ -107,6 +107,11 @@ def _log_level(self):
107107 None ,
108108 allow_none = True ,
109109 help = """
110+ ..removed::
111+
112+ No longer supported. If you want to use Google Analytics, use :attr:`extra_footer_scripts`
113+ to load JS from Google Analytics.
114+
110115 The Google Analytics code to use on the main page.
111116
112117 Note that we'll respect Do Not Track settings, despite the fact that GA does not.
@@ -118,6 +123,11 @@ def _log_level(self):
118123 google_analytics_domain = Unicode (
119124 "auto" ,
120125 help = """
126+ ..removed::
127+
128+ No longer supported. If you want to use Google Analytics, use :attr:`extra_footer_scripts`
129+ to load JS from Google Analytics.
130+
121131 The Google Analytics domain to use on the main page.
122132
123133 By default this is set to 'auto', which sets it up for current domain and all
@@ -126,6 +136,13 @@ def _log_level(self):
126136 config = True ,
127137 )
128138
139+ @observe ("google_analytics_domain" , "google_analytics_code" )
140+ def _google_analytics_deprecation (self , change ):
141+ if change .new :
142+ raise ValueError (
143+ f"Setting { change .owner .__class__ .__name__ } .{ change .name } is no longer supported. Use { change .owner .__class__ .__name__ } .extra_footer_scripts to load Google Analytics JS directly"
144+ )
145+
129146 about_message = Unicode (
130147 "" ,
131148 help = """
@@ -149,6 +166,14 @@ def _log_level(self):
149166 config = True ,
150167 )
151168
169+ default_opengraph_title = Unicode (
170+ "The Binder Project" ,
171+ help = """
172+ The default opengraph title for pages that don't have a generated opengraph title.
173+ """ ,
174+ config = True ,
175+ )
176+
152177 extra_footer_scripts = Dict (
153178 {},
154179 help = """
@@ -785,7 +810,6 @@ def _template_path_default(self):
785810 - /versions
786811 - /build/([^/]+)/(.+)
787812 - /health
788- - /_config
789813 - /* -> shows a 404 page
790814 """ ,
791815 config = True ,
@@ -913,6 +937,7 @@ def initialize(self, *args, **kwargs):
913937 "log_function" : log_request ,
914938 "image_prefix" : self .image_prefix ,
915939 "debug" : self .debug ,
940+ "default_opengraph_title" : self .default_opengraph_title ,
916941 "launcher" : self .launcher ,
917942 "ban_networks" : self .ban_networks ,
918943 "build_pool" : self .build_pool ,
@@ -931,8 +956,6 @@ def initialize(self, *args, **kwargs):
931956 "registry" : registry ,
932957 "traitlets_config" : self .config ,
933958 "traitlets_parent" : self ,
934- "google_analytics_code" : self .google_analytics_code ,
935- "google_analytics_domain" : self .google_analytics_domain ,
936959 "about_message" : self .about_message ,
937960 "banner_message" : self .banner_message ,
938961 "extra_footer_scripts" : self .extra_footer_scripts ,
@@ -961,15 +984,23 @@ def initialize(self, *args, **kwargs):
961984 (r"/versions" , VersionHandler ),
962985 (r"/build/([^/]+)/(.+)" , BuildHandler ),
963986 (r"/health" , self .health_handler_class , {"hub_url" : self .hub_url_local }),
964- (r"/_config " , ConfigHandler ),
987+ (r"/api/repoproviders " , RepoProvidersHandlers ),
965988 ]
966989 if not self .enable_api_only_mode :
967990 # In API only mode the endpoints in the list below
968- # are unregistered as they don't make sense in a API only scenario
991+ # are not registered since they are primarily about providing UI
992+
993+ for provider_id in self .repo_providers :
994+ # Register launchable URLs for all our repo providers
995+ # These render social previews, but otherwise redirect to UIHandler
996+ handlers += [
997+ (
998+ rf"/v2/({ provider_id } )/(.+)" ,
999+ RepoLaunchUIHandler ,
1000+ {"repo_provider" : self .repo_providers [provider_id ]},
1001+ )
1002+ ]
9691003 handlers += [
970- (r"/about" , AboutHandler ),
971- (r"/v2/([^/]+)/(.+)" , ParameterizedMainHandler ),
972- (r"/" , MainHandler ),
9731004 (r"/repo/([^/]+)/([^/]+)(/.*)?" , LegacyRedirectHandler ),
9741005 # for backward-compatible mybinder.org badge URLs
9751006 # /assets/images/badge.svg
@@ -1036,9 +1067,8 @@ def initialize(self, *args, **kwargs):
10361067 )
10371068 },
10381069 ),
1070+ (r"/.*" , UIHandler ),
10391071 ]
1040- # This needs to be the last handler in the list, because it needs to match "everything else"
1041- handlers .append ((r".*" , Custom404 ))
10421072 handlers = self .add_url_prefix (self .base_url , handlers )
10431073 if self .extra_static_path :
10441074 handlers .insert (
0 commit comments