mycroft-core/mycroft/util/signal.py

130 lines
3.7 KiB
Python

# Copyright 2017 Mycroft AI Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import tempfile
import time
import os
import os.path
import mycroft
from mycroft.util.log import LOG
def get_ipc_directory(domain=None):
"""Get the directory used for Inter Process Communication
Files in this folder can be accessed by different processes on the
machine. Useful for communication. This is often a small RAM disk.
Args:
domain (str): The IPC domain. Basically a subdirectory to prevent
overlapping signal filenames.
Returns:
str: a path to the IPC directory
"""
config = mycroft.configuration.Configuration.get()
dir = config.get("ipc_path")
if not dir:
# If not defined, use /tmp/mycroft/ipc
dir = os.path.join(tempfile.gettempdir(), "mycroft", "ipc")
return ensure_directory_exists(dir, domain)
def ensure_directory_exists(directory, domain=None):
""" Create a directory and give access rights to all
Args:
domain (str): The IPC domain. Basically a subdirectory to prevent
overlapping signal filenames.
Returns:
str: a path to the directory
"""
if domain:
directory = os.path.join(directory, domain)
directory = os.path.normpath(directory)
if not os.path.isdir(directory):
try:
save = os.umask(0)
os.makedirs(directory, 0o777) # give everyone rights to r/w here
except OSError:
LOG.warning("Failed to create: " + directory)
pass
finally:
os.umask(save)
return directory
def create_file(filename):
""" Create the file filename and create any directories needed
Args:
filename: Path to the file to be created
"""
try:
os.makedirs(os.path.dirname(filename))
except OSError:
pass
with open(filename, 'w') as f:
f.write('')
def create_signal(signal_name):
"""Create a named signal
Args:
signal_name (str): The signal's name. Must only contain characters
valid in filenames.
"""
try:
path = os.path.join(get_ipc_directory(), "signal", signal_name)
create_file(path)
return os.path.isfile(path)
except IOError:
return False
def check_for_signal(signal_name, sec_lifetime=0):
"""See if a named signal exists
Args:
signal_name (str): The signal's name. Must only contain characters
valid in filenames.
sec_lifetime (int, optional): How many seconds the signal should
remain valid. If 0 or not specified, it is a single-use signal.
If -1, it never expires.
Returns:
bool: True if the signal is defined, False otherwise
"""
path = os.path.join(get_ipc_directory(), "signal", signal_name)
if os.path.isfile(path):
if sec_lifetime == 0:
# consume this single-use signal
os.remove(path)
elif sec_lifetime == -1:
return True
elif int(os.path.getctime(path) + sec_lifetime) < int(time.time()):
# remove once expired
os.remove(path)
return False
return True
# No such signal exists
return False