def next_path(group_id):
    _window = utils.get_active_window()

    if _window not in ['home', 'media'] and not label_warning_shown:
        _warn()

    group = manage.get_group_by_id(group_id)
    if not group:
        utils.log(
            '\"{}\" is missing, please repoint the widget to fix it.'.format(
                group_id),
            level=xbmc.LOGERROR)
        return False, 'AutoWidget'

    group_name = group.get('label', '')
    paths = manage.find_defined_paths(group_id)

    if len(paths) > 0:
        if _window == 'media':
            call_path(group_id, paths[0]['id'])
            return False, group_name
        else:
            directory.add_menu_item(title=32013,
                                    params={'mode': 'force'},
                                    art=unpack,
                                    info={'plot': utils.get_string(32014)},
                                    isFolder=False)
            return True, group_name
    else:
        directory.add_menu_item(title=32032, art=alert, isFolder=False)
        return False, group_name
Esempio n. 2
0
def get_files_list(path, widget_id=None):
    hash = utils.path2hash(path)
    _, files, _ = utils.cache_expiry(hash, widget_id)
    if files is None:
        # We had no old content so have to block and get it now
        utils.log("Blocking cache path read: {}".format(hash[:5]), "info")
        files, changed = utils.cache_files(path, widget_id)

    new_files = []
    if "error" not in files:
        files = files.get("result").get("files")
        if not files:
            utils.log("No items found for {}".format(path))
            return

        for file in files:
            new_file = {
                k: v
                for k, v in file.items() if v not in [None, "", -1, [], {}]
            }
            if "art" in new_file:
                for art in new_file["art"]:
                    new_file["art"][art] = utils.clean_artwork_url(
                        file["art"][art])
            new_files.append(new_file)

        return new_files
def _update_strings(widget_def):
    refresh = skin_string_pattern.format(widget_def['id'], 'refresh')
    utils.set_property(refresh, '{}'.format(time.time()))
    utils.log(
        'Refreshing widget {} to display {}'.format(widget_def['id'],
                                                    widget_def['path']),
        'debug')
Esempio n. 4
0
def backup():
    choice = dialog.yesno('AutoWidget', utils.get_string(32094))

    if choice:
        filename = dialog.input(utils.get_string(32095))

        if not filename:
            dialog.notification('AutoWidget', utils.get_string(32096))
            return

        if not os.path.exists(_backup_location):
            try:
                os.makedirs(_backup_location)
            except Exception as e:
                utils.log(str(e), 'error')
                dialog.notification('AutoWidget', utils.get_string(32097))
                return

        files = [
            x for x in os.listdir(utils._addon_path) if x.endswith('.group')
        ]
        if len(files) == 0:
            dialog.notification('AutoWidget', utils.get_string(32068))
            return

        path = os.path.join(_backup_location,
                            '{}.zip'.format(filename.replace('.zip', '')))
        content = six.BytesIO()
        with zipfile.ZipFile(content, 'w', zipfile.ZIP_DEFLATED) as z:
            for file in files:
                with open(os.path.join(utils._addon_path, file), 'r') as f:
                    z.writestr(file, six.ensure_text(f.read()))

        with open(path, 'wb') as f:
            f.write(content.getvalue())
Esempio n. 5
0
 def __init__(self):
     utils.log('+++++ STARTING AUTOWIDGET SERVICE +++++',
               level=xbmc.LOGNOTICE)
     self.player = xbmc.Player()
     utils.ensure_addon_data()
     self._update_properties()
     self._update_widgets()
Esempio n. 6
0
def _update_strings(_id, path_def, setting=None, label_setting=None):
    if not path_def:
        return

    label = path_def['label']
    action = path_def['path']

    try:
        label = label.encode('utf-8')
    except:
        pass

    if setting:
        if label_setting:
            utils.log('Setting {} to {}'.format(label_setting, label))
            utils.set_skin_string(label_setting, label)

        utils.log('Setting {} to {}'.format(setting, action))
        utils.set_skin_string(setting, action)
    else:
        target = path_def['window']
        label_string = skin_string_pattern.format(_id, 'label')
        action_string = skin_string_pattern.format(_id, 'action')
        target_string = skin_string_pattern.format(_id, 'target')

        utils.log('Setting {} to {}'.format(label_string, label))
        utils.log('Setting {} to {}'.format(action_string, action))
        utils.log('Setting {} to {}'.format(target_string, target))
        utils.set_skin_string(label_string, label)
        utils.set_skin_string(action_string, action)
        utils.set_skin_string(target_string, target)
