diff --git a/gulp/common/md5.js b/gulp/common/md5.js new file mode 100644 index 0000000000..29e80d8bb4 --- /dev/null +++ b/gulp/common/md5.js @@ -0,0 +1,8 @@ +const fs = require('fs'); +const crypto = require('crypto'); + +module.exports = function md5(filename) { + return crypto.createHash('md5') + .update(fs.readFileSync(filename)).digest('hex'); +}; + diff --git a/gulp/config.js b/gulp/config.js index ff4ef9a25f..185db09813 100644 --- a/gulp/config.js +++ b/gulp/config.js @@ -1,7 +1,8 @@ var path = require('path'); module.exports = { - static_dir: path.resolve(__dirname, '../..'), polymer_dir: path.resolve(__dirname, '..'), build_dir: path.resolve(__dirname, '../build'), + output: path.resolve(__dirname, '../hass_frontend'), + output_es5: path.resolve(__dirname, '../hass_frontend_es5'), }; diff --git a/gulp/tasks/gen-index-html.js b/gulp/tasks/gen-index-html.js new file mode 100644 index 0000000000..36411fceca --- /dev/null +++ b/gulp/tasks/gen-index-html.js @@ -0,0 +1,44 @@ +const gulp = require('gulp'); +const replace = require('gulp-batch-replace'); +const path = require('path'); +const url = require('url'); +const config = require('../config'); +const md5 = require('../common/md5.js'); + +const buildReplaces = { + '/home-assistant-polymer/build/core.js': 'core.js', + '/home-assistant-polymer/src/home-assistant.html': 'frontend.html', +}; + +function generateIndex(es6) { + const targetPath = es6 ? config.output : config.output_es5; + const targetUrl = es6 ? '/frontend_latest/' : '/frontend_es5/'; + + const toReplace = [ + ['/home-assistant-polymer/hass_frontend/mdi.html', + `/static/mdi-${md5(path.resolve(config.output, 'mdi.html'))}.html`], + ['/home-assistant-polymer/build-temp/compatibility.js', + `/static/compatibility-${md5(path.resolve(config.output_es5, 'compatibility.js'))}.js`], + ]; + + if (!es6) { + toReplace.push([ + '/service_worker.js', '/service_worker_es5.js' + ]); + } + + for (const [replaceSearch, filename] of Object.entries(buildReplaces)) { + const parsed = path.parse(filename); + const hash = md5(path.resolve(targetPath, filename)); + toReplace.push([ + replaceSearch, + url.resolve(targetUrl, `${parsed.name}-${hash}${parsed.ext}`)]); + } + + gulp.src(path.resolve(config.polymer_dir, 'index.html')) + .pipe(replace(toReplace)) + .pipe(gulp.dest(targetPath)); +} + +gulp.task('gen-index-html-es5', generateIndex.bind(null, /* es6= */ false)); +gulp.task('gen-index-html', generateIndex.bind(null, /* es6= */ true)); diff --git a/gulp/tasks/gen-service-worker.js b/gulp/tasks/gen-service-worker.js index b18f5f4d6d..362f7b83fe 100755 --- a/gulp/tasks/gen-service-worker.js +++ b/gulp/tasks/gen-service-worker.js @@ -12,11 +12,11 @@ TODO: - Fix minifying the stream */ const gulp = require('gulp'); -const crypto = require('crypto'); const file = require('gulp-file'); const fs = require('fs'); const path = require('path'); const swPrecache = require('sw-precache'); +const md5 = require('../common/md5.js'); const DEV = !!JSON.parse(process.env.BUILD_DEV || 'true'); @@ -45,11 +45,6 @@ const panelsFingerprinted = [ 'dev-mqtt', 'kiosk', ]; -function md5(filename) { - return crypto.createHash('md5') - .update(fs.readFileSync(filename)).digest('hex'); -} - function processStatic(fn, rootDir, urlDir) { const parts = path.parse(fn); const base = parts.dir.length > 0 ? parts.dir + '/' + parts.name : parts.name; @@ -117,7 +112,7 @@ function generateServiceWorker(es6) { } ], stripPrefix: baseRootDir, - replacePrefix: 'static', + replacePrefix: '/static', verbose: true, // Allow our users to refresh to get latest version. clientsClaim: true, diff --git a/index.html b/index.html new file mode 100644 index 0000000000..4546133dc3 --- /dev/null +++ b/index.html @@ -0,0 +1,121 @@ + + + + + Home Assistant + + + + + + + + + + + + + + + + + + + + + +
+
+ Home Assistant had trouble
connecting to the server.

