From dfc062180bdeeba2505f45d6b65b5a5578f55e80 Mon Sep 17 00:00:00 2001 From: spl0k Date: Sat, 26 Oct 2013 13:13:19 +0200 Subject: [PATCH 1/3] Fix for files without tag Closes #6 --- api/browse.py | 2 +- scanner.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/browse.py b/api/browse.py index e9b7831..df1b691 100755 --- a/api/browse.py +++ b/api/browse.py @@ -104,7 +104,7 @@ def list_artists(): # According to the API page, there are no parameters? indexes = {} for artist in Artist.query.all(): - index = artist.name[0].upper() + index = artist.name[0].upper() if artist.name else '?' if index in map(str, xrange(10)): index = '#' elif index not in string.letters: diff --git a/scanner.py b/scanner.py index 907c1de..304d1a5 100755 --- a/scanner.py +++ b/scanner.py @@ -70,11 +70,11 @@ class Scanner: tr.disc = self.__try_read_tag(tag, 'discnumber', 1, lambda x: int(x[0].split('/')[0])) tr.number = self.__try_read_tag(tag, 'tracknumber', 1, lambda x: int(x[0].split('/')[0])) - tr.title = self.__try_read_tag(tag, 'title') + tr.title = self.__try_read_tag(tag, 'title', '') tr.year = self.__try_read_tag(tag, 'date', None, lambda x: int(x[0].split('-')[0])) tr.genre = self.__try_read_tag(tag, 'genre') tr.duration = int(tag.info.length) - tr.album = self.__find_album(self.__try_read_tag(tag, 'artist'), self.__try_read_tag(tag, 'album')) + tr.album = self.__find_album(self.__try_read_tag(tag, 'artist', ''), self.__try_read_tag(tag, 'album', '')) tr.bitrate = (tag.info.bitrate if hasattr(tag.info, 'bitrate') else int(os.path.getsize(path) * 8 / tag.info.length)) / 1000 tr.content_type = get_mime(os.path.splitext(path)[1][1:]) tr.last_modification = os.path.getmtime(path) From 78eac108a4f1eb2e09b9f795f47bee32cec33704 Mon Sep 17 00:00:00 2001 From: spl0k Date: Sat, 2 Nov 2013 19:02:45 +0100 Subject: [PATCH 2/3] Added an 'exit' command to the CLI --- cli.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cli.py b/cli.py index 80da3d4..fa2d285 100755 --- a/cli.py +++ b/cli.py @@ -53,6 +53,8 @@ class CLI(cmd.Cmd): def do_EOF(self, line): return True + do_exit = do_EOF + def default(self, line): print 'Unknown command %s' % line.split()[0] self.do_help(None) From 82992047ddac572a8482d33aeb610d991c57a138 Mon Sep 17 00:00:00 2001 From: spl0k Date: Sat, 2 Nov 2013 19:52:02 +0100 Subject: [PATCH 3/3] Added configurable extension whitelist on the scanner Closes #8 --- README.md | 2 ++ scanner.py | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8be2654..cce1c70 100755 --- a/README.md +++ b/README.md @@ -42,6 +42,8 @@ Available settings are: I personnaly use SQLite (`sqlite:////var/supysonic/supysonic.db`), but it might not be the brightest idea for large libraries. * **cache_dir**: path to a cache folder. Mostly used for resized cover art images. Defaults to `/supysonic`. * **log_file**: path and base name of a rolling log file. + * **scanner_extensions**: space-separated list of file extensions the scanner is restricted to. If omitted, files will be scanned + regardless of their extension * Section **lastfm**: * **api_key**: Last.FM [API key](http://www.last.fm/api/accounts) to enable scrobbling * **secret**: Last.FM API secret matching the key. diff --git a/scanner.py b/scanner.py index 304d1a5..3893b1d 100755 --- a/scanner.py +++ b/scanner.py @@ -22,14 +22,19 @@ class Scanner: self.__deleted_albums = 0 self.__deleted_tracks = 0 + extensions = config.get('base', 'scanner_extensions') + self.__extensions = map(str.lower, extensions.split()) if extensions else None + def scan(self, folder): for root, subfolders, files in os.walk(folder.path): for f in files: - self.__scan_file(os.path.join(root, f), folder) + path = os.path.join(root, f) + if self.__is_valid_path(path): + self.__scan_file(path, folder) folder.last_scan = int(time.time()) def prune(self, folder): - for track in [ t for t in self.__tracks if t.root_folder.id == folder.id and not os.path.exists(t.path) ]: + for track in [ t for t in self.__tracks if t.root_folder.id == folder.id and not self.__is_valid_path(t.path) ]: self.__remove_track(track) for album in [ album for artist in self.__artists for album in artist.albums if len(album.tracks) == 0 ]: @@ -48,6 +53,13 @@ class Scanner: for f in folder.children: self.check_cover_art(f) + def __is_valid_path(self, path): + if not os.path.exists(path): + return False + if not self.__extensions: + return True + return os.path.splitext(path)[1][1:].lower() in self.__extensions + def __scan_file(self, path, folder): tr = filter(lambda t: t.path == path, self.__tracks) if tr: