diff --git a/etiquette/helpers.py b/etiquette/helpers.py index 5613f50..5d850eb 100644 --- a/etiquette/helpers.py +++ b/etiquette/helpers.py @@ -8,6 +8,7 @@ import math import mimetypes import os import PIL.Image +import re import unicodedata import zipstream @@ -269,6 +270,18 @@ def is_xor(*args): ''' return [bool(a) for a in args].count(True) == 1 +def natural_sorter(x): + ''' + Used for sorting files in 'natural' order instead of lexicographic order, + so that you get 1 2 3 4 5 6 7 8 9 10 11 12 13 ... + instead of 1 10 11 12 13 2 3 4 5 ... + Thank you Mark Byers + http://stackoverflow.com/a/11150413 + ''' + convert = lambda text: int(text) if text.isdigit() else text.lower() + alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)] + return alphanum_key(x) + def now(timestamp=True): ''' Return the current UTC timestamp or datetime object. diff --git a/etiquette/photodb.py b/etiquette/photodb.py index a294a4d..21763ac 100644 --- a/etiquette/photodb.py +++ b/etiquette/photodb.py @@ -1116,6 +1116,7 @@ class PDBUtilMixin: exclude_directories=None, exclude_filenames=None, make_albums=True, + natural_sort=True, new_photo_kwargs={}, new_photo_ratelimit=None, recurse=True, @@ -1220,6 +1221,9 @@ class PDBUtilMixin: ) for (current_directory, subdirectories, files) in walk_generator: + if natural_sort: + files = sorted(files, key=lambda f: helpers.natural_sorter(f.basename)) + photos = create_or_fetch_photos(files, new_photo_kwargs=new_photo_kwargs) if not make_albums: