def _update_widgets(self):
        self._refresh(True)

        while not self.abortRequested():
            for _ in self.tick(15, 60 * 15):
                # TODO: somehow delay to all other plugins loaded?
                unrefreshed_widgets = set()
                for hash, widget_ids in utils.next_cache_queue():
                    effected_widgets = cache_and_update(widget_ids)
                    utils.remove_cache_queue(
                        hash
                    )  # Just in queued path's widget defintion has changed and it didn't update this path
                    unrefreshed_widgets = unrefreshed_widgets.union(
                        effected_widgets).difference(set(widget_ids))
                    # # wait 5s or for the skin to reload the widget
                    # # this should reduce churn at startup where widgets take too long too long show up
                    # before_update = time.time() # TODO: have .access file so we can put above update
                    # while _ in self.tick(1, 10, lambda: utils.last_read(hash) > before_update):
                    #     pass
                    # utils.log("paused queue until read {:.2} for {}".format(utils.last_read(hash)-before_update, hash[:5]), 'info')
                    if self.abortRequested():
                        break
                for widget_id in unrefreshed_widgets:
                    widget_def = manage.get_widget_by_id(widget_id)
                    if not widget_def:
                        continue
                    _update_strings(widget_def)

            if self.abortRequested():
                break

            if not self._refresh():
                continue
Esempio n. 2
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. 3
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)
Esempio n. 4
0
def refresh(widget_id, widget_def=None, paths=None, force=False, single=False):
    if not widget_def:
        widget_def = manage.get_widget_by_id(widget_id)

    if widget_def["action"] in ["static", "merged"]:
        return paths

    current_time = time.time()
    updated_at = widget_def.get("updated", 0)

    default_refresh = settings.get_setting_float("service.refresh_duration")
    refresh_duration = float(widget_def.get("refresh", default_refresh))

    if updated_at <= current_time - (3600 * refresh_duration) or force:
        group_id = widget_def["group"]
        action = widget_def.get("action")
        current = int(widget_def.get("current", 0))
        widget_def["stack"] = []

        if not paths:
            cycle_paths = widget_def.get("cycle_paths")
            if cycle_paths is None:
                cycle_paths = [
                    p.get("id") for p in manage.find_defined_paths(group_id)
                ]
                widget_def["cycle_paths"] = cycle_paths

            paths = [p for p in cycle_paths]

        if action:
            if len(paths) > 0:
                next = 0
                if action == "next":
                    next = (current + 1) % len(paths)

                elif action == "random":
                    random.shuffle(paths)
                    next = random.randrange(len(paths))

                widget_def["current"] = next
                path_id = paths[next]
                paths.remove(paths[next])

                widget_def["path"] = path_id
                if widget_def["path"]:
                    path_label = manage.get_path_by_id(path_id, group_id).get(
                        "label", "")
                    widget_def["label"] = path_label
                    widget_def["updated"] = 0 if force else current_time

                    manage.save_path_details(widget_def)
                    _update_strings(widget_def)

        if single:
            utils.update_container(True)

    return paths
Esempio n. 5
0
def merged_path(group_id, widget_id):
    _window = utils.get_active_window()

    group_def = manage.get_group_by_id(group_id)
    group_name = group_def.get("label", "")
    paths = group_def.get("paths", [])
    if len(paths) == 0:
        directory.add_menu_item(title=30019,
                                art=utils.get_art("alert"),
                                isFolder=False)
        return True, group_name, None

    widget_def = manage.get_widget_by_id(widget_id, group_id)
    if widget_def and _window != "dialog":
        paths = widget_def["path"]
    elif not widget_def:
        idxs = manage.choose_paths(utils.get_string(30089), paths, 5)

        if idxs is not None:
            if len(idxs) > 0:
                widget_def = manage.initialize(group_def,
                                               "merged",
                                               widget_id,
                                               keep=idxs)
                paths = widget_def["path"]

    if widget_def:
        titles = []
        for idx, path in enumerate(paths):
            # simple compatibility with pre-3.3.0 widgets
            if isinstance(path, dict):
                path = path.get("id", "")
                paths[idx] = path
                widget_def["path"] = paths
                manage.save_path_details(widget_def)

            path_def = manage.get_path_by_id(path, group_id)
            titles, cat, type = show_path(
                group_id,
                path_def["label"],
                widget_id,
                path_def,
                idx=idx,
                titles=titles,
                num=len(paths),
                merged=True,
            )

        return titles, cat, type
    else:
        directory.add_menu_item(title=30045, art=info, isFolder=True)
        return True, group_name, None
