mirror of
https://github.com/bspeice/Melodia
synced 2024-11-15 20:48:23 -05:00
Restructure relationship b/w Songs and Archives
Songs now have a ForeignKey to Archive - one song can not be part of many Archives.
This commit is contained in:
parent
0d467e8457
commit
17960be548
@ -1,7 +1,5 @@
|
||||
from django.db import models
|
||||
|
||||
from song import Song
|
||||
|
||||
"""
|
||||
This is the archive model for the archiving backend of Melodia.
|
||||
It's purpose is to control the high-level functionality of managing
|
||||
@ -31,8 +29,8 @@ class Archive (models.Model):
|
||||
#Note that we're not using FilePathField since this is actually a folder
|
||||
root_folder = models.CharField(max_length = 255)
|
||||
|
||||
#And a reference to the songs in this archive
|
||||
songs = models.ManyToManyField(Song)
|
||||
#We've removed the reference to "songs" - instead define it as a ForeignKey,
|
||||
#and do lookups via song_set
|
||||
|
||||
#Backup settings
|
||||
backup_location = models.CharField(max_length = 255, default = "/dev/null")
|
||||
@ -53,7 +51,7 @@ class Archive (models.Model):
|
||||
|
||||
#It's hackish, but far fewer transactions to delete everything first, and add it all back.
|
||||
#If we get interrupted, just re-run it.
|
||||
self.songs.all().delete()
|
||||
song_set.all().delete()
|
||||
|
||||
#Add new songs
|
||||
for dirname, dirnames, filenames in os.walk(self.root_folder):
|
||||
@ -63,16 +61,16 @@ class Archive (models.Model):
|
||||
full_url = os.path.abspath(rel_url)
|
||||
new_song = Song(url = full_url)
|
||||
new_song.save()
|
||||
self.songs.add(new_song)
|
||||
song_set.add(new_song)
|
||||
|
||||
def _update_song_metadata(self, use_echonest = False, progress_callback = lambda x, y: None):
|
||||
"""Scan every song in this archive (database only) and make sure all songs are correct
|
||||
The progress_callback function is called with the current song being operated on first, and the total songs second."""
|
||||
#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()
|
||||
total_songs = song_set.count()
|
||||
|
||||
for index, song in enumerate(self.songs.all()):
|
||||
for index, song in enumerate(song_set.all()):
|
||||
song.populate_metadata(use_echonest = use_echonest)
|
||||
song.save()
|
||||
progress_callback(index + 1, total_songs)
|
||||
@ -133,9 +131,9 @@ class Archive (models.Model):
|
||||
"""
|
||||
import os, shutil, errno
|
||||
|
||||
total_songs = self.songs.count()
|
||||
total_songs = song_set.count()
|
||||
|
||||
for index, song in enumerate(self.songs.all()):
|
||||
for index, song in enumerate(song_set.all()):
|
||||
_current_filename = os.path.basename(song.url)
|
||||
_current_filename_no_extension = os.path.splitext(_current_filename)[0]
|
||||
|
||||
|
@ -1,7 +1,10 @@
|
||||
from django.db import models
|
||||
from Melodia import melodia_settings
|
||||
|
||||
from archive import Archive
|
||||
|
||||
import datetime
|
||||
import os.path
|
||||
"""
|
||||
The Song model
|
||||
Each instance of a Song represents a single music file.
|
||||
@ -63,6 +66,9 @@ class Song (models.Model):
|
||||
skip_count = models.IntegerField(default = _default_int)
|
||||
rating = models.IntegerField(default = _default_int, choices = _default_rating_choices)
|
||||
|
||||
#Link back to the archive this comes from
|
||||
parent_archive = models.ForeignKey(Archive)
|
||||
|
||||
#Set a static reference to the rating options
|
||||
RATING_DEFAULT = _default_rating
|
||||
RATING_BAD = _default_rating_bad
|
||||
@ -71,6 +77,10 @@ class Song (models.Model):
|
||||
RATING_GOOD = _default_rating_good
|
||||
RATING_EXCELLENT = _default_rating_excellent
|
||||
|
||||
def _get_full_url(self):
|
||||
"Combine this song's URL with the URL of its parent"
|
||||
return os.path.join(parent_archive.root_folder, self.url)
|
||||
|
||||
def _file_not_changed(self):
|
||||
"Make sure the hash for this file is valid - return True if it has not changed."
|
||||
#Overload the hash function with whatever Melodia as a whole is using
|
||||
@ -79,7 +89,7 @@ class Song (models.Model):
|
||||
#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')
|
||||
song_file = open(self._get_full_url, 'rb')
|
||||
current_file_hash = hash(song_file.read())
|
||||
|
||||
if current_file_hash == self.file_hash:
|
||||
@ -94,10 +104,10 @@ class Song (models.Model):
|
||||
#Overload the hash function with whatever Melodia as a whole is using
|
||||
from Melodia.melodia_settings import HASH_FUNCTION as hash
|
||||
|
||||
file_handle = open(self.url, 'rb')
|
||||
file_handle = open(self._get_full_url, 'rb')
|
||||
|
||||
self.file_hash = hash(file_handle.read())
|
||||
self.file_size = os.stat(self.url).st_size
|
||||
self.file_size = os.stat(self._get_full_url).st_size
|
||||
|
||||
def _grab_metadata_echonest(self):
|
||||
"Populate this song's metadata using EchoNest"
|
||||
@ -110,8 +120,8 @@ class Song (models.Model):
|
||||
|
||||
try:
|
||||
#Use mutagen to scan local metadata - don't update anything else (i.e. play_count)
|
||||
track = mutagen.File(self.url)
|
||||
track_easy = mutagen.File(self.url, easy=True)
|
||||
track = mutagen.File(self._get_full_url)
|
||||
track_easy = mutagen.File(self._get_full_url, easy=True)
|
||||
|
||||
self.title = track_easy['title'][0] or _default_string
|
||||
self.artist = track_easy['artist'][0] or _default_string
|
||||
|
Loading…
Reference in New Issue
Block a user