Пример #1
0
 def newfunc(self, *args, **kwargs):
     start_time = time.time()
     result = func(self, *args, **kwargs)
     elapsed_time = time.time() - start_time
     ha.log(self.logger, "INFO", 'function [{}] finished in {} ms'.format(
         func.__name__, int(elapsed_time * 1000)))
     return result
Пример #2
0
 def newfunc(self, *args, **kwargs):
     start_time = time.time()
     result = func(self, *args, **kwargs)
     elapsed_time = time.time() - start_time
     ha.log(self.logger, "INFO", 'function [{}] finished in {} ms'.format(
         func.__name__, int(elapsed_time * 1000)))
     return result
Пример #3
0
    def _resolve_css_params(self, fields, subs):
        done = False
        variable = re.compile("\$(\w+)")
        index = 0
        while not done and index < 100:
            index += 1
            done = True
            for varline in fields:
                if isinstance(fields[varline], dict):
                    fields[varline] = self._resolve_css_params(fields[varline], subs)
                elif fields[varline] is not None and type(fields[varline]) == str:
                    _vars = variable.finditer(fields[varline])
                    for var in _vars:
                        subvar = var.group()[1:]
                        if subvar in subs:
                            done = False
                            fields[varline] = fields[varline].replace(var.group(), subs[subvar], 1)
                        else:
                            ha.log(self.logger, "WARNING",
                                   "Variable definition not found in CSS Skin variables: ${}".format(subvar))
                            fields[varline] = ""

        if index == 100:
            ha.log(self.logger, "WARNING", "Unable to resolve CSS Skin variables, check for circular references")

        return fields
Пример #4
0
    def _resolve_css_params(self, fields, subs):
        done = False
        variable = re.compile("\$(\w+)")
        index = 0
        while not done and index < 100:
            index += 1
            done = True
            for varline in fields:
                if isinstance(fields[varline], dict):
                    fields[varline] = self._resolve_css_params(fields[varline], subs)
                elif fields[varline] is not None and type(fields[varline]) == str:
                    _vars = variable.finditer(fields[varline])
                    for var in _vars:
                        subvar = var.group()[1:]
                        if subvar in subs:
                            done = False
                            fields[varline] = fields[varline].replace(var.group(), subs[subvar], 1)
                        else:
                            ha.log(self.logger, "WARNING",
                                   "Variable definition not found in CSS Skin variables: ${}".format(subvar))
                            fields[varline] = ""

        if index == 100:
            ha.log(self.logger, "WARNING", "Unable to resolve CSS Skin variables, check for circular references")

        return fields
Пример #5
0
def dump_objects():
    utils.log(conf.logger, "INFO", "--------------------------------------------------")
    utils.log(conf.logger, "INFO", "Objects")
    utils.log(conf.logger, "INFO", "--------------------------------------------------")
    for object_ in conf.objects.keys():
        utils.log(conf.logger, "INFO", "{}: {}".format(object_, conf.objects[object_]))
    utils.log(conf.logger, "INFO", "--------------------------------------------------")
Пример #6
0
 def run_at_sunrise(self, callback, **kwargs):
     name = self.name
     utils.log(conf.logger, "DEBUG",
            "Registering run_at_sunrise with kwargs = {} for {}".format(
                kwargs, name))
     handle = self._schedule_sun(name, "next_rising", callback, **kwargs)
     return handle
Пример #7
0
 def _get_widgets(self):
     widgets = {}
     for widget_dir in [
             os.path.join(self.dash_install_dir, "widgets"),
             os.path.join(self.config_dir, "custom_widgets")
     ]:
         #widget_dir = os.path.join(self.dash_install_dir, "widgets")
         if os.path.isdir(widget_dir):
             widget_dirs = os.listdir(path=widget_dir)
             for widget in widget_dirs:
                 if widget_dir == os.path.join(self.config_dir,
                                               "custom_widgets"):
                     ha.log(self.logger, "INFO",
                            "Loading custom widget '{}'".format(widget))
                 if os.path.isdir(os.path.join(widget_dir, widget)):
                     jspath = os.path.join(widget_dir, widget,
                                           "{}.js".format(widget))
                     csspath = os.path.join(widget_dir, widget,
                                            "{}.css".format(widget))
                     htmlpath = os.path.join(widget_dir, widget,
                                             "{}.html".format(widget))
                     with open(jspath, 'r') as fd:
                         js = fd.read()
                     with open(csspath, 'r') as fd:
                         css = fd.read()
                     with open(htmlpath, 'r') as fd:
                         html = fd.read()
                     widgets[widget] = {"js": js, "css": css, "html": html}
     return widgets
Пример #8
0
    def get_dashboard(self, name, skin, recompile):

        try:

            dash = self._conditional_compile(name, skin, recompile)

            if dash is None:
                errors = []
                head_includes = []
                body_includes = []
            else:
                errors = dash["errors"]

            if "widgets" in dash:
                widgets = dash["widgets"]
            else:
                widgets = {}

            include_path = os.path.join(self.compiled_html_dir, skin,
                                        "{}_head.html".format(name.lower()))
            with open(include_path, "r") as include_file:
                head_includes = include_file.read()
            include_path = os.path.join(self.compiled_html_dir, skin,
                                        "{}_body.html".format(name.lower()))
            with open(include_path, "r") as include_file:
                body_includes = include_file.read()

            #
            # return params
            #
            params = {
                "errors": errors,
                "name": name.lower(),
                "skin": skin,
                "widgets": widgets,
                "head_includes": head_includes,
                "body_includes": body_includes
            }

            env = Environment(loader=FileSystemLoader(self.template_dir),
                              autoescape=select_autoescape(['html', 'xml']))

            template = env.get_template("dashboard.jinja2")
            rendered_template = template.render(params)

            return (rendered_template)

        except:
            ha.log(self.logger, "WARNING", '-' * 60)
            ha.log(self.logger, "WARNING",
                   "Unexpected error during DASH creation")
            ha.log(self.logger, "WARNING", '-' * 60)
            ha.log(self.logger, "WARNING", traceback.format_exc())
            ha.log(self.logger, "WARNING", '-' * 60)
            return {
                "errors":
                ["An unrecoverable error occured fetching dashboard"]
            }
Пример #9
0
 def cancel_listen_event(self, handle):
     name = self.name
     utils.log(conf.logger, "DEBUG",
               "Canceling listen_event for {}".format(name))
     with conf.callbacks_lock:
         if name in conf.callbacks and handle in conf.callbacks[name]:
             del conf.callbacks[name][handle]
         if name in conf.callbacks and conf.callbacks[name] == {}:
             del conf.callbacks[name]