Esempio n. 7
0
def edit_widget_dialog(widget_id):
    dialog = xbmcgui.Dialog()
    updated = False
    if advanced and not warning_shown:
        _warn()

    widget_def = manage.get_widget_by_id(widget_id)
    if not widget_def:
        return

    options = _get_widget_options(widget_def)

    remove_label = utils.get_string(32025) if widget_id else utils.get_string(
        32023)
    options.append('[COLOR firebrick]{}[/COLOR]'.format(remove_label))

    idx = dialog.select(utils.get_string(32048), options)
    if idx < 0:
        return
    elif idx == len(options) - 1:
        _remove_widget(widget_id)
        utils.update_container()
        return
    else:
        key = _clean_key(options[idx])

    updated = _get_widget_value(widget_def, key)
    utils.log(updated, xbmc.LOGNOTICE)

    if updated:
        convert.save_path_details(widget_def, widget_id)
        utils.update_container()
    edit_widget_dialog(widget_id)
def get_files_list(path, titles=None, widget_id=None):
    if not titles:
        titles = []

    hash = utils.path2hash(path)
    _, files, _ = utils.cache_expiry(hash, widget_id)
    if files is None:
        # We had no old content so have to block and get it now
        utils.log("Blocking cache path read: {}".format(hash[:5]), "info")
        files, changed = utils.cache_files(path, widget_id)

    new_files = []
    if 'error' not in files:
        files = files.get('result').get('files')
        if not files:
            utils.log('No items found for {}'.format(path))
            return

        filtered_files = [x for x in files if x['title'] not in titles]
        for file in filtered_files:
            new_file = {
                k: v
                for k, v in file.items() if v not in [None, '', -1, [], {}]
            }
            if 'art' in new_file:
                for art in new_file['art']:
                    new_file['art'][art] = utils.clean_artwork_url(
                        file['art'][art])
            new_files.append(new_file)

        return new_files
Esempio n. 9
0
def update_path(widget_id, target, path=None):
    widget_def = manage.get_widget_by_id(widget_id)
    if not widget_def:
        return

    stack = widget_def.get("stack", [])

    if target == "next" and path:
        utils.log("Next Page selected from {}".format(widget_id), "debug")
        path_def = manage.get_path_by_id(widget_def["path"], widget_def["group"])
        if isinstance(path_def, dict):
            widget_def["label"] = path_def["label"]

        stack.append(path)
        widget_def["stack"] = stack
    elif target == "back" and widget_def.get("stack"):
        utils.log("Previous Page selected from {}".format(widget_id), "debug")
        widget_def["stack"] = widget_def["stack"][:-1]
    elif target == "reset":
        if len(stack) > 0:
            # simple compatibility with pre-3.3.0 widgets
            if isinstance(stack[0], dict):
                widget_def["path"] = stack[0].get("id", "")

            widget_def["stack"] = []

    manage.save_path_details(widget_def)
    _update_strings(widget_def)
    utils.update_container(True)
    back_to_top(target)
Esempio n. 10
0
def _update_strings(widget_def):
    refresh = skin_string_pattern.format(widget_def["id"], "refresh")
    utils.set_property(refresh, "{}".format(time.time()))
    utils.log(
        "Refreshing widget {} to display {}".format(widget_def["id"],
                                                    widget_def["path"]),
        "debug",
    )
 def __init__(self):
     """Starts all of the actions of AutoWidget's service."""
     super(RefreshService, self).__init__()
     utils.log('+++++ STARTING AUTOWIDGET SERVICE +++++', 'notice')
     self.player = xbmc.Player()
     utils.ensure_addon_data()
     self._update_properties()
     self._clean_widgets()
     self._update_widgets()
