Skip to content

Commit

Permalink
Consolidate frontend (home-assistant#468)
Browse files Browse the repository at this point in the history
* Consolidate frontend

* Remove no longer needed cd

* Get Roboto from bower_components

* Remove external dependency from update_mdi.py

* Copy leaflet assets on build time

* Tweak Dockerfile

* Create Python package

* Set zip_safe to False

* Update build scripts

* Version bump to 20171021.0

* Fix service worker

* Version bump to 20171021.2

* Update docker ignore

* Tweak Dockerfile thanks to Adam
  • Loading branch information
balloob authored Oct 25, 2017
1 parent cbc4475 commit 417d8e7
Show file tree
Hide file tree
Showing 49 changed files with 3,084 additions and 11 deletions.
6 changes: 6 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules
bower_components
hass_frontend
build
build-temp
.git
15 changes: 15 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,18 @@ node_modules/*
bower_components/*
npm-debug.log
.DS_Store
hass_frontend/*

# Python stuff
*.py[cod]
*.egg
*.egg-info

# venv stuff
pyvenv.cfg
pip-selfcheck.json
venv
.venv
lib
bin
dist
25 changes: 25 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
FROM node:8.2.1-alpine

# install yarn
ENV PATH /root/.yarn/bin:$PATH

RUN apk update \
&& apk add curl bash binutils tar git python3 \
&& rm -rf /var/cache/apk/* \
&& /bin/bash \
&& touch ~/.bashrc \
&& curl -o- -L https://yarnpkg.com/install.sh | bash

RUN mkdir -p /frontend
WORKDIR /frontend

ENV NODE_ENV production

COPY package.json ./
RUN yarn

COPY bower.json ./
RUN ./node_modules/.bin/bower install --allow-root

COPY . .
CMD [ "/bin/bash", "./script/build_frontend" ]
4 changes: 4 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
include README.md
include LICENSE.md
graft hass_frontend
recursive-exclude * *.py[co]
12 changes: 7 additions & 5 deletions gulp/tasks/gen-service-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const config = require('../config');

const DEV = !!JSON.parse(process.env.BUILD_DEV || 'true');

var rootDir = '..';
var rootDir = 'hass_frontend';
var panelDir = path.resolve(rootDir, 'panels');

var dynamicUrlToDependencies = {
Expand All @@ -44,8 +44,8 @@ var staticFingerprinted = [
// These panels will always be registered inside HA and thus can
// be safely assumed to be able to preload.
var panelsFingerprinted = [
'map', 'dev-event', 'dev-info', 'dev-service', 'dev-state', 'dev-template',
'dev-mqtt',
'dev-event', 'dev-info', 'dev-service', 'dev-state', 'dev-template',
'dev-mqtt', 'kiosk',
];

function md5(filename) {
Expand All @@ -71,7 +71,7 @@ gulp.task('gen-service-worker', () => {
panelsFingerprinted.forEach(panel => {
var fpath = panelDir + '/ha-panel-' + panel + '.html';
var hash = md5(fpath);
var url = '/frontend/panels/' + panel + '-' + hash + '.html';
var url = '/static/panels/ha-panel-' + panel + '-' + hash + '.html';
dynamicUrlToDependencies[url] = [fpath];
});

Expand All @@ -89,9 +89,11 @@ gulp.task('gen-service-worker', () => {
rootDir + '/fonts/roboto/Roboto-Bold.ttf',
rootDir + '/images/card_media_player_bg.png',
],
stripPrefix: '..',
stripPrefix: 'hass_frontend',
replacePrefix: 'static',
verbose: true,
// Allow our users to refresh to get latest version.
clientsClaim: true,
};

genPromise = swPrecache.generate(options);
Expand Down
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@
"author": "Paulus Schoutsen <Paulus@PaulusSchoutsen.nl> (http://paulusschoutsen.nl)",
"license": "Apache-2.0",
"dependencies": {
"es6-object-assign": "^1.1.0",
"home-assistant-js-websocket": "^1.1.0",
"preact": "^8.2.5"
},
"devDependencies": {
"babel-core": "^6.26.0",
"babel-plugin-external-helpers": "^6.22.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
Expand All @@ -34,6 +29,7 @@
"bower": "^1.8.2",
"css-slam": "^2.0.2",
"del": "^3.0.0",
"es6-object-assign": "^1.1.0",
"eslint": "^4.8.0",
"eslint-config-airbnb-base": "^12.0.2",
"eslint-plugin-html": "^3.2.2",
Expand All @@ -49,13 +45,15 @@
"gulp-rollup-each": "^2.0.0",
"gulp-uglify": "^3.0.0",
"gulp-util": "^3.0.8",
"home-assistant-js-websocket": "^1.1.0",
"html-minifier": "^3.5.5",
"merge-stream": "^1.0.1",
"parse5": "^3.0.2",
"polymer-analyzer": "^2.3.0",
"polymer-build": "^2.1.0",
"polymer-bundler": "^3.1.0",
"polymer-cli": "^1.5.6",
"preact": "^8.2.5",
"require-dir": "^0.3.2",
"rollup": "^0.50.0",
"rollup-plugin-babel": "^3.0.2",
Expand All @@ -67,7 +65,9 @@
"run-sequence": "^2.2.0",
"sw-precache": "^5.2.0",
"uglify-js": "^3.1.3",
"vulcanize": "^1.16.0",
"vulcanize": "^1.16.0"
},
"devDependencies": {
"web-component-tester": "^6.3.0"
}
}
8 changes: 8 additions & 0 deletions public/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""AUTO-GENERATED. DO NOT MODIFY"""
import os


def where():
"""Return path to the frontend."""
return os.path.dirname(__file__)

Binary file added public/icons/favicon-1024x1024.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/icons/favicon-192x192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/icons/favicon-384x384.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/icons/favicon-512x512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/icons/favicon-apple-180x180.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/icons/favicon.ico
Binary file not shown.
2,814 changes: 2,814 additions & 0 deletions public/icons/home-assistant-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/icons/tile-win-150x150.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/icons/tile-win-310x150.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/icons/tile-win-310x310.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/icons/tile-win-70x70.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/card_media_player_bg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/config_ecobee_thermostat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/config_fitbit_app.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/config_icloud.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/config_insteon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/config_philips_hue.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/config_webos.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/config_wink.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/images/darksky/weather-cloudy.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/images/darksky/weather-fog.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/images/darksky/weather-hail.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/images/darksky/weather-night.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/images/darksky/weather-partlycloudy.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/images/darksky/weather-pouring.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/images/darksky/weather-rainy.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/images/darksky/weather-snowy.svg
1 change: 1 addition & 0 deletions public/images/darksky/weather-sunny.svg
1 change: 1 addition & 0 deletions public/images/darksky/weather-windy.svg
Binary file added public/images/logo_automatic.png
Binary file added public/images/logo_axis.png
Binary file added public/images/logo_philips_hue.png
Binary file added public/images/logo_plex_mediaserver.png
Binary file added public/images/notification-badge.png
Binary file added public/images/smart-tv.png
2 changes: 2 additions & 0 deletions public/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
User-agent: *
Disallow: /
16 changes: 16 additions & 0 deletions script/bootstrap
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/sh
# Resolve all frontend dependencies that the application requires to develop.

# Stop on errors
set -e

cd "$(dirname "$0")/.."

# Install node modules
yarn install

# Install bower web components. Allow to download the components as root since the user in docker is root.
./node_modules/.bin/bower install --allow-root

# Build files that need to be generated to run development mode
yarn dev
54 changes: 54 additions & 0 deletions script/build_frontend
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/bin/sh
# Builds the frontend for production

# Stop on errors
set -e

cd "$(dirname "$0")/.."

OUTPUT_DIR=hass_frontend

rm -rf $OUTPUT_DIR
cp -r public $OUTPUT_DIR

# Build frontend
BUILD_DEV=0 ./node_modules/.bin/gulp

# Entry points
cp build/*.js build/*.html $OUTPUT_DIR

# Panels
mkdir $OUTPUT_DIR/panels
cp build/panels/*.html $OUTPUT_DIR/panels

# Local Roboto
cp -r bower_components/font-roboto-local/fonts $OUTPUT_DIR

# Polyfill web components
cp bower_components/webcomponentsjs/webcomponents-lite.js $OUTPUT_DIR
cp bower_components/webcomponentsjs/custom-elements-es5-adapter.js $OUTPUT_DIR

# Icons
script/update_mdi.py

# Leaflet
mkdir $OUTPUT_DIR/images/leaflet
cp bower_components/leaflet/dist/leaflet.css $OUTPUT_DIR/images/leaflet
cp -r bower_components/leaflet/dist/images $OUTPUT_DIR/images/leaflet/

# Generate service worker
BUILD_DEV=0 ./node_modules/.bin/gulp gen-service-worker
cp build/service_worker.js $OUTPUT_DIR


# GZIP frontend
cd $OUTPUT_DIR
gzip -f -n -k -9 *.html *.js ./panels/*.html ./fonts/roboto/*.ttf ./fonts/robotomono/*.ttf
cd ..

# Generate the __init__ file
echo "VERSION = '`git rev-parse HEAD`'" >> $OUTPUT_DIR/__init__.py
echo "CREATED_AT = `date +%s`" >> $OUTPUT_DIR/__init__.py

# Generate the MD5 hash of the new frontend
script/fingerprint_frontend.py
36 changes: 36 additions & 0 deletions script/fingerprint_frontend.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env python3
"""Generate a file with all md5 hashes of the assets."""

from collections import OrderedDict
import glob
import hashlib
import json

fingerprint_file = './hass_frontend/__init__.py'
base_dir = 'hass_frontend/'


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'))

md5s = OrderedDict()

for fil in sorted(files):
name = fil[len(base_dir):]
with open(fil) as fp:
md5 = hashlib.md5(fp.read().encode('utf-8')).hexdigest()
md5s[name] = md5

template = "FINGERPRINTS = {}\n"
result = template.format(json.dumps(md5s, indent=4))

with open(fingerprint_file, 'at') as fp:
fp.write(result)


if __name__ == '__main__':
fingerprint()
6 changes: 6 additions & 0 deletions script/release
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh
# Pushes a new version to PyPi.

cd "$(dirname "$0")/.."

python3 setup.py sdist upload
63 changes: 63 additions & 0 deletions script/update_mdi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/usr/bin/env python3
"""Download the latest Polymer v1 iconset for materialdesignicons.com."""
import os
import re
import sys
import urllib.request

GETTING_STARTED_URL = ('https://raw.githubusercontent.com/Templarian/'
'MaterialDesign/master/site/getting-started.savvy')
DOWNLOAD_LINK = re.compile(r'(/api/download/polymer/v1/([A-Z0-9-]{36}))')
START_ICONSET = '<iron-iconset-svg'

OUTPUT_BASE = 'hass_frontend'
ICONSET_OUTPUT = os.path.join(OUTPUT_BASE, 'mdi.html')


def get_text(url):
with urllib.request.urlopen(url) as f:
return f.read().decode('utf-8')


def get_remote_version():
"""Get current version and download link."""
gs_page = get_text(GETTING_STARTED_URL)

mdi_download = re.search(DOWNLOAD_LINK, gs_page)

if not mdi_download:
print("Unable to find download link")
sys.exit()

return 'https://materialdesignicons.com' + mdi_download.group(1)


def clean_component(source):
"""Clean component."""
return source[source.index(START_ICONSET):]


def write_component(source):
"""Write component."""
with open(ICONSET_OUTPUT, 'w') as outp:
print('Writing icons to', ICONSET_OUTPUT)
outp.write(source)


def main():
"""Main section of the script."""
# All scripts should have their current work dir set to project root
if os.path.basename(os.getcwd()) == 'script':
os.chdir('..')

print("materialdesignicons.com icon updater")

remote_url = get_remote_version()
source = clean_component(get_text(remote_url))
write_component(source)

print('Updated to latest version')


if __name__ == '__main__':
main()
12 changes: 12 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from setuptools import setup, find_packages

setup(name='home-assistant-frontend',
version='20171021.2',
description='The Home Assistant frontend',
url='https://github.com/home-assistant/home-assistant-polymer',
author='Paulus Schoutsen',
author_email='Paulus@PaulusSchoutsen.nl',
license='Apache License 2.0',
packages=find_packages(include=['hass_frontend', 'hass_frontend.*']),
include_package_data=True,
zip_safe=False)

0 comments on commit 417d8e7

Please sign in to comment.