Пример #10
0
 def _check_entity(self, entity):
     if "." not in entity:
         raise ValueError(
             "{}: Invalid entity ID: {}".format(self.name, entity))
     with conf.ha_state_lock:
         if entity not in conf.ha_state:
             utils.log(conf.logger, "WARNING",
                    "{}: Entity {} not found in Home Assistant".format(
                        self.name, entity))
Пример #11
0
 def func_wrapper(*args, **kwargs):
     if not reading_messages:
         utils.log(
             conf.logger, "WARNING",
             "Attempt to call Home Assistant while disconnected: {}".format(
                 func))
         return (lambda *args: None)
     else:
         return (func(*args, **kwargs))
Пример #12
0
def process_state_change(data):
    entity_id = data['data']['entity_id']
    utils.log(conf.logger, "DEBUG", "Entity ID:{}:".format(entity_id))
    device, entity = entity_id.split(".")

    # Process state callbacks

    with conf.callbacks_lock:
        for name in conf.callbacks.keys():
            for uuid_ in conf.callbacks[name]:
                callback = conf.callbacks[name][uuid_]
                if callback["type"] == "state":
                    cdevice = None
                    centity = None
                    if callback["entity"] is not None:
                        if "." not in callback["entity"]:
                            cdevice = callback["entity"]
                            centity = None
                        else:
                            cdevice, centity = callback["entity"].split(".")
                    if callback["kwargs"].get("attribute") is None:
                        cattribute = "state"
                    else:
                        cattribute = callback["kwargs"].get("attribute")

                    cold = callback["kwargs"].get("old")
                    cnew = callback["kwargs"].get("new")

                    if cdevice is None:
                        check_and_disapatch(
                            name, callback["function"], entity_id,
                            cattribute,
                            data['data']['new_state'],
                            data['data']['old_state'],
                            cold, cnew,
                            callback["kwargs"]
                        )
                    elif centity is None:
                        if device == cdevice:
                            check_and_disapatch(
                                name, callback["function"], entity_id,
                                cattribute,
                                data['data']['new_state'],
                                data['data']['old_state'],
                                cold, cnew,
                                callback["kwargs"]
                            )
                    elif device == cdevice and entity == centity:
                        check_and_disapatch(
                            name, callback["function"], entity_id,
                            cattribute,
                            data['data']['new_state'],
                            data['data']['old_state'], cold,
                            cnew,
                            callback["kwargs"]
                        )
Пример #13
0
 def info_listen_event(self, handle):
     name = self.name
     utils.log(conf.logger, "DEBUG",
               "Calling info_listen_event for {}".format(name))
     with conf.callbacks_lock:
         if name in conf.callbacks and handle in conf.callbacks[name]:
             callback = conf.callbacks[name][handle]
             return callback["event"], callback["kwargs"].copy()
         else:
             raise ValueError("Invalid handle: {}".format(handle))
Пример #14
0
 def set_app_state(self, entity_id, state):
     utils.log(conf.logger, "DEBUG", "set_app_state: {}".format(entity_id))
     if entity_id is not None and "." in entity_id:
         with conf.ha_state_lock:
             if entity_id in conf.ha_state:
                 old_state = conf.ha_state[entity_id]
             else:
                 old_state = None
             data = {"entity_id": entity_id, "new_state": state, "old_state": old_state}
             args = {"event_type": "state_changed", "data": data}
             conf.appq.put_nowait(args)
Пример #15
0
    def get_dashboard(self, name, skin, recompile):

        try:

            dash = self._conditional_compile(name, skin, recompile)

            if dash is None:
                errors = []
                head_includes = []
                body_includes = []
            else:
                errors = dash["errors"]

            if "widgets" in dash:
                widgets = dash["widgets"]
            else:
                widgets = {}

            if "scalable" in dash:
                scalable = dash["scalable"]
            else:
                scalable = True

            include_path = os.path.join(self.compiled_html_dir, skin, "{}_head.html".format(name.lower()))
            with open(include_path, "r") as include_file:
                head_includes = include_file.read()
            include_path = os.path.join(self.compiled_html_dir, skin, "{}_body.html".format(name.lower()))
            with open(include_path, "r") as include_file:
                body_includes = include_file.read()

            #
            # return params
            #
            params = {"errors": errors, "name": name.lower(), "skin": skin, "widgets": widgets,
                    "head_includes": head_includes, "body_includes": body_includes, "scalable": scalable,
                    "fa4compatibility": self.fa4compatibility  }

            env = Environment(
                loader=FileSystemLoader(self.template_dir),
                autoescape=select_autoescape(['html', 'xml'])
            )

            template = env.get_template("dashboard.jinja2")
            rendered_template = template.render(params)

            return(rendered_template)

        except:
            ha.log(self.logger, "WARNING", '-' * 60)
            ha.log(self.logger, "WARNING", "Unexpected error during DASH creation")
            ha.log(self.logger, "WARNING", '-' * 60)
            ha.log(self.logger, "WARNING", traceback.format_exc())
            ha.log(self.logger, "WARNING", '-' * 60)
            return {"errors": ["An unrecoverable error occured fetching dashboard"]}
Пример #16
0
def clear_object(object_):
    utils.log(conf.logger, "DEBUG", "Clearing callbacks for {}".format(object_))
    with conf.callbacks_lock:
        if object_ in conf.callbacks:
            del conf.callbacks[object_]
    with conf.schedule_lock:
        if object_ in conf.schedule:
            del conf.schedule[object_]
    with conf.endpoints_lock:
        if object_ in conf.endpoints:
            del conf.endpoints[object_]
Пример #17
0
 def run_in(self, callback, seconds, **kwargs):
     name = self.name
     utils.log(
         conf.logger, "DEBUG",
         "Registering run_in in {} seconds for {}".format(seconds, name))
     # convert seconds to an int if possible since a common pattern is to
     # pass this through from the config file which is a string
     exec_time = utils.get_now_ts() + int(seconds)
     handle = utils.insert_schedule(name, exec_time, callback, False, None,
                                    **kwargs)
     return handle
Пример #18
0
def handle_sig(signum, frame):
    if signum == signal.SIGUSR1:
        dump_schedule()
        dump_callbacks()
        dump_objects()
        dump_queue()
        dump_sun()
    if signum == signal.SIGHUP:
        read_apps(True)
    if signum == signal.SIGINT:
        utils.log(conf.logger, "INFO", "Keyboard interrupt")
        stopit()
Пример #19
0
 def info_listen_state(self, handle):
     name = self.name
     utils.log(conf.logger, "DEBUG",
               "Calling info_listen_state for {}".format(name))
     with conf.callbacks_lock:
         if name in conf.callbacks and handle in conf.callbacks[name]:
             callback = conf.callbacks[name][handle]
             return (callback["entity"],
                     callback["kwargs"].get("attribute", None),
                     utils.sanitize_state_kwargs(callback["kwargs"]))
         else:
             raise ValueError("Invalid handle: {}".format(handle))
Пример #20
0
 def info_timer(self, handle):
     name = self.name
     utils.log(conf.logger, "DEBUG",
               "Calling info_timer for {}".format(name))
     with conf.schedule_lock:
         if name in conf.schedule and handle in conf.schedule[name]:
             callback = conf.schedule[name][handle]
             return (datetime.datetime.fromtimestamp(callback["timestamp"]),
                     callback["interval"],
                     utils.sanitize_timer_kwargs(callback["kwargs"]))
         else:
             raise ValueError("Invalid handle: {}".format(handle))
Пример #21
0
 def fire_event(self, event, **kwargs):
     utils.log(conf.logger, "DEBUG",
            "fire_event: {}, {}".format(event, kwargs))
     if conf.ha_key != "":
         headers = {'x-ha-access': conf.ha_key}
     else:
         headers = {}
     apiurl = "{}/api/events/{}".format(conf.ha_url, event)
     r = requests.post(
         apiurl, headers=headers, json=kwargs, verify=conf.certpath
     )
     r.raise_for_status()
     return r.json()
Пример #22
0
def init_object(name, class_name, module_name, args):
    utils.log(conf.logger, "INFO", "Loading Object {} using class {} from module {}".format(name, class_name, module_name))
    module = __import__(module_name)
    app_class = getattr(module, class_name)
    conf.objects[name] = {
        "object": app_class(
            name, conf.logger, conf.error, args, conf.global_vars
        ),
        "id": uuid.uuid4()
    }

    # Call it's initialize function

    conf.objects[name]["object"].initialize()
Пример #23
0
 def run_every(self, callback, start, interval, **kwargs):
     name = self.name
     now = utils.get_now()
     if start < now:
         raise ValueError("start cannot be in the past")
     utils.log(
         conf.logger, "DEBUG",
         "Registering run_every starting {} in {}s intervals for {}".format(
              start, interval, name
         )
     )
     exec_time = start.timestamp()
     handle = utils.insert_schedule(name, exec_time, callback, True, None,
                                 interval=interval, **kwargs)
     return handle
Пример #24
0
 def get_state(self, entity_id=None, attribute=None):
     utils.log(conf.logger, "DEBUG",
            "get_state: {}.{}".format(entity_id, attribute))
     device = None
     entity = None
     if entity_id is not None and "." in entity_id:
         if not self.entity_exists(entity_id):
             return None
     if entity_id is not None:
         if "." not in entity_id:
             if attribute is not None:
                 raise ValueError(
                     "{}: Invalid entity ID: {}".format(self.name, entity))
             device = entity_id
             entity = None
         else:
             device, entity = entity_id.split(".")
     with conf.ha_state_lock:
         if device is None:
             return conf.ha_state
         elif entity is None:
             devices = {}
             for entity_id in conf.ha_state.keys():
                 thisdevice, thisentity = entity_id.split(".")
                 if device == thisdevice:
                     devices[entity_id] = conf.ha_state[entity_id]
             return devices
         elif attribute is None:
             entity_id = "{}.{}".format(device, entity)
             if entity_id in conf.ha_state:
                 return conf.ha_state[entity_id]["state"]
             else:
                 return None
         else:
             entity_id = "{}.{}".format(device, entity)
             if attribute == "all":
                 if entity_id in conf.ha_state:
                     return conf.ha_state[entity_id]
                 else:
                     return None
             else:
                 if attribute in conf.ha_state[entity_id]:
                     return conf.ha_state[entity_id][attribute]
                 elif attribute in conf.ha_state[entity_id]["attributes"]:
                     return conf.ha_state[entity_id]["attributes"][
                         attribute]
                 else:
                     return None
Пример #25
0
def ws_update(jdata):
    if len(app['websockets']) > 0:
        utils.log(
            conf.dash, "DEBUG",
            "Sending data to {} dashes: {}".format(len(app['websockets']),
                                                   jdata))

    data = json.dumps(jdata)

    for ws in app['websockets']:

        if "dashboard" in app['websockets'][ws]:
            utils.log(
                conf.dash, "DEBUG", "Found dashboard type {}".format(
                    app['websockets'][ws]["dashboard"]))
            ws.send_str(data)
Пример #26
0
 def get_callback_entries(self):
     callbacks = {}
     for name in conf.callbacks.keys():
         callbacks[name] = {}
         utils.log(conf.logger, "INFO", "{}:".format(name))
         for uuid_ in conf.callbacks[name]:
             callbacks[name][uuid_] = {}
             if "entity" in callbacks[name][uuid_]:
                 callbacks[name][uuid_]["entity"] = conf.callbacks[name][uuid_]["entity"]
             else:
                 callbacks[name][uuid_]["entity"] = None
             callbacks[name][uuid_]["type"] = conf.callbacks[name][uuid_]["type"]
             callbacks[name][uuid_]["kwargs"] = conf.callbacks[name][uuid_]["kwargs"]
             callbacks[name][uuid_]["function"] = conf.callbacks[name][uuid_]["function"]
             callbacks[name][uuid_]["name"] = conf.callbacks[name][uuid_]["name"]
     return(callbacks)