+ TRY AGAIN +
+
+ + {# -#} + {% if not latest -%} + + {% endif -%} + + {% if not dev_mode and not latest -%} + + {% endif -%} + + + {% if panel_url -%} + + {% endif -%} + + {% for extra_url in extra_urls -%} + + {% endfor -%} + + diff --git a/package.json b/package.json index b98d0d2549..165316cc14 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "eslint-plugin-react": "^7.0.0", "gulp": "^3.9.1", "gulp-babel": "^7.0.0", + "gulp-batch-replace": "^0.0.0", "gulp-file": "^0.3.0", "gulp-filter": "^5.0.1", "gulp-foreach": "^0.1.0", diff --git a/script/build_frontend b/script/build_frontend index 327ec017c1..e17e630387 100755 --- a/script/build_frontend +++ b/script/build_frontend @@ -79,3 +79,5 @@ echo "CREATED_AT = `date +%s`" >> $OUTPUT_DIR_ES5/__init__.py # Generate the MD5 hash of the new frontend script/fingerprint_frontend.py --base_dir $OUTPUT_DIR script/fingerprint_frontend.py --base_dir $OUTPUT_DIR_ES5 +gulp gen-index-html +gulp gen-index-html-es5 diff --git a/script/fingerprint_frontend.py b/script/fingerprint_frontend.py index 95c785f426..0ae9dee9f5 100755 --- a/script/fingerprint_frontend.py +++ b/script/fingerprint_frontend.py @@ -7,28 +7,26 @@ import hashlib import json import argparse from os import path +import re parser = argparse.ArgumentParser(description='Generate fingerprints of frontend files.') parser.add_argument('--base_dir', type=str, help='Base dir to look for files.', default='hass_frontend') args = parser.parse_args() base_dir = args.base_dir + '/' fingerprint_file = path.join(base_dir, '__init__.py') +panel_match = re.compile(r'ha-panel-((\w|-)+)\.html') def fingerprint(): - """Fingerprint the frontend files.""" - files = (glob.glob(base_dir + '**/*.html') + - glob.glob(base_dir + '*.html') + - glob.glob(base_dir + 'core.js') + - glob.glob(base_dir + 'compatibility.js')) - + """Fingerprint the panels.""" + files = glob.glob(base_dir + 'panels/*.html') md5s = OrderedDict() for fil in sorted(files): - name = fil[len(base_dir):] + panel = panel_match.search(fil).groups(0)[0] with open(fil) as fp: md5 = hashlib.md5(fp.read().encode('utf-8')).hexdigest() - md5s[name] = md5 + md5s[panel] = md5 template = "FINGERPRINTS = {}\n" result = template.format(json.dumps(md5s, indent=4)) diff --git a/yarn.lock b/yarn.lock index 2e0ac4e4af..c0780ed7aa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2874,7 +2874,7 @@ etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" -event-stream@^3.0.20, event-stream@^3.3.1: +event-stream@^3.0.20, event-stream@^3.3.1, event-stream@latest: version "3.3.4" resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" dependencies: @@ -3657,6 +3657,12 @@ gulp-babel@^7.0.0: through2 "^2.0.0" vinyl-sourcemaps-apply "^0.2.0" +gulp-batch-replace@^0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/gulp-batch-replace/-/gulp-batch-replace-0.0.0.tgz#7e9826ad928862722c1eacb4421b4127bffd643e" + dependencies: + event-stream latest + gulp-file@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/gulp-file/-/gulp-file-0.3.0.tgz#e8c4d763f126fb3332fc416e3d1ef46ed67d8d0d"