From 449ff5b61b6dcb3f0de9c920844bc66e80f049c7 Mon Sep 17 00:00:00 2001 From: Brendan Nee Date: Wed, 24 Jan 2024 19:42:45 -0800 Subject: [PATCH] Persist Build ID in URL --- .env-example | 3 ++- CHANGELOG.md | 6 +++++ README.md | 1 + now.json | 11 --------- package-lock.json | 63 +++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 ++ pages/_app.js | 12 +++++++++ pages/index.js | 21 +++++++++++++++- util/create.mjs | 8 +++--- 9 files changed, 110 insertions(+), 17 deletions(-) delete mode 100644 now.json create mode 100644 pages/_app.js diff --git a/.env-example b/.env-example index dd0be01..9e457eb 100644 --- a/.env-example +++ b/.env-example @@ -1,4 +1,5 @@ GTFS_AWS_ACCESS_KEY_ID=YOUR_AWS_ACCESS_KEY GTFS_AWS_ACCESS_KEY_SECRET=YOUR_AWS_SECRET GTFS_AWS_REGION=us-east-1 -GTFS_AWS_S3_URL=https://gtfs-to-html.s3.amazonaws.com +NEXT_PUBLIC_GTFS_AWS_S3_URL=https://gtfs-to-html.s3.amazonaws.com +TRANSIT_FEEDS_API_KEY=YOUR_TRANSIT_FEEDS_API_KEY diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a0c859..b8f254c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Added + +- Persist Build ID in URL + ## [1.0.4] - 2024-01-24 ### Updated diff --git a/README.md b/README.md index 3929268..f361d68 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,7 @@ If instead there is an error while processing, the response will contain the err ## Upgrading node.js + npm run build npm install pm2 -g pm2 update pm2 unstartup diff --git a/now.json b/now.json deleted file mode 100644 index 2279fb1..0000000 --- a/now.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": 1, - "alias": "gtfstohtml.com", - "env": { - "GTFS_AWS_ACCESS_KEY_ID": "@gtfs-aws-access-key-id", - "GTFS_AWS_ACCESS_KEY_SECRET": "@gtfs-aws-access-key-secret", - "GTFS_AWS_REGION": "@gtfs-aws-region", - "GTFS_AWS_S3_URL": "@gtfs-aws-s3-url", - "TRANSIT_FEEDS_API_KEY": "@transit-feeds-api-key" - } -} diff --git a/package-lock.json b/package-lock.json index 942831b..2b6d778 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "hapi-require-https": "^6.0.0", "lodash-es": "^4.17.21", "next": "^12.2.5", + "next-query-params": "^5.0.0", "node-fetch": "^3.3.2", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -25,6 +26,7 @@ "socket.io": "^4.7.4", "socket.io-client": "^4.7.4", "tmp-promise": "^3.0.3", + "use-query-params": "^2.2.1", "uuid": "^9.0.1" }, "devDependencies": { @@ -4766,6 +4768,19 @@ } } }, + "node_modules/next-query-params": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/next-query-params/-/next-query-params-5.0.0.tgz", + "integrity": "sha512-Zm9nc0QgrTMaQwGdbICcTDaYS4oRcXo628Ye6JQGdp/9JzlhzDpzcGRqciK0S62yAyE3b5ozFpgzY0gDUEbLtw==", + "dependencies": { + "tslib": "^2.0.3" + }, + "peerDependencies": { + "next": "^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "use-query-params": "^2.0.0" + } + }, "node_modules/node-abi": { "version": "3.54.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.54.0.tgz", @@ -5966,6 +5981,11 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, + "node_modules/serialize-query-params": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/serialize-query-params/-/serialize-query-params-2.0.2.tgz", + "integrity": "sha512-1chMo1dST4pFA9RDXAtF0Rbjaut4is7bzFbI1Z26IuMub68pNCILku85aYmeFhvnY//BXUPUhoRMjYcsT93J/Q==" + }, "node_modules/serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", @@ -6817,6 +6837,28 @@ "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-9.0.0.tgz", "integrity": "sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==" }, + "node_modules/use-query-params": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/use-query-params/-/use-query-params-2.2.1.tgz", + "integrity": "sha512-i6alcyLB8w9i3ZK3caNftdb+UnbfBRNPDnc89CNQWkGRmDrm/gfydHvMBfVsQJRq3NoHOM2dt/ceBWG2397v1Q==", + "dependencies": { + "serialize-query-params": "^2.0.2" + }, + "peerDependencies": { + "@reach/router": "^1.2.1", + "react": ">=16.8.0", + "react-dom": ">=16.8.0", + "react-router-dom": ">=5" + }, + "peerDependenciesMeta": { + "@reach/router": { + "optional": true + }, + "react-router-dom": { + "optional": true + } + } + }, "node_modules/use-sync-external-store": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", @@ -10553,6 +10595,14 @@ "use-sync-external-store": "1.2.0" } }, + "next-query-params": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/next-query-params/-/next-query-params-5.0.0.tgz", + "integrity": "sha512-Zm9nc0QgrTMaQwGdbICcTDaYS4oRcXo628Ye6JQGdp/9JzlhzDpzcGRqciK0S62yAyE3b5ozFpgzY0gDUEbLtw==", + "requires": { + "tslib": "^2.0.3" + } + }, "node-abi": { "version": "3.54.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.54.0.tgz", @@ -11457,6 +11507,11 @@ } } }, + "serialize-query-params": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/serialize-query-params/-/serialize-query-params-2.0.2.tgz", + "integrity": "sha512-1chMo1dST4pFA9RDXAtF0Rbjaut4is7bzFbI1Z26IuMub68pNCILku85aYmeFhvnY//BXUPUhoRMjYcsT93J/Q==" + }, "serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", @@ -12061,6 +12116,14 @@ "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-9.0.0.tgz", "integrity": "sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==" }, + "use-query-params": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/use-query-params/-/use-query-params-2.2.1.tgz", + "integrity": "sha512-i6alcyLB8w9i3ZK3caNftdb+UnbfBRNPDnc89CNQWkGRmDrm/gfydHvMBfVsQJRq3NoHOM2dt/ceBWG2397v1Q==", + "requires": { + "serialize-query-params": "^2.0.2" + } + }, "use-sync-external-store": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", diff --git a/package.json b/package.json index 2d3525f..7d8a6c4 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "hapi-require-https": "^6.0.0", "lodash-es": "^4.17.21", "next": "^12.2.5", + "next-query-params": "^5.0.0", "node-fetch": "^3.3.2", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -34,6 +35,7 @@ "socket.io": "^4.7.4", "socket.io-client": "^4.7.4", "tmp-promise": "^3.0.3", + "use-query-params": "^2.2.1", "uuid": "^9.0.1" }, "devDependencies": { diff --git a/pages/_app.js b/pages/_app.js new file mode 100644 index 0000000..3c9d2ec --- /dev/null +++ b/pages/_app.js @@ -0,0 +1,12 @@ +import { NextAdapter } from 'next-query-params'; +import { QueryParamProvider } from 'use-query-params'; + +function MyApp({ Component, pageProps: { session, ...pageProps } }) { + return ( + + + + ); +} + +export default MyApp; diff --git a/pages/index.js b/pages/index.js index 45d43eb..5f39e86 100644 --- a/pages/index.js +++ b/pages/index.js @@ -1,5 +1,6 @@ import React, { useState, useEffect } from 'react'; import Head from 'next/head.js'; +import { useQueryParam } from 'use-query-params'; import io from 'socket.io-client'; import { initGA, logPageView, logEvent } from '../util/analytics.js'; @@ -69,11 +70,11 @@ function Home() { const [showOptions, setShowOptions] = useState(false); const [processing, setProcessing] = useState(false); const [statuses, setStatuses] = useState([]); - const [buildId, setBuildId] = useState(); const [locations, setLocations] = useState(); const [selectedLocation, setSelectedLocation] = useState(''); const [feeds, setFeeds] = useState(); const [selectedFeed, setSelectedFeed] = useState(''); + const [buildId, setBuildId] = useQueryParam('build'); const statusContainer = React.createRef(); @@ -86,6 +87,24 @@ function Home() { logPageView(); }, []); + useEffect(() => { + if (buildId && statuses.length === 0) { + setStatuses([ + { + status: 'Timetable creation completed', + html_download_url: new URL( + `/${buildId}/timetables.zip`, + process.env.NEXT_PUBLIC_GTFS_AWS_S3_URL, + ), + html_preview_url: new URL( + `/${buildId}/index.html`, + process.env.NEXT_PUBLIC_GTFS_AWS_S3_URL, + ), + }, + ]); + } + }, [buildId]); + useEffect(() => { socket.on('status', (payload) => { if (statuses.length > 0 && payload.overwrite === true) { diff --git a/util/create.mjs b/util/create.mjs index b0b31db..2dc307f 100644 --- a/util/create.mjs +++ b/util/create.mjs @@ -1,5 +1,5 @@ import {join} from 'node:path'; -import {fileURLToPath, resolve} from 'node:url'; +import {fileURLToPath} from 'node:url'; import {readFile, stat, writeFile} from 'node:fs/promises'; import fetch from 'node-fetch'; import { throttle } from 'lodash-es'; @@ -123,9 +123,9 @@ export default async (data, socket) => { uploader.on('end', () => { setTimeout(() => { socket.emit('status', { - status: 'Timetable upload completed', - html_download_url: resolve(process.env.GTFS_AWS_S3_URL, join(buildId, 'timetables.zip')), - html_preview_url: resolve(process.env.GTFS_AWS_S3_URL, join(buildId, 'index.html')) + status: 'Timetable creation completed', + html_download_url: new URL(`/${buildId}/timetables.zip`, process.env.NEXT_PUBLIC_GTFS_AWS_S3_URL), + html_preview_url: new URL(`/${buildId}/index.html`, process.env.NEXT_PUBLIC_GTFS_AWS_S3_URL), }); }, 1000); });