Пример #27
0
    def _add_layout(self, value, layout, occupied, dash, page, includes,
                    css_vars, global_parameters):
        if value is None:
            return
        widgetdimensions = re.compile("^(.+)\\((\d+)x(\d+)\\)$")
        value = ''.join(value.split())
        widgets = value.split(",")
        column = 1
        for wid in widgets:
            size = widgetdimensions.search(wid)
            if size:
                name = size.group(1)
                xsize = size.group(2)
                ysize = size.group(3)

            elif "widget_size" in dash:
                name = wid
                xsize = dash["widget_size"][0]
                ysize = dash["widget_size"][1]
            else:
                name = wid
                xsize = 1
                ysize = 1

            while "{}x{}".format(column, layout) in occupied:
                column += 1

            if name != "spacer":
                sanitized_name = name.replace(".", "-").replace("_",
                                                                "-").lower()
                widget = {}
                widget["id"] = "{}-{}".format(page, sanitized_name)

                if self._widget_exists(dash["widgets"], widget["id"]):
                    ha.log(self.logger, "WARNING",
                           "Duplicate widget name '{}' - ignored".format(name))
                else:
                    widget["position"] = [column, layout]
                    widget["size"] = [xsize, ysize]
                    widget["parameters"] = self._load_widget(
                        dash, includes, name, css_vars, global_parameters)
                    dash["widgets"].append(widget)

            for x in range(column, column + int(xsize)):
                for y in range(layout, layout + int(ysize)):
                    occupied["{}x{}".format(x, y)] = 1
            column += int(xsize)
Пример #28
0
    def _get_styles(self, style_str, name, field):
        #
        # Parse styles in order from a string and allow later entries to override earlier ones
        #
        result = {}
        styles = style_str.split(";")
        for style in styles:
            if style != "" and style is not None:
                pieces = style.split(":")
                if len(pieces) == 2:
                    result[pieces[0].strip()] = pieces[1]
                else:
                    ha.log(self.logger, "WARNING",
                           "malformed CSS: {} in widget '{}', field '{}' (could be a problem in the skin) - ignoring".
                           format(style, name, field))

        return result
Пример #29
0
def process_sun(action):
    utils.log(
            conf.logger, "DEBUG",
            "Process sun: {}, next sunrise: {}, next sunset: {}".format(
                action, conf.sun["next_rising"], conf.sun["next_setting"]
            )
    )
    with conf.schedule_lock:
        for name in conf.schedule.keys():
            for entry in sorted(
                    conf.schedule[name].keys(),
                    key=lambda uuid_: conf.schedule[name][uuid_]["timestamp"]
            ):
                schedule = conf.schedule[name][entry]
                if schedule["type"] == action and "inactive" in schedule:
                    del schedule["inactive"]
                    c_offset = utils.get_offset(schedule)
                    schedule["timestamp"] = utils.calc_sun(action) + c_offset
                    schedule["offset"] = c_offset
Пример #30
0
    def _add_layout(self, value, layout, occupied, dash, page, includes, css_vars, global_parameters):
        if value is None:
            return
        widgetdimensions = re.compile("^(.+)\\((\d+)x(\d+)\\)$")
        value = ''.join(value.split())
        widgets = value.split(",")
        column = 1
        for wid in widgets:
            size = widgetdimensions.search(wid)
            if size:
                name = size.group(1)
                xsize = size.group(2)
                ysize = size.group(3)

            elif "widget_size" in dash:
                name = wid
                xsize = dash["widget_size"][0]
                ysize = dash["widget_size"][1]
            else:
                name = wid
                xsize = 1
                ysize = 1

            while "{}x{}".format(column, layout) in occupied:
                column += 1

            if name != "spacer":
                sanitized_name = name.replace(".", "-").replace("_", "-").lower()
                widget = {}
                widget["id"] = "{}-{}".format(page, sanitized_name)

                if self._widget_exists(dash["widgets"], widget["id"]):
                    ha.log(self.logger, "WARNING", "Duplicate widget name '{}' - ignored".format(name))
                else:
                    widget["position"] = [column, layout]
                    widget["size"] = [xsize, ysize]
                    widget["parameters"] = self._load_widget(dash, includes, name, css_vars, global_parameters)
                    dash["widgets"].append(widget)

            for x in range(column, column + int(xsize)):
                for y in range(layout, layout + int(ysize)):
                    occupied["{}x{}".format(x, y)] = 1
            column += int(xsize)
Пример #31
0
    def set_state(self, entity_id, **kwargs):
        with conf.ha_state_lock:
            self._check_entity(entity_id)
            utils.log(
                conf.logger, "DEBUG",
                "set_state: {}, {}".format(entity_id, kwargs)
            )
            if conf.ha_key != "":
                headers = {'x-ha-access': conf.ha_key}
            else:
                headers = {}
            apiurl = "{}/api/states/{}".format(conf.ha_url, entity_id)

            if entity_id not in conf.ha_state:
                # Its a new state entry
                conf.ha_state[entity_id] = {}
                conf.ha_state[entity_id]["attributes"] = {}

            args = {}

            if "state" in kwargs:
                args["state"] = kwargs["state"]
            else:
                if "state" in conf.ha_state[entity_id]:
                    args["state"] = conf.ha_state[entity_id]["state"]

            if "attributes" in conf.ha_state[entity_id]:
                args["attributes"] = conf.ha_state[entity_id]["attributes"]
                if "attributes" in kwargs:
                    args["attributes"].update(kwargs["attributes"])
            else:
                if "attributes" in kwargs:
                    args["attributes"] = kwargs["attributes"]

            r = requests.post(apiurl, headers=headers, json=args,
                              verify=conf.certpath)
            r.raise_for_status()
            # Update our local copy of state
            state = r.json()
            conf.ha_state[entity_id] = state

            return state
Пример #32
0
 def _get_widgets(self):
     widgets = {}
     for widget_dir in [os.path.join(self.dash_install_dir, "widgets"), os.path.join(self.config_dir, "custom_widgets")]:
         #widget_dir = os.path.join(self.dash_install_dir, "widgets")
         if os.path.isdir(widget_dir):
             widget_dirs = os.listdir(path=widget_dir)
             for widget in widget_dirs:
                 if widget_dir == os.path.join(self.config_dir, "custom_widgets"):
                     ha.log(self.logger, "INFO", "Loading custom widget '{}'".format(widget))
                 if os.path.isdir(os.path.join(widget_dir, widget)):
                     jspath = os.path.join(widget_dir, widget, "{}.js".format(widget))
                     csspath = os.path.join(widget_dir, widget, "{}.css".format(widget))
                     htmlpath = os.path.join(widget_dir, widget, "{}.html".format(widget))
                     with open(jspath, 'r') as fd:
                         js = fd.read()
                     with open(csspath, 'r') as fd:
                         css = fd.read()
                     with open(htmlpath, 'r') as fd:
                         html = fd.read()
                     widgets[widget] = {"js": js, "css": css, "html": html}
     return widgets