Esempio n. 12
0
def predict_update_frequency(history):
    if not history:
        return DEFAULT_CACHE_TIME
    update_count = 0
    duration = 0
    changes = []
    last_when, last = history[0]
    for when, content in history[1:]:
        update_count += 1
        if content == last:
            duration += when - last_when
        else:
            duration = (
                +(when - last_when) / 2
            )  # change could have happened any time inbetween
            changes.append((duration, update_count))
            duration = 0
            update_count = 0
        last_when = when
        last = content
    if not changes and duration:
        # drop the last part of the history that hasn't changed yet unless we have no other history to work with
        # This is an underestimate as we aren't sure when in the future it will change
        changes.append((duration, update_count))
    # TODO: the first change is potentially an underestimate too because we don't know how long it was unchanged for
    # before we started recording.

    # Now we have changes, we can do some trends on them.
    durations = [duration for duration, update_count in changes if update_count > 1]
    if not durations:
        return DEFAULT_CACHE_TIME
    med_dur = sorted(durations)[int(math.floor(len(durations) / 2)) - 1]
    avg_dur = sum(durations) / len(durations)
    # weighted by how many snapshots we took inbetween.
    # TODO: number of snapshots inbetween is really just increasing the confidence on the end time bot the duration as a whole.
    # so perhaps a better metric is the error margin of the duration? and not weighting by that completely.
    # ie durations with wide margin of error should be less important. e.g. times kodi was never turned on for months/weeks.
    weighted = sum([d * c for d, c in changes]) / sum([c for _, c in changes])
    # TODO: also try exponential decay. Older durations are less important than newer ones.
    ones = len([c for d, c in changes if c == 1]) / float(len(changes))
    # TODO: if many streaks with lots of counts then its stable and can predict
    utils.log(
        "avg_dur {:0.0f}s, med_dur {:0.0f}s, weighted {:0.0f}s, ones {:0.2f}, all {}".format(
            avg_dur, med_dur, weighted, ones, changes
        ),
        "debug",
    )
    if ones > 0.9:
        # too unstable so no point guessing
        return DEFAULT_CACHE_TIME
    elif DEFAULT_CACHE_TIME > avg_dur / 2.0:
        # should not got less than 5min otherwise our updates go in a loop
        return DEFAULT_CACHE_TIME
    else:
        return (
            avg_dur / 2.0
        )  # we want to ensure we check more often than the actual predicted expiry
Esempio n. 13
0
def group_menu(group_id):
    _window = utils.get_active_window()
    _id = uuid.uuid4()

    group_def = manage.get_group_by_id(group_id)
    if not group_def:
        utils.log(
            '"{}" is missing, please repoint the widget to fix it.'.format(
                group_id),
            "error",
        )
        return False, "AutoWidget", None

    group_name = group_def["label"]
    group_type = group_def["type"]
    paths = group_def["paths"]
    content = group_def.get("content")

    if len(paths) > 0:
        utils.log(
            u"Showing {} group: {}".format(group_type,
                                           six.text_type(group_name)),
            "debug",
        )
        cm = []
        art = folder_shortcut if group_type == "shortcut" else folder_sync

        for idx, path_def in enumerate(paths):
            if _window == "media":
                cm = _create_path_context_items(group_id, path_def["id"], idx,
                                                len(paths), group_type)

            directory.add_menu_item(
                title=path_def["label"],
                params={
                    "mode": "path",
                    "group": group_id,
                    "path_id": path_def["id"]
                },
                info=path_def["file"],
                art=path_def["file"].get("art", art),
                cm=cm,
                isFolder=False,
            )

        if _window != "home":
            _create_action_items(group_def, _id)
    else:
        directory.add_menu_item(
            title=30019,
            art=utils.get_art("alert"),
            isFolder=False,
            props={"specialsort": "bottom"},
        )

    return True, group_name, content
