diff --git a/apps/remote_content/__init__.py b/apps/remote_content/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/apps/remote_content/apps.py b/apps/remote_content/apps.py new file mode 100644 index 000000000..a759ec1b8 --- /dev/null +++ b/apps/remote_content/apps.py @@ -0,0 +1,4 @@ +from django.apps import AppConfig + +class remoteContentAppConfig(AppConfig): + name = 'apps.remote_content' diff --git a/apps/remote_content/templates/remote_content/markup.html b/apps/remote_content/templates/remote_content/markup.html new file mode 100644 index 000000000..c73b79ae6 --- /dev/null +++ b/apps/remote_content/templates/remote_content/markup.html @@ -0,0 +1 @@ +{{ markup|safe }} diff --git a/apps/remote_content/urls.py b/apps/remote_content/urls.py new file mode 100644 index 000000000..502538b8d --- /dev/null +++ b/apps/remote_content/urls.py @@ -0,0 +1,17 @@ +import re + +from django.urls import re_path +# from django.conf import settings + +from .views import RemoteMarkup + + +app_name = 'remote_content' + +# blogRemoteUrlPattern = r'^' + re.escape(settings.PORTAL_REMOTE_CONTENT_CLIENT_PATH) +urlpatterns = [ + # To render a blog (or any page) from another website + # TODO: Use query parameter, not URL path + # TODO: Use settings.PORTAL_REMOTE_CONTENT_CLIENT_PATH + re_path(r'^markup/', RemoteMarkup.as_view(), name='remote_markup'), +] diff --git a/apps/remote_content/views.py b/apps/remote_content/views.py new file mode 100644 index 000000000..43dcc1f06 --- /dev/null +++ b/apps/remote_content/views.py @@ -0,0 +1,72 @@ +import requests + +from urllib.parse import urlparse, urlencode, parse_qsl + +from django.conf import settings +from django.template import Template, Context +from django.shortcuts import render +from django.views.generic.base import TemplateView + +class RemoteMarkup(TemplateView): + template_name = 'remote_content/markup.html' + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + source_url = self.get_source_url() + source_markup = self.get_source_markup(source_url) + client_markup = self.get_client_markup(source_markup) + + context['markup'] = client_markup + + return context + + def get_source_url(self): + source_root = settings.PORTAL_REMOTE_CONTENT_SOURCE_ROOT + client = urlparse(self.request.build_absolute_uri()) + source = urlparse(source_root) + + client_path = settings.PORTAL_REMOTE_CONTENT_CLIENT_PATH + source_path = source.path + client.path.replace(client_path, '') + + source_url = client._replace( + scheme=source.scheme, + netloc=source.netloc, + path=source_path, + ).geturl() + source_url = add_query_params(source_url, {'raw':''}) + + return source_url + + def get_source_markup(self, url): + response = requests.get(url) + + if response.status_code == 200: + return response.text + else: + return None + + # CAVEAT: Causes a view request for every resource (img/script/stylesheet) + def get_client_markup(self, source_markup): + client_markup = None + + source = urlparse(settings.PORTAL_REMOTE_CONTENT_SOURCE_ROOT) + source_site = source.scheme + '://' + source.netloc + + # FAQ: No markup for bad URL or a resource specific to source wesbite + if source_markup: + client_markup = source_markup.replace( + 'src="', + 'crossorigin="anonymous" src="' + source_site + ).replace( + 'href="' + source.path, + 'target="_blank" href="' + source_site + source.path + ) + + return client_markup + +def add_query_params(url, params): + request = requests.PreparedRequest() + + request.prepare_url(url, params) + + return request.url diff --git a/taccsite_cms/custom_app_settings.example.py b/taccsite_cms/custom_app_settings.example.py index 3ac04c50d..a48ec503a 100644 --- a/taccsite_cms/custom_app_settings.example.py +++ b/taccsite_cms/custom_app_settings.example.py @@ -1,3 +1,3 @@ -CUSTOM_APPS = ['apps.custom_example'] +CUSTOM_APPS = ['apps.custom_example', 'apps.remote_content'] CUSTOM_MIDDLEWARE = [] STATICFILES_DIRS = ()