Пример #33
0
def logon(request):
    data = yield from request.post()
    success = False
    password = data["password"]

    if password == conf.dash_password:
        utils.log(conf.dash, "INFO",
                  "Succesful logon from {}".format(request.host))

        hashed = bcrypt.hashpw(str.encode(conf.dash_password),
                               bcrypt.gensalt())

        # utils.log(conf.dash, "INFO", hashed)

        response = yield from list_dash_no_secure(request)
        response.set_cookie("adcreds", hashed.decode("utf-8"))

    else:
        utils.log(conf.dash, "WARNING",
                  "Unsuccesful logon from {}".format(request.host))
        response = yield from list_dash(request)

    return response
Пример #34
0
def run_api(loop, tasks):
    # noinspection PyBroadException
    try:
        setup_api()

        if conf.api_ssl_certificate is not None and conf.api_ssl_key is not None:
            context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
            context.load_cert_chain(conf.api_ssl_certificate, conf.api_ssl_key)
        else:
            context = None

        handler = app.make_handler()

        f = loop.create_server(handler,
                               "0.0.0.0",
                               int(conf.api_port),
                               ssl=context)
        tasks.append(asyncio. async (f))
    except:
        ha.log(conf.dash, "WARNING", '-' * 60)
        ha.log(conf.dash, "WARNING", "Unexpected error in api thread")
        ha.log(conf.dash, "WARNING", '-' * 60)
        ha.log(conf.dash, "WARNING", traceback.format_exc())
        ha.log(conf.dash, "WARNING", '-' * 60)
Пример #35
0
def run_dash(loop, tasks):
    # noinspection PyBroadException
    try:
        conf.dashboard_obj = dashboard.Dashboard(
            conf.config_dir,
            conf.dash,
            dash_compile_on_start=conf.dash_compile_on_start,
            dash_force_compile=conf.dash_force_compile,
            profile_dashboard=conf.profile_dashboard,
            dashboard_dir=conf.dashboard_dir,
        )
        setup_routes(conf.dashboard_obj)

        if conf.dash_ssl_certificate is not None and conf.dash_ssl_key is not None:
            context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
            context.load_cert_chain(conf.dash_ssl_certificate,
                                    conf.dash_ssl_key)
        else:
            context = None

        handler = app.make_handler()

        f = loop.create_server(handler,
                               "0.0.0.0",
                               int(conf.dash_port),
                               ssl=context)

        tasks.append(asyncio. async (f))
        tasks.append(asyncio. async (update_rss()))
        return f
    except:
        utils.log(conf.dash, "WARNING", '-' * 60)
        utils.log(conf.dash, "WARNING", "Unexpected error in dashboard thread")
        utils.log(conf.dash, "WARNING", '-' * 60)
        utils.log(conf.dash, "WARNING", traceback.format_exc())
        utils.log(conf.dash, "WARNING", '-' * 60)
Пример #36
0
 def _log_error(self, dash, name, error):
     dash["errors"].append("{}: {}".format(os.path.basename(name), error))
     ha.log(self.logger, "WARNING", error)
Пример #37
0
    def _get_dash(self, name, skin, skindir):
        pydashfile = os.path.join(self.dashboard_dir, "{}.pydash".format(name))
        dashfile = os.path.join(self.dashboard_dir, "{}.dash".format(name))

        #
        # Grab CSS Variables
        #
        css_vars = self._load_css_params(skin, skindir)
        if css_vars is None:
            return None
        if os.path.isfile(pydashfile):
            with open(pydashfile, 'r') as dashfd:
                dash = ast.literal_eval(dashfd.read())
        elif os.path.isfile(dashfile):
            dash = self._create_dash(name, css_vars)
            if dash is None:
                return None
        else:
            ha.log(self.logger, "WARNING", "Dashboard '{}' not found".format(name))
            return None

        if "head_includes" in css_vars and css_vars["head_includes"] is not None:
            dash["head_includes"] = css_vars["head_includes"]
        else:
            dash["head_includes"] = []
        if "body_includes" in css_vars and css_vars["body_includes"] is not None:
            dash["body_includes"] = css_vars["body_includes"]
        else:
            dash["body_includes"] = []
        #
        # Load Widgets
        #
        widgets = self._get_widgets()

        css = ""
        js = ""
        rendered_css = None

        widget = None
        try:
            #
            # Base CSS template and compile
            #
            if not os.path.isfile(os.path.join(skindir, "dashboard.css")):
                ha.log(self.logger, "WARNING", "Error loading dashboard.css for skin '{}'".format(skin))
            else:
                template = os.path.join(skindir, "dashboard.css")
                rendered_css, subs = self._do_subs(template, css_vars, "")

                css = css + rendered_css + "\n"

            #
            # Template and compile widget CSS
            #
            for widget in dash["widgets"]:
                css_template = Environment(loader=BaseLoader).from_string(
                    widgets[widget["parameters"]["widget_type"]]["css"])
                css_vars["id"] = widget["id"]
                rendered_css = css_template.render(css_vars)

                css = css + rendered_css + "\n"

            for widget in widgets:
                js = js + widgets[widget]["js"] + "\n"

        except KeyError:
            ha.log(self.logger, "WARNING", "Widget type not found: {}".format(widget["parameters"]["widget_type"]))
            return None
        except:
            ha.log(self.logger, "WARNING", '-' * 60)
            ha.log(self.logger, "WARNING", "Unexpected error in CSS file")
            ha.log(self.logger, "WARNING", '-' * 60)
            ha.log(self.logger, "WARNING", traceback.format_exc())
            ha.log(self.logger, "WARNING", '-' * 60)
            if rendered_css is not None:
                ha.log(self.logger, "WARNING", "Rendered CSS:")
                ha.log(self.logger, "WARNING", rendered_css)
                ha.log(self.logger, "WARNING", '-' * 60)
            return None

        if not os.path.exists(os.path.join(self.compiled_css_dir, skin)):
            os.makedirs(os.path.join(self.compiled_css_dir, skin))

        css_path = os.path.join(self.compiled_css_dir, skin, "{}_application.css".format(name.lower()))
        with open(css_path, "w") as css_file:
            css_file.write(css)

        if not os.path.exists(self.compiled_javascript_dir):
            os.makedirs(self.compiled_javascript_dir)

        if not os.path.exists(os.path.join(self.compiled_javascript_dir, skin)):
            os.makedirs(os.path.join(self.compiled_javascript_dir, skin))

        if not os.path.exists(self.compiled_html_dir):
            os.makedirs(self.compiled_html_dir)

        if not os.path.exists(os.path.join(self.compiled_html_dir, skin)):
            os.makedirs(os.path.join(self.compiled_html_dir, skin))

        js_path = os.path.join(self.compiled_javascript_dir, "application.js")
        with open(js_path, "w") as js_file:
            js_file.write(js)

        for widget in dash["widgets"]:
            html = widgets[widget["parameters"]["widget_type"]]["html"].replace('\n', '').replace('\r', '')
            widget["html"] = html

        return dash