Esempio n. 14
0
def _log_params(_plugin, _handle, _params):
    msg = "[{}]"

    params = dict(parse_qsl(_params))
    if params:
        msg = msg.format("][".join([" {}: {} ".format(p, params[p]) for p in params]))
    else:
        msg = msg.format(" root ")
    utils.log(msg, "info")

    return params
def _log_params(_plugin, _handle, _params):
    msg = '[{}]'

    params = dict(parse_qsl(_params))
    if params:
        msg = msg.format(']['.join(
            [' {}: {} '.format(p, params[p]) for p in params]))
    else:
        msg = msg.format(' root ')
    utils.log(msg, 'info')

    return params
Esempio n. 16
0
 def __init__(self):
     """Starts all of the actions of AutoWidget's service."""
     super(RefreshService, self).__init__()
     utils.log("+++++ STARTING AUTOWIDGET SERVICE +++++", "info")
     self.player = Player()
     utils.ensure_addon_data()
     self._update_properties()
     self._clean_widgets()
     self._update_widgets()
     # Shutting down. Close thread
     if _thread is not None:
         _thread.stop()
Esempio n. 17
0
def get_group_by_id(group_id):
    if not group_id:
        return

    filename = '{}.group'.format(group_id)
    path = os.path.join(_addon_path, filename)

    try:
        group_def = utils.read_json(path)
    except ValueError:
        utils.log('Unable to parse: {}'.format(path))

    return group_def
Esempio n. 18
0
def chance_playback_updates_widget(history_path, plays, cutoff_time=60 * 5):
    cache_data = utils.read_json(history_path)
    history = cache_data.setdefault("history", [])
    # Complex version
    # - for each widget
    #    - come up with chance it will update after a playback
    #    - each pair of updates, is there a playback inbetween and updated with X min after playback
    #    - num playback with change / num playback with no change
    changes, non_changes, unrelated_changes = 0, 0, 0
    update = ""
    time_since_play = 0
    for play_time, media_type in plays:
        while True:
            last_update = update
            if not history:
                break
            update_time, update = history.pop(0)
            time_since_play = update_time - play_time
            # log("{} {} {} {}".format(update[:5],last_update[:5], unrelated_changes, time_since_play), 'notice')
            if time_since_play > 0:
                break
            elif update != last_update:
                unrelated_changes += 1

        if update == last_update:
            non_changes += 1
        elif (
            time_since_play > cutoff_time
        ):  # update too long after playback to be releated
            pass
        else:
            changes += 1
        # TODO: what if the previous update was a long time before playback?

    # There is probably a more statistically correct way of doing this but the idea is that
    # with few datapoints we should tend towards 0.5 probability but as we get more datapoints
    # then error goes down and rely on actual changes vs nonchanges
    # We will do a simple weighted average with 0.5 to simulate this
    # TODO: currently random widgets score higher than recently played widgets. need to score them lower
    # as they are less relevent
    utils.log(
        "changes={}, non_changes={}, unrelated_changes={}".format(
            changes, non_changes, unrelated_changes
        ),
        "debug",
    )
    datapoints = float(changes + non_changes)
    prob = changes / float(changes + non_changes + unrelated_changes)
    unknown_weight = 4
    prob = (prob * datapoints + 0.5 * unknown_weight) / (datapoints + unknown_weight)
    return prob
Esempio n. 19
0
def _log_params(_plugin, _handle, _params):
    params = dict(parse_qsl(_params))
    
    logstring = ''
    
    for param in params:
        logstring += '[ {0}: {1} ] '.format(param, params[param])
    
    if not logstring:
        logstring = '[ Root Menu ]'

    utils.log(logstring, level=xbmc.LOGNOTICE)

    return params
