We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Initial load of skills fails if auto_update is true.
On a new clone of the dev tree on an Ubuntu 16.04 machine **that's never run mycroft before.**

I ran _msm/msm default_ and it downloaded 27 skills, but mycroft wouldn't load any skills except _pairing_. I looked at the skills loading code and saw it wasn't getting past this:

```
    if (exists(SKILLS_DIR) and
          (self.next_download or not update)):
```

After I changed my config to _auto_update: false_, they loaded.





--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mycroft/util/__init__.py`
Content:
```
1 # Copyright 2017 Mycroft AI Inc.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #    http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 #
15 from __future__ import absolute_import
16 import socket
17 import subprocess
18 from threading import Thread
19 from time import sleep
20 
21 import json
22 import os.path
23 import psutil
24 from stat import S_ISREG, ST_MTIME, ST_MODE, ST_SIZE
25 
26 import signal as sig
27 
28 import mycroft.audio
29 import mycroft.configuration
30 from mycroft.util.format import nice_number
31 # Officially exported methods from this file:
32 # play_wav, play_mp3, get_cache_directory,
33 # resolve_resource_file, wait_while_speaking
34 from mycroft.util.log import LOG
35 from mycroft.util.parse import extract_datetime, extractnumber, normalize
36 from mycroft.util.signal import *
37 
38 
39 def resolve_resource_file(res_name):
40     """Convert a resource into an absolute filename.
41 
42     Resource names are in the form: 'filename.ext'
43     or 'path/filename.ext'
44 
45     The system wil look for ~/.mycroft/res_name first, and
46     if not found will look at /opt/mycroft/res_name,
47     then finally it will look for res_name in the 'mycroft/res'
48     folder of the source code package.
49 
50     Example:
51     With mycroft running as the user 'bob', if you called
52         resolve_resource_file('snd/beep.wav')
53     it would return either '/home/bob/.mycroft/snd/beep.wav' or
54     '/opt/mycroft/snd/beep.wav' or '.../mycroft/res/snd/beep.wav',
55     where the '...' is replaced by the path where the package has
56     been installed.
57 
58     Args:
59         res_name (str): a resource path/name
60     """
61 
62     # First look for fully qualified file (e.g. a user setting)
63     if os.path.isfile(res_name):
64         return res_name
65 
66     # Now look for ~/.mycroft/res_name (in user folder)
67     filename = os.path.expanduser("~/.mycroft/" + res_name)
68     if os.path.isfile(filename):
69         return filename
70 
71     # Next look for /opt/mycroft/res/res_name
72     filename = os.path.expanduser("/opt/mycroft/" + res_name)
73     if os.path.isfile(filename):
74         return filename
75 
76     # Finally look for it in the source package
77     filename = os.path.join(os.path.dirname(__file__), '..', 'res', res_name)
78     filename = os.path.abspath(os.path.normpath(filename))
79     if os.path.isfile(filename):
80         return filename
81 
82     return None  # Resource cannot be resolved
83 
84 
85 def play_wav(uri):
86     config = mycroft.configuration.Configuration.get()
87     play_cmd = config.get("play_wav_cmdline")
88     play_wav_cmd = str(play_cmd).split(" ")
89     for index, cmd in enumerate(play_wav_cmd):
90         if cmd == "%1":
91             play_wav_cmd[index] = (get_http(uri))
92     return subprocess.Popen(play_wav_cmd)
93 
94 
95 def play_mp3(uri):
96     config = mycroft.configuration.Configuration.get()
97     play_cmd = config.get("play_mp3_cmdline")
98     play_mp3_cmd = str(play_cmd).split(" ")
99     for index, cmd in enumerate(play_mp3_cmd):
100         if cmd == "%1":
101             play_mp3_cmd[index] = (get_http(uri))
102     return subprocess.Popen(play_mp3_cmd)
103 
104 
105 def record(file_path, duration, rate, channels):
106     if duration > 0:
107         return subprocess.Popen(
108             ["arecord", "-r", str(rate), "-c", str(channels), "-d",
109              str(duration), file_path])
110     else:
111         return subprocess.Popen(
112             ["arecord", "-r", str(rate), "-c", str(channels), file_path])
113 
114 
115 def get_http(uri):
116     return uri.replace("https://", "http://")
117 
118 
119 def remove_last_slash(url):
120     if url and url.endswith('/'):
121         url = url[:-1]
122     return url
123 
124 
125 def read_stripped_lines(filename):
126     with open(filename, 'r') as f:
127         return [line.strip() for line in f]
128 
129 
130 def read_dict(filename, div='='):
131     d = {}
132     with open(filename, 'r') as f:
133         for line in f:
134             (key, val) = line.split(div)
135             d[key.strip()] = val.strip()
136     return d
137 
138 
139 def connected(host="8.8.8.8", port=53, timeout=3):
140     """
141     Thanks to 7h3rAm on
142     Host: 8.8.8.8 (google-public-dns-a.google.com)
143     OpenPort: 53/tcp
144     Service: domain (DNS/TCP)
145 
146     NOTE:
147     This is no longer in use by this version
148     New method checks for a connection using ConnectionError only when
149     a question is asked
150     """
151     try:
152         socket.setdefaulttimeout(timeout)
153         socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, port))
154         return True
155     except IOError:
156         try:
157             socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect(
158                 ("8.8.4.4", port))
159             return True
160         except IOError:
161             return False
162 
163 
164 def curate_cache(directory, min_free_percent=5.0, min_free_disk=50):
165     """Clear out the directory if needed
166 
167     This assumes all the files in the directory can be deleted as freely
168 
169     Args:
170         directory (str): directory path that holds cached files
171         min_free_percent (float): percentage (0.0-100.0) of drive to keep free,
172                                   default is 5% if not specified.
173         min_free_disk (float): minimum allowed disk space in MB, default
174                                value is 50 MB if not specified.
175     """
176 
177     # Simpleminded implementation -- keep a certain percentage of the
178     # disk available.
179     # TODO: Would be easy to add more options, like whitelisted files, etc.
180     space = psutil.disk_usage(directory)
181 
182     # convert from MB to bytes
183     min_free_disk *= 1024 * 1024
184     # space.percent = space.used/space.total*100.0
185     percent_free = 100.0 - space.percent
186     if percent_free < min_free_percent and space.free < min_free_disk:
187         LOG.info('Low diskspace detected, cleaning cache')
188         # calculate how many bytes we need to delete
189         bytes_needed = (min_free_percent - percent_free) / 100.0 * space.total
190         bytes_needed = int(bytes_needed + 1.0)
191 
192         # get all entries in the directory w/ stats
193         entries = (os.path.join(directory, fn) for fn in os.listdir(directory))
194         entries = ((os.stat(path), path) for path in entries)
195 
196         # leave only regular files, insert modification date
197         entries = ((stat[ST_MTIME], stat[ST_SIZE], path)
198                    for stat, path in entries if S_ISREG(stat[ST_MODE]))
199 
200         # delete files with oldest modification date until space is freed
201         space_freed = 0
202         for moddate, fsize, path in sorted(entries):
203             try:
204                 os.remove(path)
205                 space_freed += fsize
206             except:
207                 pass
208 
209             if space_freed > bytes_needed:
210                 return  # deleted enough!
211 
212 
213 def get_cache_directory(domain=None):
214     """Get a directory for caching data
215 
216     This directory can be used to hold temporary caches of data to
217     speed up performance.  This directory will likely be part of a
218     small RAM disk and may be cleared at any time.  So code that
219     uses these cached files must be able to fallback and regenerate
220     the file.
221 
222     Args:
223         domain (str): The cache domain.  Basically just a subdirectory.
224 
225     Return:
226         str: a path to the directory where you can cache data
227     """
228     config = mycroft.configuration.Configuration.get()
229     dir = config.get("cache_path")
230     if not dir:
231         # If not defined, use /tmp/mycroft/cache
232         dir = os.path.join(tempfile.gettempdir(), "mycroft", "cache")
233     return ensure_directory_exists(dir, domain)
234 
235 
236 def validate_param(value, name):
237     if not value:
238         raise ValueError("Missing or empty %s in mycroft.conf " % name)
239 
240 
241 def is_speaking():
242     """Determine if Text to Speech is occurring
243 
244     Returns:
245         bool: True while still speaking
246     """
247     LOG.info("mycroft.utils.is_speaking() is depreciated, use "
248              "mycroft.audio.is_speaking() instead.")
249     return mycroft.audio.is_speaking()
250 
251 
252 def wait_while_speaking():
253     """Pause as long as Text to Speech is still happening
254 
255     Pause while Text to Speech is still happening.  This always pauses
256     briefly to ensure that any preceeding request to speak has time to
257     begin.
258     """
259     LOG.info("mycroft.utils.wait_while_speaking() is depreciated, use "
260              "mycroft.audio.wait_while_speaking() instead.")
261     return mycroft.audio.wait_while_speaking()
262 
263 
264 def stop_speaking():
265     # TODO: Less hacky approach to this once Audio Manager is implemented
266     # Skills should only be able to stop speech they've initiated
267     LOG.info("mycroft.utils.stop_speaking() is depreciated, use "
268              "mycroft.audio.stop_speaking() instead.")
269     mycroft.audio.stop_speaking()
270 
271 
272 def get_arch():
273     """ Get architecture string of system. """
274     return os.uname()[4]
275 
276 
277 def reset_sigint_handler():
278     """
279     Reset the sigint handler to the default. This fixes KeyboardInterrupt
280     not getting raised when started via start-mycroft.sh
281     """
282     sig.signal(sig.SIGINT, sig.default_int_handler)
283 
284 
285 def create_daemon(target, args=(), kwargs=None):
286     """Helper to quickly create and start a thread with daemon = True"""
287     t = Thread(target=target, args=args, kwargs=kwargs)
288     t.daemon = True
289     t.start()
290     return t
291 
292 
293 def wait_for_exit_signal():
294     """Blocks until KeyboardInterrupt is received"""
295     try:
296         while True:
297             sleep(100)
298     except KeyboardInterrupt:
299         pass
300 
301 
302 def create_echo_function(name, whitelist=None):
303     from mycroft.configuration import Configuration
304     blacklist = Configuration.get().get("ignore_logs")
305 
306     def echo(message):
307         """Listen for messages and echo them for logging"""
308         try:
309             js_msg = json.loads(message)
310 
311             if whitelist and js_msg.get("type") not in whitelist:
312                 return
313 
314             if blacklist and js_msg.get("type") in blacklist:
315                 return
316 
317             if js_msg.get("type") == "registration":
318                 # do not log tokens from registration messages
319                 js_msg["data"]["token"] = None
320                 message = json.dumps(js_msg)
321         except Exception:
322             pass
323         LOG(name).debug(message)
324     return echo
325
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/mycroft/util/__init__.py b/mycroft/util/__init__.py
--- a/mycroft/util/__init__.py
+++ b/mycroft/util/__init__.py
@@ -22,6 +22,7 @@
 import os.path
 import psutil
 from stat import S_ISREG, ST_MTIME, ST_MODE, ST_SIZE
+import requests
 
 import signal as sig
 
@@ -136,18 +137,41 @@
     return d
 
 
-def connected(host="8.8.8.8", port=53, timeout=3):
+def connected():
+    """ Check connection by connecting to 8.8.8.8, if this is
+    blocked/fails, Microsoft NCSI is used as a backup
+
+    Returns:
+        True if internet connection can be detected
+    """
+    return connected_dns() or connected_ncsi()
+
+
+def connected_ncsi():
+    """ Check internet connection by retrieving the Microsoft NCSI endpoint.
+
+    Returns:
+        True if internet connection can be detected
     """
-    Thanks to 7h3rAm on
-    Host: 8.8.8.8 (google-public-dns-a.google.com)
-    OpenPort: 53/tcp
-    Service: domain (DNS/TCP)
-
-    NOTE:
-    This is no longer in use by this version
-    New method checks for a connection using ConnectionError only when
-    a question is asked
+    try:
+        r = requests.get('http://www.msftncsi.com/ncsi.txt')
+        if r.text == u'Microsoft NCSI':
+            return True
+    except Exception:
+        pass
+    return False
+
+
+def connected_dns(host="8.8.8.8", port=53, timeout=3):
+    """ Check internet connection by connecting to DNS servers
+
+    Returns:
+        True if internet connection can be detected
     """
