GEN_PARAMS_INT, GEN_PARAMS_STR, # noqa: E402
GEN_PARAMS) # noqa: E402
-PromptsDiff = dict[str, str]
BasicItemsAttrs = dict[str, set[str]]
AttrVals: TypeAlias = list[str]
AttrValsByVisibility: TypeAlias = dict[str, AttrVals]
def __init__(self, path: str, name: str, cache: Cache) -> None:
super().__init__(path, name)
+ self.subprompt1: str = ''
+ self.subprompt2: str = ''
mtime = getmtime(self.full_path)
dt = datetime.fromtimestamp(mtime, tz=timezone.utc)
iso8601_str: str = dt.isoformat(timespec='microseconds')
self.items_attrs: ItemsAttrs = {}
self.selected_idx = 0
self.slots: list[GallerySlot] = []
- self._prompts_diff: PromptsDiff = {}
self._grid = Gtk.Grid()
self._force_width, self._force_height = 0, 0
else:
self.request_update(build_grid=True)
- def _prep_items_attrs(self,
- entries: list[GalleryItem]
- ) -> tuple[BasicItemsAttrs, PromptsDiff]:
-
- def diff_prompts(basic_items_attrs: BasicItemsAttrs) -> PromptsDiff:
- if 'prompt' not in basic_items_attrs:
- return {}
- prompts_diff: PromptsDiff = {}
- prompts = list(basic_items_attrs['prompt'])
-
- def find_longest_equal(prompts, j, matcher):
- longest_total, temp_longest = '', ''
- while j < len(prompts[0]):
- if 'end' == matcher:
- temp_longest = prompts[0][-j] + temp_longest
- else:
- temp_longest += prompts[0][j]
- if len(temp_longest) > len(longest_total):
- found_in_all = True
- for prompt in prompts[1:]:
- if ('start' == matcher
- and not prompt.startswith(temp_longest)) or\
- ('end' == matcher
- and not prompt.endswith(temp_longest)) or\
- ('in' == matcher
- and temp_longest not in prompt):
- found_in_all = False
- break
- if not found_in_all:
- break
- longest_total = temp_longest
- j += 1
- return longest_total
-
- prefix = find_longest_equal(prompts, 0, 'start')
- suffix = find_longest_equal(prompts, 1, matcher='end')
- cores = [p[len(prefix):] for p in prompts]
- if suffix:
- for i, p in enumerate(cores):
- cores[i] = p[:-len(suffix)]
- longest_total = ''
- for i in range(len(cores[0])):
- temp_longest = find_longest_equal(cores, j=i, matcher='in')
+ @staticmethod
+ def _diff_prompts(prompts: list[str]) -> dict[str, tuple[str, str]]:
+ if not prompts:
+ return {}
+
+ def find_longest_equal(prompts, j, matcher):
+ longest_total, temp_longest = '', ''
+ while j < len(prompts[0]):
+ if 'end' == matcher:
+ temp_longest = prompts[0][-j] + temp_longest
+ else:
+ temp_longest += prompts[0][j]
if len(temp_longest) > len(longest_total):
+ found_in_all = True
+ for prompt in prompts[1:]:
+ if ('start' == matcher
+ and not prompt.startswith(temp_longest)) or\
+ ('end' == matcher
+ and not prompt.endswith(temp_longest)) or\
+ ('in' == matcher
+ and temp_longest not in prompt):
+ found_in_all = False
+ break
+ if not found_in_all:
+ break
longest_total = temp_longest
- middle = longest_total
- for i, p in enumerate(prompts):
- remains = p[len(prefix):]
- idx_middle = remains.index(middle)
- second = remains[:idx_middle]
- remains = remains[idx_middle + len(middle):]
- first = remains[:-len(suffix)] if suffix else remains
- pre_ell = '…' if prefix else ''
- post_ell = '…' if suffix else ''
- prompts_diff[p] = f'{pre_ell}{first}…{second}{post_ell}'
- return prompts_diff
-
+ j += 1
+ return longest_total
+
+ prefix = find_longest_equal(prompts, 0, 'start')
+ suffix = find_longest_equal(prompts, 1, matcher='end')
+ cores = [p[len(prefix):] for p in prompts]
+ if suffix:
+ for i, p in enumerate(cores):
+ cores[i] = p[:-len(suffix)]
+ longest_total = ''
+ for i in range(len(cores[0])):
+ temp_longest = find_longest_equal(cores, j=i, matcher='in')
+ if len(temp_longest) > len(longest_total):
+ longest_total = temp_longest
+ middle = longest_total
+ prompts_diff = {}
+ for i, p in enumerate(prompts):
+ remains = p[len(prefix):] if prefix else p
+ idx_middle = remains.index(middle)
+ first = remains[:idx_middle] if idx_middle else ''
+ remains = remains[idx_middle + len(middle):]
+ second = remains[:-len(suffix)] if suffix else remains
+ if first:
+ first = f'…{first}' if prefix else first
+ first = f'{first}…' if suffix or middle else first
+ if second:
+ second = f'…{second}' if prefix or middle else second
+ second = f'{second}…' if suffix else second
+ prompts_diff[p] = (first if first else '…',
+ second if second else '…')
+ return prompts_diff
+
+ def _prep_items_attrs(self, entries: list[GalleryItem]) -> BasicItemsAttrs:
basic_items_attrs = {}
for attr_name in (s.name for s in self._sort_order):
vals: set[str] = set()
if val is not None:
vals.add(val)
basic_items_attrs[attr_name] = vals
- prompts_diff = diff_prompts(basic_items_attrs)
- return basic_items_attrs, prompts_diff
+ return basic_items_attrs
def _load_directory(self) -> None:
"""(Re-)build .dir_entries from ._img_dir_path, ._basic_items_attrs."""
read_directory(path)
read_directory(self._img_dir_path, make_parent=True)
- self._basic_items_attrs, self._prompts_diff = self._prep_items_attrs(
- self.dir_entries)
+ prompts_set: set[str] = set()
+ for entry in [e for e in self.dir_entries
+ if isinstance(e, ImgItem) and hasattr(e, 'prompt')]:
+ prompts_set.add(entry.prompt)
+ prompts_diff = self._diff_prompts(list(prompts_set))
+ for entry in [e for e in self.dir_entries if isinstance(e, ImgItem)]:
+ entry.subprompt1 = prompts_diff[entry.prompt][0]
+ entry.subprompt2 = prompts_diff[entry.prompt][1]
+ if self._sort_order.by_name('prompt'):
+ self._sort_order.remove('prompt')
+ self._sort_order._list.append(SorterAndFilterer('subprompt1'))
+ self._sort_order._list.append(SorterAndFilterer('subprompt2'))
+ self._basic_items_attrs = self._prep_items_attrs(self.dir_entries)
ignorable_attrs = []
for attr_name, attr_vals in self._basic_items_attrs.items():
if len(attr_vals) < 2:
items_attrs_tmp_1 = separate_items_attrs(self._basic_items_attrs)
filtered = filter_entries(items_attrs_tmp_1)
- reduced_basic_items_attrs = self._prep_items_attrs(filtered)[0]
+ reduced_basic_items_attrs = self._prep_items_attrs(filtered)
items_attrs_tmp_2 = separate_items_attrs(reduced_basic_items_attrs)
for attr_name in (s.name for s in self._sort_order):
final_values: AttrValsByVisibility = {'incl': [], 'semi': []}
attr_name, attr_values = remaining[0]
if 1 == len(remaining):
for i, attr in enumerate(ancestors):
- parent_attr_name, parent_attr_value = attr
- if 'prompt' == parent_attr_name:
- parent_attr_value = self\
- ._prompts_diff[parent_attr_value]
- txt = f'<b>{parent_attr_name}</b>: {parent_attr_value}'
+ txt = f'<b>{attr[0]}</b>: {attr[1]}'
vlabel = VerticalLabel(txt, self._slots_geometry)
self._grid.attach(vlabel, i, i_row_ref[0], 1, 1)
row: list[Optional[GalleryItem]]
self._col_headers_grid.attach(Gtk.Box(), 0, 0, 1, 1)
top_attr_name: str = sort_attrs[-1][0]
for i, val in enumerate(sort_attrs[-1][1]):
- if 'prompt' == top_attr_name:
- val = self._prompts_diff[val]
label = Gtk.Label(label=f'<b>{top_attr_name}</b>: {val}',
xalign=0,
ellipsize=Pango.EllipsizeMode.MIDDLE)