Updates for default folder

This commit is contained in:
Matt Walsh
2025-03-24 18:24:49 -05:00
parent 65444978b7
commit e9164d8c36
15 changed files with 169 additions and 30 deletions

View File

@@ -1,3 +1,4 @@
.git/
Dockerfile
.vscode/
dist/

9
.gitignore vendored
View File

@@ -7,7 +7,8 @@ server/music/*
#except for the readme
!server/music/readme.txt
#and the sample songs
!server/music/Catch the Sun.mp3
!server/music/Crisp day.mp3
!server/music/Rolling Clouds.mp3
!server/music/Strong Breeze.mp3
!server/music/default
#dist folder
dist/*
!dist/readme.txt

View File

@@ -98,6 +98,13 @@ As time allows I will be working on the following enhancements.
* Better error reporting when api.weather.gov is down (happens more often than you would think)
## Serving static files
The app can be served as a static set of files on any web server. Run the provided gulp task to create a set of static distribution files:
```
npm run buildDist
```
The resulting files will be in the /dist folder in the root of the project. These can then be uploaded to a web server for hosting, no server-side scripting is required.
## Community Notes
Thanks to the WeatherStar community for providing these discussions to further extend your retro forecasts!

1
dist/readme.txt vendored Normal file
View File

@@ -0,0 +1 @@
This folder is a placeholder for static files generated by the gulp task buildDist

View File

@@ -12,11 +12,13 @@ import s3Upload from 'gulp-s3-upload';
import webpack from 'webpack-stream';
import TerserPlugin from 'terser-webpack-plugin';
import { readFile } from 'fs/promises';
import reader from '../src/playlist-reader.mjs';
import file from "gulp-file";
// get cloudfront
import { CloudFrontClient, CreateInvalidationCommand } from '@aws-sdk/client-cloudfront';
const clean = () => deleteAsync(['./dist**']);
const clean = () => deleteAsync(['./dist/**/*', '!./dist/readme.txt']);
const cloudfront = new CloudFrontClient({ region: 'us-east-1' });
@@ -122,8 +124,9 @@ const compressHtml = async () => {
const otherFiles = [
'server/robots.txt',
'server/manifest.json',
'server/music/**/*.mp3'
];
const copyOtherFiles = () => src(otherFiles, { base: 'server/' })
const copyOtherFiles = () => src(otherFiles, { base: 'server/', encoding: false })
.pipe(dest('./dist'));
const s3 = s3Upload({
@@ -170,10 +173,20 @@ const invalidate = () => cloudfront.send(new CreateInvalidationCommand({
},
}));
const buildDist = series(clean, parallel(buildJs, compressJsData, compressJsVendor, copyCss, compressHtml, copyOtherFiles));
const buildPlaylist = async () => {
const availableFiles = await reader();
const playlist = { availableFiles };
return file('playlist.json', JSON.stringify(playlist)).pipe(dest('./dist'))
}
const buildDist = series(clean, parallel(buildJs, compressJsData, compressJsVendor, copyCss, compressHtml, copyOtherFiles, buildPlaylist));
// upload_images could be in parallel with upload, but _images logs a lot and has little changes
// by running upload last the majority of the changes will be at the bottom of the log for easy viewing
const publishFrontend = series(buildDist, uploadImages, upload, invalidate);
export default publishFrontend;
export {
buildDist,
}

View File

@@ -1,7 +1,8 @@
import updateVendor from './gulp/update-vendor.mjs';
import publishFrontend from './gulp/publish-frontend.mjs';
import publishFrontend, { buildDist } from './gulp/publish-frontend.mjs'
export {
updateVendor,
publishFrontend,
buildDist,
};

97
package-lock.json generated
View File

@@ -22,6 +22,7 @@
"gulp-awspublish": "^8.0.0",
"gulp-concat": "^2.6.1",
"gulp-ejs": "^5.1.0",
"gulp-file": "^0.4.0",
"gulp-htmlmin": "^5.0.1",
"gulp-rename": "^2.0.0",
"gulp-s3-upload": "^1.7.3",
@@ -5473,6 +5474,102 @@
"readable-stream": "2 || 3"
}
},
"node_modules/gulp-file": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/gulp-file/-/gulp-file-0.4.0.tgz",
"integrity": "sha512-3NPCJpAPpbNoV2aml8T96OK3Aof4pm4PMOIa1jSQbMNSNUUXdZ5QjVgLXLStjv0gg9URcETc7kvYnzXdYXUWug==",
"dev": true,
"license": "BSD",
"dependencies": {
"through2": "^0.4.1",
"vinyl": "^2.1.0"
}
},
"node_modules/gulp-file/node_modules/isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
"dev": true,
"license": "MIT"
},
"node_modules/gulp-file/node_modules/object-keys": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
"integrity": "sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==",
"dev": true,
"license": "MIT"
},
"node_modules/gulp-file/node_modules/readable-stream": {
"version": "1.0.34",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
"integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==",
"dev": true,
"license": "MIT",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.1",
"isarray": "0.0.1",
"string_decoder": "~0.10.x"
}
},
"node_modules/gulp-file/node_modules/replace-ext": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz",
"integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.10"
}
},
"node_modules/gulp-file/node_modules/string_decoder": {
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==",
"dev": true,
"license": "MIT"
},
"node_modules/gulp-file/node_modules/through2": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/through2/-/through2-0.4.2.tgz",
"integrity": "sha512-45Llu+EwHKtAZYTPPVn3XZHBgakWMN3rokhEv5hu596XP+cNgplMg+Gj+1nmAvj+L0K7+N49zBKx5rah5u0QIQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"readable-stream": "~1.0.17",
"xtend": "~2.1.1"
}
},
"node_modules/gulp-file/node_modules/vinyl": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz",
"integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==",
"dev": true,
"license": "MIT",
"dependencies": {
"clone": "^2.1.1",
"clone-buffer": "^1.0.0",
"clone-stats": "^1.0.0",
"cloneable-readable": "^1.0.0",
"remove-trailing-separator": "^1.0.1",
"replace-ext": "^1.0.0"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/gulp-file/node_modules/xtend": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
"integrity": "sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ==",
"dev": true,
"dependencies": {
"object-keys": "~0.4.0"
},
"engines": {
"node": ">=0.4"
}
},
"node_modules/gulp-htmlmin": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/gulp-htmlmin/-/gulp-htmlmin-5.0.1.tgz",

