From 870efac03fa6e2eac4d2d69d6596a7102b70b42e Mon Sep 17 00:00:00 2001 From: Bradlee Speice Date: Thu, 10 Jan 2013 09:38:23 -0500 Subject: [PATCH] Various bugfixes, add test case for playlists --- archiver/archive.py | 20 +++++++++++--------- archiver/playlist.py | 18 +++++++++++------- archiver/tests.py | 41 ++++++++++++++++++++++++++++++++++++++--- 3 files changed, 60 insertions(+), 19 deletions(-) diff --git a/archiver/archive.py b/archiver/archive.py index e275657..82f3869 100644 --- a/archiver/archive.py +++ b/archiver/archive.py @@ -81,12 +81,11 @@ class Archive (models.Model): #This method operates only on the songs that are in the database - if you need to make #sure that new songs are added, use the _scan_filesystem() method in addition total_songs = self.songs.count() - current_song = 0 - for song in self.songs.all(): - current_song += 1 + for index, song in enumerate(self.songs.all()): song.populate_metadata(use_echonest = use_echonest) - progress_callback(current_song, total_songs) + song.save() + progress_callback(index + 1, total_songs) def _needs_backup(self): "Check if the current archive is due for a backup" @@ -129,7 +128,7 @@ class Archive (models.Model): import subprocess subprocess.call(['rsync', '-av', self.root_folder, self.backup_location]) - def reorganize(self, format_string, progress_function = lambda x, y: None, song_status_function = lambda x, y: None, dry_run = False): + def reorganize(self, format_string, progress_function = lambda w, x, y, z: None, dry_run = False): """Reorganize a music archive using a specified format string. Recognized escape characters: %a - Artist Name %A - Album Name @@ -139,11 +138,14 @@ class Archive (models.Model): %y - Album year Note that all organization takes place relative to the archive's root folder. - The progress_function is called with the current song number as its first argument, and total songs as its second. - The song_status_function is called with the current song url as its first argument, and new url as its second.""" + The progress_function is called with the current song number as its first argument, total songs as its second, + current song URL as the third argument, and new URL as the fourth. + """ import os, shutil, errno - for song in self.songs.all(): + total_songs = self.songs.count() + + for index, song in enumerate(self.songs.all()): _current_filename = os.path.basename(song.url) _current_filename_no_extension = os.path.splitext(_current_filename)[0] @@ -161,7 +163,7 @@ class Archive (models.Model): new_url = os.path.join(self.root_folder, new_location) - song_status_function(song.url, new_url) + progress_function(index + 1, total_songs, song.url, new_url) if not dry_run: new_folder = os.path.dirname(new_url) diff --git a/archiver/playlist.py b/archiver/playlist.py index 6b7d8c8..ad09194 100644 --- a/archiver/playlist.py +++ b/archiver/playlist.py @@ -68,7 +68,7 @@ class Playlist (models.Model): self.song_list.insert(position, new_song.id) - _populate_songs() + self._populate_songs() def append(self, new_song): """ @@ -82,7 +82,7 @@ class Playlist (models.Model): self.song_list.append(new_song.id) - _populate_songs() + self._populate_songs() def move(self, original_position, new_position): """ @@ -103,7 +103,7 @@ class Playlist (models.Model): del self.song_list[original_position] self.song_list.insert(new_position - 1, song_id) #Account for the list indices shifting down. - _populate_songs() + self._populate_songs() def remove(self, position): if position > len(self.song_list): @@ -111,7 +111,7 @@ class Playlist (models.Model): del self.song_list[position] - _populate_songs() + self._populate_songs() def export(self, playlist_type = "m3u"): """ @@ -135,7 +135,7 @@ class Playlist (models.Model): playlist_string += "File" + str(index + 1) + "=" + song.url + "\n" playlist_string += "Title" + str(index + 1) + "=" + song.title + "\n" - playlist_string += "Length" + str(index + 1) + "=" + song.duration + "\n" + playlist_string += "Length" + str(index + 1) + "=" + str(song.duration) + "\n" #Playlist footer playlist_string += "NumberOfEntries=" + str(len(self.song_list)) @@ -151,15 +151,19 @@ class Playlist (models.Model): for song_id in self.song_list: song = self.songs.get(id = song_id) - playlist_string += "#EXTINF:" + song.duration + "," + song.artist + " - " + song.title + "\n" + playlist_string += "#EXTINF:" + str(song.duration) + "," + song.artist + " - " + song.title + "\n" playlist_string += song.url + "\n" #Playlist footer + return playlist_string + def _import(self, playlist_string = None): """ Import and convert a playlist into native DB format. As a side note - the _import() name is used since python doesn't let you name a function import(). """ - pass + if not playlist_string: + #Make sure we have a string to operate on. + return False diff --git a/archiver/tests.py b/archiver/tests.py index 1c5bd36..663142e 100644 --- a/archiver/tests.py +++ b/archiver/tests.py @@ -22,6 +22,8 @@ class FilesystemScanTest(TestCase): new_archive.quick_scan() + new_archive.save() + class ScanTest(TestCase): def test_archive_scan(self): "Tests that we can scan an archive correctly." @@ -34,12 +36,12 @@ class ScanTest(TestCase): #We must save the archive before we can start adding songs to it new_archive.save() - new_archive.scan() + new_archive.save() class DeepScanTest(TestCase): def test_archive_deep_scan(self): - "Tests that we can deep scan an archive correctly." + "Tests that we can deep scan an archive correctly. This is currently broken, as EchoNest support does not exist." import os from archiver.archive import Archive from Melodia.settings import PROJECT_FOLDER @@ -49,5 +51,38 @@ class DeepScanTest(TestCase): #We must save the archive before we can start adding songs to it new_archive.save() - new_archive.deep_scan() + new_archive.save() + +class PlaylistExportTest(TestCase): + def test_playlist_export(self): + "Tests that we can export a playlist." + from archiver.archive import Archive + from archiver.playlist import Playlist + + #---------------------------------------------------------------------------- + #- Re-using code from the scan to set up our archive. + import os + from archiver.archive import Archive + from Melodia.settings import PROJECT_FOLDER + + TEST_DATA_FOLDER = os.path.join(PROJECT_FOLDER, "test_data") + new_archive = Archive(root_folder = TEST_DATA_FOLDER) + + #We must save the archive before we can start adding songs to it + new_archive.save() + new_archive.scan() + new_archive.save() + #---------------------------------------------------------------------------- + + #Resume playlist testing code + a_playlist = Playlist() + a_playlist.name = "Testing..." + a_playlist.save() + + for song in new_archive.songs.all(): + a_playlist.append(song) + + a_playlist.save() + + playlist_string = a_playlist.export()