Various bugfixes, add test case for playlists

master
Bradlee Speice 2013-01-10 09:38:23 -05:00
parent 811fdc652d
commit 870efac03f
3 changed files with 60 additions and 19 deletions

View File

@ -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)

View File

@ -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

View File

@ -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()