From 8125942901307f4fb72d0e50d80bb1788f7858f4 Mon Sep 17 00:00:00 2001 From: Bradlee Speice Date: Tue, 15 Jan 2013 13:32:34 -0500 Subject: [PATCH] Playlist import code, various cleanups --- archiver/listfield.py | 6 +++-- archiver/playlist.py | 57 ++++++++++++++++++++++++++++++++++++++++++- archiver/song.py | 2 +- archiver/views.py | 2 +- 4 files changed, 62 insertions(+), 5 deletions(-) diff --git a/archiver/listfield.py b/archiver/listfield.py index 204c633..99cb76d 100644 --- a/archiver/listfield.py +++ b/archiver/listfield.py @@ -2,9 +2,11 @@ from django.db import models import re, itertools class IntegerListField(models.TextField): - """Store a list of integers in a database string. + """ + Store a list of integers in a database string. Format is: - [, , , ... , ]""" + [, , , ... , ] + """ description = "Field type for storing lists of integers." diff --git a/archiver/playlist.py b/archiver/playlist.py index ad09194..4eb292c 100644 --- a/archiver/playlist.py +++ b/archiver/playlist.py @@ -1,8 +1,12 @@ from django.db import models +from django.core.exceptions import ObjectDoesNotExist from song import Song from listfield import IntegerListField +import re +from warnings import warn + """ Playlist model Each playlist is a high-level ordering of songs. There really isn't much to a playlist - just its name, and the songs inside it. @@ -152,7 +156,7 @@ class Playlist (models.Model): song = self.songs.get(id = song_id) playlist_string += "#EXTINF:" + str(song.duration) + "," + song.artist + " - " + song.title + "\n" - playlist_string += song.url + "\n" + playlist_string += song.url + "\n\n" #Playlist footer @@ -161,9 +165,60 @@ class Playlist (models.Model): def _import(self, playlist_string = None): """ Import and convert a playlist into native DB format. + This function will return true if the playlist format was recognized, false otherwise. + It will return true even if there are errors processing individual songs in the playlist. As a side note - the _import() name is used since python doesn't let you name a function import(). """ + #TODO: Code playlist importing + self.song_list = [] if not playlist_string: #Make sure we have a string to operate on. return False + + #Figure out what format we're in + if playlist_string[0:7] == "#EXTM3U": + #Import m3u format playlist + + #Expected format is "#EXTINF:" followed by the song url on the next line. + line_iterator = playlist_string.split("\n").__iter__() + + #In case we end iteration early + try: + for line in line_iterator: + if line[0:8] != "#EXTINF:": + song_url = line.next() #Consume the next line + + try: + song = Song.objects.get(url = song_url) + self.song_list.append(song.id) + + except ObjectDoesNotExist: + #The URL of our song could not be found + warn("The playlist entry: " + song_url + " could not be found, and has not been added to your playlist." + + #Silently end processing + except StopIteration: + pass + + return True + + if playlist_string[0:10] == "[playlist]": + #Import pls format playlist + #This one is a bit simpler - we're just looking for lines that start with "File=" + pls_regex = re.compile("^File=", re.IGNORECASE) + + for file_line in pls_regex.match(pls_regex, playlist_string): + song_url = file_line[5:] + try: + song = Song.objects.get(url = song_url) + self.song_list.append(song.id) + + except ObjectDoesNotExist: + #The URL of our song could not be found + warn("The playlist entry: " + song_url + " could not be found, and has not been added to your playlist." + + return True + + #If we got here, the playlist format wasn't recognized. + return False diff --git a/archiver/song.py b/archiver/song.py index e65107c..e1ec7ae 100644 --- a/archiver/song.py +++ b/archiver/song.py @@ -12,7 +12,7 @@ and helps in doing sorting etc. _default_title = "_UNAVAILABLE_" _default_artist = "_UNAVAILABLE_" _default_album = "_UNAVAILABLE_" -_default_release_date = datetime.datetime.now #Function will be called per new song, rather than once at loading the file +_default_release_date = datetime.datetime.now #Function will be called per new song, rather than only being called right now. _default_genre = "_UNAVAILABLE_" _default_bpm = -1 _default_disc_number = -1 diff --git a/archiver/views.py b/archiver/views.py index 60f00ef..eb2cf3b 100644 --- a/archiver/views.py +++ b/archiver/views.py @@ -1 +1 @@ -# Create your views here. +#The archiver application is view-less - this is purely a backend manager.