Пример #38
0
    def _create_sub_dash(self, name, extension, layout, occupied, includes, level, css_vars, global_parameters):
        if extension == "dash":
            dash = {"title": "HADashboard", "widget_dimensions": [120, 120], "widget_margins": [5, 5], "columns": 8}
        else:
            dash = {}

        dash["widgets"] = []
        dash["errors"] = []
        valid_params = ["title", "widget_dimensions", "widget_margins", "columns", "widget_size", "rows", "namespace", "scalable"]
        layouts = []

        if level > self.max_include_depth:
            self._log_error(dash, name, "Maximum include level reached ({})".format(self.max_include_depth))
            return dash, layout, occupied, includes

        dashfile = os.path.join(self.dashboard_dir, "{}.{}".format(name, extension))
        page = "default"

        try:
            with open(dashfile, 'r') as yamlfd:
                defs = yamlfd.read()
        except:
            self._log_error(dash, name, "Error opening dashboard file '{}'".format(dashfile))
            return dash, layout, occupied, includes

        try:
            yaml.add_constructor('!secret', ha._secret_yaml, Loader=yaml.SafeLoader)
            dash_params = yaml.load(defs, Loader=yaml.SafeLoader)
        except yaml.YAMLError as exc:
            self._log_error(dash, name, "Error while parsing dashboard '{}':".format(dashfile))
            if hasattr(exc, 'problem_mark'):
                if exc.context is not None:
                    self._log_error(dash, name, "parser says")
                    self._log_error(dash, name, str(exc.problem_mark))
                    self._log_error(dash, name, str(exc.problem) + " " + str(exc.context))
                else:
                    self._log_error(dash, name, "parser says")
                    self._log_error(dash, name, str(exc.problem_mark))
                    self._log_error(dash, name, str(exc.problem))
            else:
                self._log_error(dash, name, "Something went wrong while parsing dashboard file")

            return dash, layout, occupied, includes
        if dash_params is not None:
            if "global_parameters" in dash_params:
                if extension == "dash":
                    global_parameters = dash_params["global_parameters"]
                else:
                    ha.log(self.logger, "WARNING",
                           "global_parameters dashboard directive illegal in imported dashboard '{}.{}'".
                           format(name, extension))

            if global_parameters is None:
                global_parameters = {"namespace": "default"}

            if "namespace" not in global_parameters:
                global_parameters["namespace"] = "default"

            for param in dash_params:
                if param == "layout" and dash_params[param] is not None:
                    for lay in dash_params[param]:
                        layouts.append(lay)
                elif param in valid_params:
                    if extension == "dash":
                        dash[param] = dash_params[param]
                    else:
                        ha.log(self.logger, "WARNING",
                               "Top level dashboard directive illegal in imported dashboard '{}.{}': {}: {}".
                               format(name, extension, param, dash_params[param]))
                else:
                    includes.append({param: dash_params[param]})

            for lay in layouts:
                if isinstance(lay, dict):
                    if "include" in lay:
                        new_dash, layout, occupied, includes = self._create_sub_dash(
                            os.path.join(self.dashboard_dir, lay["include"]),
                            "yaml", layout, occupied, includes, level + 1, css_vars, global_parameters)
                        if new_dash is not None:
                            self._merge_dashes(dash, new_dash)
                    elif "empty" in lay:
                        layout += lay["empty"]
                    else:
                        self._log_error(dash, name, "Incorrect directive, should be 'include or empty': {}".format(lay))
                else:
                    layout += 1
                    self._add_layout(lay, layout, occupied, dash, page, includes, css_vars, global_parameters)

        return dash, layout, occupied, includes
Пример #39
0
 def log(self, logger, level, msg, name=""):
     utils.log(logger, level, msg, name)
Пример #40
0
 def log_access(self, level, message):
     utils.log(self.access, level, message, "AppDaemon")
Пример #41
0
 def log(self, level, message):
     utils.log(self.logger, level, message, "AppDaemon")
Пример #42
0
 def _load_css_params(self, skin, skindir):
     yaml_path = os.path.join(skindir, "variables.yaml")
     if os.path.isfile(yaml_path):
         with open(yaml_path, 'r') as yamlfd:
             css_text = yamlfd.read()
         try:
             yaml.add_constructor('!secret', ha._secret_yaml, Loader=yaml.SafeLoader)
             css = yaml.load(css_text, Loader=yaml.SafeLoader)
         except yaml.YAMLError as exc:
             ha.log(self.logger, "WARNING", "Error loading CSS variables")
             if hasattr(exc, 'problem_mark'):
                 if exc.context is not None:
                     ha.log(self.logger, "WARNING", "parser says")
                     ha.log(self.logger, "WARNING", str(exc.problem_mark))
                     ha.log(self.logger, "WARNING", str(exc.problem) + " " + str(exc.context))
                 else:
                     ha.log(self.logger, "WARNING", "parser says")
                     ha.log(self.logger, "WARNING", str(exc.problem_mark))
                     ha.log(self.logger, "WARNING", str(exc.problem))
             return None
         if css is None:
             return {}
         else:
             return self._resolve_css_params(css, css)
     else:
         ha.log(self.logger, "WARNING", "Error loading variables.yaml for skin '{}'".format(skin))
         return None
