From 332f7621ce7c3feda64aea3b8782b0c8e6e2ee63 Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Tue, 15 Sep 2015 01:06:31 -0400 Subject: [PATCH 01/18] launchd script for loading HA at boot and background on OS X --- scripts/org.home-assistant.plist | 39 ++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 scripts/org.home-assistant.plist diff --git a/scripts/org.home-assistant.plist b/scripts/org.home-assistant.plist new file mode 100644 index 00000000000..b445852e05f --- /dev/null +++ b/scripts/org.home-assistant.plist @@ -0,0 +1,39 @@ + + + + + Label + org.home-assitant + + EnvironmentVariables + + PATH + /usr/local/bin/:/usr/bin:$PATH + + + Program + %HASS_PATH% + + AbandonProcessGroup + + + RunAtLoad + + + KeepAlive + + SuccessfulExit + + + + WorkingDirectory + %PATH% + + StandardErrorPath + /Users/%USER%/Library/Logs/home-assitant.log + + StandardOutPath + /Users/%USER%/Library/Logs/home-assitant.log + + + From e86ee9eae7ad23edb41a508b3b5ce25964f0771e Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Tue, 15 Sep 2015 01:07:25 -0400 Subject: [PATCH 02/18] install/uninstall scripts for OS X --- scripts/osx_install | 17 +++++++++++++++++ scripts/osx_uninstall | 4 ++++ 2 files changed, 21 insertions(+) create mode 100755 scripts/osx_install create mode 100755 scripts/osx_uninstall diff --git a/scripts/osx_install b/scripts/osx_install new file mode 100755 index 00000000000..45525861f01 --- /dev/null +++ b/scripts/osx_install @@ -0,0 +1,17 @@ +#!/bin/sh + +set -e + +echo "Installing homebridge..." + +APP_PATH=`pwd` +HASS_PATH=`which hass` +USER_NAME=`whoami` + +cp scripts/org.home-assistant.plist ~/Library/LaunchAgents/org.home-assistant.plist + +sed -i '' -e "s#%USER%#$USER_NAME#g" ~/Library/LaunchAgents/org.home-assistant.plist +sed -i '' -e "s#%PATH%#$APP_PATH#g" ~/Library/LaunchAgents/org.home-assistant.plist +sed -i '' -e "s#%HASS_PATH%#$HASS_PATH#g" ~/Library/LaunchAgents/org.home-assistant.plist + +launchctl load -w -F ~/Library/LaunchAgents/org.home-assistant.plist diff --git a/scripts/osx_uninstall b/scripts/osx_uninstall new file mode 100755 index 00000000000..1d66ba3f48a --- /dev/null +++ b/scripts/osx_uninstall @@ -0,0 +1,4 @@ +#!/bin/sh + +launchctl unload ~/Library/LaunchAgents/org.home-assistant.plist +rm ~/Library/LaunchAgents/org.home-assistant.plist From a4aa2e43836acfc2677ccb056055c47def53082d Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Tue, 15 Sep 2015 02:08:43 -0400 Subject: [PATCH 03/18] change vars --- scripts/org.home-assistant.plist | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/org.home-assistant.plist b/scripts/org.home-assistant.plist index b445852e05f..b4ed5176006 100644 --- a/scripts/org.home-assistant.plist +++ b/scripts/org.home-assistant.plist @@ -12,7 +12,7 @@ Program - %HASS_PATH% + $HASS_PATH$ AbandonProcessGroup @@ -27,13 +27,13 @@ WorkingDirectory - %PATH% + $APP_PATH$ StandardErrorPath - /Users/%USER%/Library/Logs/home-assitant.log + /Users/$USER$/Library/Logs/home-assitant.log StandardOutPath - /Users/%USER%/Library/Logs/home-assitant.log + /Users/$USER$/Library/Logs/home-assitant.log From 9588fcc5cc55b25871724ab4a6fbecf305b591ef Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Tue, 15 Sep 2015 02:09:02 -0400 Subject: [PATCH 04/18] install scripts --- homeassistant/__main__.py | 43 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/homeassistant/__main__.py b/homeassistant/__main__.py index 2641961f5c3..ff72ead880f 100644 --- a/homeassistant/__main__.py +++ b/homeassistant/__main__.py @@ -4,6 +4,7 @@ from __future__ import print_function import sys import os import argparse +import codecs from homeassistant import bootstrap import homeassistant.config as config_util @@ -95,6 +96,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.') if os.name != "nt": parser.add_argument( '--daemon', @@ -151,6 +160,32 @@ def write_pid(pid_file): print('Fatal Error: Unable to write pid file {}'.format(pid_file)) sys.exit(1) +def install_osx(): + app_path = os.popen('pwd').read().strip() + hass_path = os.popen('which hass').read().strip() + user = os.popen('whoami').read().strip() + + plist = codecs.open('scripts/org.home-assistant.plist', 'r', 'utf-8').read() + + plist = plist.replace("$APP_PATH$", app_path) + plist = plist.replace("$HASS_PATH$", hass_path) + plist = plist.replace("$USER$", user) + + path = os.path.expanduser("~/Library/LaunchAgents/org.home-assistant.plist") + plist_file = codecs.open(path, 'w', 'utf-8') + plist_file.write(plist) + plist_file.close() + os.popen('launchctl load -w -F ' + path) + + print("Home Assistant has been installed. Open it here: http://localhost:8123") + + +def uninstall_osx(): + path = os.path.expanduser("~/Library/LaunchAgents/org.home-assistant.plist") + os.popen('launchctl unload ' + path) + + print("Home Assistant has been uninstalled.") + def main(): """ Starts Home Assistant. """ @@ -161,6 +196,14 @@ def main(): 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 + if args.uninstall_osx: + uninstall_osx() + return + # daemon functions if args.pid_file: check_pid(args.pid_file) From e12cc2fbbfbdc9d11a075dfd1a25383232e87e0b Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Tue, 15 Sep 2015 02:12:31 -0400 Subject: [PATCH 05/18] attempts at dodging pep8 terror --- homeassistant/__main__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/homeassistant/__main__.py b/homeassistant/__main__.py index ff72ead880f..fb77cd685bb 100644 --- a/homeassistant/__main__.py +++ b/homeassistant/__main__.py @@ -165,19 +165,22 @@ def install_osx(): hass_path = os.popen('which hass').read().strip() user = os.popen('whoami').read().strip() - plist = codecs.open('scripts/org.home-assistant.plist', 'r', 'utf-8').read() + plist = codecs.open('scripts/org.home-assistant.plist', 'r', 'utf-8') + plist = plist.read() plist = plist.replace("$APP_PATH$", app_path) plist = plist.replace("$HASS_PATH$", hass_path) plist = plist.replace("$USER$", user) path = os.path.expanduser("~/Library/LaunchAgents/org.home-assistant.plist") + os.remove(path) plist_file = codecs.open(path, 'w', 'utf-8') plist_file.write(plist) plist_file.close() os.popen('launchctl load -w -F ' + path) - print("Home Assistant has been installed. Open it here: http://localhost:8123") + print("Home Assistant has been installed. \ + Open it here: http://localhost:8123") def uninstall_osx(): From fcad068016ebe2c552bab4e7058a265d0a427632 Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Tue, 15 Sep 2015 02:17:01 -0400 Subject: [PATCH 06/18] strip the dash --- homeassistant/__main__.py | 12 ++++++++---- ....home-assistant.plist => org.homeassistant.plist} | 6 +++--- 2 files changed, 11 insertions(+), 7 deletions(-) rename scripts/{org.home-assistant.plist => org.homeassistant.plist} (80%) diff --git a/homeassistant/__main__.py b/homeassistant/__main__.py index fb77cd685bb..1736dee9176 100644 --- a/homeassistant/__main__.py +++ b/homeassistant/__main__.py @@ -160,20 +160,24 @@ def write_pid(pid_file): print('Fatal Error: Unable to write pid file {}'.format(pid_file)) sys.exit(1) + def install_osx(): app_path = os.popen('pwd').read().strip() hass_path = os.popen('which hass').read().strip() user = os.popen('whoami').read().strip() - plist = codecs.open('scripts/org.home-assistant.plist', 'r', 'utf-8') + plist = codecs.open('scripts/org.homeassistant.plist', 'r', 'utf-8') plist = plist.read() plist = plist.replace("$APP_PATH$", app_path) plist = plist.replace("$HASS_PATH$", hass_path) plist = plist.replace("$USER$", user) - path = os.path.expanduser("~/Library/LaunchAgents/org.home-assistant.plist") - os.remove(path) + path = os.path.expanduser("~/Library/LaunchAgents/org.homeassistant.plist") + + if os.path.isfile(path): + os.remove(path) + plist_file = codecs.open(path, 'w', 'utf-8') plist_file.write(plist) plist_file.close() @@ -184,7 +188,7 @@ def install_osx(): def uninstall_osx(): - path = os.path.expanduser("~/Library/LaunchAgents/org.home-assistant.plist") + path = os.path.expanduser("~/Library/LaunchAgents/org.homeassistant.plist") os.popen('launchctl unload ' + path) print("Home Assistant has been uninstalled.") diff --git a/scripts/org.home-assistant.plist b/scripts/org.homeassistant.plist similarity index 80% rename from scripts/org.home-assistant.plist rename to scripts/org.homeassistant.plist index b4ed5176006..e199b990a72 100644 --- a/scripts/org.home-assistant.plist +++ b/scripts/org.homeassistant.plist @@ -3,7 +3,7 @@ Label - org.home-assitant + org.homeassitant EnvironmentVariables @@ -30,10 +30,10 @@ $APP_PATH$ StandardErrorPath - /Users/$USER$/Library/Logs/home-assitant.log + /Users/$USER$/Library/Logs/homeassitant.log StandardOutPath - /Users/$USER$/Library/Logs/home-assitant.log + /Users/$USER$/Library/Logs/homeassitant.log From 6e927d68e5d210900ae3b4b0454f6325d1603f0f Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Tue, 15 Sep 2015 02:20:40 -0400 Subject: [PATCH 07/18] don't need these anymore --- scripts/osx_install | 17 ----------------- scripts/osx_uninstall | 4 ---- 2 files changed, 21 deletions(-) delete mode 100755 scripts/osx_install delete mode 100755 scripts/osx_uninstall diff --git a/scripts/osx_install b/scripts/osx_install deleted file mode 100755 index 45525861f01..00000000000 --- a/scripts/osx_install +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -set -e - -echo "Installing homebridge..." - -APP_PATH=`pwd` -HASS_PATH=`which hass` -USER_NAME=`whoami` - -cp scripts/org.home-assistant.plist ~/Library/LaunchAgents/org.home-assistant.plist - -sed -i '' -e "s#%USER%#$USER_NAME#g" ~/Library/LaunchAgents/org.home-assistant.plist -sed -i '' -e "s#%PATH%#$APP_PATH#g" ~/Library/LaunchAgents/org.home-assistant.plist -sed -i '' -e "s#%HASS_PATH%#$HASS_PATH#g" ~/Library/LaunchAgents/org.home-assistant.plist - -launchctl load -w -F ~/Library/LaunchAgents/org.home-assistant.plist diff --git a/scripts/osx_uninstall b/scripts/osx_uninstall deleted file mode 100755 index 1d66ba3f48a..00000000000 --- a/scripts/osx_uninstall +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -launchctl unload ~/Library/LaunchAgents/org.home-assistant.plist -rm ~/Library/LaunchAgents/org.home-assistant.plist From 9ada5e6b2b9ce1b62868ca8003e939a0d05c012c Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Tue, 15 Sep 2015 02:29:57 -0400 Subject: [PATCH 08/18] move launchd script inside package --- homeassistant/startup/__init__.py | 0 .../startup/launchd.plist | 3 --- setup.py | 3 ++- 3 files changed, 2 insertions(+), 4 deletions(-) create mode 100644 homeassistant/startup/__init__.py rename scripts/org.homeassistant.plist => homeassistant/startup/launchd.plist (92%) diff --git a/homeassistant/startup/__init__.py b/homeassistant/startup/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/scripts/org.homeassistant.plist b/homeassistant/startup/launchd.plist similarity index 92% rename from scripts/org.homeassistant.plist rename to homeassistant/startup/launchd.plist index e199b990a72..50bc18e3e38 100644 --- a/scripts/org.homeassistant.plist +++ b/homeassistant/startup/launchd.plist @@ -26,9 +26,6 @@ - WorkingDirectory - $APP_PATH$ - StandardErrorPath /Users/$USER$/Library/Logs/homeassitant.log diff --git a/setup.py b/setup.py index ce8a75072ac..fde7f9bf898 100755 --- a/setup.py +++ b/setup.py @@ -12,7 +12,8 @@ PACKAGES = find_packages(exclude=['tests', 'tests.*']) PACKAGE_DATA = \ {'homeassistant.components.frontend': ['index.html.template'], 'homeassistant.components.frontend.www_static': ['*.*'], - 'homeassistant.components.frontend.www_static.images': ['*.*']} + 'homeassistant.components.frontend.www_static.images': ['*.*'], + 'homeassistant.startup': ['*.*']} REQUIRES = [ 'requests>=2,<3', From 834ce5269dc98aec71a5df992617778020370efd Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Tue, 15 Sep 2015 02:30:13 -0400 Subject: [PATCH 09/18] we don't actually have to do this --- homeassistant/__main__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/homeassistant/__main__.py b/homeassistant/__main__.py index 1736dee9176..d1b0e574d2d 100644 --- a/homeassistant/__main__.py +++ b/homeassistant/__main__.py @@ -162,14 +162,12 @@ def write_pid(pid_file): def install_osx(): - app_path = os.popen('pwd').read().strip() hass_path = os.popen('which hass').read().strip() user = os.popen('whoami').read().strip() plist = codecs.open('scripts/org.homeassistant.plist', 'r', 'utf-8') plist = plist.read() - plist = plist.replace("$APP_PATH$", app_path) plist = plist.replace("$HASS_PATH$", hass_path) plist = plist.replace("$USER$", user) From 1fc2204ca94d260f026017e1206014453b85baaf Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Tue, 15 Sep 2015 02:30:19 -0400 Subject: [PATCH 10/18] get the right path --- homeassistant/__main__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/homeassistant/__main__.py b/homeassistant/__main__.py index d1b0e574d2d..ee9b595eeaa 100644 --- a/homeassistant/__main__.py +++ b/homeassistant/__main__.py @@ -165,7 +165,10 @@ def install_osx(): hass_path = os.popen('which hass').read().strip() user = os.popen('whoami').read().strip() - plist = codecs.open('scripts/org.homeassistant.plist', 'r', 'utf-8') + cwd = os.path.dirname(__file__) + template_path = os.path.join(cwd, 'startup', 'launchd.plist') + + plist = codecs.open(template_path, 'r', 'utf-8') plist = plist.read() plist = plist.replace("$HASS_PATH$", hass_path) From 3b27bef1acdfe21d5dacd7b0dad1eb9bf2b1a2bd Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Tue, 15 Sep 2015 02:35:20 -0400 Subject: [PATCH 11/18] DOCS --- homeassistant/__main__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/homeassistant/__main__.py b/homeassistant/__main__.py index ee9b595eeaa..8166ef583d9 100644 --- a/homeassistant/__main__.py +++ b/homeassistant/__main__.py @@ -162,6 +162,7 @@ def write_pid(pid_file): def install_osx(): + """ Setup to run via launchd on OS X """ hass_path = os.popen('which hass').read().strip() user = os.popen('whoami').read().strip() @@ -189,6 +190,7 @@ def install_osx(): def uninstall_osx(): + """ Unload from launchd on OS X """ path = os.path.expanduser("~/Library/LaunchAgents/org.homeassistant.plist") os.popen('launchctl unload ' + path) From 8bba0b88fd9329b44a53fcf43413e78ff2a55a30 Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Tue, 15 Sep 2015 02:46:06 -0400 Subject: [PATCH 12/18] blocks! --- homeassistant/__main__.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/homeassistant/__main__.py b/homeassistant/__main__.py index 8166ef583d9..79f5d43ca04 100644 --- a/homeassistant/__main__.py +++ b/homeassistant/__main__.py @@ -163,13 +163,20 @@ def write_pid(pid_file): def install_osx(): """ Setup to run via launchd on OS X """ - hass_path = os.popen('which hass').read().strip() - user = os.popen('whoami').read().strip() + 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 = codecs.open(template_path, 'r', 'utf-8') + plist = plist.read() plist = plist.replace("$HASS_PATH$", hass_path) @@ -180,9 +187,9 @@ def install_osx(): if os.path.isfile(path): os.remove(path) - plist_file = codecs.open(path, 'w', 'utf-8') - plist_file.write(plist) - plist_file.close() + with codecs.open(path, 'w', 'utf-8') as outp: + outp.write(plist) + os.popen('launchctl load -w -F ' + path) print("Home Assistant has been installed. \ From 5cbcd7291296da40024733d90abc3943689796ed Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Tue, 15 Sep 2015 02:48:23 -0400 Subject: [PATCH 13/18] dupe --- homeassistant/__main__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/homeassistant/__main__.py b/homeassistant/__main__.py index 79f5d43ca04..5e83ee0126c 100644 --- a/homeassistant/__main__.py +++ b/homeassistant/__main__.py @@ -175,8 +175,6 @@ def install_osx(): with open(template_path, 'r', encoding='utf-8') as inp: plist = inp.read() - plist = codecs.open(template_path, 'r', 'utf-8') - plist = plist.read() plist = plist.replace("$HASS_PATH$", hass_path) From 37cd62447e95d97e8f7e759edc22bd4bf944f57e Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Tue, 15 Sep 2015 02:50:15 -0400 Subject: [PATCH 14/18] let it get overwritten --- homeassistant/__main__.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/homeassistant/__main__.py b/homeassistant/__main__.py index 5e83ee0126c..a160e8ad973 100644 --- a/homeassistant/__main__.py +++ b/homeassistant/__main__.py @@ -182,9 +182,6 @@ def install_osx(): path = os.path.expanduser("~/Library/LaunchAgents/org.homeassistant.plist") - if os.path.isfile(path): - os.remove(path) - with codecs.open(path, 'w', 'utf-8') as outp: outp.write(plist) From fb29611c158e517d62c549141cc6c8829c484e0c Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Tue, 15 Sep 2015 02:51:23 -0400 Subject: [PATCH 15/18] :fire: codecs --- homeassistant/__main__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/homeassistant/__main__.py b/homeassistant/__main__.py index a160e8ad973..2cd97a20bb0 100644 --- a/homeassistant/__main__.py +++ b/homeassistant/__main__.py @@ -4,7 +4,6 @@ from __future__ import print_function import sys import os import argparse -import codecs from homeassistant import bootstrap import homeassistant.config as config_util @@ -182,7 +181,7 @@ def install_osx(): path = os.path.expanduser("~/Library/LaunchAgents/org.homeassistant.plist") - with codecs.open(path, 'w', 'utf-8') as outp: + with open(path, 'w', encoding='utf-8') as outp: outp.write(plist) os.popen('launchctl load -w -F ' + path) From c7565baa6d3c7a99a4fafdb916f9ece71c203822 Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Tue, 15 Sep 2015 02:54:11 -0400 Subject: [PATCH 16/18] NOPE --- homeassistant/__main__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/homeassistant/__main__.py b/homeassistant/__main__.py index 2cd97a20bb0..1fa496c991b 100644 --- a/homeassistant/__main__.py +++ b/homeassistant/__main__.py @@ -174,8 +174,6 @@ def install_osx(): with open(template_path, 'r', encoding='utf-8') as inp: plist = inp.read() - plist = plist.read() - plist = plist.replace("$HASS_PATH$", hass_path) plist = plist.replace("$USER$", user) From acb288f9e7e9b325a997df5c9203fbcc28655fdf Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Tue, 15 Sep 2015 02:54:22 -0400 Subject: [PATCH 17/18] error handling when writing --- homeassistant/__main__.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/homeassistant/__main__.py b/homeassistant/__main__.py index 1fa496c991b..dc405b54af4 100644 --- a/homeassistant/__main__.py +++ b/homeassistant/__main__.py @@ -179,8 +179,12 @@ def install_osx(): path = os.path.expanduser("~/Library/LaunchAgents/org.homeassistant.plist") - with open(path, 'w', encoding='utf-8') as outp: - outp.write(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) From bb172d8c98d50bdea41081d21f331bda70f93343 Mon Sep 17 00:00:00 2001 From: Jon Maddox Date: Tue, 15 Sep 2015 02:58:13 -0400 Subject: [PATCH 18/18] indention --- homeassistant/__main__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/__main__.py b/homeassistant/__main__.py index dc405b54af4..428845031a5 100644 --- a/homeassistant/__main__.py +++ b/homeassistant/__main__.py @@ -163,16 +163,16 @@ def write_pid(pid_file): def install_osx(): """ Setup to run via launchd on OS X """ with os.popen('which hass') as inp: - hass_path = inp.read().strip() + hass_path = inp.read().strip() with os.popen('whoami') as inp: - user = inp.read().strip() + 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 = inp.read() plist = plist.replace("$HASS_PATH$", hass_path) plist = plist.replace("$USER$", user) @@ -181,7 +181,7 @@ def install_osx(): try: with open(path, 'w', encoding='utf-8') as outp: - outp.write(plist) + outp.write(plist) except IOError as err: print('Unable to write to ' + path, err) return