Most of the backend work to get album switching working (selecting which release from a releasegroup you want headphones to point to)

This commit is contained in:
rembo10
2012-08-14 21:07:36 +05:30
parent 70351e0e56
commit ceea8977e8
5 changed files with 390 additions and 178 deletions

View File

@@ -719,10 +719,12 @@ def dbcheck():
conn=sqlite3.connect(DB_FILE)
c=conn.cursor()
c.execute('CREATE TABLE IF NOT EXISTS artists (ArtistID TEXT UNIQUE, ArtistName TEXT, ArtistSortName TEXT, DateAdded TEXT, Status TEXT, IncludeExtras INTEGER, LatestAlbum TEXT, ReleaseDate TEXT, AlbumID TEXT, HaveTracks INTEGER, TotalTracks INTEGER, LastUpdated TEXT, ArtworkURL TEXT, ThumbURL TEXT)')
c.execute('CREATE TABLE IF NOT EXISTS albums (ArtistID TEXT, ArtistName TEXT, AlbumTitle TEXT, AlbumASIN TEXT, ReleaseDate TEXT, DateAdded TEXT, AlbumID TEXT UNIQUE, Status TEXT, Type TEXT, ArtworkURL TEXT, ThumbURL TEXT)')
c.execute('CREATE TABLE IF NOT EXISTS tracks (ArtistID TEXT, ArtistName TEXT, AlbumTitle TEXT, AlbumASIN TEXT, AlbumID TEXT, TrackTitle TEXT, TrackDuration, TrackID TEXT, TrackNumber INTEGER, Location TEXT, BitRate INTEGER, CleanName TEXT, Format TEXT)')
c.execute('CREATE TABLE IF NOT EXISTS albums (ArtistID TEXT, ArtistName TEXT, AlbumTitle TEXT, AlbumASIN TEXT, ReleaseDate TEXT, DateAdded TEXT, AlbumID TEXT UNIQUE, Status TEXT, Type TEXT, ArtworkURL TEXT, ThumbURL TEXT, ReleaseID TEXT, ReleaseCountry TEXT, ReleaseFormat TEXT)') # ReleaseFormat here means CD,Digital,Vinyl, etc. If using the default Headphones hybrid release, ReleaseID will equal AlbumID (AlbumID is releasegroup id)
c.execute('CREATE TABLE IF NOT EXISTS tracks (ArtistID TEXT, ArtistName TEXT, AlbumTitle TEXT, AlbumASIN TEXT, AlbumID TEXT, TrackTitle TEXT, TrackDuration, TrackID TEXT, TrackNumber INTEGER, Location TEXT, BitRate INTEGER, CleanName TEXT, Format TEXT, ReleaseID TEXT)') # Format here means mp3, flac, etc.
c.execute('CREATE TABLE IF NOT EXISTS allalbums (ArtistID TEXT, ArtistName TEXT, AlbumTitle TEXT, AlbumASIN TEXT, ReleaseDate TEXT, AlbumID TEXT, Type TEXT, ReleaseID TEXT, ReleaseCountry TEXT, ReleaseFormat TEXT)')
c.execute('CREATE TABLE IF NOT EXISTS alltracks (ArtistID TEXT, ArtistName TEXT, AlbumTitle TEXT, AlbumASIN TEXT, AlbumID TEXT, TrackTitle TEXT, TrackDuration, TrackID TEXT, TrackNumber INTEGER, Location TEXT, BitRate INTEGER, CleanName TEXT, Format TEXT, ReleaseID TEXT)')
c.execute('CREATE TABLE IF NOT EXISTS snatched (AlbumID TEXT, Title TEXT, Size INTEGER, URL TEXT, DateAdded TEXT, Status TEXT, FolderName TEXT)')
c.execute('CREATE TABLE IF NOT EXISTS have (ArtistName TEXT, AlbumTitle TEXT, TrackNumber TEXT, TrackTitle TEXT, TrackLength TEXT, BitRate TEXT, Genre TEXT, Date TEXT, TrackID TEXT, Location TEXT, CleanName TEXT, Format TEXT)')
c.execute('CREATE TABLE IF NOT EXISTS have (ArtistName TEXT, AlbumTitle TEXT, TrackNumber TEXT, TrackTitle TEXT, TrackLength TEXT, BitRate TEXT, Genre TEXT, Date TEXT, TrackID TEXT, Location TEXT, CleanName TEXT, Format TEXT, Matched TEXT)') # Matched is a temporary value used to see if there was a match found in alltracks
c.execute('CREATE TABLE IF NOT EXISTS lastfmcloud (ArtistName TEXT, ArtistID TEXT, Count INTEGER)')
c.execute('CREATE TABLE IF NOT EXISTS descriptions (ArtistID TEXT, ReleaseGroupID TEXT, ReleaseID TEXT, Summary TEXT, Content TEXT, LastUpdated TEXT)')
c.execute('CREATE TABLE IF NOT EXISTS blacklist (ArtistID TEXT UNIQUE)')
@@ -846,6 +848,27 @@ def dbcheck():
c.execute('SELECT LastUpdated from descriptions')
except sqlite3.OperationalError:
c.execute('ALTER TABLE descriptions ADD COLUMN LastUpdated TEXT DEFAULT NULL')
try:
c.execute('SELECT ReleaseID from albums')
except sqlite3.OperationalError:
c.execute('ALTER TABLE albums ADD COLUMN ReleaseID TEXT DEFAULT NULL')
c.execute('UPDATE TABLE albums SET ReleaseID = AlbumID')
try:
c.execute('SELECT ReleaseFormat from albums')
except sqlite3.OperationalError:
c.execute('ALTER TABLE albums ADD COLUMN ReleaseFormat TEXT DEFAULT NULL')
try:
c.execute('SELECT ReleaseCountry from albums')
except sqlite3.OperationalError:
c.execute('ALTER TABLE albums ADD COLUMN ReleaseCountry TEXT DEFAULT NULL')
try:
c.execute('SELECT ReleaseID from tracks')
except sqlite3.OperationalError:
c.execute('ALTER TABLE tracks ADD COLUMN ReleaseID TEXT DEFAULT NULL')
conn.commit()
c.close()

