From 117c6fab36b8a6012f08b04012c03dd150f79fb0 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Wed, 29 May 2024 18:27:42 -0400 Subject: [PATCH] site: Vendor javascript dependencies Download our javascript dependencies when building the site. This allows us to improve load times since the browser can reuse the same connection. It also mildly improves privacy. I also looked at webpack, but it seemed to be overkill for what I want to do. Most of the files on this site are already split into independent bundles included only when necessary. And it also pull in a lot of javascript depenencies/overhead. I think it would still be nice to run a tree shaker on our dependencies. Closes: #59 Signed-off-by: Sean Anderson --- .gitignore | 3 + setup.py | 77 +++++++++++++++++++++++- trends/site/templates/base.html | 7 ++- trends/site/templates/player/trends.html | 3 +- 4 files changed, 85 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 6b9fd31..bd7ad8d 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,6 @@ logs/* # Build artifacts *.pkg.tar* *.deb + +# Vendored dependencies +trends/site/static/vendor/ diff --git a/setup.py b/setup.py index 4024ec7..4430a2d 100755 --- a/setup.py +++ b/setup.py @@ -2,7 +2,74 @@ # SPDX-License-Identifier: AGPL-3.0-only # Copyright (C) 2020-21 Sean Anderson +from distutils.command.build import build as distutils_build import setuptools +from setuptools.command.develop import develop as setuptools_develop +import os + +class build_fetch(setuptools.Command): + def initialize_options(self): + self.build_lib = None + self.inplace = False + self.package_dir = None + + def finalize_options(self): + self.set_undefined_options('build_ext', + ('build_lib', 'build_lib'), + ('inplace', 'inplace'), + ) + + def run(self): + import requests + + if self.inplace: + build_py = self.get_finalized_command('build_py') + vendor = f"{build_py.get_package_dir('trends.site')}/static/vendor" + else: + vendor = f"{self.build_lib}/trends/site/static/vendor" + + try: + os.mkdir(vendor) + except FileExistsError: + pass + + ts = ["js/tom-select.popular.min.js", "css/tom-select.min.css"] + ts += [f"{file}.map" for file in ts] + urls = [f"https://cdn.jsdelivr.net/npm/tom-select@2.0.0/dist/{file}" for file in ts] + urls.append("https://cdn.jsdelivr.net/npm/chart.js@3.7.0/dist/chart.min.js") + + with requests.Session() as s: + for url in urls: + file = os.path.basename(url) + etag = f".{file}.etag" + file = os.path.join(vendor, file) + etag = os.path.join(vendor, etag) + + print(f"Saving {url} to {file}") + headers = {} + try: + with open(etag) as e: + headers['If-None-Match'] = e.read() + except FileNotFoundError: + pass + + resp = s.get(url, headers=headers) + resp.raise_for_status() + if not len(headers) or resp.status_code != requests.codes.not_modified: + with open(file, 'wb') as f: + f.write(resp.content) + + with open(etag, 'w') as e: + e.write(resp.headers['etag']) + +class develop(setuptools_develop): + def run(self): + self.reinitialize_command('build_fetch', inplace=1) + self.run_command('build_fetch') + super().run() + +class build(distutils_build): + sub_commands = [('build_fetch', None)] + distutils_build.sub_commands setuptools.setup( name = 'trends.tf', @@ -20,7 +87,10 @@ 'COPYING', 'LICENSES/*', ], - setup_requires = ['setuptools_scm'], + setup_requires = [ + 'requests', + 'setuptools_scm', + ], install_requires = [ 'flask >= 2.0', 'mpmetrics', @@ -42,6 +112,11 @@ 'testing.postgresql' ], }, + cmdclass = { + 'build': build, + 'build_fetch': build_fetch, + 'develop': develop, + }, entry_points = { 'console_scripts': [ "trends_importer=trends.importer.cli:main", diff --git a/trends/site/templates/base.html b/trends/site/templates/base.html index 659edce..2c2848c 100644 --- a/trends/site/templates/base.html +++ b/trends/site/templates/base.html @@ -10,9 +10,10 @@ {% block title %}trends.tf{% endblock %} - {% set tom_select_prefix = "https://cdn.jsdelivr.net/npm/tom-select@2.0.0/dist" %} - - + + {{ local_js("js/dates.js") }} {{ local_js("js/filter.js") }} diff --git a/trends/site/templates/player/trends.html b/trends/site/templates/player/trends.html index 22a5461..e0dde7e 100644 --- a/trends/site/templates/player/trends.html +++ b/trends/site/templates/player/trends.html @@ -9,7 +9,8 @@ {{ super() }} - + {{ local_js("js/trends.js") }} {% endblock %} {% block content %}