Esempio n. 20
0
def call_path(path_id):
    path_def = manage.get_path_by_id(path_id)
    if not path_def:
        return

    utils.call_builtin("Dialog.Close(busydialog)", 500)
    final_path = ""

    if path_def["target"] == "settings":
        final_path = "Addon.OpenSettings({})".format(
            path_def["file"]["file"]
            .replace("plugin://", "")
            .replace("script://", "")
            .split("/")[0]
        )
    elif (
        path_def["target"] == "shortcut"
        and path_def["file"]["filetype"] == "file"
        and path_def["content"] != "addons"
    ):
        if path_def["file"]["file"] == "addons://install/":
            final_path = "InstallFromZip"
        elif not path_def["content"] or path_def["content"] == "files":
            if path_def["file"]["file"].startswith("androidapp://sources/apps/"):
                final_path = "StartAndroidActivity({})".format(
                    path_def["file"]["file"].replace("androidapp://sources/apps/", "")
                )
            elif path_def["file"]["file"].startswith("pvr://"):
                final_path = "PlayMedia({})".format(path_def["file"]["file"])
            else:
                final_path = "RunPlugin({})".format(path_def["file"]["file"])
        elif (
            all(i in path_def["file"]["file"] for i in ["(", ")"])
            and "://" not in path_def["file"]["file"]
        ):
            final_path = path_def["file"]["file"]
        else:
            final_path = "PlayMedia({})".format(path_def["file"]["file"])
    elif (
        path_def["target"] == "widget"
        or path_def["file"]["filetype"] == "directory"
        or path_def["content"] == "addons"
    ):
        final_path = "ActivateWindow({},{},return)".format(
            path_def.get("window", "Videos"), path_def["file"]["file"]
        )

    if final_path:
        utils.log("Calling path from {} using {}".format(path_id, final_path), "debug")
        utils.call_builtin(final_path)
Esempio n. 21
0
def get_group_by_id(group_id):
    if not group_id:
        return {}

    filename = "{}.group".format(group_id)
    path = os.path.join(_addon_data, filename)

    try:
        group_def = utils.read_json(path)
    except ValueError:
        utils.log("Unable to parse: {}".format(path))
        return

    return group_def
Esempio n. 22
0
def group_menu(group_id):
    _window = utils.get_active_window()
    _id = uuid.uuid4()

    group_def = manage.get_group_by_id(group_id)
    if not group_def:
        utils.log(
            '\"{}\" is missing, please repoint the widget to fix it.'.format(
                group_id), 'error')
        return False, 'AutoWidget'

    group_name = group_def['label']
    group_type = group_def['type']
    paths = group_def['paths']

    if len(paths) > 0:
        utils.log(
            u'Showing {} group: {}'.format(group_type,
                                           six.text_type(group_name)), 'debug')
        cm = []
        art = folder_shortcut if group_type == 'shortcut' else folder_sync

        for idx, path_def in enumerate(paths):
            if _window == 'media':
                cm = _create_context_items(group_id, path_def['id'], idx,
                                           len(paths), group_type)

            directory.add_menu_item(title=path_def['label'],
                                    params={
                                        'mode': 'path',
                                        'group': group_id,
                                        'path_id': path_def['id']
                                    },
                                    info=path_def['file'],
                                    art=path_def['file']['art'] or art,
                                    cm=cm,
                                    isFolder=False)

        if _window != 'home':
            _create_action_items(group_def, _id)
    else:
        directory.add_menu_item(title=32032,
                                art=utils.get_art('alert'),
                                isFolder=False,
                                props={'specialsort': 'bottom'})

    return True, group_name
Esempio n. 23
0
def edit_dialog(group_id, path_id=''):
    dialog = xbmcgui.Dialog()
    updated = False
    if advanced and not warning_shown:
        _warn()

    group_def = manage.get_group_by_id(group_id)
    if not group_def:
        return
    if path_id:
        path_def = manage.get_path_by_id(path_id, group_id)
        if not path_def:
            return

    edit_def = path_def if path_id else group_def
    options = _get_options(edit_def)

    remove_label = utils.get_string(32025) if path_id else utils.get_string(
        32023)
    options.append('[COLOR firebrick]{}[/COLOR]'.format(remove_label))

    idx = dialog.select(utils.get_string(32048), options)
    if idx < 0:
        return
    elif idx == len(options) - 1:
        if path_id:
            _remove_path(path_id, group_id)
            utils.update_container(group_def['type'])
        else:
            _remove_group(group_id)
            utils.update_container(group_def['type'])
        return
    else:
        key = _clean_key(options[idx])

    updated = _get_value(edit_def, key)
    utils.log(updated, xbmc.LOGNOTICE)

    if updated:
        if path_id:
            manage.write_path(group_def, path_def=path_def, update=path_id)
        else:
            manage.write_path(group_def)

        utils.update_container(group_def['type'])
    edit_dialog(group_id, path_id)