Пример #43
0
    def _load_widget(self, dash, includes, name, css_vars, global_parameters):
        instantiated_widget = None
        #
        # Check if we have already encountered a definition
        #
        for include in includes:
            if name in include:
                instantiated_widget = include[name]
        #
        # If not, go find it elsewhere
        #
        if instantiated_widget is None:
            # Try to find in in a yaml file
            yaml_path = os.path.join(self.dashboard_dir, "{}.yaml".format(name))
            if os.path.isfile(yaml_path):
                with open(yaml_path, 'r') as yamlfd:
                    widget = yamlfd.read()
                try:
                    yaml.add_constructor('!secret', ha._secret_yaml, Loader=yaml.SafeLoader)
                    instantiated_widget = yaml.load(widget, Loader=yaml.SafeLoader)
                except yaml.YAMLError as exc:
                    _log_error(dash, name, "Error while parsing dashboard '{}':".format(yaml_path))
                    if hasattr(exc, 'problem_mark'):
                        if exc.context is not None:
                            _log_error(dash, name, "parser says")
                            _log_error(dash, name, str(exc.problem_mark))
                            _log_error(dash, name, str(exc.problem) + " " + str(exc.context))
                        else:
                            _log_error(dash, name, "parser says")
                            _log_error(dash, name, str(exc.problem_mark))
                            _log_error(dash, name, str(exc.problem))
                    return self.error_widget("Error loading widget")

            elif name.find(".") != -1:
                #
                # No file, check if it is implicitly defined via an entity id
                #
                parts = name.split(".")
                instantiated_widget = {"widget_type": parts[0], "entity": name, "title_is_friendly_name": 1}
            else:
                ha.log(self.logger, "WARNING", "Unable to find widget definition for '{}'".format(name))
                # Return some valid data so the browser will render a blank widget
                return self.error_widget("Widget definition not found")

        widget_type = None
        try:
            if "widget_type" not in instantiated_widget:
                return self.error_widget("Widget type not specified")

            #
            # One way or another we now have the widget definition
            #
            widget_type = instantiated_widget["widget_type"]

            if widget_type == "text_sensor":
                ha.log(self.logger, "WARNING",
                       "'text_sensor' widget is deprecated, please use 'sensor' instead for widget '{}'".format(name))

            # Check for custom base widgets first
            if os.path.isdir(os.path.join(self.config_dir, "custom_widgets", widget_type)):
                # This is a custom base widget so return it in full
                return self._resolve_css_params(instantiated_widget, css_vars)

            # Now regular base widgets
            if os.path.isdir(os.path.join(self.dash_install_dir, "widgets", widget_type)):
                # This is a base widget so return it in full
                return self._resolve_css_params(instantiated_widget, css_vars)

            # We are working with a derived widget so we need to do some merges and substitutions

            # first check for custom widget

            yaml_path = os.path.join(self.config_dir, "custom_widgets", "{}.yaml".format(widget_type))
            if not os.path.isfile(yaml_path):
                yaml_path = os.path.join(self.dash_install_dir, "widgets", "{}.yaml".format(widget_type))

            #
            # Variable substitutions
            #
            yaml_file, templates = self._do_subs(yaml_path, instantiated_widget, '""')
            try:
                #
                # Parse the substituted YAML file - this is a derived widget definition
                #
                yaml.add_constructor('!secret', ha._secret_yaml, Loader=yaml.SafeLoader)
                final_widget = yaml.load(yaml_file, Loader=yaml.SafeLoader)
            except yaml.YAMLError as exc:
                _log_error(dash, name, "Error in widget definition '{}':".format(widget_type))
                if hasattr(exc, 'problem_mark'):
                    if exc.context is not None:
                        _log_error(dash, name, "parser says")
                        _log_error(dash, name, str(exc.problem_mark))
                        _log_error(dash, name, str(exc.problem) + " " + str(exc.context))
                    else:
                        _log_error(dash, name, "parser says")
                        _log_error(dash, name, str(exc.problem_mark))
                        _log_error(dash, name, str(exc.problem))
                return self.error_widget("Error loading widget definition")

            #
            # Add in global params
            #
            if global_parameters is not None:
                for key in global_parameters:
                    if key == "devices":
                        if widget_type in global_parameters["devices"]:
                            for dkey in global_parameters["devices"][widget_type]:
                                if dkey not in instantiated_widget:
                                    instantiated_widget[dkey] = global_parameters["devices"][widget_type][dkey]
                    else:
                        if key not in instantiated_widget:
                            instantiated_widget[key] = global_parameters[key]

            #
            # Override defaults with parameters in users definition
            #
            for key in instantiated_widget:
                if key != "widget_type" and key not in templates:
                    # if it is an existing key and it is a style attribute, prepend, don't overwrite
                    if key in final_widget and key.find("style") != -1:
                        # if it is an existing key and it is a style attirpute, prepend, don't overwrite
                        final_widget[key] = final_widget[key] + ";" + instantiated_widget[key]
                    else:
                        final_widget[key] = instantiated_widget[key]
                    if "fields" in final_widget and key in final_widget["fields"]:
                        final_widget["fields"][key] = instantiated_widget[key]
                    if "css" in final_widget and key in final_widget["css"]:
                        final_widget["css"][key] = final_widget["css"][key] + ";" + instantiated_widget[key]
                    if "static_css" in final_widget and key in final_widget["static_css"]:
                        final_widget["static_css"][key] = final_widget["static_css"][key] + ";" + instantiated_widget[key]
                    if "icons" in final_widget and key in final_widget["icons"]:
                        final_widget["icons"][key] = instantiated_widget[key]
                    if "static_icons" in final_widget and key in final_widget["static_icons"]:
                        final_widget["static_icons"][key] = instantiated_widget[key]

            #
            # Process variables from skin
            #
            final_widget = self._resolve_css_params(final_widget, css_vars)
            #
            # Merge styles
            #
            final_widget = self._merge_styles(final_widget, name)
            return final_widget

        except FileNotFoundError:
            ha.log(self.logger, "WARNING", "Unable to find widget type '{}'".format(widget_type))
            ha.log(self.logger, "WARNING", traceback.format_exc())
            # Return some valid data so the browser will render a blank widget
            return self.error_widget("Unable to find widget type '{}'".format(widget_type))
