Add support for dynamic frontend panels
|
@ -1,37 +1,112 @@
|
|||
"""Handle the frontend for Home Assistant."""
|
||||
import logging
|
||||
import os
|
||||
|
||||
from homeassistant.const import EVENT_HOMEASSISTANT_START
|
||||
from homeassistant.components import api
|
||||
from homeassistant.components.http import HomeAssistantView
|
||||
from . import version, mdi_version
|
||||
from .version import FINGERPRINTS
|
||||
|
||||
DOMAIN = 'frontend'
|
||||
DEPENDENCIES = ['api']
|
||||
PANELS = {}
|
||||
URL_PANEL_COMPONENT = '/frontend/panels/{}.html'
|
||||
URL_PANEL_COMPONENT_FP = '/frontend/panels/{}-{}.html'
|
||||
STATIC_PATH = os.path.join(os.path.dirname(__file__), 'www_static')
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def register_built_in_panel(hass, component_name, title=None, icon=None,
|
||||
url_name=None, config=None):
|
||||
"""Register a built-in panel."""
|
||||
|
||||
path = 'panels/ha-panel-{}.html'.format(component_name)
|
||||
|
||||
register_panel(hass, component_name, os.path.join(STATIC_PATH, path),
|
||||
FINGERPRINTS[path], title, icon, url_name, config)
|
||||
|
||||
|
||||
def register_panel(hass, component_name, path, md5, title=None, icon=None,
|
||||
url_name=None, config=None):
|
||||
"""Register a panel for the frontend.
|
||||
|
||||
component_name: name of the web component
|
||||
path: path to the HTML of the web component
|
||||
md5: the md5 hash of the web component (for versioning)
|
||||
title: title to show in the sidebar (optional)
|
||||
icon: icon to show next to title in sidebar (optional)
|
||||
url_name: name to use in the url (defaults to component_name)
|
||||
config: config to be passed into the web component
|
||||
|
||||
Warning: this API will probably change. Use at own risk.
|
||||
"""
|
||||
if url_name is None:
|
||||
url_name = component_name
|
||||
|
||||
if url_name in PANELS:
|
||||
_LOGGER.warning('Overwriting component %s', url_name)
|
||||
if not os.path.isfile(path):
|
||||
_LOGGER.warning('Panel %s component does not exist: %s',
|
||||
component_name, path)
|
||||
|
||||
data = {
|
||||
'url_name': url_name,
|
||||
'component_name': component_name,
|
||||
}
|
||||
|
||||
if title:
|
||||
data['title'] = title
|
||||
if icon:
|
||||
data['icon'] = icon
|
||||
if config is not None:
|
||||
data['config'] = config
|
||||
|
||||
if hass.wsgi.development:
|
||||
data['url'] = ('/static/home-assistant-polymer/panels/'
|
||||
'{0}/ha-panel-{0}.html'.format(component_name))
|
||||
else:
|
||||
url = URL_PANEL_COMPONENT.format(component_name)
|
||||
fprinted_url = URL_PANEL_COMPONENT_FP.format(component_name, md5)
|
||||
hass.wsgi.register_static_path(url, path)
|
||||
data['url'] = fprinted_url
|
||||
|
||||
PANELS[url_name] = data
|
||||
|
||||
# TODO register /<component_name> to index view.
|
||||
|
||||
|
||||
def setup(hass, config):
|
||||
"""Setup serving the frontend."""
|
||||
hass.wsgi.register_view(IndexView)
|
||||
hass.wsgi.register_view(BootstrapView)
|
||||
|
||||
www_static_path = os.path.join(os.path.dirname(__file__), 'www_static')
|
||||
if hass.wsgi.development:
|
||||
sw_path = "home-assistant-polymer/build/service_worker.js"
|
||||
else:
|
||||
sw_path = "service_worker.js"
|
||||
|
||||
hass.wsgi.register_static_path(
|
||||
"/service_worker.js",
|
||||
os.path.join(www_static_path, sw_path),
|
||||
0
|
||||
)
|
||||
hass.wsgi.register_static_path(
|
||||
"/robots.txt",
|
||||
os.path.join(www_static_path, "robots.txt")
|
||||
)
|
||||
hass.wsgi.register_static_path("/static", www_static_path)
|
||||
hass.wsgi.register_static_path("/service_worker.js",
|
||||
os.path.join(STATIC_PATH, sw_path), 0)
|
||||
hass.wsgi.register_static_path("/robots.txt",
|
||||
os.path.join(STATIC_PATH, "robots.txt"))
|
||||
hass.wsgi.register_static_path("/static", STATIC_PATH)
|
||||
hass.wsgi.register_static_path("/local", hass.config.path('www'))
|
||||
|
||||
register_built_in_panel(hass, 'map', 'Map', 'mdi:account-location')
|
||||
|
||||
for panel in ('dev-event', 'dev-info', 'dev-service', 'dev-state',
|
||||
'dev-template'):
|
||||
register_built_in_panel(hass, panel)
|
||||
|
||||
def register_frontend_index(event):
|
||||
"""Register the frontend index urls.
|
||||
|
||||
Done when Home Assistant is started so that all panels are known.
|
||||
"""
|
||||
hass.wsgi.register_view(IndexView(
|
||||
hass, ['/{}'.format(name) for name in PANELS]))
|
||||
|
||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_START, register_frontend_index)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
|
@ -48,6 +123,7 @@ class BootstrapView(HomeAssistantView):
|
|||
'states': self.hass.states.all(),
|
||||
'events': api.events_json(self.hass),
|
||||
'services': api.services_json(self.hass),
|
||||
'panels': PANELS,
|
||||
})
|
||||
|
||||
|
||||
|
@ -57,16 +133,15 @@ class IndexView(HomeAssistantView):
|
|||
url = '/'
|
||||
name = "frontend:index"
|
||||
requires_auth = False
|
||||
extra_urls = ['/logbook', '/history', '/map', '/devService', '/devState',
|
||||
'/devEvent', '/devInfo', '/devTemplate',
|
||||
'/states', '/states/<entity:entity_id>']
|
||||
extra_urls = ['/states', '/states/<entity:entity_id>']
|
||||
|
||||
def __init__(self, hass):
|
||||
def __init__(self, hass, extra_urls):
|
||||
"""Initialize the frontend view."""
|
||||
super().__init__(hass)
|
||||
|
||||
from jinja2 import FileSystemLoader, Environment
|
||||
|
||||
self.extra_urls = self.extra_urls + extra_urls
|
||||
self.templates = Environment(
|
||||
loader=FileSystemLoader(
|
||||
os.path.join(os.path.dirname(__file__), 'templates/')
|
||||
|
@ -76,32 +151,24 @@ class IndexView(HomeAssistantView):
|
|||
def get(self, request, entity_id=None):
|
||||
"""Serve the index view."""
|
||||
if self.hass.wsgi.development:
|
||||
core_url = '/static/home-assistant-polymer/build/_core_compiled.js'
|
||||
core_url = '/static/home-assistant-polymer/build/core.js'
|
||||
ui_url = '/static/home-assistant-polymer/src/home-assistant.html'
|
||||
map_url = ('/static/home-assistant-polymer/src/layouts/'
|
||||
'partial-map.html')
|
||||
dev_url = ('/static/home-assistant-polymer/src/entry-points/'
|
||||
'dev-tools.html')
|
||||
else:
|
||||
core_url = '/static/core-{}.js'.format(version.CORE)
|
||||
ui_url = '/static/frontend-{}.html'.format(version.UI)
|
||||
map_url = '/static/partial-map-{}.html'.format(version.MAP)
|
||||
dev_url = '/static/dev-tools-{}.html'.format(version.DEV)
|
||||
core_url = '/static/core-{}.js'.format(
|
||||
FINGERPRINTS['core.js'])
|
||||
ui_url = '/static/frontend-{}.html'.format(
|
||||
FINGERPRINTS['frontend.html'])
|
||||
|
||||
# auto login if no password was set
|
||||
if self.hass.config.api.api_password is None:
|
||||
auth = 'true'
|
||||
else:
|
||||
auth = 'false'
|
||||
|
||||
icons_url = '/static/mdi-{}.html'.format(mdi_version.VERSION)
|
||||
no_auth = 'false' if self.hass.config.api.api_password else 'true'
|
||||
|
||||
icons_url = '/static/mdi-{}.html'.format(FINGERPRINTS['mdi.html'])
|
||||
template = self.templates.get_template('index.html')
|
||||
|
||||
# pylint is wrong
|
||||
# pylint: disable=no-member
|
||||
resp = template.render(
|
||||
core_url=core_url, ui_url=ui_url, map_url=map_url, auth=auth,
|
||||
dev_url=dev_url, icons_url=icons_url, icons=mdi_version.VERSION)
|
||||
core_url=core_url, ui_url=ui_url, no_auth=no_auth,
|
||||
icons_url=icons_url, icons=FINGERPRINTS['mdi.html'])
|
||||
|
||||
return self.Response(resp, mimetype='text/html')
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
"""DO NOT MODIFY. Auto-generated by update_mdi script."""
|
||||
VERSION = "758957b7ea989d6beca60e218ea7f7dd"
|
|
@ -5,14 +5,14 @@
|
|||
<title>Home Assistant</title>
|
||||
|
||||
<link rel='manifest' href='/static/manifest.json'>
|
||||
<link rel='icon' href='/static/favicon.ico'>
|
||||
<link rel='icon' href='/static/icons/favicon.ico'>
|
||||
<link rel='apple-touch-icon' sizes='180x180'
|
||||
href='/static/favicon-apple-180x180.png'>
|
||||
href='/static/icons/favicon-apple-180x180.png'>
|
||||
<meta name='apple-mobile-web-app-capable' content='yes'>
|
||||
<meta name="msapplication-square70x70logo" content="/static/tile-win-70x70.png"/>
|
||||
<meta name="msapplication-square150x150logo" content="/static/tile-win-150x150.png"/>
|
||||
<meta name="msapplication-wide310x150logo" content="/static/tile-win-310x150.png"/>
|
||||
<meta name="msapplication-square310x310logo" content="/static/tile-win-310x310.png"/>
|
||||
<meta name="msapplication-square70x70logo" content="/static/icons/tile-win-70x70.png"/>
|
||||
<meta name="msapplication-square150x150logo" content="/static/icons/tile-win-150x150.png"/>
|
||||
<meta name="msapplication-wide310x150logo" content="/static/icons/tile-win-310x150.png"/>
|
||||
<meta name="msapplication-square310x310logo" content="/static/icons/tile-win-310x310.png"/>
|
||||
<meta name="msapplication-TileColor" content="#3fbbf4ff"/>
|
||||
<meta name='mobile-web-app-capable' content='yes'>
|
||||
<meta name='viewport' content='width=device-width, user-scalable=no'>
|
||||
|
@ -65,16 +65,12 @@
|
|||
.getElementById('ha-init-skeleton')
|
||||
.classList.add('error');
|
||||
};
|
||||
window.noAuth = {{ auth }};
|
||||
window.deferredLoading = {
|
||||
map: '{{ map_url }}',
|
||||
dev: '{{ dev_url }}',
|
||||
};
|
||||
window.noAuth = {{ no_auth }};
|
||||
</script>
|
||||
</head>
|
||||
<body fullbleed>
|
||||
<div id='ha-init-skeleton'>
|
||||
<img src='/static/favicon-192x192.png' height='192'>
|
||||
<img src='/static/icons/favicon-192x192.png' height='192'>
|
||||
<paper-spinner active></paper-spinner>
|
||||
Home Assistant had trouble<br>connecting to the server.<br><br><a href='/'>TRY AGAIN</a>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,24 @@
|
|||
<<<<<<< HEAD
|
||||
"""DO NOT MODIFY. Auto-generated by build_frontend script."""
|
||||
CORE = "7d80cc0e4dea6bc20fa2889be0b3cd15"
|
||||
UI = "805f8dda70419b26daabc8e8f625127f"
|
||||
MAP = "c922306de24140afd14f857f927bf8f0"
|
||||
DEV = "b7079ac3121b95b9856e5603a6d8a263"
|
||||
=======
|
||||
"""DO NOT MODIFY. Auto-generated by script/fingerprint_frontend."""
|
||||
|
||||
FINGERPRINTS = {
|
||||
"core.js": "4783ccdb2f15d3a63fcab9be411629b7",
|
||||
"frontend.html": "6c50bcdd8c8b7d840bc2cdef02e9ee39",
|
||||
"mdi.html": "a7fa9237b7da93951076b4fe26cb8cd2",
|
||||
"panels/ha-panel-dev-event.html": "f1f47bf3f0e305f855a99dd1ee788045",
|
||||
"panels/ha-panel-dev-info.html": "50a7817f60675feef3e4c9aa9a043fe1",
|
||||
"panels/ha-panel-dev-service.html": "d507e0018faf73d58a1fdeb2a0368505",
|
||||
"panels/ha-panel-dev-state.html": "6a4418826419f235fd9fcc5e952e858c",
|
||||
"panels/ha-panel-dev-template.html": "cc8917fdad5a4fc81cc1d4104ea0d2dc",
|
||||
"panels/ha-panel-history.html": "999ecb591df76d6a4aba1fe84e04baf1",
|
||||
"panels/ha-panel-iframe.html": "f4aaaf31321cd8bfb57755c24af7fc31",
|
||||
"panels/ha-panel-logbook.html": "6dde7050246875774ec9fce60df05442",
|
||||
"panels/ha-panel-map.html": "d2cf412d52f43431307bbc2e216be9c9"
|
||||
}
|
||||
>>>>>>> Add support for dynamic frontend panels
|
||||
|
|
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 93 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.2 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
|
@ -7,22 +7,22 @@
|
|||
"background_color": "#FFFFFF",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/static/favicon-192x192.png",
|
||||
"src": "/static/icons/favicon-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/favicon-384x384.png",
|
||||
"src": "/static/icons/favicon-384x384.png",
|
||||
"sizes": "384x384",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/favicon-512x512.png",
|
||||
"src": "/static/icons/favicon-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/static/favicon-1024x1024.png",
|
||||
"src": "/static/icons/favicon-1024x1024.png",
|
||||
"sizes": "1024x1024",
|
||||
"type": "image/png"
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ from itertools import groupby
|
|||
|
||||
import homeassistant.util.dt as dt_util
|
||||
from homeassistant.components import recorder, script
|
||||
from homeassistant.components.frontend import register_built_in_panel
|
||||
from homeassistant.components.http import HomeAssistantView
|
||||
|
||||
DOMAIN = 'history'
|
||||
|
@ -153,6 +154,7 @@ def setup(hass, config):
|
|||
"""Setup the history hooks."""
|
||||
hass.wsgi.register_view(Last5StatesView)
|
||||
hass.wsgi.register_view(HistoryPeriodView)
|
||||
register_built_in_panel(hass, 'history', 'History', 'mdi:poll-box')
|
||||
|
||||
return True
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import voluptuous as vol
|
|||
import homeassistant.helpers.config_validation as cv
|
||||
import homeassistant.util.dt as dt_util
|
||||
from homeassistant.components import recorder, sun
|
||||
from homeassistant.components.frontend import register_built_in_panel
|
||||
from homeassistant.components.http import HomeAssistantView
|
||||
from homeassistant.const import (EVENT_HOMEASSISTANT_START,
|
||||
EVENT_HOMEASSISTANT_STOP, EVENT_STATE_CHANGED,
|
||||
|
@ -24,7 +25,7 @@ from homeassistant.helpers import template
|
|||
from homeassistant.helpers.entity import split_entity_id
|
||||
|
||||
DOMAIN = "logbook"
|
||||
DEPENDENCIES = ['recorder', 'http']
|
||||
DEPENDENCIES = ['recorder', 'frontend']
|
||||
|
||||
URL_LOGBOOK = re.compile(r'/api/logbook(?:/(?P<date>\d{4}-\d{1,2}-\d{1,2})|)')
|
||||
|
||||
|
@ -75,6 +76,9 @@ def setup(hass, config):
|
|||
|
||||
hass.wsgi.register_view(LogbookView)
|
||||
|
||||
register_built_in_panel(hass, 'logbook', 'Logbook',
|
||||
'mdi:format-list-bulleted-type')
|
||||
|
||||
hass.services.register(DOMAIN, 'log', log_message,
|
||||
schema=LOG_MESSAGE_SCHEMA)
|
||||
return True
|
||||
|
|
|
@ -2,36 +2,21 @@
|
|||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
cd homeassistant/components/frontend/www_static/home-assistant-polymer
|
||||
cd homeassistant/components/frontend/www_static
|
||||
rm -rf core.js* frontend.html* webcomponents-lite.min.js* panels
|
||||
cd home-assistant-polymer
|
||||
npm run clean
|
||||
npm run frontend_prod
|
||||
|
||||
cp bower_components/webcomponentsjs/webcomponents-lite.min.js ..
|
||||
cp build/frontend.html ..
|
||||
gzip build/frontend.html -c -k -9 > ../frontend.html.gz
|
||||
cp build/partial-map.html ..
|
||||
gzip build/partial-map.html -c -k -9 > ../partial-map.html.gz
|
||||
cp build/dev-tools.html ..
|
||||
gzip build/dev-tools.html -c -k -9 > ../dev-tools.html.gz
|
||||
cp build/_core_compiled.js ../core.js
|
||||
gzip build/_core_compiled.js -c -k -9 > ../core.js.gz
|
||||
|
||||
cp -r build/* ..
|
||||
node script/sw-precache.js
|
||||
cp build/service_worker.js ..
|
||||
gzip build/service_worker.js -c -k -9 > ../service_worker.js.gz
|
||||
|
||||
cd ..
|
||||
|
||||
gzip -f -k -9 *.html *.js ./panels/*.html
|
||||
|
||||
# Generate the MD5 hash of the new frontend
|
||||
cd ../..
|
||||
echo '"""DO NOT MODIFY. Auto-generated by build_frontend script."""' > version.py
|
||||
if [ $(command -v md5) ]; then
|
||||
echo 'CORE = "'`md5 -q www_static/core.js`'"' >> version.py
|
||||
echo 'UI = "'`md5 -q www_static/frontend.html`'"' >> version.py
|
||||
echo 'MAP = "'`md5 -q www_static/partial-map.html`'"' >> version.py
|
||||
echo 'DEV = "'`md5 -q www_static/dev-tools.html`'"' >> version.py
|
||||
elif [ $(command -v md5sum) ]; then
|
||||
echo 'CORE = "'`md5sum www_static/core.js | cut -c-32`'"' >> version.py
|
||||
echo 'UI = "'`md5sum www_static/frontend.html | cut -c-32`'"' >> version.py
|
||||
echo 'MAP = "'`md5sum www_static/partial-map.html | cut -c-32`'"' >> version.py
|
||||
echo 'DEV = "'`md5sum www_static/dev-tools.html | cut -c-32`'"' >> version.py
|
||||
else
|
||||
echo 'Could not find an MD5 utility'
|
||||
fi
|
||||
cd ../../../..
|
||||
script/fingerprint_frontend.py
|
||||
|
|
37
script/fingerprint_frontend.py
Executable file
|
@ -0,0 +1,37 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from collections import OrderedDict
|
||||
import glob
|
||||
import hashlib
|
||||
import json
|
||||
|
||||
fingerprint_file = 'homeassistant/components/frontend/version.py'
|
||||
base_dir = 'homeassistant/components/frontend/www_static/'
|
||||
|
||||
|
||||
def fingerprint():
|
||||
"""Fingerprint the frontend files."""
|
||||
files = (glob.glob(base_dir + '**/*.html') +
|
||||
glob.glob(base_dir + '*.html') +
|
||||
glob.glob(base_dir + 'core.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 = """\"\"\"DO NOT MODIFY. Auto-generated by script/fingerprint_frontend.\"\"\"
|
||||
|
||||
FINGERPRINTS = {}
|
||||
"""
|
||||
|
||||
result = template.format(json.dumps(md5s, indent=4))
|
||||
|
||||
with open(fingerprint_file, 'w') as fp:
|
||||
fp.write(result)
|
||||
|
||||
if __name__ == '__main__':
|
||||
fingerprint()
|
|
@ -1,38 +1,24 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
"""Download the latest Polymer v1 iconset for materialdesignicons.com."""
|
||||
import hashlib
|
||||
import gzip
|
||||
import os
|
||||
import re
|
||||
import requests
|
||||
import sys
|
||||
|
||||
from fingerprint_frontend import fingerprint
|
||||
|
||||
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'
|
||||
|
||||
CUR_VERSION = re.compile(r'VERSION = "([A-Za-z0-9]{32})"')
|
||||
|
||||
OUTPUT_BASE = os.path.join('homeassistant', 'components', 'frontend')
|
||||
VERSION_OUTPUT = os.path.join(OUTPUT_BASE, 'mdi_version.py')
|
||||
ICONSET_OUTPUT = os.path.join(OUTPUT_BASE, 'www_static', 'mdi.html')
|
||||
ICONSET_OUTPUT_GZ = os.path.join(OUTPUT_BASE, 'www_static', 'mdi.html.gz')
|
||||
|
||||
|
||||
def get_local_version():
|
||||
"""Parse the local version."""
|
||||
try:
|
||||
with open(VERSION_OUTPUT) as inp:
|
||||
for line in inp:
|
||||
match = CUR_VERSION.search(line)
|
||||
if match:
|
||||
return match.group(1)
|
||||
except FileNotFoundError:
|
||||
return False
|
||||
return False
|
||||
|
||||
|
||||
def get_remote_version():
|
||||
"""Get current version and download link."""
|
||||
gs_page = requests.get(GETTING_STARTED_URL).text
|
||||
|
@ -43,10 +29,7 @@ def get_remote_version():
|
|||
print("Unable to find download link")
|
||||
sys.exit()
|
||||
|
||||
url = 'https://materialdesignicons.com' + mdi_download.group(1)
|
||||
version = mdi_download.group(2).replace('-', '')
|
||||
|
||||
return version, url
|
||||
return 'https://materialdesignicons.com' + mdi_download.group(1)
|
||||
|
||||
|
||||
def clean_component(source):
|
||||
|
@ -54,7 +37,7 @@ def clean_component(source):
|
|||
return source[source.index(START_ICONSET):]
|
||||
|
||||
|
||||
def write_component(version, source):
|
||||
def write_component(source):
|
||||
"""Write component."""
|
||||
with open(ICONSET_OUTPUT, 'w') as outp:
|
||||
print('Writing icons to', ICONSET_OUTPUT)
|
||||
|
@ -64,12 +47,6 @@ def write_component(version, source):
|
|||
print('Writing icons gz to', ICONSET_OUTPUT_GZ)
|
||||
outp.write(source.encode('utf-8'))
|
||||
|
||||
with open(VERSION_OUTPUT, 'w') as outp:
|
||||
print('Generating version file', VERSION_OUTPUT)
|
||||
outp.write(
|
||||
'"""DO NOT MODIFY. Auto-generated by update_mdi script."""\n')
|
||||
outp.write('VERSION = "{}"\n'.format(version))
|
||||
|
||||
|
||||
def main():
|
||||
"""Main section of the script."""
|
||||
|
@ -79,19 +56,11 @@ def main():
|
|||
|
||||
print("materialdesignicons.com icon updater")
|
||||
|
||||
local_version = get_local_version()
|
||||
|
||||
# The remote version is not reliable.
|
||||
_, remote_url = get_remote_version()
|
||||
|
||||
remote_url = get_remote_version()
|
||||
source = clean_component(requests.get(remote_url).text)
|
||||
new_version = hashlib.md5(source.encode('utf-8')).hexdigest()
|
||||
write_component(source)
|
||||
fingerprint()
|
||||
|
||||
if local_version == new_version:
|
||||
print('Already on the latest version.')
|
||||
sys.exit()
|
||||
|
||||
write_component(new_version, source)
|
||||
print('Updated to latest version')
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -7,7 +7,7 @@ import unittest
|
|||
import requests
|
||||
|
||||
import homeassistant.bootstrap as bootstrap
|
||||
import homeassistant.components.http as http
|
||||
from homeassistant.components import frontend, http
|
||||
from homeassistant.const import HTTP_HEADER_HA_AUTH
|
||||
|
||||
from tests.common import get_test_instance_port, get_test_home_assistant
|
||||
|
@ -48,6 +48,7 @@ def setUpModule(): # pylint: disable=invalid-name
|
|||
def tearDownModule(): # pylint: disable=invalid-name
|
||||
"""Stop everything that was started."""
|
||||
hass.stop()
|
||||
frontend.PANELS = {}
|
||||
|
||||
|
||||
class TestFrontend(unittest.TestCase):
|
||||
|
|