mirror of
				https://github.com/bspeice/Melodia
				synced 2025-11-04 02:10:42 -05:00 
			
		
		
		
	Various bugfixes, add test case for playlists
This commit is contained in:
		@ -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)
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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()
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user