mirror of
https://github.com/AUTOMATIC1111/stable-diffusion-webui.git
synced 2024-06-07 21:20:49 +00:00
fix hidden directory options and their functionality.
This commit is contained in:
parent
da204f8602
commit
b497467436
@ -1,2 +1,2 @@
|
||||
<button class='lg secondary gradio-button custom-button extra-network-dirs-view-button {extra_class}' title="{title}"
|
||||
data-path="{path}">{label}</button>
|
||||
{data_attributes}>{label}</button>
|
@ -748,8 +748,12 @@ class ExtraNetworksTab {
|
||||
await this.tree_list.onRowSelected();
|
||||
}
|
||||
// Don't use escaped path here since this is pure javascript beyond this point.
|
||||
let directory_filter = source_elem.dataset.path;
|
||||
if ("directoryFilterOverride" in source_elem.dataset) {
|
||||
directory_filter = source_elem.dataset.directoryFilterOverride;
|
||||
}
|
||||
this.applyDirectoryFilter(
|
||||
"selected" in source_elem.dataset ? source_elem.dataset.path : null,
|
||||
"selected" in source_elem.dataset ? directory_filter : null,
|
||||
"recurse" in source_elem.dataset,
|
||||
);
|
||||
return;
|
||||
@ -770,8 +774,12 @@ class ExtraNetworksTab {
|
||||
const div_id = source_is_tree ? source_elem.dataset.divId : other_elem.dataset.divId;
|
||||
_set_recursion_depth(div_id, data_recurse);
|
||||
// Don't use escaped path here since this is pure javascript beyond this point.
|
||||
let directory_filter = source_elem.dataset.path;
|
||||
if ("directoryFilterOverride" in source_elem.dataset) {
|
||||
directory_filter = source_elem.dataset.directoryFilterOverride;
|
||||
}
|
||||
this.applyDirectoryFilter(
|
||||
"selected" in source_elem.dataset ? source_elem.dataset.path : null,
|
||||
"selected" in source_elem.dataset ? directory_filter : null,
|
||||
"recurse" in source_elem.dataset,
|
||||
);
|
||||
}
|
||||
|
@ -581,28 +581,26 @@ class ExtraNetworksClusterizeCardsList extends ExtraNetworksClusterize {
|
||||
if (this.directory_filter_str && this.directory_filter_recurse) {
|
||||
// Filter as directory with recurse shows all nested children.
|
||||
// Case sensitive comparison against the relative directory of each object.
|
||||
this.data_obj[div_id].visible = v.rel_parent_dir.startsWith(this.directory_filter_str);
|
||||
if (!this.data_obj[div_id].visible) {
|
||||
v.visible = v.rel_parent_dir.startsWith(this.directory_filter_str);
|
||||
if (!v.visible) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// Filtering as directory without recurse only shows direct children.
|
||||
// Case sensitive comparison against the relative directory of each object.
|
||||
if (this.directory_filter_str && this.directory_filter_str !== v.rel_parent_dir) {
|
||||
this.data_obj[div_id].visible = false;
|
||||
v.visible = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (v.search_only && this.filter_str.length >= 4) {
|
||||
if (v.search_only) {
|
||||
// Custom filter for items marked search_only=true.
|
||||
// TODO: Not ideal. This disregards any search_terms set on the model.
|
||||
// However the search terms are currently set up in a way that would
|
||||
// reveal hidden models if the user searches for any visible parent
|
||||
// directories. For example, searching for "Lora" would reveal a hidden
|
||||
// model in "Lora/.hidden/model.safetensors" since that full path is
|
||||
// included in the search terms.
|
||||
visible = v.rel_parent_dir.toLowerCase().indexOf(this.filter_str.toLowerCase()) !== -1;
|
||||
if (this.directory_filter_str || this.filter_str.length >= 4) {
|
||||
visible = v.search_terms.toLowerCase().indexOf(this.filter_str.toLowerCase()) !== -1;
|
||||
} else {
|
||||
visible = false;
|
||||
}
|
||||
} else {
|
||||
// All other filters treated case insensitive.
|
||||
visible = v.search_terms.toLowerCase().indexOf(this.filter_str.toLowerCase()) !== -1;
|
||||
|
@ -250,8 +250,9 @@ options_templates.update(options_section(('interrogate', "Interrogate"), {
|
||||
}))
|
||||
|
||||
options_templates.update(options_section(('extra_networks', "Extra Networks", "sd"), {
|
||||
"extra_networks_show_hidden_directories": OptionInfo(True, "Show hidden directories").info("directory is hidden if its name starts with \".\".").needs_reload_ui(),
|
||||
"extra_networks_hidden_models": OptionInfo("When searched", "Show cards for models in hidden directories", gr.Radio, {"choices": ["Always", "When searched", "Never"]}).info('"When searched" option will only show the item when the search string has 4 characters or more').needs_reload_ui(),
|
||||
"extra_networks_show_hidden_directories_buttons": OptionInfo(False, "Show buttons for hidden directories in the directory and tree views.").info("a directory is hidden if its name starts with a period (\".\").").needs_reload_ui(),
|
||||
"extra_networks_show_hidden_models_cards": OptionInfo("Never", "Show cards for models in hidden directories", gr.Radio, {"choices": ["Always", "When searched", "Never"]}).info("\"When searched\" will only show cards when the search string has 4 characters or more and the search string matches either the model name or the hidden directory name (or any of its subdirectories).").needs_reload_ui(),
|
||||
"extra_networks_show_hidden_models_in_tree_view": OptionInfo(False, "Show entries for models inside hidden directories in the tree view.").info("This option only applies if the \"Show buttons for hidden directories\" option is enabled.").needs_reload_ui(),
|
||||
"extra_networks_default_multiplier": OptionInfo(1.0, "Default multiplier for extra networks", gr.Slider, {"minimum": 0.0, "maximum": 2.0, "step": 0.01}),
|
||||
"extra_networks_card_width": OptionInfo(0, "Card width for Extra Networks").info("in pixels"),
|
||||
"extra_networks_card_height": OptionInfo(0, "Card height for Extra Networks").info("in pixels"),
|
||||
|
@ -94,13 +94,22 @@ class DirectoryTreeNode:
|
||||
self.root_dir = root_dir
|
||||
self.abspath = abspath
|
||||
self.parent = parent
|
||||
|
||||
self.id = ""
|
||||
self.depth = 0
|
||||
self.is_dir = False
|
||||
self.item = None
|
||||
self.relpath = os.path.relpath(self.abspath, self.root_dir)
|
||||
self.children: list["DirectoryTreeNode"] = []
|
||||
self.is_dir = os.path.isdir(self.abspath)
|
||||
# If any parent dirs are hidden, this node is also considered hidden.
|
||||
self.is_hidden = any(x.startswith(".") for x in self.abspath.split(os.sep))
|
||||
self.id = ""
|
||||
self.depth = 0
|
||||
self.item = None
|
||||
|
||||
self.rel_from_hidden = None
|
||||
if self.is_hidden:
|
||||
# Get the relative path starting from the first hidden directory.
|
||||
parts = self.relpath.split(os.sep)
|
||||
idxs = [i for i, x in enumerate(parts) if x.startswith(".")]
|
||||
if len(idxs) > 0:
|
||||
self.rel_from_hidden = os.path.join(*parts[idxs[0] :])
|
||||
|
||||
# If a parent is passed, then we add this instance to the parent's children.
|
||||
if self.parent is not None:
|
||||
@ -110,24 +119,19 @@ class DirectoryTreeNode:
|
||||
def add_child(self, child: "DirectoryTreeNode") -> None:
|
||||
self.children.append(child)
|
||||
|
||||
def build(self, items: dict[str, dict], include_hidden: bool = False) -> None:
|
||||
def build(self, items: dict[str, dict]) -> None:
|
||||
"""Builds a tree of nodes as children of this instance.
|
||||
|
||||
Args:
|
||||
items: A dictionary where keys are absolute filepaths for directories/files.
|
||||
The values are dictionaries representing extra networks items.
|
||||
include_hidden: Whether to include hidden directories in the tree.
|
||||
"""
|
||||
self.is_dir = os.path.isdir(self.abspath)
|
||||
if self.is_dir:
|
||||
for x in os.listdir(self.abspath):
|
||||
child_path = os.path.join(self.abspath, x)
|
||||
# Skip hidden directories if include_hidden is False
|
||||
if os.path.isdir(child_path) and os.path.basename(child_path).startswith(".") and not include_hidden:
|
||||
continue
|
||||
# Add all directories but only add files if they are in the items dict.
|
||||
if os.path.isdir(child_path) or child_path in items:
|
||||
DirectoryTreeNode(self.root_dir, child_path, self).build(items, include_hidden)
|
||||
DirectoryTreeNode(self.root_dir, child_path, self).build(items)
|
||||
else:
|
||||
self.item = items.get(self.abspath, None)
|
||||
|
||||
@ -420,14 +424,10 @@ class ExtraNetworksPage:
|
||||
filename = os.path.normpath(item.get("filename", ""))
|
||||
# if this is true, the item must not be shown in the default view,
|
||||
# and must instead only be shown when searching for it
|
||||
show_hidden_models = str(shared.opts.extra_networks_hidden_models).strip().lower()
|
||||
if show_hidden_models == "always":
|
||||
search_only = False
|
||||
else:
|
||||
# If any parent dirs are hidden, the model is also hidden.
|
||||
search_only = any(x.startswith(".") for x in filename.split(os.sep))
|
||||
|
||||
if search_only and show_hidden_models == "never":
|
||||
show_hidden_models = str(shared.opts.extra_networks_show_hidden_models_cards).strip().lower()
|
||||
# If any parent dirs are hidden, the model is also hidden.
|
||||
is_hidden = any(x.startswith(".") for x in filename.split(os.sep))
|
||||
if show_hidden_models == "never" and is_hidden:
|
||||
return ""
|
||||
|
||||
sort_keys = {}
|
||||
@ -506,7 +506,17 @@ class ExtraNetworksPage:
|
||||
# Mapping from the self.nodes div_ids to the sorted index.
|
||||
div_id_to_idx[node.id] = i
|
||||
|
||||
show_hidden_cards = str(shared.opts.extra_networks_show_hidden_models_cards).strip().lower()
|
||||
for node in nodes.values():
|
||||
search_only = False
|
||||
if show_hidden_cards == "always":
|
||||
search_only = False
|
||||
elif show_hidden_cards == "when searched":
|
||||
search_only = node.is_hidden
|
||||
elif "never" == show_hidden_cards and node.is_hidden:
|
||||
# We never show hidden cards here so don't even add it to the results.
|
||||
continue
|
||||
|
||||
card = CardListItem(node.id, "")
|
||||
card.node = node
|
||||
item = node.item
|
||||
@ -518,13 +528,7 @@ class ExtraNetworksPage:
|
||||
sort_keys["path"] = div_id_to_idx[node.id]
|
||||
|
||||
search_terms = item.get("search_terms", [])
|
||||
show_hidden_models = str(shared.opts.extra_networks_hidden_models).strip().lower()
|
||||
if show_hidden_models == "always":
|
||||
search_only = False
|
||||
else:
|
||||
# If any parent dirs are hidden, the model is also hidden.
|
||||
filename = os.path.normpath(item.get("filename", ""))
|
||||
search_only = any(x.startswith(".") for x in filename.split(os.sep))
|
||||
|
||||
card.abspath = os.path.normpath(item.get("filename", ""))
|
||||
for path in self.allowed_directories_for_previews():
|
||||
parent_dir = os.path.dirname(os.path.abspath(path))
|
||||
@ -534,15 +538,14 @@ class ExtraNetworksPage:
|
||||
card.sort_keys = sort_keys
|
||||
card.search_terms = " ".join(search_terms)
|
||||
card.search_only = search_only
|
||||
|
||||
card.rel_parent_dir = os.path.dirname(card.relpath)
|
||||
if card.search_only:
|
||||
parents = card.relpath.split(os.sep)
|
||||
idxs = [i for i, x in enumerate(parents) if x.startswith(".")]
|
||||
if len(idxs) > 0:
|
||||
card.rel_parent_dir = os.path.join(*parents[idxs[0]:])
|
||||
else:
|
||||
print(f"search_only is enabled but no hidden dir found: {card.abspath}")
|
||||
if card.node.rel_from_hidden is not None:
|
||||
card.rel_parent_dir = os.path.dirname(card.node.rel_from_hidden)
|
||||
|
||||
if card.search_only and card.node.rel_from_hidden is not None:
|
||||
# Limit the ways of searching for `search_only` cards so that the user
|
||||
# can't search for a parent to a hidden directory to see hidden cards.
|
||||
card.search_terms = card.search_terms.replace(node.relpath, card.node.rel_from_hidden)
|
||||
|
||||
self.cards[node.id] = card
|
||||
|
||||
@ -595,7 +598,15 @@ class ExtraNetworksPage:
|
||||
_res.extend(_gen_indents(node.parent))
|
||||
return _res
|
||||
|
||||
show_hidden_dirs = shared.opts.extra_networks_show_hidden_directories_buttons
|
||||
show_hidden_models = shared.opts.extra_networks_show_hidden_models_in_tree_view
|
||||
for node in self.nodes.values():
|
||||
if node.is_hidden and node.is_dir and not show_hidden_dirs:
|
||||
continue
|
||||
|
||||
if node.is_hidden and not node.is_dir and show_hidden_dirs and not show_hidden_models:
|
||||
continue
|
||||
|
||||
tree_item = TreeListItem(node.id, "")
|
||||
# If root node, expand and set visible.
|
||||
if node.parent is None:
|
||||
@ -616,12 +627,37 @@ class ExtraNetworksPage:
|
||||
indent_html = "".join(indent_html)
|
||||
indent_html = f"<div class='tree-list-item-indent'>{indent_html}</div>"
|
||||
|
||||
children = []
|
||||
|
||||
if node.is_dir: # directory
|
||||
if show_files:
|
||||
dir_is_empty = node.children == []
|
||||
else:
|
||||
dir_is_empty = all(not x.is_dir for x in node.children)
|
||||
|
||||
if node.is_hidden and not show_hidden_models:
|
||||
dir_is_empty = all(not x.is_dir for x in node.children)
|
||||
|
||||
if not dir_is_empty:
|
||||
if show_files and show_hidden_models:
|
||||
children = [x.id for x in tree_item.node.children]
|
||||
elif show_files and not show_hidden_models:
|
||||
children = [x.id for x in tree_item.node.children if x.is_dir or (not x.is_dir and not x.is_hidden)]
|
||||
else:
|
||||
children = [x.id for x in tree_item.node.children if x.is_dir]
|
||||
|
||||
data_attributes = {
|
||||
"data-div-id": f'"{node.id}"',
|
||||
"data-parent-id": f'"{parent_id}"',
|
||||
"data-tree-entry-type": "dir",
|
||||
"data-depth": node.depth,
|
||||
"data-path": f'"{node.relpath}"',
|
||||
"data-expanded": node.parent is None, # Expand root directories
|
||||
}
|
||||
|
||||
if node.is_hidden:
|
||||
data_attributes["data-directory-filter-override"] = f'"{node.rel_from_hidden}"'
|
||||
|
||||
tree_item.html = self.build_tree_html_row(
|
||||
tabname=tabname,
|
||||
label=os.path.basename(node.abspath),
|
||||
@ -629,14 +665,7 @@ class ExtraNetworksPage:
|
||||
btn_title=f'"{node.abspath}"',
|
||||
dir_is_empty=dir_is_empty,
|
||||
indent_html=indent_html,
|
||||
data_attributes={
|
||||
"data-div-id": f'"{node.id}"',
|
||||
"data-parent-id": f'"{parent_id}"',
|
||||
"data-tree-entry-type": "dir",
|
||||
"data-depth": node.depth,
|
||||
"data-path": f'"{node.relpath}"',
|
||||
"data-expanded": node.parent is None, # Expand root directories
|
||||
},
|
||||
data_attributes=data_attributes,
|
||||
)
|
||||
self.tree[node.id] = tree_item
|
||||
else: # file
|
||||
@ -644,6 +673,9 @@ class ExtraNetworksPage:
|
||||
# Don't add file if files are disabled in the options.
|
||||
continue
|
||||
|
||||
if node.is_hidden and not show_hidden_models:
|
||||
continue
|
||||
|
||||
item_name = node.item.get("name", "").strip()
|
||||
data_path = os.path.normpath(node.item.get("filename", "").strip())
|
||||
data_attributes = {
|
||||
@ -673,11 +705,6 @@ class ExtraNetworksPage:
|
||||
)
|
||||
self.tree[node.id] = tree_item
|
||||
|
||||
if show_files:
|
||||
children = [x.id for x in tree_item.node.children]
|
||||
else:
|
||||
children = [x.id for x in tree_item.node.children if x.is_dir]
|
||||
|
||||
res[node.id] = {
|
||||
"parent": parent_id,
|
||||
"children": children,
|
||||
@ -697,6 +724,9 @@ class ExtraNetworksPage:
|
||||
if not node.is_dir:
|
||||
continue
|
||||
|
||||
if node.is_hidden and not shared.opts.extra_networks_show_hidden_directories_buttons:
|
||||
continue
|
||||
|
||||
if node.parent is None:
|
||||
label = node.relpath
|
||||
else:
|
||||
@ -704,14 +734,28 @@ class ExtraNetworksPage:
|
||||
parts = [x for x in node.relpath.split(os.sep) if x]
|
||||
label = os.path.join(*parts[1:])
|
||||
|
||||
data_attributes = {"data-path": f'"{node.relpath}"'}
|
||||
|
||||
if node.is_hidden:
|
||||
data_attributes["data-directory-filter-override"] = f'"{node.rel_from_hidden}"'
|
||||
|
||||
data_attributes_str = ""
|
||||
for k, v in data_attributes.items():
|
||||
if isinstance(v, (bool,)):
|
||||
# Boolean data attributes only need a key when true.
|
||||
if v:
|
||||
data_attributes_str += f"{k} "
|
||||
elif v not in [None, "", "''", '""']:
|
||||
data_attributes_str += f"{k}={v} "
|
||||
|
||||
res.append(
|
||||
self.btn_dirs_view_item_tpl.format(
|
||||
**{
|
||||
"extra_class": "search-all" if node.relpath == "" else "",
|
||||
"tabname_full": f"{tabname}_{self.extra_networks_tabname}",
|
||||
"title": html.escape(node.abspath),
|
||||
"path": html.escape(node.relpath),
|
||||
"label": html.escape(label),
|
||||
"data_attributes": data_attributes_str,
|
||||
}
|
||||
)
|
||||
)
|
||||
@ -754,15 +798,10 @@ class ExtraNetworksPage:
|
||||
if not os.path.exists(abspath):
|
||||
continue
|
||||
self.tree_roots[abspath] = DirectoryTreeNode(os.path.dirname(abspath), abspath, None)
|
||||
self.tree_roots[abspath].build(
|
||||
tree_items,
|
||||
include_hidden=shared.opts.extra_networks_show_hidden_directories,
|
||||
)
|
||||
self.tree_roots[abspath].build(tree_items)
|
||||
|
||||
cards_list_loading_splash_content = "Loading..."
|
||||
no_cards_html_dirs = "".join(
|
||||
[f"<li>{x}</li>" for x in self.allowed_directories_for_previews()]
|
||||
)
|
||||
no_cards_html_dirs = "".join([f"<li>{x}</li>" for x in self.allowed_directories_for_previews()])
|
||||
cards_list_no_data_splash_content = (
|
||||
"<div class='nocards'>"
|
||||
"<h1>Nothing here. Add some content to the following directories:</h1>"
|
||||
@ -1220,11 +1259,7 @@ def create_ui(interface: gr.Blocks, unrelated_tabs, tabname):
|
||||
elem_id=f"{tabname_full}_extra_refresh_internal",
|
||||
visible=False,
|
||||
)
|
||||
button_refresh.click(
|
||||
fn=functools.partial(refresh, tabname_full),
|
||||
inputs=[],
|
||||
outputs=list(ui.pages.values()),
|
||||
).then(
|
||||
button_refresh.click(fn=functools.partial(refresh, tabname_full), inputs=[], outputs=list(ui.pages.values()),).then(
|
||||
fn=lambda: None,
|
||||
_js="setupAllResizeHandles",
|
||||
).then(
|
||||
|
Loading…
Reference in New Issue
Block a user