+    # Thanks to 7h3rAm on
+    # Host: 8.8.8.8 (google-public-dns-a.google.com)
+    # OpenPort: 53/tcp
+    # Service: domain (DNS/TCP)
     try:
         socket.setdefaulttimeout(timeout)
         socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, port))

{"golden_diff": "diff --git a/mycroft/util/__init__.py b/mycroft/util/__init__.py\n--- a/mycroft/util/__init__.py\n+++ b/mycroft/util/__init__.py\n@@ -22,6 +22,7 @@\n import os.path\n import psutil\n from stat import S_ISREG, ST_MTIME, ST_MODE, ST_SIZE\n+import requests\n \n import signal as sig\n \n@@ -136,18 +137,41 @@\n     return d\n \n \n-def connected(host=\"8.8.8.8\", port=53, timeout=3):\n+def connected():\n+    \"\"\" Check connection by connecting to 8.8.8.8, if this is\n+    blocked/fails, Microsoft NCSI is used as a backup\n+\n+    Returns:\n+        True if internet connection can be detected\n+    \"\"\"\n+    return connected_dns() or connected_ncsi()\n+\n+\n+def connected_ncsi():\n+    \"\"\" Check internet connection by retrieving the Microsoft NCSI endpoint.\n+\n+    Returns:\n+        True if internet connection can be detected\n     \"\"\"\n-    Thanks to 7h3rAm on\n-    Host: 8.8.8.8 (google-public-dns-a.google.com)\n-    OpenPort: 53/tcp\n-    Service: domain (DNS/TCP)\n-\n-    NOTE:\n-    This is no longer in use by this version\n-    New method checks for a connection using ConnectionError only when\n-    a question is asked\n+    try:\n+        r = requests.get('http://www.msftncsi.com/ncsi.txt')\n+        if r.text == u'Microsoft NCSI':\n+            return True\n+    except Exception:\n+        pass\n+    return False\n+\n+\n+def connected_dns(host=\"8.8.8.8\", port=53, timeout=3):\n+    \"\"\" Check internet connection by connecting to DNS servers\n+\n+    Returns:\n+        True if internet connection can be detected\n     \"\"\"\n+    # Thanks to 7h3rAm on\n+    # Host: 8.8.8.8 (google-public-dns-a.google.com)\n+    # OpenPort: 53/tcp\n+    # Service: domain (DNS/TCP)\n     try:\n         socket.setdefaulttimeout(timeout)\n         socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, port))\n", "issue": "Initial load of skills fails if auto_update is true.\nOn a new clone of the dev tree on an Ubuntu 16.04 machine **that's never run mycroft before.**\r\n\r\nI ran _msm/msm default_ and it downloaded 27 skills, but mycroft wouldn't load any skills except _pairing_. I looked at the skills loading code and saw it wasn't getting past this:\r\n\r\n```\r\n    if (exists(SKILLS_DIR) and\r\n          (self.next_download or not update)):\r\n```\r\n\r\nAfter I changed my config to _auto_update: false_, they loaded.\r\n\r\n\r\n\r\n\n", "before_files": [{"content": "# Copyright 2017 Mycroft AI Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#    http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\nfrom __future__ import absolute_import\nimport socket\nimport subprocess\nfrom threading import Thread\nfrom time import sleep\n\nimport json\nimport os.path\nimport psutil\nfrom stat import S_ISREG, ST_MTIME, ST_MODE, ST_SIZE\n\nimport signal as sig\n\nimport mycroft.audio\nimport mycroft.configuration\nfrom mycroft.util.format import nice_number\n# Officially exported methods from this file:\n# play_wav, play_mp3, get_cache_directory,\n# resolve_resource_file, wait_while_speaking\nfrom mycroft.util.log import LOG\nfrom mycroft.util.parse import extract_datetime, extractnumber, normalize\nfrom mycroft.util.signal import *\n\n\ndef resolve_resource_file(res_name):\n    \"\"\"Convert a resource into an absolute filename.\n\n    Resource names are in the form: 'filename.ext'\n    or 'path/filename.ext'\n\n    The system wil look for ~/.mycroft/res_name first, and\n    if not found will look at /opt/mycroft/res_name,\n    then finally it will look for res_name in the 'mycroft/res'\n    folder of the source code package.\n\n    Example:\n    With mycroft running as the user 'bob', if you called\n        resolve_resource_file('snd/beep.wav')\n    it would return either '/home/bob/.mycroft/snd/beep.wav' or\n    '/opt/mycroft/snd/beep.wav' or '.../mycroft/res/snd/beep.wav',\n    where the '...' is replaced by the path where the package has\n    been installed.\n\n    Args:\n        res_name (str): a resource path/name\n    \"\"\"\n\n    # First look for fully qualified file (e.g. a user setting)\n    if os.path.isfile(res_name):\n        return res_name\n\n    # Now look for ~/.mycroft/res_name (in user folder)\n    filename = os.path.expanduser(\"~/.mycroft/\" + res_name)\n    if os.path.isfile(filename):\n        return filename\n\n    # Next look for /opt/mycroft/res/res_name\n    filename = os.path.expanduser(\"/opt/mycroft/\" + res_name)\n    if os.path.isfile(filename):\n        return filename\n\n    # Finally look for it in the source package\n    filename = os.path.join(os.path.dirname(__file__), '..', 'res', res_name)\n    filename = os.path.abspath(os.path.normpath(filename))\n    if os.path.isfile(filename):\n        return filename\n\n    return None  # Resource cannot be resolved\n\n\ndef play_wav(uri):\n    config = mycroft.configuration.Configuration.get()\n    play_cmd = config.get(\"play_wav_cmdline\")\n    play_wav_cmd = str(play_cmd).split(\" \")\n    for index, cmd in enumerate(play_wav_cmd):\n        if cmd == \"%1\":\n            play_wav_cmd[index] = (get_http(uri))\n    return subprocess.Popen(play_wav_cmd)\n\n\ndef play_mp3(uri):\n    config = mycroft.configuration.Configuration.get()\n    play_cmd = config.get(\"play_mp3_cmdline\")\n    play_mp3_cmd = str(play_cmd).split(\" \")\n    for index, cmd in enumerate(play_mp3_cmd):\n        if cmd == \"%1\":\n            play_mp3_cmd[index] = (get_http(uri))\n    return subprocess.Popen(play_mp3_cmd)\n\n\ndef record(file_path, duration, rate, channels):\n    if duration > 0:\n        return subprocess.Popen(\n            [\"arecord\", \"-r\", str(rate), \"-c\", str(channels), \"-d\",\n             str(duration), file_path])\n    else:\n        return subprocess.Popen(\n            [\"arecord\", \"-r\", str(rate), \"-c\", str(channels), file_path])\n\n\ndef get_http(uri):\n    return uri.replace(\"https://\", \"http://\")\n\n\ndef remove_last_slash(url):\n    if url and url.endswith('/'):\n        url = url[:-1]\n    return url\n\n\ndef read_stripped_lines(filename):\n    with open(filename, 'r') as f:\n        return [line.strip() for line in f]\n\n\ndef read_dict(filename, div='='):\n    d = {}\n    with open(filename, 'r') as f:\n        for line in f:\n            (key, val) = line.split(div)\n            d[key.strip()] = val.strip()\n    return d\n\n\ndef connected(host=\"8.8.8.8\", port=53, timeout=3):\n    \"\"\"\n    Thanks to 7h3rAm on\n    Host: 8.8.8.8 (google-public-dns-a.google.com)\n    OpenPort: 53/tcp\n    Service: domain (DNS/TCP)\n\n    NOTE:\n    This is no longer in use by this version\n    New method checks for a connection using ConnectionError only when\n    a question is asked\n    \"\"\"\n    try:\n        socket.setdefaulttimeout(timeout)\n        socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, port))\n        return True\n    except IOError:\n        try:\n            socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect(\n                (\"8.8.4.4\", port))\n            return True\n        except IOError:\n            return False\n\n\ndef curate_cache(directory, min_free_percent=5.0, min_free_disk=50):\n    \"\"\"Clear out the directory if needed\n\n    This assumes all the files in the directory can be deleted as freely\n\n    Args:\n        directory (str): directory path that holds cached files\n        min_free_percent (float): percentage (0.0-100.0) of drive to keep free,\n                                  default is 5% if not specified.\n        min_free_disk (float): minimum allowed disk space in MB, default\n                               value is 50 MB if not specified.\n    \"\"\"\n\n    # Simpleminded implementation -- keep a certain percentage of the\n    # disk available.\n    # TODO: Would be easy to add more options, like whitelisted files, etc.\n    space = psutil.disk_usage(directory)\n\n    # convert from MB to bytes\n    min_free_disk *= 1024 * 1024\n    # space.percent = space.used/space.total*100.0\n    percent_free = 100.0 - space.percent\n    if percent_free < min_free_percent and space.free < min_free_disk:\n        LOG.info('Low diskspace detected, cleaning cache')\n        # calculate how many bytes we need to delete\n        bytes_needed = (min_free_percent - percent_free) / 100.0 * space.total\n        bytes_needed = int(bytes_needed + 1.0)\n\n        # get all entries in the directory w/ stats\n        entries = (os.path.join(directory, fn) for fn in os.listdir(directory))\n        entries = ((os.stat(path), path) for path in entries)\n\n        # leave only regular files, insert modification date\n        entries = ((stat[ST_MTIME], stat[ST_SIZE], path)\n                   for stat, path in entries if S_ISREG(stat[ST_MODE]))\n\n        # delete files with oldest modification date until space is freed\n        space_freed = 0\n        for moddate, fsize, path in sorted(entries):\n            try:\n                os.remove(path)\n                space_freed += fsize\n            except:\n                pass\n\n            if space_freed > bytes_needed:\n                return  # deleted enough!\n\n\ndef get_cache_directory(domain=None):\n    \"\"\"Get a directory for caching data\n\n    This directory can be used to hold temporary caches of data to\n    speed up performance.  This directory will likely be part of a\n    small RAM disk and may be cleared at any time.  So code that\n    uses these cached files must be able to fallback and regenerate\n    the file.\n\n    Args:\n        domain (str): The cache domain.  Basically just a subdirectory.\n\n    Return:\n        str: a path to the directory where you can cache data\n    \"\"\"\n    config = mycroft.configuration.Configuration.get()\n    dir = config.get(\"cache_path\")\n    if not dir:\n        # If not defined, use /tmp/mycroft/cache\n        dir = os.path.join(tempfile.gettempdir(), \"mycroft\", \"cache\")\n    return ensure_directory_exists(dir, domain)\n\n\ndef validate_param(value, name):\n    if not value:\n        raise ValueError(\"Missing or empty %s in mycroft.conf \" % name)\n\n\ndef is_speaking():\n    \"\"\"Determine if Text to Speech is occurring\n\n    Returns:\n        bool: True while still speaking\n    \"\"\"\n    LOG.info(\"mycroft.utils.is_speaking() is depreciated, use \"\n             \"mycroft.audio.is_speaking() instead.\")\n    return mycroft.audio.is_speaking()\n\n\ndef wait_while_speaking():\n    \"\"\"Pause as long as Text to Speech is still happening\n\n    Pause while Text to Speech is still happening.  This always pauses\n    briefly to ensure that any preceeding request to speak has time to\n    begin.\n    \"\"\"\n    LOG.info(\"mycroft.utils.wait_while_speaking() is depreciated, use \"\n             \"mycroft.audio.wait_while_speaking() instead.\")\n    return mycroft.audio.wait_while_speaking()\n\n\ndef stop_speaking():\n    # TODO: Less hacky approach to this once Audio Manager is implemented\n    # Skills should only be able to stop speech they've initiated\n    LOG.info(\"mycroft.utils.stop_speaking() is depreciated, use \"\n             \"mycroft.audio.stop_speaking() instead.\")\n    mycroft.audio.stop_speaking()\n\n\ndef get_arch():\n    \"\"\" Get architecture string of system. \"\"\"\n    return os.uname()[4]\n\n\ndef reset_sigint_handler():\n    \"\"\"\n    Reset the sigint handler to the default. This fixes KeyboardInterrupt\n    not getting raised when started via start-mycroft.sh\n    \"\"\"\n    sig.signal(sig.SIGINT, sig.default_int_handler)\n\n\ndef create_daemon(target, args=(), kwargs=None):\n    \"\"\"Helper to quickly create and start a thread with daemon = True\"\"\"\n    t = Thread(target=target, args=args, kwargs=kwargs)\n    t.daemon = True\n    t.start()\n    return t\n\n\ndef wait_for_exit_signal():\n    \"\"\"Blocks until KeyboardInterrupt is received\"\"\"\n    try:\n        while True:\n            sleep(100)\n    except KeyboardInterrupt:\n        pass\n\n\ndef create_echo_function(name, whitelist=None):\n    from mycroft.configuration import Configuration\n    blacklist = Configuration.get().get(\"ignore_logs\")\n\n    def echo(message):\n        \"\"\"Listen for messages and echo them for logging\"\"\"\n        try:\n            js_msg = json.loads(message)\n\n            if whitelist and js_msg.get(\"type\") not in whitelist:\n                return\n\n            if blacklist and js_msg.get(\"type\") in blacklist:\n                return\n\n            if js_msg.get(\"type\") == \"registration\":\n                # do not log tokens from registration messages\n                js_msg[\"data\"][\"token\"] = None\n                message = json.dumps(js_msg)\n        except Exception:\n            pass\n        LOG(name).debug(message)\n    return echo\n", "path": "mycroft/util/__init__.py"}], "after_files": [{"content": "# Copyright 2017 Mycroft AI Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#    http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\nfrom __future__ import absolute_import\nimport socket\nimport subprocess\nfrom threading import Thread\nfrom time import sleep\n\nimport json\nimport os.path\nimport psutil\nfrom stat import S_ISREG, ST_MTIME, ST_MODE, ST_SIZE\nimport requests\n\nimport signal as sig\n\nimport mycroft.audio\nimport mycroft.configuration\nfrom mycroft.util.format import nice_number\n# Officially exported methods from this file:\n# play_wav, play_mp3, get_cache_directory,\n# resolve_resource_file, wait_while_speaking\nfrom mycroft.util.log import LOG\nfrom mycroft.util.parse import extract_datetime, extractnumber, normalize\nfrom mycroft.util.signal import *\n\n\ndef resolve_resource_file(res_name):\n    \"\"\"Convert a resource into an absolute filename.\n\n    Resource names are in the form: 'filename.ext'\n    or 'path/filename.ext'\n\n    The system wil look for ~/.mycroft/res_name first, and\n    if not found will look at /opt/mycroft/res_name,\n    then finally it will look for res_name in the 'mycroft/res'\n    folder of the source code package.\n\n    Example:\n    With mycroft running as the user 'bob', if you called\n        resolve_resource_file('snd/beep.wav')\n    it would return either '/home/bob/.mycroft/snd/beep.wav' or\n    '/opt/mycroft/snd/beep.wav' or '.../mycroft/res/snd/beep.wav',\n    where the '...' is replaced by the path where the package has\n    been installed.\n\n    Args:\n        res_name (str): a resource path/name\n    \"\"\"\n\n    # First look for fully qualified file (e.g. a user setting)\n    if os.path.isfile(res_name):\n        return res_name\n\n    # Now look for ~/.mycroft/res_name (in user folder)\n    filename = os.path.expanduser(\"~/.mycroft/\" + res_name)\n    if os.path.isfile(filename):\n        return filename\n\n    # Next look for /opt/mycroft/res/res_name\n    filename = os.path.expanduser(\"/opt/mycroft/\" + res_name)\n    if os.path.isfile(filename):\n        return filename\n\n    # Finally look for it in the source package\n    filename = os.path.join(os.path.dirname(__file__), '..', 'res', res_name)\n    filename = os.path.abspath(os.path.normpath(filename))\n    if os.path.isfile(filename):\n        return filename\n\n    return None  # Resource cannot be resolved\n\n\ndef play_wav(uri):\n    config = mycroft.configuration.Configuration.get()\n    play_cmd = config.get(\"play_wav_cmdline\")\n    play_wav_cmd = str(play_cmd).split(\" \")\n    for index, cmd in enumerate(play_wav_cmd):\n        if cmd == \"%1\":\n            play_wav_cmd[index] = (get_http(uri))\n    return subprocess.Popen(play_wav_cmd)\n\n\ndef play_mp3(uri):\n    config = mycroft.configuration.Configuration.get()\n    play_cmd = config.get(\"play_mp3_cmdline\")\n    play_mp3_cmd = str(play_cmd).split(\" \")\n    for index, cmd in enumerate(play_mp3_cmd):\n        if cmd == \"%1\":\n            play_mp3_cmd[index] = (get_http(uri))\n    return subprocess.Popen(play_mp3_cmd)\n\n\ndef record(file_path, duration, rate, channels):\n    if duration > 0:\n        return subprocess.Popen(\n            [\"arecord\", \"-r\", str(rate), \"-c\", str(channels), \"-d\",\n             str(duration), file_path])\n    else:\n        return subprocess.Popen(\n            [\"arecord\", \"-r\", str(rate), \"-c\", str(channels), file_path])\n\n\ndef get_http(uri):\n    return uri.replace(\"https://\", \"http://\")\n\n\ndef remove_last_slash(url):\n    if url and url.endswith('/'):\n        url = url[:-1]\n    return url\n\n\ndef read_stripped_lines(filename):\n    with open(filename, 'r') as f:\n        return [line.strip() for line in f]\n\n\ndef read_dict(filename, div='='):\n    d = {}\n    with open(filename, 'r') as f:\n        for line in f:\n            (key, val) = line.split(div)\n            d[key.strip()] = val.strip()\n    return d\n\n\ndef connected():\n    \"\"\" Check connection by connecting to 8.8.8.8, if this is\n    blocked/fails, Microsoft NCSI is used as a backup\n\n    Returns:\n        True if internet connection can be detected\n    \"\"\"\n    return connected_dns() or connected_ncsi()\n\n\ndef connected_ncsi():\n    \"\"\" Check internet connection by retrieving the Microsoft NCSI endpoint.\n\n    Returns:\n        True if internet connection can be detected\n    \"\"\"\n    try:\n        r = requests.get('http://www.msftncsi.com/ncsi.txt')\n        if r.text == u'Microsoft NCSI':\n            return True\n    except Exception:\n        pass\n    return False\n\n\ndef connected_dns(host=\"8.8.8.8\", port=53, timeout=3):\n    \"\"\" Check internet connection by connecting to DNS servers\n\n    Returns:\n        True if internet connection can be detected\n    \"\"\"\n    # Thanks to 7h3rAm on\n    # Host: 8.8.8.8 (google-public-dns-a.google.com)\n    # OpenPort: 53/tcp\n    # Service: domain (DNS/TCP)\n    try:\n        socket.setdefaulttimeout(timeout)\n        socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, port))\n        return True\n    except IOError:\n        try:\n            socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect(\n                (\"8.8.4.4\", port))\n            return True\n        except IOError:\n            return False\n\n\ndef curate_cache(directory, min_free_percent=5.0, min_free_disk=50):\n    \"\"\"Clear out the directory if needed\n\n    This assumes all the files in the directory can be deleted as freely\n\n    Args:\n        directory (str): directory path that holds cached files\n        min_free_percent (float): percentage (0.0-100.0) of drive to keep free,\n                                  default is 5% if not specified.\n        min_free_disk (float): minimum allowed disk space in MB, default\n                               value is 50 MB if not specified.\n    \"\"\"\n\n    # Simpleminded implementation -- keep a certain percentage of the\n    # disk available.\n    # TODO: Would be easy to add more options, like whitelisted files, etc.\n    space = psutil.disk_usage(directory)\n\n    # convert from MB to bytes\n    min_free_disk *= 1024 * 1024\n    # space.percent = space.used/space.total*100.0\n    percent_free = 100.0 - space.percent\n    if percent_free < min_free_percent and space.free < min_free_disk:\n        LOG.info('Low diskspace detected, cleaning cache')\n        # calculate how many bytes we need to delete\n        bytes_needed = (min_free_percent - percent_free) / 100.0 * space.total\n        bytes_needed = int(bytes_needed + 1.0)\n\n        # get all entries in the directory w/ stats\n        entries = (os.path.join(directory, fn) for fn in os.listdir(directory))\n        entries = ((os.stat(path), path) for path in entries)\n\n        # leave only regular files, insert modification date\n        entries = ((stat[ST_MTIME], stat[ST_SIZE], path)\n                   for stat, path in entries if S_ISREG(stat[ST_MODE]))\n\n        # delete files with oldest modification date until space is freed\n        space_freed = 0\n        for moddate, fsize, path in sorted(entries):\n            try:\n                os.remove(path)\n                space_freed += fsize\n            except:\n                pass\n\n            if space_freed > bytes_needed:\n                return  # deleted enough!\n\n\ndef get_cache_directory(domain=None):\n    \"\"\"Get a directory for caching data\n\n    This directory can be used to hold temporary caches of data to\n    speed up performance.  This directory will likely be part of a\n    small RAM disk and may be cleared at any time.  So code that\n    uses these cached files must be able to fallback and regenerate\n    the file.\n\n    Args:\n        domain (str): The cache domain.  Basically just a subdirectory.\n\n    Return:\n        str: a path to the directory where you can cache data\n    \"\"\"\n    config = mycroft.configuration.Configuration.get()\n    dir = config.get(\"cache_path\")\n    if not dir:\n        # If not defined, use /tmp/mycroft/cache\n        dir = os.path.join(tempfile.gettempdir(), \"mycroft\", \"cache\")\n    return ensure_directory_exists(dir, domain)\n\n\ndef validate_param(value, name):\n    if not value:\n        raise ValueError(\"Missing or empty %s in mycroft.conf \" % name)\n\n\ndef is_speaking():\n    \"\"\"Determine if Text to Speech is occurring\n\n    Returns:\n        bool: True while still speaking\n    \"\"\"\n    LOG.info(\"mycroft.utils.is_speaking() is depreciated, use \"\n             \"mycroft.audio.is_speaking() instead.\")\n    return mycroft.audio.is_speaking()\n\n\ndef wait_while_speaking():\n    \"\"\"Pause as long as Text to Speech is still happening\n\n    Pause while Text to Speech is still happening.  This always pauses\n    briefly to ensure that any preceeding request to speak has time to\n    begin.\n    \"\"\"\n    LOG.info(\"mycroft.utils.wait_while_speaking() is depreciated, use \"\n             \"mycroft.audio.wait_while_speaking() instead.\")\n    return mycroft.audio.wait_while_speaking()\n\n\ndef stop_speaking():\n    # TODO: Less hacky approach to this once Audio Manager is implemented\n    # Skills should only be able to stop speech they've initiated\n    LOG.info(\"mycroft.utils.stop_speaking() is depreciated, use \"\n             \"mycroft.audio.stop_speaking() instead.\")\n    mycroft.audio.stop_speaking()\n\n\ndef get_arch():\n    \"\"\" Get architecture string of system. \"\"\"\n    return os.uname()[4]\n\n\ndef reset_sigint_handler():\n    \"\"\"\n    Reset the sigint handler to the default. This fixes KeyboardInterrupt\n    not getting raised when started via start-mycroft.sh\n    \"\"\"\n    sig.signal(sig.SIGINT, sig.default_int_handler)\n\n\ndef create_daemon(target, args=(), kwargs=None):\n    \"\"\"Helper to quickly create and start a thread with daemon = True\"\"\"\n    t = Thread(target=target, args=args, kwargs=kwargs)\n    t.daemon = True\n    t.start()\n    return t\n\n\ndef wait_for_exit_signal():\n    \"\"\"Blocks until KeyboardInterrupt is received\"\"\"\n    try:\n        while True:\n            sleep(100)\n    except KeyboardInterrupt:\n        pass\n\n\ndef create_echo_function(name, whitelist=None):\n    from mycroft.configuration import Configuration\n    blacklist = Configuration.get().get(\"ignore_logs\")\n\n    def echo(message):\n        \"\"\"Listen for messages and echo them for logging\"\"\"\n        try:\n            js_msg = json.loads(message)\n\n            if whitelist and js_msg.get(\"type\") not in whitelist:\n                return\n\n            if blacklist and js_msg.get(\"type\") in blacklist:\n                return\n\n            if js_msg.get(\"type\") == \"registration\":\n                # do not log tokens from registration messages\n                js_msg[\"data\"][\"token\"] = None\n                message = json.dumps(js_msg)\n        except Exception:\n            pass\n        LOG(name).debug(message)\n    return echo\n", "path": "mycroft/util/__init__.py"}]}