View File

@@ -0,0 +1,81 @@
# This file is part of Headphones.
#
# Headphones is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Headphones is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Headphones. If not, see <http://www.gnu.org/licenses/>.
import headphones
from headphones import db, logger
def switch(AlbumID, ReleaseID):
'''
Takes the contents from allalbums & alltracks (based on ReleaseID) and switches them into
the albums & tracks table.
'''
myDB = db.DBConnection()
oldalbumdata = myDB.select('SELECT * from albums WHERE AlbumID=?', [AlbumID])
newalbumdata = myDB.select('SELECT * from allalbums WHERE ReleaseID=?', [ReleaseID])
newtrackdata = myDB.select('SELECT * from alltracks WHERE ReleaseID=?', [ReleaseID])
myDB.action('DELETE * from tracks WHERE AlbumID=?', [AlbumID])
controlValueDict = {"AlbumID": AlbumID}
newValueDict = {"ArtistID": newalbumdata['ArtistID'],
"ArtistName": newalbumdata['ArtistName'],
"AlbumTitle": newalbumdata['AlbumTitle'],
"ReleaseID": newalbumdata['ReleaseID'],
"AlbumASIN": newalbumdata['AlbumASIN'],
"ReleaseDate": newalbumdata['ReleaseDate'],
"Type": newalbumdata['Type'],
"ReleaseCountry": newalbumdata['ReleaseCountry'],
"ReleaseFormat": newalbumdata['ReleaseFormat']
}
myDB.upsert("albums", newValueDict, controlValueDict)
for track in newtrackdata:
controlValueDict = {"TrackID": track['TrackID'],
"AlbumID": AlbumID
newValueDict = {"ArtistID": track['ArtistID'],
"ArtistName": track['ArtistName'],
"AlbumTitle": track['AlbumTitle'],
"AlbumASIN": track['AlbumASIN'],
"ReleaseID": track['ReleaseID'],
"TrackTitle": track['TrackTitle'],
"TrackDuration": track['TrackDuration'],
"TrackNumber": track['TrackNumber'],
"CleanName": track['CleanName'],
"Location": track['Location'],
"Format": track['Format'],
"BitRate": track['BitRate']
}
myDB.upsert("tracks", newValueDict, controlValueDict)
# Mark albums as downloaded if they have at least 80% (by default, configurable) of the album
have_track_count = len(myDB.select('SELECT * from tracks WHERE AlbumID=? AND Location IS NOT NULL', [AlbumID]))
if oldalbumdata['Status'] == 'Skipped' and ((have_track_count/float(total_track_count)) >= (headphones.ALBUM_COMPLETION_PCT/100.0)):
myDB.action('UPDATE albums SET Status=? WHERE AlbumID=?', ['Downloaded', rg['id']])
# Update have track counts on index
totaltracks = len(myDB.select('SELECT TrackTitle from tracks WHERE ArtistID=?', [artistid]))
havetracks = len(myDB.select('SELECT TrackTitle from tracks WHERE ArtistID=? AND Location IS NOT NULL', [artistid])) + len(myDB.select('SELECT TrackTitle from have WHERE ArtistName like ?', [artist['artist_name']]))
controlValueDict = {"ArtistID": newalbumdata['ArtistID']}
newValueDict = { "TotalTracks": totaltracks,
"HaveTracks": havetracks}
myDB.upsert("artists", newValueDict, controlValueDict)

View File

@@ -159,29 +159,160 @@ def addArtisttoDB(artistid, extrasonly=False):
rg_exists = myDB.action("SELECT * from albums WHERE AlbumID=?", [rg['id']]).fetchone()
try:
release_dict = mb.getReleaseGroup(rgid)
releaselist = mb.getReleaseGroup(rgid)
except Exception, e:
logger.info('Unable to get release information for %s - there may not be any official releases in this release group' % rg['title'])
continue
if not release_dict:
if not releaselist:
continue
# This will be used later to build a hybrid release
fullreleaselist = []
for release in releaselist:
releaseid = release['id']
try:
releasedict = mb.getRelease(releaseid, include_artist_info=False)
except Exception, e:
logger.info('Unable to get release information for %s' % release['id'])
continue
if not releasedict:
continue
controlValueDict = {"ReleaseID": release['id']}
newValueDict = {"ArtistID": artistid,
"ArtistName": artist['artist_name'],
"AlbumTitle": rg['title'],
"AlbumID": rg['id'],
"AlbumASIN": releasedict['asin'],
"ReleaseDate": releasedict['date'],
"Type": rg['type'],
"ReleaseCountry": releasedict['country'],
"ReleaseFormat": releasedict['format']
}
myDB.upsert("allalbums", newValueDict, controlValueDict)
# Build the dictionary for the fullreleaselist
newValueDict['ReleaseID'] = release['id']
newValueDict['Tracks'] = releasedict['tracks']
fullreleaselist.append(newValueDict)
for track in releasedict['tracks']:
cleanname = helpers.cleanName(artist['artist_name'] + ' ' + rg['title'] + ' ' + track['title'])
controlValueDict = {"TrackID": track['id'],
"ReleaseID": release['id']}
newValueDict = {"ArtistID": artistid,
"ArtistName": artist['artist_name'],
"AlbumTitle": rg['title'],
"AlbumASIN": releasedict['asin'],
"AlbumID": rg['id'],
"TrackTitle": track['title'],
"TrackDuration": track['duration'],
"TrackNumber": track['number'],
"CleanName": cleanname
}
match = myDB.action('SELECT Location, BitRate, Format from have WHERE CleanName=?', [cleanname]).fetchone()
if not match:
match = myDB.action('SELECT Location, BitRate, Format from have WHERE ArtistName LIKE ? AND AlbumTitle LIKE ? AND TrackTitle LIKE ?', [artist['artist_name'], rg['title'], track['title']]).fetchone()
if not match:
match = myDB.action('SELECT Location, BitRate, Format from have WHERE TrackID=?', [track['id']]).fetchone()
if match:
newValueDict['Location'] = match['Location']
newValueDict['BitRate'] = match['BitRate']
newValueDict['Format'] = match['Format']
myDB.action('UPDATE tracks SET Matched="True" WHERE Location=?', match['Location'])
myDB.upsert("alltracks", newValueDict, controlValueDict)
# Basically just do the same thing again for the hybrid release
hybridrelease = getHybridRelease(fullreleaselist)
# Use the ReleaseGroupID as the ReleaseID for the hybrid release to differentiate it
# We can then use the condition WHERE ReleaseID == ReleaseGroupID to select it
# The hybrid won't have a country or a format
controlValueDict = {"ReleaseID": rg['id']}
newValueDict = {"ArtistID": artistid,
"ArtistName": artist['artist_name'],
"AlbumTitle": rg['title'],
"AlbumID": rg['id'],
"AlbumASIN": hybridrelease['AlbumASIN'],
"ReleaseDate": hybridrelease['ReleaseDate'],
"Type": rg['type']
}
myDB.upsert("allalbums", newValueDict, controlValueDict)
for track in hybridrelease['Tracks']:
cleanname = helpers.cleanName(artist['artist_name'] + ' ' + rg['title'] + ' ' + track['title'])
logger.info(u"Now adding/updating album: " + rg['title'])
controlValueDict = {"TrackID": track['id'],
"ReleaseID": rg['id']}
newValueDict = {"ArtistID": artistid,
"ArtistName": artist['artist_name'],
"AlbumTitle": rg['title'],
"AlbumASIN": hybridrelease['AlbumASIN'],
"AlbumID": rg['id'],
"TrackTitle": track['title'],
"TrackDuration": track['duration'],
"TrackNumber": track['number'],
"CleanName": cleanname
}
match = myDB.action('SELECT Location, BitRate, Format from have WHERE CleanName=?', [cleanname]).fetchone()
if not match:
match = myDB.action('SELECT Location, BitRate, Format from have WHERE ArtistName LIKE ? AND AlbumTitle LIKE ? AND TrackTitle LIKE ?', [artist['artist_name'], rg['title'], track['title']]).fetchone()
if not match:
match = myDB.action('SELECT Location, BitRate, Format from have WHERE TrackID=?', [track['id']]).fetchone()
if match:
newValueDict['Location'] = match['Location']
newValueDict['BitRate'] = match['BitRate']
newValueDict['Format'] = match['Format']
myDB.action('UPDATE tracks SET Matched="True" WHERE Location=?', match['Location'])
myDB.upsert("alltracks", newValueDict, controlValueDict)
# Delete matched tracks from the have table
myDB.action('DELETE * from have WHERE Matched="True"')
# If there's no release in the main albums tables, add the default (hybrid)
# If there is a release, check the ReleaseID against the AlbumID to see if they differ (user updated)
if not rg_exists:
releaseid = rg['id']
else:
releaseid = rg_exists['ReleaseID']
album = myDB.select('SELECT * from allallbums WHERE ReleaseID=?', releaseid)
controlValueDict = {"AlbumID": rg['id']}
newValueDict = {"ArtistID": artistid,
"ArtistName": artist['artist_name'],
"AlbumTitle": rg['title'],
"AlbumASIN": release_dict['asin'],
"ReleaseDate": release_dict['releasedate'],
"Type": rg['type']
}
# Only change the status & add DateAdded if the album is not already in the database
"ReleaseID": album['ReleaseID'],
"AlbumASIN": album['AlbumASIN'],
"ReleaseDate": album['ReleaseDate'],
"Type": album['Type'],
"ReleaseCountry": album['ReleaseCountry'],
"ReleaseFormat": album['ReleaseFormat']
}
if not rg_exists:
newValueDict['DateAdded']= helpers.today()
if headphones.AUTOWANT_ALL:
@@ -193,38 +324,31 @@ def addArtisttoDB(artistid, extrasonly=False):
myDB.upsert("albums", newValueDict, controlValueDict)
myDB.action('DELETE * from tracks WHERE AlbumID=?', rg['id'])
tracks = myDB.select('SELECT * from alltracks WHERE ReleaseID=?', [releaseid])
# This is used to see how many tracks you have from an album - to mark it as downloaded. Default is 80%, can be set in config as ALBUM_COMPLETION_PCT
total_track_count = len(release_dict['tracks'])
total_track_count = len(tracks)
for track in release_dict['tracks']:
for track in tracks:
cleanname = helpers.cleanName(artist['artist_name'] + ' ' + rg['title'] + ' ' + track['title'])
controlValueDict = {"TrackID": track['id'],
controlValueDict = {"TrackID": track['TrackID'],
"AlbumID": rg['id']}
newValueDict = {"ArtistID": artistid,
"ArtistName": artist['artist_name'],
"AlbumTitle": rg['title'],
"AlbumASIN": release_dict['asin'],
"TrackTitle": track['title'],
"TrackDuration": track['duration'],
"TrackNumber": track['number'],
"CleanName": cleanname
newValueDict = {"ArtistID": track['ArtistID'],
"ArtistName": track['ArtistName'],
"AlbumTitle": track['AlbumTitle'],
"AlbumASIN": track['AlbumASIN'],
"ReleaseID": track['ReleaseID'],
"TrackTitle": track['TrackTitle'],
"TrackDuration": track['TrackDuration'],
"TrackNumber": track['TrackNumber'],
"CleanName": track['CleanName'],
"Location": track['Location'],
"Format": track['Format'],
"BitRate": track['BitRate']
}
match = myDB.action('SELECT Location, BitRate, Format from have WHERE CleanName=?', [cleanname]).fetchone()
if not match:
match = myDB.action('SELECT Location, BitRate, Format from have WHERE ArtistName LIKE ? AND AlbumTitle LIKE ? AND TrackTitle LIKE ?', [artist['artist_name'], rg['title'], track['title']]).fetchone()
if not match:
match = myDB.action('SELECT Location, BitRate, Format from have WHERE TrackID=?', [track['id']]).fetchone()
if match:
newValueDict['Location'] = match['Location']
newValueDict['BitRate'] = match['BitRate']
newValueDict['Format'] = match['Format']
myDB.action('DELETE from have WHERE Location=?', [match['Location']])
myDB.upsert("tracks", newValueDict, controlValueDict)
# Mark albums as downloaded if they have at least 80% (by default, configurable) of the album
@@ -412,3 +536,76 @@ def updateFormat():
newValueDict = {"Format": f.format}
myDB.upsert("have", newValueDict, controlValueDict)
logger.info('Finished finding media format for %s files' % len(havetracks))
def getHybridRelease(fullreleaselist):
"""
Returns a dictionary of best group of tracks from the list of releases & earliest release date
"""
sortable_release_list = []
for release in fullreleaselist:
formats = {
'2xVinyl': '2',
'Vinyl': '2',
'CD': '0',
'Cassette': '3',
'2xCD': '1',
'Digital Media': '0'
}
countries = {
'US': '0',
'GB': '1',
'JP': '2',
}
try:
format = int(formats[release['Format']])
except:
format = 3
try:
country = int(countries[release['Country']])
except:
country = 3
release_dict = {
'hasasin': bool(release['AlbumASIN']),
'asin': release['AlbumASIN']
'trackscount': len(release['Tracks'],
'releaseid': release['ReleaseID'],
'releasedate': release['ReleaseDate'],
'format': format,
'country': country,
'tracks': release['Tracks']
}
sortable_release_list.append(release_dict)
#necessary to make dates that miss the month and/or day show up after full dates
def getSortableReleaseDate(releaseDate):
if releaseDate == None:
return 'None';#change this value to change the sorting behaviour of none, returning 'None' will put it at the top
#which was normal behaviour for pre-ngs versions
if releaseDate.count('-') == 2:
return releaseDate
elif releaseDate.count('-') == 1:
return releaseDate + '32'
else:
return releaseDate + '13-32'
sortable_release_list.sort(key=lambda x:getSortableReleaseDate(x['releasedate']))
average_tracks = sum(x['trackscount'] for x in releaselist) / float(len(releaselist))
for item in sortable_release_list:
item['trackscount_delta'] = abs(average_tracks - item['trackscount'])
a = multikeysort(sortable_release_list, ['-hasasin', 'country', 'format', 'trackscount_delta'])
release_dict = {'ReleaseDate' : sortable_release_list[0]['releasedate'],
'Tracks' : a[0]['tracks'],
'AlbumASIN' : a[0]['asin']
}
return release_dict

View File

@@ -124,9 +124,9 @@ def findArtist(name, limit=1):
else:
artistlist.append({
'name': unicode(result['sort-name']),
'uniquename': uniquename,
'id': unicode(result['id']),
'url': unicode("http://musicbrainz.org/artist/" + result['id']),#probably needs to be changed
'uniquename': uniquename,
'id': unicode(result['id']),
'url': unicode("http://musicbrainz.org/artist/" + result['id']),#probably needs to be changed
'score': int(result['ext:score'])
})
return artistlist
@@ -158,10 +158,10 @@ def findRelease(name, limit=1):
'uniquename': unicode(result['artist-credit'][0]['artist']['name']),
'title': unicode(result['title']),
'id': unicode(result['artist-credit'][0]['artist']['id']),
'albumid': unicode(result['id']),
'url': unicode("http://musicbrainz.org/artist/" + result['artist-credit'][0]['artist']['id']),#probably needs to be changed
'albumurl': unicode("http://musicbrainz.org/release/" + result['id']),#probably needs to be changed
'score': int(result['ext:score'])
'albumid': unicode(result['id']),
'url': unicode("http://musicbrainz.org/artist/" + result['artist-credit'][0]['artist']['id']),#probably needs to be changed
'albumurl': unicode("http://musicbrainz.org/release/" + result['id']),#probably needs to be changed
'score': int(result['ext:score'])
})
return releaselistngs
@@ -215,8 +215,7 @@ def getArtist(artistid, extrasonly=False):
# if 'end' in artist['life-span']:
# artist_dict['artist_enddate'] = unicode(artist['life-span']['end'])
releasegroups = []
if not extrasonly:
@@ -224,10 +223,10 @@ def getArtist(artistid, extrasonly=False):
if rg['type'] != 'Album': #only add releases without a secondary type
continue
releasegroups.append({
'title': unicode(rg['title']),
'id': unicode(rg['id']),
'url': u"http://musicbrainz.org/release-group/" + rg['id'],
'type': unicode(rg['type'])
'title': unicode(rg['title']),
'id': unicode(rg['id']),
'url': u"http://musicbrainz.org/release-group/" + rg['id'],
'type': unicode(rg['type'])
})
# See if we need to grab extras
@@ -255,18 +254,18 @@ def getArtist(artistid, extrasonly=False):
for rg in artist['release-group-list']:
releasegroups.append({
'title': unicode(rg['title']),
'id': unicode(rg['id']),
'url': u"http://musicbrainz.org/release-group/" + rg['id'],
'type': unicode(rg['type'])
'id': unicode(rg['id']),
'url': u"http://musicbrainz.org/release-group/" + rg['id'],
'type': unicode(rg['type'])
})
artist_dict['releasegroups'] = releasegroups
return artist_dict
def getReleaseGroup(rgid):
"""
Returns a dictionary of the best stuff from a release group
Returns a list of releases in a release group
"""
with mb_lock:
@@ -284,113 +283,10 @@ def getReleaseGroup(rgid):
if not releaseGroup:
return False
time.sleep(sleepytime)
# I think for now we have to make separate queries for each release, in order
# to get more detailed release info (ASIN, track count, etc.)
for release in releaseGroup['release-list']:
releaseResult = None
try:
releaseResult = musicbrainzngs.get_release_by_id(release['id'],["recordings","media"])['release']
except WebServiceError, e:
logger.warn('Attempt to retrieve release information for %s from MusicBrainz failed (%s)' % (releaseResult.title, str(e)))
time.sleep(5)
if not releaseResult:
continue
if releaseGroup['type'] == 'live' and releaseResult['status'] != 'Official':
logger.debug('%s is not an official live album. Skipping' % releaseResult.name)
continue
time.sleep(sleepytime)
formats = {
'2xVinyl': '2',
'Vinyl': '2',
'CD': '0',
'Cassette': '3',
'2xCD': '1',
'Digital Media': '0'
}
countries = {
'US': '0',
'GB': '1',
'JP': '2',
}
try:
format = int(formats[releaseResult['medium-list'][0]['format']])
except:
format = 3
try:
country = int(countries[releaseResult['country']])
except:
country = 3
totalTracks = 0
tracks = []
for medium in releaseResult['medium-list']:
for track in medium['track-list']:
tracks.append({
'number': totalTracks + 1,
'title': unicode(track['recording']['title']),
'id': unicode(track['recording']['id']),
'url': u"http://musicbrainz.org/track/" + track['recording']['id'],
'duration': int(track['recording']['length'] if 'length' in track['recording'] else track['length'] if 'length' in track else 0)
})
totalTracks += 1
release_dict = {
'hasasin': bool(releaseResult.get('asin')),
'asin': unicode(releaseResult.get('asin')) if 'asin' in releaseResult else None,
'trackscount': totalTracks,
'releaseid': unicode(releaseResult.get('id')),
'releasedate': unicode(releaseResult.get('date')) if 'date' in releaseResult else None,
'format': format,
'country': country
}
release_dict['tracks'] = tracks
releaselist.append(release_dict)
#necessary to make dates that miss the month and/or day show up after full dates
def getSortableReleaseDate(releaseDate):
if releaseDate == None:
return 'None';#change this value to change the sorting behaviour of none, returning 'None' will put it at the top
#which was normal behaviour for pre-ngs versions
if releaseDate.count('-') == 2:
return releaseDate
elif releaseDate.count('-') == 1:
return releaseDate + '32'
else:
return releaseDate + '13-32'
releaselist.sort(key=lambda x:getSortableReleaseDate(x['releasedate']))
average_tracks = sum(x['trackscount'] for x in releaselist) / float(len(releaselist))
for item in releaselist:
item['trackscount_delta'] = abs(average_tracks - item['trackscount'])
a = multikeysort(releaselist, ['-hasasin', 'country', 'format', 'trackscount_delta'])
release_dict = {'releaseid' :a[0]['releaseid'],
'releasedate' : releaselist[0]['releasedate'],
'trackcount' : a[0]['trackscount'],
'tracks' : a[0]['tracks'],
'asin' : a[0]['asin'],
'releaselist' : releaselist,
'artist_name' : unicode(releaseGroup['artist-credit'][0]['artist']['name']),
'artist_id' : unicode(releaseGroup['artist-credit'][0]['artist']['id']),
'title' : unicode(releaseGroup['title']),
'type' : unicode(releaseGroup['type'])
}
return release_dict
else:
return releaseGroup['release-list']
def getRelease(releaseid):
def getRelease(releaseid, include_artist_info=True):
"""
Deep release search to get track info
"""
@@ -402,7 +298,10 @@ def getRelease(releaseid):
q, sleepytime = startmb()
try:
results = musicbrainzngs.get_release_by_id(releaseid,["artists","release-groups","media","recordings"]).get('release')
if include_artist_info:
results = musicbrainzngs.get_release_by_id(releaseid,["artists","release-groups","media","recordings"]).get('release')
else:
results = musicbrainzngs.get_release_by_id(releaseid,["media","recordings"]).get('release')
except WebServiceError, e:
logger.warn('Attempt to retrieve information from MusicBrainz for release "%s" failed (%s)' % (releaseid, str(e)))
time.sleep(5)
@@ -416,28 +315,32 @@ def getRelease(releaseid):
release['id'] = unicode(results['id'])
release['asin'] = unicode(results['asin']) if 'asin' in results else None
release['date'] = unicode(results['date'])
release['format'] = unicode(results['medium-list'][0]['format'])
release['country'] = unicode(results['country'])
if 'release-group' in results:
release['rgid'] = unicode(results['release-group']['id'])
release['rg_title'] = unicode(results['release-group']['title'])
release['rg_type'] = unicode(results['release-group']['type'])
else:
logger.warn("Release " + releaseid + "had no ReleaseGroup associated")
if include_artist_info:
if 'release-group' in results:
release['rgid'] = unicode(results['release-group']['id'])
release['rg_title'] = unicode(results['release-group']['title'])
release['rg_type'] = unicode(results['release-group']['type'])
else:
logger.warn("Release " + releaseid + "had no ReleaseGroup associated")
release['artist_name'] = unicode(results['artist-credit'][0]['artist']['name'])
release['artist_id'] = unicode(results['artist-credit'][0]['artist']['id'])
release['artist_name'] = unicode(results['artist-credit'][0]['artist']['name'])
release['artist_id'] = unicode(results['artist-credit'][0]['artist']['id'])
totalTracks = 0
totalTracks = 1
tracks = []
for medium in results['medium-list']:
for track in medium['track-list']:
tracks.append({
'number': totalTracks + 1,
'title': unicode(track['recording']['title']),
'number': totalTracks,
'title': unicode(track['recording']['title']),
'id': unicode(track['recording']['id']),
'url': u"http://musicbrainz.org/track/" + track['recording']['id'],
'duration': int(track['length']) if 'length' in track else 0
'url': u"http://musicbrainz.org/track/" + track['recording']['id'],
'duration': int(track['length']) if 'length' in track else 0
})
totalTracks += 1

View File

@@ -211,6 +211,14 @@ class WebInterface(object):
else:
raise cherrypy.HTTPRedirect("home")
deleteAlbum.exposed = True
def switchAlbum(self, AlbumID, ReleaseID):
'''
Take the values from allalbums/alltracks (based on the ReleaseID) and swap it into the album & track tables
'''
from headphones import albumswitcher
albumswitcher.switch(AlbumID, ReleaseID)
switchAlbum.exposed = True
def upcoming(self):
myDB = db.DBConnection()