Esempio n. 6
0
def refresh(widget_id, widget_def=None, paths=None, force=False, single=False):
    if not widget_def:
        widget_def = manage.get_widget_by_id(widget_id)

    if widget_def["action"] in ["static", "merged"]:
        return paths

    current_time = time.time()
    updated_at = widget_def.get("updated", 0)

    default_refresh = utils.get_setting_float("service.refresh_duration")
    refresh_duration = float(widget_def.get("refresh", default_refresh))

    if updated_at <= current_time - (3600 * refresh_duration) or force:
        group_id = widget_def["group"]
        action = widget_def.get("action")
        current = int(widget_def.get("current", -1))
        widget_def["stack"] = []
        widget_def["label"] = ""

        if not paths:
            paths = manage.find_defined_paths(group_id)

        if action:
            if len(paths) > 0:
                next = 0
                if action == "next":
                    next = (current + 1) % len(paths)
                elif action == "random":
                    random.shuffle(paths)
                    next = random.randrange(len(paths))
                elif action == 'randomized':
                    next = manage.get_inactive_path(paths)
                    if next == []:
                        next = current

                widget_def['current'] = next
                path_def = paths[next]
                paths.remove(paths[next])

                widget_def["path"] = path_def
                if widget_def["path"]:
                    widget_def["updated"] = 0 if force else current_time

                    manage.save_path_details(widget_def)
                    _update_strings(widget_def)

        if single:
            utils.update_container(True)

    return paths
Esempio n. 7
0
def merged_path(group_id, widget_id):
    _window = utils.get_active_window()

    group_def = manage.get_group_by_id(group_id)
    group_name = group_def.get("label", "")
    paths = group_def.get("paths", [])
    if len(paths) == 0:
        directory.add_menu_item(title=32032,
                                art=utils.get_art("alert"),
                                isFolder=False)
        return True, group_name

    widget_def = manage.get_widget_by_id(widget_id, group_id)
    if widget_def and _window != "dialog":
        paths = widget_def["path"]
    elif not widget_def:
        dialog = xbmcgui.Dialog()
        idxs = dialog.multiselect(
            utils.get_string(32115),
            [i["label"] for i in paths],
            preselect=list(range(len(paths))) if len(paths) <= 5 else [],
        )

        if idxs is not None:
            if len(idxs) > 0:
                widget_def = manage.initialize(group_def,
                                               "merged",
                                               widget_id,
                                               keep=idxs)
                paths = widget_def["path"]

    if widget_def:
        titles = []
        for idx, path_def in enumerate(paths):
            titles, cat = show_path(
                group_id,
                path_def["label"],
                widget_id,
                path_def["file"]["file"],
                idx=idx,
                titles=titles,
                num=len(paths),
                merged=True,
            )

        return titles, cat
    else:
        directory.add_menu_item(title=32067,
                                art=utils.get_art("information_outline"),
                                isFolder=True)
        return True, group_name
def edit_widget_dialog(widget_id):
    updated = False
    if advanced and not warning_shown:
        _warn()

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

    updated = _show_widget_options(widget_def)
    if updated:
        manage.save_path_details(widget_def)
        utils.update_container(True)
        edit_widget_dialog(widget_id)
def refresh(widget_id, widget_def=None, paths=None, force=False, single=False):
    if not widget_def:
        widget_def = manage.get_widget_by_id(widget_id)

    if widget_def['action'] in ['static', 'merged']:
        return paths

    current_time = time.time()
    updated_at = widget_def.get('updated', 0)

    default_refresh = utils.get_setting_float('service.refresh_duration')
    refresh_duration = float(widget_def.get('refresh', default_refresh))

    if updated_at <= current_time - (3600 * refresh_duration) or force:
        group_id = widget_def['group']
        action = widget_def.get('action')
        current = int(widget_def.get('current', -1))
        widget_def['stack'] = []
        widget_def['label'] = ''

        if not paths:
            paths = manage.find_defined_paths(group_id)

        if action:
            if len(paths) > 0:
                next = 0
                if action == 'next':
                    next = (current + 1) % len(paths)
                elif action == 'random':
                    random.shuffle(paths)
                    next = random.randrange(len(paths))

                widget_def['current'] = next
                path_def = paths[next]
                paths.remove(paths[next])

                widget_def['path'] = path_def
                if widget_def['path']:
                    widget_def['updated'] = 0 if force else current_time

                    manage.save_path_details(widget_def)
                    _update_strings(widget_def)

        if single:
            utils.update_container(True)

    return paths
