mirror of
https://github.com/bspeice/Melodia
synced 2024-11-16 04:58:20 -05:00
190f9a7890
Remove references to a 'collection' object - it was a half-baked idea, and the concepts it represented should be implemented in the webapp, not in the archive itself.
113 lines
4.3 KiB
Python
113 lines
4.3 KiB
Python
from django.db import models
|
|
from Melodia import melodia_settings
|
|
|
|
import datetime
|
|
"""
|
|
The Song model
|
|
Each instance of a Song represents a single music file.
|
|
This database model is used for storing the metadata information about a song,
|
|
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_genre = "<UNAVAILABLE>"
|
|
_default_bpm = -1
|
|
|
|
_default_bit_rate = -1
|
|
_default_duration = -1
|
|
_default_echonest_song_id = ""
|
|
|
|
class Song (models.Model):
|
|
|
|
"""
|
|
This class defines the fields and functions related to controlling
|
|
individual music files.
|
|
"""
|
|
|
|
#Standard user-populated metadata
|
|
title = models.CharField(max_length = 64, default = _default_title)
|
|
artist = models.CharField(max_length = 64, default = _default_artist)
|
|
album = models.CharField(max_length = 64, default = _default_album)
|
|
release_date = models.DateField(default = _default_release_date)
|
|
genre = models.CharField(max_length = 64, default = _default_genre)
|
|
bpm = models.IntegerField(default = _default_bpm)
|
|
|
|
#File metadata
|
|
bit_rate = models.IntegerField(default = _default_bit_rate)
|
|
duration = models.IntegerField(default = _default_bit_rate)
|
|
echonest_song_id = models.CharField(max_length = 64, default = _default_echonest_song_id)
|
|
url = models.CharField(max_length = 64)
|
|
file_hash = melodia_settings.HASH_RESULT_DB_TYPE
|
|
|
|
def populate_metadata(self, use_echonest = False):
|
|
"Populate the metadata of this song (only if file hash has changed)"
|
|
#Overload the hash function with whatever Melodia as a whole is using
|
|
from Melodia.melodia_settings import HASH_FUNCTION as hash
|
|
|
|
#Check if there's a hash entry - if there is, the song may not have changed,
|
|
#and we can go ahead and return
|
|
if self.file_hash != None:
|
|
song_file = open(self.url, 'rb')
|
|
current_file_hash = hash(song_file.read())
|
|
|
|
if current_file_hash == self.file_hash:
|
|
#The song data hasn't changed at all, we don't need to do anything
|
|
return
|
|
|
|
#If we've gotten to here, we do actually need to fully update the metadata
|
|
if use_echonest:
|
|
#Code to grab metadata from echonest here
|
|
pass
|
|
|
|
else:
|
|
#Grab metadata for the database using what is in the track.
|
|
from Melodia.resources import add_resource_dir
|
|
add_resource_dir()
|
|
|
|
import audiotools
|
|
|
|
try:
|
|
track = audiotools.open(self.url)
|
|
track_metadata = track.get_metadata()
|
|
|
|
self.title = track_metadata.track_name or _default_title
|
|
self.artist = track_metadata.artist_name or _default_artist
|
|
self.album = track_metadata.album_name or _default_album
|
|
self.release_date = datetime.date(int(track_metadata.year or 1), 1, 1)
|
|
self.bpm = _default_bpm
|
|
|
|
self.bit_rate = track.bits_per_sample() or _default_bit_rate
|
|
self.duration = int(track.seconds_length()) or _default_duration
|
|
self.echonest_song_id = _default_echonest_song_id
|
|
|
|
except audiotools.UnsupportedFile, e:
|
|
#Couldn't grab the local data - fill in the remaining data for this record, preserving
|
|
#anything that already exists.
|
|
self.title = self.title or _default_title
|
|
self.artist = self.artist or _default_artist
|
|
self.album = self.album or _default_album
|
|
self.release_date = self.release_date or _default_release_date()
|
|
|
|
self.bpm = self.bpm or _default_bpm
|
|
self.bit_rate = self.bit_rate or _default_bitrate
|
|
self.duration = self.bit_rate or _default_duration
|
|
self.echonest_song_id = self.echonest_song_id or _default_echonest_song_id
|
|
|
|
def convert(self, output_location, output_format, progress_func = lambda x, y: None):
|
|
"Convert a song to a new format."
|
|
#Note that output_format over-rides the format guessed by output_location
|
|
|
|
from Melodia.resources import add_resource_dir
|
|
add_resource_dir()
|
|
|
|
import audiotools
|
|
|
|
convert_from = audiotools.open(self.url)
|
|
convert_from.convert(output_location,
|
|
output_format,
|
|
progress_func)
|
|
|