From 84992bf80ea665c5e0ee5d63da8da15c95263da4 Mon Sep 17 00:00:00 2001 From: mopidy-dev Date: Mon, 23 Jan 2017 21:24:39 +0800 Subject: [PATCH 1/4] File: Add feature to file module for sorting files vs directories. Add configuration option in [file] section of mopidy.conf Add documentation for feature with the valid options. Signed-off-by: caysho@internode.on.net --- docs/ext/file.rst | 13 +++++++++++++ mopidy/file/__init__.py | 1 + mopidy/file/ext.conf | 1 + mopidy/file/library.py | 29 ++++++++++++++++++++++++++--- 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/docs/ext/file.rst b/docs/ext/file.rst index 661bf869..23ad7504 100644 --- a/docs/ext/file.rst +++ b/docs/ext/file.rst @@ -51,3 +51,16 @@ See :ref:`config` for general help on configuring Mopidy. Number of milliseconds before giving up scanning a file and moving on to the next file. Reducing the value might speed up the directory listing, but can lead to some tracks not being shown. + +.. confval:: file/sort_order + + Sort the files and directories in the given order. + Options are: + + ``DirectoriesFirst`` + + ``FilesFirst`` + + ``Mixed`` + + Default is ``DirectoriesFirst`` diff --git a/mopidy/file/__init__.py b/mopidy/file/__init__.py index 771a65a4..fe296f18 100644 --- a/mopidy/file/__init__.py +++ b/mopidy/file/__init__.py @@ -26,6 +26,7 @@ class Extension(ext.Extension): schema['show_dotfiles'] = config.Boolean(optional=True) schema['follow_symlinks'] = config.Boolean(optional=True) schema['metadata_timeout'] = config.Integer(optional=True) + schema['sort_order'] = config.String(optional=True) return schema def setup(self, registry): diff --git a/mopidy/file/ext.conf b/mopidy/file/ext.conf index 5470a8ec..d57f7da6 100644 --- a/mopidy/file/ext.conf +++ b/mopidy/file/ext.conf @@ -9,3 +9,4 @@ excluded_file_extensions = .jpeg follow_symlinks = false metadata_timeout = 1000 +sort_order = DirectoriesFirst diff --git a/mopidy/file/library.py b/mopidy/file/library.py index 6d426b85..35d2a98c 100644 --- a/mopidy/file/library.py +++ b/mopidy/file/library.py @@ -43,9 +43,19 @@ class FileLibraryProvider(backend.LibraryProvider): self._scanner = scan.Scanner( timeout=config['file']['metadata_timeout']) + self._sort_order = config['file']['sort_order'] + logger.info('File browing sort order is: %s', self._sort_order) + + self._sort_files_first = (self._sort_order == 'FilesFirst') + self._sort_directories_first = (self._sort_order == + 'DirectoriesFirst') + self._sort_mixed = (self._sort_order == 'Mixed') + def browse(self, uri): logger.debug('Browsing files at: %s', uri) result = [] + result_directories = [] + result_files = [] local_path = path.uri_to_path(uri) if local_path == 'root': @@ -78,11 +88,24 @@ class FileLibraryProvider(backend.LibraryProvider): name = dir_entry.decode(FS_ENCODING, 'replace') if os.path.isdir(child_path): - result.append(models.Ref.directory(name=name, uri=uri)) + result_directories.append(models.Ref.directory(name=name, + uri=uri)) elif os.path.isfile(child_path): - result.append(models.Ref.track(name=name, uri=uri)) + result_files.append(models.Ref.track(name=name, uri=uri)) + + if not self._sort_mixed: + result_directories.sort(key=operator.attrgetter('name')) + result_files.sort(key=operator.attrgetter('name')) + + if self._sort_mixed or self._sort_directories_first: + result = result_directories + result_files + + if self._sort_files_first: + result = result_files + result_directories + + if self._sort_mixed: + result.sort(key=operator.attrgetter('name')) - result.sort(key=operator.attrgetter('name')) return result def lookup(self, uri): From 0e1e703cbe83c602a75445783378b25068720aa4 Mon Sep 17 00:00:00 2001 From: Caysho Date: Wed, 1 Feb 2017 20:35:41 +0800 Subject: [PATCH 2/4] Discussion in mopidy PR 1595: remove sort order configuration item. Browse/File sort order to be directories first, otherwise all items alphabetically. Final sort order to be left to clients. Change mopidy/file/library.py to sort as described. Remove changes to: 1. docs/ext/file.rst 2. mopidy/file/__init__.py 3. mopidy/file/ext.conf Thanks go to sumpfralle for providing the base code for the sort lambda and stable sort suggestion. Signed-off-by: Caysho --- docs/ext/file.rst | 12 ------------ mopidy/file/__init__.py | 1 - mopidy/file/ext.conf | 2 +- mopidy/file/library.py | 32 ++++++++------------------------ 4 files changed, 9 insertions(+), 38 deletions(-) diff --git a/docs/ext/file.rst b/docs/ext/file.rst index 23ad7504..f855b310 100644 --- a/docs/ext/file.rst +++ b/docs/ext/file.rst @@ -52,15 +52,3 @@ See :ref:`config` for general help on configuring Mopidy. the next file. Reducing the value might speed up the directory listing, but can lead to some tracks not being shown. -.. confval:: file/sort_order - - Sort the files and directories in the given order. - Options are: - - ``DirectoriesFirst`` - - ``FilesFirst`` - - ``Mixed`` - - Default is ``DirectoriesFirst`` diff --git a/mopidy/file/__init__.py b/mopidy/file/__init__.py index fe296f18..771a65a4 100644 --- a/mopidy/file/__init__.py +++ b/mopidy/file/__init__.py @@ -26,7 +26,6 @@ class Extension(ext.Extension): schema['show_dotfiles'] = config.Boolean(optional=True) schema['follow_symlinks'] = config.Boolean(optional=True) schema['metadata_timeout'] = config.Integer(optional=True) - schema['sort_order'] = config.String(optional=True) return schema def setup(self, registry): diff --git a/mopidy/file/ext.conf b/mopidy/file/ext.conf index d57f7da6..78974f8a 100644 --- a/mopidy/file/ext.conf +++ b/mopidy/file/ext.conf @@ -9,4 +9,4 @@ excluded_file_extensions = .jpeg follow_symlinks = false metadata_timeout = 1000 -sort_order = DirectoriesFirst + diff --git a/mopidy/file/library.py b/mopidy/file/library.py index 35d2a98c..aaa45486 100644 --- a/mopidy/file/library.py +++ b/mopidy/file/library.py @@ -43,19 +43,9 @@ class FileLibraryProvider(backend.LibraryProvider): self._scanner = scan.Scanner( timeout=config['file']['metadata_timeout']) - self._sort_order = config['file']['sort_order'] - logger.info('File browing sort order is: %s', self._sort_order) - - self._sort_files_first = (self._sort_order == 'FilesFirst') - self._sort_directories_first = (self._sort_order == - 'DirectoriesFirst') - self._sort_mixed = (self._sort_order == 'Mixed') - def browse(self, uri): logger.debug('Browsing files at: %s', uri) result = [] - result_directories = [] - result_files = [] local_path = path.uri_to_path(uri) if local_path == 'root': @@ -88,23 +78,17 @@ class FileLibraryProvider(backend.LibraryProvider): name = dir_entry.decode(FS_ENCODING, 'replace') if os.path.isdir(child_path): - result_directories.append(models.Ref.directory(name=name, - uri=uri)) + result.append(models.Ref.directory(name=name, uri=uri)) elif os.path.isfile(child_path): - result_files.append(models.Ref.track(name=name, uri=uri)) + result.append(models.Ref.track(name=name, uri=uri)) - if not self._sort_mixed: - result_directories.sort(key=operator.attrgetter('name')) - result_files.sort(key=operator.attrgetter('name')) + sort_funcs = [operator.attrgetter('name'), + lambda item: 0 if item.type == models.Ref.DIRECTORY + else 1] + logger.debug('sort_funcs %s', sort_funcs) - if self._sort_mixed or self._sort_directories_first: - result = result_directories + result_files - - if self._sort_files_first: - result = result_files + result_directories - - if self._sort_mixed: - result.sort(key=operator.attrgetter('name')) + for key_func in sort_funcs: + result.sort(key=key_func) return result From 3f77f03057cfe09cd602aeac5832661ed2f413a7 Mon Sep 17 00:00:00 2001 From: Caysho Date: Fri, 3 Feb 2017 18:58:08 +0800 Subject: [PATCH 3/4] mopidy/file/library.py Improve sort efficiency with tkem's suggestion in PR 1595. Remove import operator because operator.attrgetter() not used now. mopidy/file/ext.conf Remove errant new line character introduced in commit 0e1e703cbe83c602a75445783378b25068720aa4. Signed-off-by: Caysho --- mopidy/file/ext.conf | 1 - mopidy/file/library.py | 11 +++-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/mopidy/file/ext.conf b/mopidy/file/ext.conf index 78974f8a..5470a8ec 100644 --- a/mopidy/file/ext.conf +++ b/mopidy/file/ext.conf @@ -9,4 +9,3 @@ excluded_file_extensions = .jpeg follow_symlinks = false metadata_timeout = 1000 - diff --git a/mopidy/file/library.py b/mopidy/file/library.py index aaa45486..ca879238 100644 --- a/mopidy/file/library.py +++ b/mopidy/file/library.py @@ -1,7 +1,6 @@ from __future__ import unicode_literals import logging -import operator import os import sys import urllib2 @@ -82,13 +81,9 @@ class FileLibraryProvider(backend.LibraryProvider): elif os.path.isfile(child_path): result.append(models.Ref.track(name=name, uri=uri)) - sort_funcs = [operator.attrgetter('name'), - lambda item: 0 if item.type == models.Ref.DIRECTORY - else 1] - logger.debug('sort_funcs %s', sort_funcs) - - for key_func in sort_funcs: - result.sort(key=key_func) + def order(item): + return (item.type != models.Ref.DIRECTORY, item.name) + result.sort(key=order) return result From 249533f0007a2fb187ccb4a4926314c27d3c7a09 Mon Sep 17 00:00:00 2001 From: Caysho Date: Fri, 3 Feb 2017 19:08:33 +0800 Subject: [PATCH 4/4] docs/etc/file.rst Remove trailing new line character Signed-off-by: Caysho --- docs/ext/file.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/ext/file.rst b/docs/ext/file.rst index f855b310..661bf869 100644 --- a/docs/ext/file.rst +++ b/docs/ext/file.rst @@ -51,4 +51,3 @@ See :ref:`config` for general help on configuring Mopidy. Number of milliseconds before giving up scanning a file and moving on to the next file. Reducing the value might speed up the directory listing, but can lead to some tracks not being shown. -