Esempio n. 10
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. 11
0
def refresh(widget_id, widget_def=None, paths=None, force=False):
    if not widget_def:
        widget_def = manage.get_widget_by_id(widget_id)

    current_time = time.time()
    updated_at = widget_def.get('updated', 0)

    default_refresh = utils.get_setting_float('service.refresh_duration')
    refresh_duration = float(widget_def.get('refresh', default_refresh))

    if updated_at <= current_time - (3600 * refresh_duration) or force:
        path_def = {}

        _id = widget_def['id']
        group_id = widget_def['group']
        action = widget_def.get('action')
        setting = widget_def.get('path_setting')
        label_setting = widget_def.get('label_setting')
        current = int(widget_def.get('current', -1))

        if not paths:
            paths = manage.find_defined_paths(group_id)
            random.shuffle(paths)

        if action:
            if len(paths) > 0:
                next = 0
                if action == 'next':
                    next = (current + 1) % len(paths)
                elif action == 'random':
                    next = random.randrange(len(paths))

                widget_def['current'] = next
                path_def = paths[next]
                paths.remove(paths[next])

                widget_def['path'] = path_def.get('id')
                if widget_def['path']:
                    widget_def['updated'] = 0 if force else current_time

                    convert.save_path_details(widget_def, _id)
                    _update_strings(_id, path_def, setting, label_setting)

                    utils.update_container()

    return paths
Esempio n. 12
0
def merged_path(group_id, widget_id):
    _window = utils.get_active_window()

    group_def = manage.get_group_by_id(group_id)
    group_name = group_def.get('label', '')
    paths = group_def.get('paths', [])
    if len(paths) == 0:
        directory.add_menu_item(title=32032,
                                art=utils.get_art('alert'),
                                isFolder=False)
        return True, group_name

    widget_def = manage.get_widget_by_id(widget_id, group_id)
    if widget_def and _window != 'dialog':
        paths = widget_def['path']
    elif not widget_def:
        dialog = xbmcgui.Dialog()
        idxs = dialog.multiselect(
            utils.get_string(32115), [i['label'] for i in paths],
            preselect=list(range(len(paths))) if len(paths) <= 5 else [])

        if idxs is not None:
            if len(idxs) > 0:
                widget_def = manage.initialize(group_def,
                                               'merged',
                                               widget_id,
                                               keep=idxs)
                paths = widget_def['path']

    if widget_def:
        titles = []
        for idx, path_def in enumerate(paths):
            titles, cat = show_path(group_id,
                                    path_def['label'],
                                    widget_id,
                                    path_def['file']['file'],
                                    idx=idx,
                                    num=len(paths),
                                    merged=True)

        return titles, cat
    else:
        directory.add_menu_item(title=32067,
                                art=utils.get_art('information_outline'),
                                isFolder=True)
        return True, group_name
Esempio n. 13
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 = widget_def["path"]
        if isinstance(path_def, dict):
            widget_def["label"] = path_def["label"]

        stack.append(widget_def["path"])
        widget_def["stack"] = stack
        widget_def["path"] = path
    elif target == "back" and widget_def.get("stack"):
        utils.log("Previous Page selected from {}".format(widget_id), "debug")
        widget_def["path"] = widget_def["stack"][-1]
        widget_def["stack"] = widget_def["stack"][:-1]

        if len(widget_def["stack"]) == 0:
            widget_def["label"] = ""
    elif target == "reset":
        if len(stack) > 0:
            widget_def["path"] = widget_def["stack"][0]
            widget_def["stack"] = []
            widget_def["label"] = ""

    action = widget_def[
        "path"] if widget_def["action"] != "merged" else "merged"
    if isinstance(widget_def["path"], dict):
        action = widget_def["path"]["file"]["file"]
    manage.save_path_details(widget_def)
    _update_strings(widget_def)
    utils.update_container(True)
    back_to_top(target)
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 = widget_def['path']
        if isinstance(path_def, dict):
            widget_def['label'] = path_def['label']

        stack.append(widget_def['path'])
        widget_def['stack'] = stack
        widget_def['path'] = path
    elif target == 'back' and widget_def.get('stack'):
        utils.log('Previous Page selected from {}'.format(widget_id), 'debug')
        widget_def['path'] = widget_def['stack'][-1]
        widget_def['stack'] = widget_def['stack'][:-1]

        if len(widget_def['stack']) == 0:
            widget_def['label'] = ''
    elif target == 'reset':
        if len(stack) > 0:
            widget_def['path'] = widget_def['stack'][0]
            widget_def['stack'] = []
            widget_def['label'] = ''

    action = widget_def[
        'path'] if widget_def['action'] != 'merged' else 'merged'
    if isinstance(widget_def['path'], dict):
        action = widget_def['path']['file']['file']
    manage.save_path_details(widget_def)
    _update_strings(widget_def)
    utils.update_container(True)
    back_to_top(target)
Esempio n. 15
0
def cache_and_update(path, widget_id, cache_data, notify=None):
    """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_id
    assert cache_data.get("path") == path
    assert widget_id in cache_data["widgets"]

    hash = path2hash(path)
    if not is_cache_queue(hash):
        return []

    if notify is not None:
        widget_def = manage.get_widget_by_id(widget_id)
        if widget_def is not None:
            notify(widget_def.get("label", ""), path)

    new_files, files_changed = cache_files(path, widget_id)
    remove_cache_queue(hash)

    # TODO: this is all widgets that ever requested this path. do we
    # need to update all of them?
    return cache_data["widgets"] if files_changed else []
Esempio n. 16
0
def path_menu(group_id, action, widget_id):
    group_def = manage.get_group_by_id(group_id)
    if not group_def:
        directory.add_menu_item(title=32073,
                                info={'plot': utils.get_string(32075)},
                                art=utils.get_art('alert'),
                                isFolder=True)
        return True, 'AutoWidget'

    group_name = group_def.get('label', '')
    paths = group_def.get('paths', [])
    if len(paths) == 0:
        directory.add_menu_item(title=32032,
                                art=utils.get_art('alert'),
                                isFolder=True)
        return True, group_name

    widget_def = manage.get_widget_by_id(widget_id, group_id)
    if not widget_def:
        dialog = xbmcgui.Dialog()
        if action == 'static':
            idx = dialog.select(utils.get_string(32114),
                                [i['label'] for i in paths])
            if idx == -1:
                return True, 'AutoWidget'

            widget_def = manage.initialize(group_def,
                                           action,
                                           widget_id,
                                           keep=idx)
        elif action == 'cycling':
            idx = dialog.select(
                utils.get_string(32081),
                [utils.get_string(32079),
                 utils.get_string(32080)])
            if idx == -1:
                return True, 'AutoWidget'

            _action = 'random' if idx == 0 else 'next'
            widget_def = manage.initialize(group_def, _action, widget_id)

    if widget_def:
        widget_path = widget_def.get('path', {})

        if isinstance(widget_path, dict):
            _label = widget_path['label']
            widget_path = widget_path['file']['file']
        else:
            stack = widget_def.get('stack', [])
            if stack:
                _label = stack[0]['label']
            else:
                _label = widget_def.get('label', '')
        utils.log('Showing widget {}'.format(widget_id), 'debug')
        titles, cat = show_path(group_id, _label, widget_id, widget_path)
        return titles, cat
    else:
        directory.add_menu_item(title=32067,
                                art=utils.get_art('information_outline'),
                                isFolder=True)
        return True, group_name
Esempio n. 17
0
def show_path(group_id,
              path_label,
              widget_id,
              path,
              idx=0,
              titles=None,
              num=1,
              merged=False):
    hide_watched = utils.get_setting_bool('widgets.hide_watched')
    show_next = utils.get_setting_int('widgets.show_next')
    paged_widgets = utils.get_setting_bool('widgets.paged')
    default_color = utils.get_setting('ui.color')

    widget_def = manage.get_widget_by_id(widget_id)
    if not widget_def:
        return True, 'AutoWidget'

    if not titles:
        titles = []

    files = refresh.get_files_list(path, titles, widget_id)
    if not files:
        return titles, path_label

    utils.log('Loading items from {}'.format(path), 'debug')

    if isinstance(widget_def['path'], list):
        color = widget_def['path'][idx].get('color', default_color)
    elif isinstance(widget_def['path'], six.text_type):
        color = widget_def['stack'][0].get('color', default_color)
    else:
        color = widget_def['path'].get('color', default_color)

    stack = widget_def.get('stack', [])
    if stack:
        title = utils.get_string(32110).format(len(stack))
        directory.add_menu_item(title=title,
                                params={
                                    'mode': 'path',
                                    'action': 'update',
                                    'id': widget_id,
                                    'path': '',
                                    'target': 'back'
                                },
                                art=utils.get_art('back', color),
                                isFolder=num > 1,
                                props={
                                    'specialsort': 'top',
                                    'autoLabel': path_label
                                })

    for file in files:
        properties = {'autoLabel': path_label, 'autoID': widget_id}
        if 'customproperties' in file:
            for prop in file['customproperties']:
                properties[prop] = file['customproperties'][prop]

        clean_pattern = '[^\w \xC0-\xFF]'
        tag_pattern = '(\[[^\]]*\])'

        next_pattern = (
            '(?:^(?:next)?\s*(?:(?:>>)|(?:\.*)$)?)\s*'
            '(?:page\s*(?:(?:\d+\D*\d?$)|(?:(?:>>)|(?:\.*)$)|(?:\(\d+|.*\)$))?)?$'
        )
        prev_pattern = '^(?:previous(?: page)?)$|^(?:back)$'

        cleaned_title = re.sub(tag_pattern, '',
                               file.get('label', '').lower()).strip()
        next_item = re.search(next_pattern, cleaned_title)
        prev_item = re.search(prev_pattern, cleaned_title)

        if (prev_item and stack) or (next_item and show_next == 0):
            continue
        elif next_item and show_next > 0:
            label = utils.get_string(32111)
            properties['specialsort'] = 'bottom'

            if num > 1:
                if show_next == 1:
                    continue

                label = '{} - {}'.format(label, path_label)

            update_params = {
                'mode': 'path',
                'action': 'update',
                'id': widget_id,
                'path': file['file'],
                'target': 'next'
            }

            directory.add_menu_item(
                title=label,
                params=update_params if paged_widgets and not merged else None,
                path=file['file'] if not paged_widgets or merged else None,
                art=utils.get_art('next_page', color),
                info=file,
                isFolder=not paged_widgets or merged,
                props=properties)
        else:
            dupe = False
            title = (file['label'], file.get('imdbnumber'))
            for t in titles:
                if t == title:
                    dupe = True

            if (hide_watched and file.get('playcount', 0) > 0) or dupe:
                continue

            directory.add_menu_item(title=title[0],
                                    path=file['file'],
                                    art=file['art'],
                                    info=file,
                                    isFolder=file['filetype'] == 'directory',
                                    props=properties)

            titles.append(title)

    return titles, path_label
Esempio n. 18
0
def path_menu(group_id, action, widget_id):
    group_def = manage.get_group_by_id(group_id)
    if not group_def:
        directory.add_menu_item(
            title=32073,
            info={"plot": utils.get_string(32075)},
            art=utils.get_art("alert"),
            isFolder=True,
        )
        return True, "AutoWidget"

    group_name = group_def.get("label", "")
    paths = group_def.get("paths", [])
    if len(paths) == 0:
        directory.add_menu_item(title=32032,
                                art=utils.get_art("alert"),
                                isFolder=True)
        return True, group_name

    widget_def = manage.get_widget_by_id(widget_id, group_id)
    if not widget_def:
        dialog = xbmcgui.Dialog()
        if action == "static":
            idx = dialog.select(utils.get_string(32114),
                                [i["label"] for i in paths])
            if idx == -1:
                return True, "AutoWidget"

            widget_def = manage.initialize(group_def,
                                           action,
                                           widget_id,
                                           keep=idx)
        elif action == 'cycling':
            idx = dialog.select(utils.get_string(32081), [
                utils.get_string(32079),
                utils.get_string(32080),
                utils.get_string(32242)
            ])
            if idx == -1:
                return True, 'AutoWidget'
            elif idx == 0:
                _action = 'random'
            elif idx == 1:
                _action = 'next'
            else:
                _action = 'randomized'

            widget_def = manage.initialize(group_def, _action, widget_id)

    if widget_def:
        widget_path = widget_def.get("path", {})

        if isinstance(widget_path, dict):
            _label = widget_path["label"]
            widget_path = widget_path["file"]["file"]
        else:
            stack = widget_def.get("stack", [])
            if stack:
                _label = stack[0]["label"]
            else:
                _label = widget_def.get("label", "")
        utils.log("Showing widget {}".format(widget_id), "debug")
        titles, cat = show_path(group_id, _label, widget_id, widget_path)
        return titles, cat
    else:
        directory.add_menu_item(title=32067,
                                art=utils.get_art("information_outline"),
                                isFolder=True)
        return True, group_name
Esempio n. 19
0
def show_path(group_id,
              path_label,
              widget_id,
              path,
              idx=0,
              titles=None,
              num=1,
              merged=False):
    hide_watched = utils.get_setting_bool("widgets.hide_watched")
    show_next = utils.get_setting_int("widgets.show_next")
    paged_widgets = utils.get_setting_bool("widgets.paged")
    default_color = utils.get_setting("ui.color")

    widget_def = manage.get_widget_by_id(widget_id)
    if not widget_def:
        return True, "AutoWidget"

    if not titles:
        titles = []

    files = refresh.get_files_list(path, widget_id)
    if not files:
        return titles, path_label

    utils.log("Loading items from {}".format(path), "debug")

    if isinstance(widget_def["path"], list):
        color = widget_def["path"][idx].get("color", default_color)
    elif isinstance(widget_def["path"], six.text_type):
        color = widget_def["stack"][0].get("color", default_color)
    else:
        color = widget_def["path"].get("color", default_color)

    stack = widget_def.get("stack", [])
    if stack:
        title = utils.get_string(32110).format(len(stack))
        directory.add_menu_item(
            title=title,
            params={
                "mode": "path",
                "action": "update",
                "id": widget_id,
                "path": "",
                "target": "back",
            },
            art=utils.get_art("back", color),
            isFolder=num > 1,
            props={
                "specialsort": "top",
                "autoLabel": path_label
            },
        )

    for file in files:
        properties = {"autoLabel": path_label, "autoID": widget_id}
        if "customproperties" in file:
            for prop in file["customproperties"]:
                properties[prop] = file["customproperties"][prop]

        clean_pattern = "[^\w \xC0-\xFF]"
        tag_pattern = "(\[[^\]]*\])"

        next_pattern = (
            "(?:^(?:next)?\s*(?:(?:>>)|(?:\.*)$)?)\s*"
            "(?:page\s*(?:(?:\d+\D*\d?$)|(?:(?:>>)|(?:\.*)$)|(?:\(\d+|.*\)$))?)?$"
        )
        prev_pattern = "^(?:previous(?: page)?)$|^(?:back)$"

        cleaned_title = re.sub(tag_pattern, "",
                               file.get("label", "").lower()).strip()
        next_item = re.search(next_pattern, cleaned_title)
        prev_item = re.search(prev_pattern, cleaned_title)

        if (prev_item and stack) or (next_item and show_next == 0):
            continue
        elif next_item and show_next > 0:
            label = utils.get_string(32111)
            properties["specialsort"] = "bottom"

            if num > 1:
                if show_next == 1:
                    continue

                label = "{} - {}".format(label, path_label)

            update_params = {
                "mode": "path",
                "action": "update",
                "id": widget_id,
                "path": file["file"],
                "target": "next",
            }

            directory.add_menu_item(
                title=label,
                params=update_params if paged_widgets and not merged else None,
                path=file["file"] if not paged_widgets or merged else None,
                art=utils.get_art("next_page", color),
                info=file,
                isFolder=not paged_widgets or merged,
                props=properties,
            )
        else:
            title = {
                "type": file.get("type"),
                "label": file.get("label"),
                "imdbnumber": file.get("imdbnumber"),
                "showtitle": file.get("showtitle"),
            }
            dupe = refresh.is_duplicate(title, titles)

            if (hide_watched and file.get("playcount", 0) > 0) or dupe:
                continue

            art = file.get("art", {})
            if not art.get("landscape") and art.get("thumb"):
                art["landscape"] = art["thumb"]

            directory.add_menu_item(
                title=file["label"],
                path=file["file"],
                art=art,
                info=file,
                isFolder=file["filetype"] == "directory",
                props=properties,
            )

            titles.append(title)

    return titles, path_label
Esempio n. 20
0
def show_path(
    group_id,
    path_label,
    widget_id,
    widget_path,
    idx=0,
    titles=None,
    num=1,
    merged=False,
):
    hide_watched = settings.get_setting_bool("widgets.hide_watched")
    show_next = settings.get_setting_int("widgets.show_next")
    paged_widgets = settings.get_setting_bool("widgets.paged")
    default_color = settings.get_setting_string("ui.color")

    widget_def = manage.get_widget_by_id(widget_id)
    if not widget_def:
        return True, "AutoWidget", None

    content = widget_path.get("content")
    action = widget_def.get("action", "")
    if not titles:
        titles = []

    stack = widget_def.get("stack", [])
    path = widget_path["file"]["file"] if not stack else stack[-1]

    files, hash = refresh.get_files_list(path, widget_id)
    # if not files:
    #     properties = {
    #         "autoLabel": path_label,
    #         "autoID": widget_id,
    #         "autoAction": action,
    #         "autoCache": hash,
    #     }
    #     if files is None:
    #         show_error(path_label, properties)
    #     elif files == []:
    #         show_empty(path_label, properties)
    #     return titles if titles else True, path_label, content

    utils.log("Loading items from {}".format(path), "debug")

    color = widget_path.get("color", default_color)

    if stack:
        title = _previous
        # title = utils.get_string(30085).format(len(stack))
        directory.add_menu_item(
            title=title,
            params={
                "mode": "path",
                "action": "update",
                "id": widget_id,
                "path": "",
                "target": "back",
            },
            art=utils.get_art("back", color),
            isFolder=num > 1,
            props={
                "specialsort": "top",
                "autoLabel": path_label
            },
        )

    for pos, file in enumerate(files):
        properties = {
            "autoLabel": path_label,
            "autoID": widget_id,
            "autoAction": action,
            "autoCache": hash,
        }
        next_item = False
        prev_item = False
        is_folder = file["filetype"] == "directory"

        if pos == len(files) - 1 and is_folder:
            next_item = _is_page_item(file.get("label", ""))
        elif pos == 0 and is_folder:
            prev_item = _is_page_item(file.get("label", ""), next=False)

        if (prev_item and stack) or (next_item and show_next == 0):
            continue
        elif next_item and show_next > 0:
            label = _next_page
            properties["specialsort"] = "bottom"

            if num > 1:
                if show_next == 1:
                    continue

                label = "{} - {}".format(label, path_label)

            update_params = {
                "mode": "path",
                "action": "update",
                "id": widget_id,
                "path": file["file"],
                "target": "next",
            }

            directory.add_menu_item(
                title=label,
                params=update_params if paged_widgets and not merged else None,
                path=file["file"] if not paged_widgets or merged else None,
                art=utils.get_art("next_page", color),
                info=file,
                isFolder=not paged_widgets or merged,
                props=properties,
            )
        else:
            filetype = file.get("type", "")
            title = {
                "type": filetype,
                "label": file.get("label"),
                "imdbnumber": file.get("imdbnumber"),
                "showtitle": file.get("showtitle"),
            }
            dupe = refresh.is_duplicate(title, titles)

            if (hide_watched and file.get("playcount", 0) > 0) or dupe:
                continue

            filepath = ""
            info_type = directory.info_types.get(filetype, "video")
            if (path.startswith("library://{}/".format(info_type))
                    or path.startswith("{}db://".format(info_type) or
                                       path.endswith(".xsp"))) and is_folder:
                filepath = directory.make_library_path(info_type, filetype,
                                                       file.get("id", -1))

            directory.add_menu_item(
                title=file["label"],
                path=file["file"] if not filepath else filepath,
                info=file,
                isFolder=is_folder,
                props=properties,
            )

            titles.append(title)

    return titles, path_label, content
Esempio n. 21
0
def path_menu(group_id, action, widget_id):
    group_def = manage.get_group_by_id(group_id)
    if not group_def:
        directory.add_menu_item(
            title=30051,
            info={"plot": utils.get_string(30053)},
            art=utils.get_art("alert"),
            isFolder=True,
        )
        return True, "AutoWidget", None

    group_name = group_def.get("label", "")
    paths = group_def.get("paths", [])
    if len(paths) == 0:
        directory.add_menu_item(title=30019,
                                art=utils.get_art("alert"),
                                isFolder=True)
        return True, group_name, None

    widget_def = manage.get_widget_by_id(widget_id, group_id)
    if not widget_def:
        dialog = xbmcgui.Dialog()
        if action == "static":
            idx = manage.choose_paths(utils.get_string(30088),
                                      paths,
                                      indices=True,
                                      single=True)
            if idx == -1:
                return True, "AutoWidget", None

            widget_def = manage.initialize(group_def,
                                           action,
                                           widget_id,
                                           keep=idx)
        elif action == "cycling":
            idx = dialog.select(
                utils.get_string(30059),
                [utils.get_string(30057),
                 utils.get_string(30058)],
            )
            if idx == -1:
                del dialog
                return True, "AutoWidget", None

            _action = "random" if idx == 0 else "next"

            cycle_paths = manage.choose_paths(utils.get_string(30123),
                                              paths,
                                              threshold=-1,
                                              indices=True)

            widget_def = manage.initialize(group_def,
                                           _action,
                                           widget_id,
                                           keep=cycle_paths)
        del dialog

    if widget_def:
        widget_path = widget_def.get("path", "")

        # simple compatibility with pre-3.3.0 widgets
        if isinstance(widget_path, dict):
            widget_path = widget_def.get("path", {}).get("id", "")
            widget_def["path"] = widget_path
            manage.save_path_details(widget_def)

        widget_path = manage.get_path_by_id(widget_path, group_id)

        _label = ""
        if isinstance(widget_path, dict):
            _label = widget_path.get("label", "")

        utils.log("Showing widget {}".format(widget_id), "debug")
        titles, cat, type = show_path(group_id, _label, widget_id, widget_path)
        return titles, cat, type
    else:
        directory.add_menu_item(title=30045, art=info, isFolder=True)
        return True, group_name, None
Esempio n. 22
0
    def _update_widgets(self):
        self._refresh(True)

        while not self.abortRequested():
            for _ in self.tick(step=1, max=60 * 15):
                # don't process cache queue during video playback
                if self.player.isPlayingVideo():
                    continue

                # TODO: somehow delay till all other plugins loaded?
                updated = False
                unrefreshed_widgets = set()
                queue = list(cache.next_cache_queue())

                # class Progress(object):
                #     dialog = None
                #     service = self
                #     done = set()

                #     def __call__(self, groupname, path):
                #         if self.dialog is None:
                #             self.dialog = xbmcgui.DialogProgressBG()
                #             self.dialog.create("AutoWidget", utils.get_string(30141))
                #         if not self.service.player.isPlayingVideo():
                #             percent = (
                #                 len(self.done)
                #                 / float(len(queue) + len(self.done) + 1)
                #                 * 100
                #             )
                #             self.dialog.update(
                #                 int(percent), "AutoWidget", message=groupname
                #             )
                #         self.done.add(path)

                # progress = Progress()

                while queue:
                    path, cache_data, widget_id = queue.pop(0)
                    hash = cache.path2hash(path)
                    utils.log("Dequeued cache update: {}".format(hash[:5]), "notice")

                    affected_widgets = set(
                        cache.cache_and_update(
                            path,
                            widget_id,
                            cache_data,  # notify=progress
                        )
                    )
                    if affected_widgets:
                        updated = True
                    unrefreshed_widgets = unrefreshed_widgets.union(affected_widgets)
                    # # wait 5s or for the skin to reload the widget
                    # # this should reduce churn at startup where widgets take too long too long show up
                    # before_update = time.time() # TODO: have .access file so we can put above update
                    # while _ in self.tick(1, 10, lambda: cache.last_read(hash) > before_update):
                    #     pass
                    # utils.log("paused queue until read {:.2} for {}".format(cache.last_read(hash)-before_update, hash[:5]), 'info')
                    if self.abortRequested():
                        break
                    if self.player.isPlayingVideo():
                        # Video stop will cause another refresh anyway.
                        break
                    queue = list(cache.next_cache_queue())
                for widget_id in unrefreshed_widgets:
                    widget_def = manage.get_widget_by_id(widget_id)
                    if not widget_def:
                        continue
                    _update_strings(widget_def)
                if (
                    os.path.exists(os.path.join(_addon_data, "refresh.time"))
                    and utils.get_active_window() == "home"
                ):
                    utils.update_container(True)
                # if progress.dialog is not None:
                #     progress.dialog.update(100)
                #     progress.dialog.close()
                if (
                    updated
                    and self.refresh_enabled == 1
                    and not self.player.isPlayingVideo()
                ):
                    dialog = xbmcgui.Dialog()
                    dialog.notification(
                        u"AutoWidget", utils.get_string(30142), sound=False
                    )

            if self.abortRequested():
                break

            if not self._refresh():
                continue
Esempio n. 23
0
def show_path(group_id,
              path_label,
              widget_id,
              path,
              idx=0,
              titles=None,
              num=1,
              merged=False):
    hide_watched = utils.get_setting_bool("widgets.hide_watched")
    show_next = utils.get_setting_int("widgets.show_next")
    paged_widgets = utils.get_setting_bool("widgets.paged")
    default_color = utils.get_setting("ui.color")

    widget_def = manage.get_widget_by_id(widget_id)
    if not widget_def:
        return True, "AutoWidget"

    if not titles:
        titles = []

    files = refresh.get_files_list(path, widget_id)
    if not files:
        return titles, path_label

    utils.log("Loading items from {}".format(path), "debug")

    if isinstance(widget_def["path"], list):
        color = widget_def["path"][idx].get("color", default_color)
    elif isinstance(widget_def["path"], six.text_type):
        color = widget_def["stack"][0].get("color", default_color)
    else:
        color = widget_def["path"].get("color", default_color)

    stack = widget_def.get("stack", [])
    if stack:
        title = _previous
        # title = utils.get_string(30085).format(len(stack))
        directory.add_menu_item(
            title=title,
            params={
                "mode": "path",
                "action": "update",
                "id": widget_id,
                "path": "",
                "target": "back",
            },
            art=utils.get_art("back", color),
            isFolder=num > 1,
            props={
                "specialsort": "top",
                "autoLabel": path_label
            },
        )

    for pos, file in enumerate(files):
        properties = {"autoLabel": path_label, "autoID": widget_id}
        next_item = False
        prev_item = False

        if "customproperties" in file:
            for prop in file["customproperties"]:
                properties[prop] = file["customproperties"][prop]

        if pos == len(files) - 1:
            next_item = _is_page_item(file.get("label", ""))
        elif pos == 0:
            prev_item = _is_page_item(file.get("label", ""), next=False)

        if (prev_item and stack) or (next_item and show_next == 0):
            continue
        elif next_item and show_next > 0:
            label = _next_page
            properties["specialsort"] = "bottom"

            if num > 1:
                if show_next == 1:
                    continue

                label = "{} - {}".format(label, path_label)

            update_params = {
                "mode": "path",
                "action": "update",
                "id": widget_id,
                "path": file["file"],
                "target": "next",
            }

            directory.add_menu_item(
                title=label,
                params=update_params if paged_widgets and not merged else None,
                path=file["file"] if not paged_widgets or merged else None,
                art=utils.get_art("next_page", color),
                info=file,
                isFolder=not paged_widgets or merged,
                props=properties,
            )
        else:
            title = {
                "type": file.get("type"),
                "label": file.get("label"),
                "imdbnumber": file.get("imdbnumber"),
                "showtitle": file.get("showtitle"),
            }
            dupe = refresh.is_duplicate(title, titles)

            if (hide_watched and file.get("playcount", 0) > 0) or dupe:
                continue

            art = file.get("art", {})
            if not art.get("landscape") and art.get("thumb"):
                art["landscape"] = art["thumb"]

            directory.add_menu_item(
                title=file["label"],
                path=file["file"],
                art=art,
                info=file,
                isFolder=file["filetype"] == "directory",
                props=properties,
            )

            titles.append(title)

    return titles, path_label