Пример #44
0
    def _conditional_compile(self, name, skin, recompile):

        #
        # Check skin exists
        #
        skindir = os.path.join(self.config_dir, "custom_css", skin)
        if os.path.isdir(skindir):
            ha.log(self.logger, "INFO", "Loading custom skin '{}'".format(skin))
        else:
            # Not a custom skin, try product skins
            skindir = os.path.join(self.css_dir, skin)
            if not os.path.isdir(skindir):
                ha.log(self.logger, "WARNING", "Skin '{}' does not exist".format(skin))
                skin = "default"
                skindir = os.path.join(self.css_dir, "default")

        if self.dash_force_compile is False:
            do_compile = False

            if recompile is True:
                do_compile = True
            #
            # Check if compiled versions even exist and get their timestamps.
            #
            last_compiled = datetime.datetime.now()
            for file in [
                os.path.join(self.compiled_css_dir, skin, "{}_application.css".format(name.lower())),
                os.path.join(self.compiled_javascript_dir, "application.js"),
                os.path.join(self.compiled_javascript_dir, skin, "{}_init.js".format(name.lower())),
                os.path.join(self.compiled_html_dir, skin, "{}_head.html".format(name.lower())),
                os.path.join(self.compiled_html_dir, skin, "{}_body.html".format(name.lower())),
            ]:
                if not os.path.isfile(file):
                    do_compile = True

                try:
                    mtime = os.path.getmtime(file)
                except OSError:
                    mtime = 86400
                last_modified_date = datetime.datetime.fromtimestamp(mtime)
                if last_modified_date < last_compiled:
                    last_compiled = last_modified_date

            widget_mod = self._latest_file(os.path.join(self.dash_install_dir, "widgets"))
            custom_widget_mod = self._latest_file(os.path.join(self.config_dir, "custom_widgets"))
            skin_mod = self._latest_file(skindir)
            dash_mod = self._latest_file(self.dashboard_dir)

            if custom_widget_mod > last_compiled or widget_mod > last_compiled or skin_mod > last_compiled or dash_mod > last_compiled:
                do_compile = True

            # Force compilation at startup

            if self.start_time > last_compiled and self.dash_compile_on_start is True:
                do_compile = True

            if do_compile is False:
                return {"errors": []}

        ha.log(self.logger, "INFO", "Compiling dashboard '{}'".format(name))

        dash = self._get_dash(name, skin, skindir)
        if dash is None:
            dash_list = self._list_dashes()
            return {"errors": ["Dashboard has errors or is not found - check verbose_log for details"], "dash_list": dash_list}

        params = dash
        params["base_url"] = self.base_url
        params["name"] = name.lower()
        params["skin"] = skin

        #
        # Build dash specific code
        #
        env = Environment(
            loader=FileSystemLoader(self.template_dir),
            autoescape=select_autoescape(['html', 'xml'])
        )

        template = env.get_template("dashinit.jinja2")
        rendered_template = template.render(params)
        js_path = os.path.join(self.compiled_javascript_dir, skin, "{}_init.js".format(name.lower()))
        with open(js_path, "w") as js_file:
            js_file.write(rendered_template)

        template = env.get_template("head_include.jinja2")
        rendered_template = template.render(params)
        js_path = os.path.join(self.compiled_html_dir, skin, "{}_head.html".format(name.lower()))
        with open(js_path, "w") as js_file:
            js_file.write(rendered_template)

        template = env.get_template("body_include.jinja2")
        rendered_template = template.render(params)
        js_path = os.path.join(self.compiled_html_dir, skin, "{}_body.html".format(name.lower()))
        with open(js_path, "w") as js_file:
            js_file.write(rendered_template)

        return dash
Пример #45
0
 def log(self, level, message):
     utils.log(self.logger, level, message, "HADasboard")
Пример #46
0
    def __init__(self, config_dir, logger, **kwargs):
        #
        # Set Defaults
        #
        self.config_dir = config_dir
        self.logger = logger
        self.dash_install_dir = os.path.dirname(__file__)
        self.dashboard_dir = os.path.join(config_dir, "dashboards")
        self.profile_dashboard = False
        self.compile_dir = os.path.join(self.config_dir, "compiled")
        self.javascript_dir = os.path.join(self.dash_install_dir, "assets", "javascript")
        self.compiled_javascript_dir = os.path.join(self.compile_dir, "javascript")
        self.compiled_html_dir = os.path.join(self.compile_dir, "html")
        self.template_dir = os.path.join(self.dash_install_dir, "assets", "templates")
        self.css_dir = os.path.join(self.dash_install_dir, "assets", "css")
        self.compiled_css_dir = os.path.join(self.compile_dir, "css")
        self.fonts_dir = os.path.join(self.dash_install_dir, "assets", "fonts")
        self.webfonts_dir = os.path.join(self.dash_install_dir, "assets", "webfonts")
        self.images_dir = os.path.join(self.dash_install_dir, "assets", "images")
        self.base_url = ""
        self.dash_force_compile = False
        self.dash_compile_on_start = False
        self.max_include_depth = 10
        self.fa4compatibility = False
        #
        # Process any overrides
        #
        self._process_arg("profile_dashboard", kwargs)
        self._process_arg("dashboard_dir", kwargs)
        self._process_arg("compile_dir", kwargs)
        self._process_arg("javascript_dir", kwargs)
        self._process_arg("compiled_javascript_dir", kwargs)
        self._process_arg("compiled_html_dir", kwargs)
        self._process_arg("template_dir", kwargs)
        self._process_arg("css_dir", kwargs)
        self._process_arg("compiled_css_dir", kwargs)
        self._process_arg("fonts_dir", kwargs)
        self._process_arg("webfonts_dir", kwargs)
        self._process_arg("images_dir", kwargs)
        self._process_arg("base_url", kwargs)
        self._process_arg("dash_force_compile", kwargs)
        self._process_arg("dash_compile_on_start", kwargs)
        self._process_arg("max_include_depth", kwargs)
        self._process_arg("fa4compatibility", kwargs)
        #
        # Create some dirs
        #
        try:
            js = os.path.join(self.compile_dir, "javascript")
            css = os.path.join(self.compile_dir, "css")
            if not os.path.isdir(self.compile_dir):
                os.makedirs(self.compile_dir)

            if not os.path.isdir(os.path.join(self.compile_dir, "javascript")):
                os.makedirs(js)

            if not os.path.isdir(os.path.join(self.compile_dir, "css")):
                os.makedirs(css)

            ha.check_path("css", self.logger, css, permissions="rwx")
            ha.check_path("javascript", self.logger, js, permissions="rwx")


        except:
            ha.log(self.logger, "WARNING", '-' * 60)
            ha.log(self.logger, "WARNING", "Unexpected error during HADashboard initialization")
            ha.log(self.logger, "WARNING", '-' * 60)
            ha.log(self.logger, "WARNING", traceback.format_exc())
            ha.log(self.logger, "WARNING", '-' * 60)

        #
        # Set a start time
        #
        self.start_time = datetime.datetime.now()
Пример #47
0
 def access(self, level, message):
     utils.log(self.acc, level, message, "HADashboard")
Пример #48
0
 def log(self, level, message):
     utils.log(self.logger, level, message, "ADAdmin")
Пример #49
0
 def access(self, level, message):
     utils.log(self.acc, level, message, "ADAdmin")