Skip to content

Commit

Permalink
Fix #480: Improve image searching: Avoid deep/huge folders causing Va…
Browse files Browse the repository at this point in the history
…riety to ignore the other folders
  • Loading branch information
peterlevi committed Jun 16, 2022
1 parent 8ee5eea commit b0a04ae
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 68 deletions.
60 changes: 24 additions & 36 deletions variety/PreferencesVarietyDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -848,54 +848,42 @@ def show_thumbs(self, source_rows, pin=False, thumbs_type=None):

images = []
folders = []
image_count = 0

for row in source_rows:
if not row:
continue

type = row[1]
if type == Options.SourceType.IMAGE:
image_count += 1
images.append(row[2])
else:
folder = self.parent.get_folder_of_source(self.model_row_to_source(row))
image_count += sum(
1
for f in Util.list_files(
folders=(folder,),
filter_func=Util.is_image,
max_files=1,
randomize=False,
)
)
folders.append(folder)

if image_count > -1:
folder_images = list(
Util.list_files(folders=folders, filter_func=Util.is_image, max_files=1000)
)
if len(source_rows) == 1 and source_rows[0][1] == Options.SourceType.ALBUM_FILENAME:
folder_images = sorted(folder_images)
elif len(source_rows) == 1 and source_rows[0][1] == Options.SourceType.ALBUM_DATE:
folder_images = sorted(folder_images, key=os.path.getmtime)
else:
random.shuffle(folder_images)
to_show = images + folder_images
if hasattr(self, "focused_image") and self.focused_image is not None:
try:
to_show.remove(self.focused_image)
except Exception:
pass
to_show.insert(0, self.focused_image)
self.focused_image = None
self.parent.thumbs_manager.show(
to_show, screen=self.get_screen(), folders=folders, type=thumbs_type
)
if pin:
self.parent.thumbs_manager.pin()
if thumbs_type:
self.parent.update_indicator(auto_changed=False)
folder_images = list(
Util.list_files(folders=folders, filter_func=Util.is_image, max_files=10000)
)
if len(source_rows) == 1 and source_rows[0][1] == Options.SourceType.ALBUM_FILENAME:
folder_images = sorted(folder_images)
elif len(source_rows) == 1 and source_rows[0][1] == Options.SourceType.ALBUM_DATE:
folder_images = sorted(folder_images, key=os.path.getmtime)
else:
random.shuffle(folder_images)
to_show = images + folder_images
if hasattr(self, "focused_image") and self.focused_image is not None:
try:
to_show.remove(self.focused_image)
except Exception:
pass
to_show.insert(0, self.focused_image)
self.focused_image = None
self.parent.thumbs_manager.show(
to_show, screen=self.get_screen(), folders=folders, type=thumbs_type
)
if pin:
self.parent.thumbs_manager.pin()
if thumbs_type:
self.parent.update_indicator(auto_changed=False)

except Exception:
logger.exception(lambda: "Could not create thumbs window:")
Expand Down
58 changes: 35 additions & 23 deletions variety/Util.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,9 @@ def is_animated_gif(filename):
def list_files(
files=(), folders=(), filter_func=(lambda f: True), max_files=10000, randomize=True
):
class NextFolderException(Exception):
pass

count = 0
for filepath in files:
logger.debug(
Expand All @@ -411,29 +414,38 @@ def list_files(
random.shuffle(folders)

for folder in folders:
if os.path.isdir(folder):
try:
for root, subFolders, files in os.walk(folder, followlinks=True):
if randomize:
random.shuffle(files)
random.shuffle(subFolders)
for filename in files:
logger.debug(
lambda: "checking file %s against filter_func %s (root=%s)"
% (filename, filter_func, root)
)
path = os.path.join(root, filename)
if filter_func(path):
count += 1
if count > max_files:
logger.info(
lambda: "More than %d files in the folders, stop listing"
% max_files
)
return
yield path
except Exception:
logger.exception(lambda: "Could not walk folder " + folder)
folder_quota = max(20, int(max_files / len(folders)))
if not os.path.isdir(folder):
continue
try:
count_in_folder = 0
for root, subfolders, files in os.walk(folder, followlinks=True):
subfolder_quota = max(10, int(folder_quota / (1 + len(subfolders))))
if randomize:
random.shuffle(files)
random.shuffle(subfolders)
for filename in files[:subfolder_quota]:
logger.debug(
lambda: "checking file %s against filter_func %s (root=%s)"
% (filename, filter_func, root)
)
path = os.path.join(root, filename)
if filter_func(path):
count += 1
if count > max_files:
logger.info(
lambda: "More than %d files in the folders, stop listing"
% max_files
)
return
yield path
count_in_folder += 1
if count_in_folder > folder_quota:
raise NextFolderException
except NextFolderException:
continue
except Exception:
logger.exception(lambda: "Could not walk folder " + folder)

@staticmethod
def start_force_exit_thread(delay):
Expand Down
15 changes: 6 additions & 9 deletions variety/VarietyWindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
import gi # isort:skip

gi.require_version("Notify", "0.7")
from gi.repository import Gdk, GdkPixbuf, Gio, GObject, Gtk, Notify # isort:skip
from gi.repository import Gdk, Gio, GObject, Gtk, Notify # isort:skip
Notify.init("Variety")
# fmt: on

Expand Down Expand Up @@ -1579,11 +1579,10 @@ def _set_icon_to_current():
except Exception:
logger.exception(lambda: "Error while setting wallpaper")

def list_images(self):
return Util.list_files(self.individual_images, self.folders, Util.is_image, max_files=10000)

def select_random_images(self, count):
all_images = list(self.list_images())
all_images = list(
Util.list_files(self.individual_images, self.folders, Util.is_image, max_files=10000)
)
self.image_count = len(all_images)

# add just the first image of each album to the selection,
Expand Down Expand Up @@ -1847,9 +1846,7 @@ def image_ok(self, img, fuzziness):
width = self.image_colors_cache[img][3]
height = self.image_colors_cache[img][4]
else:
i = PILImage.open(img)
width = i.size[0]
height = i.size[1]
width, height = Util.get_size(img)

if not self.size_ok(width, height, fuzziness):
return False
Expand Down Expand Up @@ -1899,7 +1896,7 @@ def image_ok(self, img, fuzziness):
return True

except Exception:
logger.exception(lambda: "Error in image_ok for file %s" % img)
logger.warning(lambda: "Error in image_ok for file %s" % img)
return False

def size_ok(self, width, height, fuzziness=0):
Expand Down

0 comments on commit b0a04ae

Please sign in to comment.