View File

@@ -7,6 +7,7 @@
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build:css": "sass --style=compressed ./server/styles/scss/main.scss ./server/styles/main.css",
"build": "gulp buildDist",
"lint": "eslint ./server/scripts/**/*.mjs",
"lint:fix": "eslint --fix ./server/scripts/**/*.mjs"
},
@@ -21,32 +22,33 @@
},
"homepage": "https://github.com/netbymatt/ws4kp#readme",
"devDependencies": {
"del": "^8.0.0",
"jquery": "^3.6.0",
"jquery-touchswipe": "^1.6.19",
"luxon": "^3.0.0",
"nosleep.js": "^0.12.0",
"suncalc": "^1.8.0",
"swiped-events": "^1.1.4",
"@aws-sdk/client-cloudfront": "^3.609.0",
"gulp-awspublish": "^8.0.0",
"gulp-s3-upload": "^1.7.3",
"del": "^8.0.0",
"eslint": "^8.2.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-plugin-import": "^2.10.0",
"gulp": "^5.0.0",
"gulp-awspublish": "^8.0.0",
"gulp-concat": "^2.6.1",
"gulp-ejs": "^5.1.0",
"gulp-file": "^0.4.0",
"gulp-htmlmin": "^5.0.1",
"gulp-rename": "^2.0.0",
"gulp-s3-upload": "^1.7.3",
"gulp-sass": "^6.0.0",
"gulp-terser": "^2.0.0",
"jquery": "^3.6.0",
"jquery-touchswipe": "^1.6.19",
"luxon": "^3.0.0",
"nosleep.js": "^0.12.0",
"sass": "^1.54.0",
"suncalc": "^1.8.0",
"swiped-events": "^1.1.4",
"terser-webpack-plugin": "^5.3.6",
"webpack-stream": "^7.0.0",
"sass": "^1.54.0"
"webpack-stream": "^7.0.0"
},
"dependencies": {
"express": "^4.17.1",
"ejs": "^3.1.5"
"ejs": "^3.1.5",
"express": "^4.17.1"
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,2 +1,3 @@
.mp3 files placed in this folder will be available via the un-mute button in the application.
No subdirectories will be scanned, and music will be played in a random order.
The default folder will be used only if no .mp3 files are found in this /server/music folder

View File

@@ -63,12 +63,17 @@ const toggleMedia = (forcedState) => {
stateChanged();
};
const startMedia = () => {
const startMedia = async () => {
// if there's not media player yet, enable it
if (!player) {
initializePlayer();
} else {
player.play();
try {
await player.play();
} catch (e) {
console.error('Couldn\'t play music');
console.error(e);
}
}
};
@@ -128,11 +133,12 @@ const initializePlayer = () => {
console.log('player initialized');
};
const playerCanPlay = () => {
const playerCanPlay = async () => {
// check to make sure they user still wants music (protect against slow loading music)
if (!mediaPlaying.value) return;
// start playing
player.play();
startMedia();
};
const playerEnded = () => {

View File

@@ -1,12 +1,21 @@
import fs from 'fs/promises';
const mp3Filter = (file) => file.match(/\.mp3$/);
const reader = async () => {
// get the listing of files in the folder
const rawFiles = await fs.readdir('./server/music');
// filter for mp3 files
const files = rawFiles.filter((file) => file.match(/\.mp3$/));
console.log(files);
return files;
const files = rawFiles.filter(mp3Filter);
// if files were found return them
if (files.length > 0) {
return files;
}
// fall back to the default folder
const defaultFiles = await fs.readdir('./server/music/default');
return defaultFiles.map(file => `default/${file}`).filter(mp3Filter);
};
export default reader;