Esempio n. 24
0
def backup():
    dialog = xbmcgui.Dialog()
    choice = dialog.yesno("AutoWidget", utils.get_string(30071))

    if choice:
        filename = dialog.input(utils.get_string(30072))

        if not filename:
            dialog.notification("AutoWidget", utils.get_string(30073))
            del dialog
            return

        if not os.path.exists(_backup_location):
            try:
                os.makedirs(_backup_location)
            except Exception as e:
                utils.log(str(e), "error")
                dialog.notification("AutoWidget", utils.get_string(30074))
                del dialog
                return

        files = [
            x
            for x in os.listdir(_addon_data)
            if any(
                x.endswith(i)
                for i in [".group", ".widget", ".history", ".cache", ".log"]
            )
        ]
        if len(files) == 0:
            dialog.notification("AutoWidget", utils.get_string(30046))
            del dialog
            return

        path = os.path.join(
            _backup_location, "{}.zip".format(filename.replace(".zip", ""))
        )
        content = six.BytesIO()
        with zipfile.ZipFile(content, "w", zipfile.ZIP_DEFLATED) as z:
            for file in files:
                with open(os.path.join(_addon_data, file), "r") as f:
                    z.writestr(file, six.ensure_text(f.read()))

        with open(path, "wb") as f:
            f.write(content.getvalue())
    del dialog
Esempio n. 25
0
def cache_and_update(widget_ids):
    """a widget might have many paths. Ensure each path is either queued for an update
    or is expired and if so force it to be refreshed. When going through the queue this
    could mean we refresh paths that other widgets also use. These will then be skipped.
    """

    assert widget_ids
    effected_widgets = set()
    for widget_id in widget_ids:
        widget_def = manage.get_widget_by_id(widget_id)
        if not widget_def:
            continue
        changed = False
        widget_path = widget_def.get("path", {})
        utils.log(
            "trying to update {} with widget def {}".format(
                widget_id, widget_def),
            "inspect",
        )
        if type(widget_path) != list:
            widget_path = [widget_path]
        for path in widget_path:
            if isinstance(path, dict):
                _label = path["label"]
                path = path["file"]["file"]
            hash = utils.path2hash(path)
            # TODO: we might be updating paths used by widgets that weren't initiall queued.
            # We need to return those and ensure they get refreshed also.
            effected_widgets = effected_widgets.union(
                utils.widgets_for_path(path))
            if utils.is_cache_queue(hash):
                # we need to update this path regardless
                new_files, files_changed = utils.cache_files(path, widget_id)
                changed = changed or files_changed
                utils.remove_cache_queue(hash)
            # else:
            #     # double check this hasn't been updated already when updating another widget
            #     expiry, _  = utils.cache_expiry(hash, widget_id, no_queue=True)
            #     if expiry <= time.time():
            #         utils.cache_files(path, widget_id)
            #     else:
            #         pass # Skipping this path because its already been updated
        # TODO: only need to do that if a path has changed which we can tell from the history
        if changed:
            _update_strings(widget_def)
    return effected_widgets
Esempio n. 26
0
def find_defined_paths(group_id=None):
    paths = []
    if group_id:
        filename = '{}.group'.format(group_id)
        path = os.path.join(_addon_path, filename)

        try:
            group_def = utils.read_json(path)
        except ValueError:
            utils.log('Unable to parse: {}'.format(path))

        if group_def:
            return group_def.get('paths', [])
    else:
        for group in find_defined_groups():
            paths.append(find_defined_paths(group_id=group.get('id')))

    return paths
