From 3447fdc76ff9ec57a5f1c9922f9386a53ea9d645 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 3 Jul 2016 11:38:14 -0700 Subject: [PATCH] Make scripts available via CLI (#2426) * Rename sqlalchemy migrate script * Add script support to CLI --- homeassistant/__main__.py | 75 ++----------------- homeassistant/scripts/__init__.py | 22 ++++++ ...ert_db_to_sqlalchemy.py => db_migrator.py} | 23 +++--- homeassistant/scripts/macos.py | 64 ++++++++++++++++ 4 files changed, 105 insertions(+), 79 deletions(-) create mode 100644 homeassistant/scripts/__init__.py rename homeassistant/scripts/{convert_db_to_sqlalchemy.py => db_migrator.py} (94%) mode change 100755 => 100644 create mode 100644 homeassistant/scripts/macos.py diff --git a/homeassistant/__main__.py b/homeassistant/__main__.py index 186485973af3..d92c434d22b9 100644 --- a/homeassistant/__main__.py +++ b/homeassistant/__main__.py @@ -7,7 +7,6 @@ import platform import subprocess import sys import threading -import time from homeassistant.const import ( __version__, @@ -110,22 +109,14 @@ def get_arguments(): type=int, default=None, help='Enables daily log rotation and keeps up to the specified days') - parser.add_argument( - '--install-osx', - action='store_true', - help='Installs as a service on OS X and loads on boot.') - parser.add_argument( - '--uninstall-osx', - action='store_true', - help='Uninstalls from OS X.') - parser.add_argument( - '--restart-osx', - action='store_true', - help='Restarts on OS X.') parser.add_argument( '--runner', action='store_true', help='On restart exit with code {}'.format(RESTART_EXIT_CODE)) + parser.add_argument( + '--script', + nargs=argparse.REMAINDER, + help='Run one of the embedded scripts') if os.name == "posix": parser.add_argument( '--daemon', @@ -196,46 +187,6 @@ def write_pid(pid_file): sys.exit(1) -def install_osx(): - """Setup to run via launchd on OS X.""" - with os.popen('which hass') as inp: - hass_path = inp.read().strip() - - with os.popen('whoami') as inp: - user = inp.read().strip() - - cwd = os.path.dirname(__file__) - template_path = os.path.join(cwd, 'startup', 'launchd.plist') - - with open(template_path, 'r', encoding='utf-8') as inp: - plist = inp.read() - - plist = plist.replace("$HASS_PATH$", hass_path) - plist = plist.replace("$USER$", user) - - path = os.path.expanduser("~/Library/LaunchAgents/org.homeassistant.plist") - - try: - with open(path, 'w', encoding='utf-8') as outp: - outp.write(plist) - except IOError as err: - print('Unable to write to ' + path, err) - return - - os.popen('launchctl load -w -F ' + path) - - print("Home Assistant has been installed. \ - Open it here: http://localhost:8123") - - -def uninstall_osx(): - """Unload from launchd on OS X.""" - path = os.path.expanduser("~/Library/LaunchAgents/org.homeassistant.plist") - os.popen('launchctl unload ' + path) - - print("Home Assistant has been uninstalled.") - - def closefds_osx(min_fd, max_fd): """Make sure file descriptors get closed when we restart. @@ -358,23 +309,13 @@ def main(): args = get_arguments() + if args.script is not None: + from homeassistant import scripts + return scripts.run(args.script) + config_dir = os.path.join(os.getcwd(), args.config) ensure_config_path(config_dir) - # OS X launchd functions - if args.install_osx: - install_osx() - return 0 - if args.uninstall_osx: - uninstall_osx() - return 0 - if args.restart_osx: - uninstall_osx() - # A small delay is needed on some systems to let the unload finish. - time.sleep(0.5) - install_osx() - return 0 - # Daemon functions if args.pid_file: check_pid(args.pid_file) diff --git a/homeassistant/scripts/__init__.py b/homeassistant/scripts/__init__.py new file mode 100644 index 000000000000..a0e16efc7d11 --- /dev/null +++ b/homeassistant/scripts/__init__.py @@ -0,0 +1,22 @@ +"""Home Assistant command line scripts.""" +import importlib +import os + + +def run(args): + """Run a script.""" + scripts = [fil[:-3] for fil in os.listdir(os.path.dirname(__file__)) + if fil.endswith('.py') and fil != '__init__.py'] + + if not args: + print('Please specify a script to run.') + print('Available scripts:', ', '.join(scripts)) + return 1 + + if args[0] not in scripts: + print('Invalid script specified.') + print('Available scripts:', ', '.join(scripts)) + return 1 + + script = importlib.import_module('homeassistant.scripts.' + args[0]) + return script.run(args[1:]) diff --git a/homeassistant/scripts/convert_db_to_sqlalchemy.py b/homeassistant/scripts/db_migrator.py old mode 100755 new mode 100644 similarity index 94% rename from homeassistant/scripts/convert_db_to_sqlalchemy.py rename to homeassistant/scripts/db_migrator.py index 85104a7d38f2..b00ed163942a --- a/homeassistant/scripts/convert_db_to_sqlalchemy.py +++ b/homeassistant/scripts/db_migrator.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - """Script to convert an old-format home-assistant.db to a new format one.""" import argparse @@ -46,11 +44,11 @@ def print_progress(iteration, total, prefix='', suffix='', decimals=2, print("\n") -def main(): +def run(args): """The actual script body.""" # pylint: disable=too-many-locals,invalid-name,too-many-statements parser = argparse.ArgumentParser( - description="Home Assistant: Observe, Control, Automate.") + description="Migrate legacy DB to SQLAlchemy format.") parser.add_argument( '-c', '--config', metavar='path_to_config_dir', @@ -66,6 +64,9 @@ def main(): type=str, help="Connect to URI and import (implies --append)" "eg: mysql://localhost/homeassistant") + parser.add_argument( + '--script', + choices=['db_migrator']) args = parser.parse_args() @@ -76,7 +77,7 @@ def main(): if config_dir != config_util.get_default_config_dir(): print(('Fatal Error: Specified configuration directory does ' 'not exist {} ').format(config_dir)) - sys.exit(1) + return 1 else: config_dir = config_util.get_default_config_dir() @@ -86,13 +87,13 @@ def main(): if not os.path.exists(src_db): print("Fatal Error: Old format database '{}' does not exist".format( src_db)) - sys.exit(1) + return 1 if not args.uri and (os.path.exists(dst_db) and not args.append): print("Fatal Error: New format database '{}' exists already - " "Remove it or use --append".format(dst_db)) - print("Note: --append must maintain an ID mapping and is much slower") - print("and requires sufficient memory to track all event IDs") - sys.exit(1) + print("Note: --append must maintain an ID mapping and is much slower" + "and requires sufficient memory to track all event IDs") + return 1 conn = sqlite3.connect(src_db) uri = args.uri or "sqlite:///{}".format(dst_db) @@ -182,6 +183,4 @@ def main(): print_progress(n, num_rows) session.commit() c.close() - -if __name__ == "__main__": - main() + return 0 diff --git a/homeassistant/scripts/macos.py b/homeassistant/scripts/macos.py new file mode 100644 index 000000000000..e16d1f6c2726 --- /dev/null +++ b/homeassistant/scripts/macos.py @@ -0,0 +1,64 @@ +"""Script to install/uninstall HA into OS X.""" +import os +import time + + +def install_osx(): + """Setup to run via launchd on OS X.""" + with os.popen('which hass') as inp: + hass_path = inp.read().strip() + + with os.popen('whoami') as inp: + user = inp.read().strip() + + cwd = os.path.dirname(__file__) + template_path = os.path.join(cwd, 'startup', 'launchd.plist') + + with open(template_path, 'r', encoding='utf-8') as inp: + plist = inp.read() + + plist = plist.replace("$HASS_PATH$", hass_path) + plist = plist.replace("$USER$", user) + + path = os.path.expanduser("~/Library/LaunchAgents/org.homeassistant.plist") + + try: + with open(path, 'w', encoding='utf-8') as outp: + outp.write(plist) + except IOError as err: + print('Unable to write to ' + path, err) + return + + os.popen('launchctl load -w -F ' + path) + + print("Home Assistant has been installed. \ + Open it here: http://localhost:8123") + + +def uninstall_osx(): + """Unload from launchd on OS X.""" + path = os.path.expanduser("~/Library/LaunchAgents/org.homeassistant.plist") + os.popen('launchctl unload ' + path) + + print("Home Assistant has been uninstalled.") + + +def run(args): + """Handle OSX commandline script.""" + commands = 'install', 'uninstall', 'restart' + if not args or args[0] not in commands: + print('Invalid command. Available commands:', ', '.join(commands)) + return 1 + + if args[0] == 'install': + install_osx() + return 0 + elif args[0] == 'uninstall': + uninstall_osx() + return 0 + elif args[0] == 'restart': + uninstall_osx() + # A small delay is needed on some systems to let the unload finish. + time.sleep(0.5) + install_osx() + return 0