Esempio n. 27
0
def call_path(path_id):
    path_def = manage.get_path_by_id(path_id)
    if not path_def:
        return

    utils.call_builtin('Dialog.Close(busydialog)', 500)
    final_path = ''

    if path_def['target'] == 'shortcut' and path_def['file']['filetype'] == 'file' \
            and path_def['content'] != 'addons':
        if path_def['file']['file'] == 'addons://install/':
            final_path = 'InstallFromZip'
        elif not path_def['content'] or path_def['content'] == 'files':
            if path_def['file']['file'].startswith(
                    'androidapp://sources/apps/'):
                final_path = 'StartAndroidActivity({})'.format(
                    path_def['file']['file'].replace(
                        'androidapp://sources/apps/', ''))
            elif path_def['file']['file'].startswith('pvr://'):
                final_path = 'PlayMedia({})'.format(path_def['file']['file'])
            else:
                final_path = 'RunPlugin({})'.format(path_def['file']['file'])
        elif all(
                i in path_def['file']['file']
                for i in ['(', ')']) and '://' not in path_def['file']['file']:
            final_path = path_def['file']['file']
        else:
            final_path = 'PlayMedia({})'.format(path_def['file']['file'])
    elif path_def['target'] == 'widget' or path_def['file']['filetype'] == 'directory' \
            or path_def['content'] == 'addons':
        final_path = 'ActivateWindow({},{},return)'.format(
            path_def.get('window', 'Videos'), path_def['file']['file'])
    elif path_def['target'] == 'settings':
        final_path = 'Addon.OpenSettings({})'.format(
            path_def['file']['file'].replace('plugin://', ''))

    if final_path:
        utils.log('Calling path from {} using {}'.format(path_id, final_path),
                  'debug')
        utils.call_builtin(final_path)

    return False, path_def['label']
Esempio n. 28
0
def widgets_changed_by_watching(media_type):
    # Predict which widgets the skin might have that could have changed based on recently finish
    # watching something

    all_cache = filter(
        os.path.isfile, glob.glob(os.path.join(_addon_data, "*.history"))
    )

    # Simple version. Anything updated recently (since startup?)
    # priority = sorted(all_cache, key=os.path.getmtime)
    # Sort by chance of it updating
    plays = utils.read_json(_playback_history_path, default={}).setdefault("plays", [])
    plays_for_type = [(time, t) for time, t in plays if t == media_type]
    priority = sorted(
        [
            (
                chance_playback_updates_widget(path, plays_for_type),
                utils.read_json(path).get("path", ""),
                path,
            )
            for path in all_cache
        ],
        reverse=True,
    )

    for chance, path, history_path in priority:
        hash = path2hash(path)
        last_update = os.path.getmtime(history_path) - _startup_time
        if last_update < 0:
            utils.log(
                "widget not updated since startup {} {}".format(last_update, hash[:5]),
                "notice",
            )
        # elif chance < 0.3:
        #     log("chance widget changed after play {}% {}".format(chance, hash[:5]), 'notice')
        else:
            utils.log(
                "chance widget changed after play {}% {}".format(chance, hash[:5]),
                "notice",
            )
            yield hash, path
Esempio n. 29
0
def get_inactive_path(paths):
    active_widgets = sorted(clean(all=True),
                            key=lambda x: x.get('updated', 0),
                            reverse=True)
    active_paths = []
    inactive_path_ids = []

    if len(active_widgets) > 0:
        for active_widget in active_widgets:
            active_paths.append(active_widget.get('path', {}))

        for index, path in enumerate(paths, start=0):
            if path not in active_paths:
                inactive_path_ids.append(index)
                utils.log(path, 'info')
                utils.log('inactive path: ' + path['label'], 'info')

    if not inactive_path_ids:
        return []
    else:
        return random.choice(inactive_path_ids)
Esempio n. 30
0
def find_defined_groups(_type=''):
    groups = []

    for filename in [
            x for x in os.listdir(_addon_path) if x.endswith('.group')
    ]:
        path = os.path.join(_addon_path, filename)

        try:
            group_def = utils.read_json(path)
        except ValueError:
            utils.log('Unable to parse: {}'.format(path))

        if group_def:
            if _type:
                if group_def['type'] == _type:
                    groups.append(group_def)
            else:
                groups.append(group_def)

    return groups