import templates import config import cherrypy import musicbrainz2.webservice as ws import musicbrainz2.model as m import musicbrainz2.utils as u import os import string import time import datetime import sqlite3 import sys import configobj from headphones import FULL_PATH, config_file database = os.path.join(FULL_PATH, 'headphones.db') class Headphones: def index(self): page = [templates._header] page.append(templates._logobar) page.append(templates._nav) #Display Database if it exists: if os.path.exists(database): conn=sqlite3.connect(database) c=conn.cursor() c.execute('SELECT ArtistName, ArtistID, Status from artists order by ArtistSortName collate nocase') results = c.fetchall() i = 0 page.append('''
''') while i < len(results): c.execute('''SELECT AlbumTitle, ReleaseDate, DateAdded, AlbumID from albums WHERE ArtistID='%s' order by ReleaseDate DESC''' % results[i][1]) latestalbum = c.fetchall() today = datetime.date.today() if len(latestalbum) > 0: if latestalbum[0][1] > datetime.date.isoformat(today): newalbumName = '%s' % (latestalbum[0][3], latestalbum[0][0]) releaseDate = '(%s)' % latestalbum[0][1] else: newalbumName = 'None' releaseDate = "" if len(latestalbum) == 0: newalbumName = 'None' releaseDate = "" if results[i][2] == 'Paused': newStatus = '''%s(resume)''' % (results[i][2], results[i][1]) else: newStatus = '''%s(pause)''' % (results[i][2], results[i][1]) page.append('''''' % (results[i][1], results[i][0], results[i][1], results[i][1], newStatus, newalbumName, releaseDate)) i = i+1 c.close() page.append('''
Artist Name Status Upcoming Albums
%s (link) [delete] %s %s %s
''') else: page.append("""
Add some artists to the database!
""") page.append(templates._footer) return page index.exposed = True def artistPage(self, ArtistID): page = [templates._header] page.append(templates._logobar) page.append(templates._nav) conn=sqlite3.connect(database) c=conn.cursor() c.execute('''SELECT ArtistName from artists WHERE ArtistID="%s"''' % ArtistID) artistname = c.fetchall() c.execute('''SELECT AlbumTitle, ReleaseDate, AlbumID, Status, ArtistName, AlbumASIN from albums WHERE ArtistID="%s" order by ReleaseDate DESC''' % ArtistID) results = c.fetchall() c.close() i = 0 page.append('''

%s

''' % (artistname[0])) while i < len(results): if results[i][3] == 'Skipped': newStatus = '''%s [want]''' % (results[i][3], results[i][2], ArtistID) elif results[i][3] == 'Wanted': newStatus = '''%s[skip]''' % (results[i][3], results[i][2], ArtistID) elif results[i][3] == 'Downloaded': newStatus = '''%s[retry]''' % (results[i][3], results[i][2], ArtistID) elif results[i][3] == 'Snatched': newStatus = '''%s[retry]''' % (results[i][3], results[i][2], ArtistID) else: newStatus = '%s' % (results[i][3]) page.append('''''' % (results[i][5], results[i][2], results[i][0], results[i][2], results[i][1], newStatus)) i = i+1 page.append('''
Album Name Release Date Status
%s (link) %s %s
''') page.append(templates._footer) return page artistPage.exposed = True def albumPage(self, AlbumID): page = [templates._header] page.append(templates._logobar) page.append(templates._nav) conn=sqlite3.connect(database) c=conn.cursor() c.execute('''SELECT ArtistID, ArtistName, AlbumTitle, TrackTitle, TrackDuration, TrackID, AlbumASIN from tracks WHERE AlbumID="%s"''' % AlbumID) results = c.fetchall() if results[0][6]: albumart = '''


''' % results[0][6] else: albumart = '' c.close() i = 0 page.append('''
%s - %s
Download
%s

''' % (results[0][0], results[0][1], results[0][2], AlbumID, results[0][0], albumart)) while i < len(results): if results[i][4]: duration = time.strftime("%M:%S", time.gmtime(int(results[i][4])/1000)) else: duration = 'n/a' page.append('''''' % (i+1, results[i][3], results[i][5], duration)) i = i+1 page.append('''
Track # Track Title Duration
%s %s (link) %s
''') page.append(templates._footer) return page albumPage.exposed = True def findArtist(self, name): page = [templates._header] if len(name) == 0 or name == 'Add an artist': raise cherrypy.HTTPRedirect("/") else: artistResults = ws.Query().getArtists(ws.ArtistFilter(string.replace(name, '&', '%38'), limit=8)) if len(artistResults) == 0: page.append('''No results!Go back''') elif len(artistResults) > 1: page.append('''Search returned multiple artists. Click the artist you want to add:

''') for result in artistResults: artist = result.artist page.append('''%s (more info)
''' % (u.extractUuid(artist.id), artist.name, u.extractUuid(artist.id))) return page else: for result in artistResults: artist = result.artist raise cherrypy.HTTPRedirect("/addArtist?artistid=%s" % u.extractUuid(artist.id)) findArtist.exposed = True def artistInfo(self, artistid): page = [templates._header] inc = ws.ArtistIncludes(releases=(m.Release.TYPE_OFFICIAL, m.Release.TYPE_ALBUM), releaseGroups=True) artist = ws.Query().getArtistById(artistid, inc) page.append('''Artist Name: %s
''' % artist.name) page.append('''Unique ID: %s

Albums:
''' % u.extractUuid(artist.id)) for rg in artist.getReleaseGroups(): page.append('''%s
''' % rg.title) return page artistInfo.exposed = True def addArtist(self, artistid): inc = ws.ArtistIncludes(releases=(m.Release.TYPE_OFFICIAL, m.Release.TYPE_ALBUM), ratings=False, releaseGroups=False) artist = ws.Query().getArtistById(artistid, inc) conn=sqlite3.connect(database) c=conn.cursor() c.execute('CREATE TABLE IF NOT EXISTS artists (ArtistID TEXT UNIQUE, ArtistName TEXT, ArtistSortName TEXT, DateAdded TEXT, Status 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)') c.execute('CREATE TABLE IF NOT EXISTS tracks (ArtistID TEXT, ArtistName TEXT, AlbumTitle TEXT, AlbumASIN TEXT, AlbumID TEXT, TrackTitle TEXT, TrackDuration, TrackID TEXT)') c.execute('SELECT ArtistID from artists') artistlist = c.fetchall() if any(artistid in x for x in artistlist): page = [templates._header] page.append('''%s has already been added. Go back.''' % artist.name) c.close() return page else: c.execute('INSERT INTO artists VALUES( ?, ?, ?, CURRENT_DATE, ?)', (artistid, artist.name, artist.sortName, 'Active')) for release in artist.getReleases(): releaseid = u.extractUuid(release.id) inc = ws.ReleaseIncludes(artist=True, releaseEvents= True, tracks= True, releaseGroup=True) results = ws.Query().getReleaseById(releaseid, inc) time.sleep(0.6) for event in results.releaseEvents: if event.country == 'US': c.execute('INSERT INTO albums VALUES( ?, ?, ?, ?, ?, CURRENT_DATE, ?, ?)', (artistid, results.artist.name, results.title, results.asin, results.getEarliestReleaseDate(), u.extractUuid(results.id), 'Skipped')) c.execute('SELECT ReleaseDate, DateAdded from albums WHERE AlbumID="%s"' % u.extractUuid(results.id)) latestrelease = c.fetchall() if latestrelease[0][0] > latestrelease[0][1]: c.execute('UPDATE albums SET Status = "Wanted" WHERE AlbumID="%s"' % u.extractUuid(results.id)) else: pass for track in results.tracks: c.execute('INSERT INTO tracks VALUES( ?, ?, ?, ?, ?, ?, ?, ?)', (artistid, results.artist.name, results.title, results.asin, u.extractUuid(results.id), track.title, track.duration, u.extractUuid(track.id))) else: pass conn.commit() c.close() raise cherrypy.HTTPRedirect("/") addArtist.exposed = True #page for pausing an artist def pauseArtist(self, ArtistID): conn=sqlite3.connect(database) c=conn.cursor() c.execute('UPDATE artists SET status = "Paused" WHERE ArtistId="%s"' % ArtistID) conn.commit() c.close() raise cherrypy.HTTPRedirect("/") pauseArtist.exposed = True def resumeArtist(self, ArtistID): conn=sqlite3.connect(database) c=conn.cursor() c.execute('UPDATE artists SET status = "Active" WHERE ArtistId="%s"' % ArtistID) conn.commit() c.close() raise cherrypy.HTTPRedirect("/") resumeArtist.exposed = True def deleteArtist(self, ArtistID): conn=sqlite3.connect(database) c=conn.cursor() c.execute('''DELETE from artists WHERE ArtistID="%s"''' % ArtistID) c.execute('''DELETE from albums WHERE ArtistID="%s"''' % ArtistID) c.execute('''DELETE from tracks WHERE ArtistID="%s"''' % ArtistID) conn.commit() c.close() raise cherrypy.HTTPRedirect("/") deleteArtist.exposed = True def queueAlbum(self, AlbumID, ArtistID): conn=sqlite3.connect(database) c=conn.cursor() c.execute('UPDATE albums SET status = "Wanted" WHERE AlbumID="%s"' % AlbumID) conn.commit() c.close() import searcher searcher.searchNZB(AlbumID) raise cherrypy.HTTPRedirect("/artistPage?ArtistID=%s" % ArtistID) queueAlbum.exposed = True def unqueueAlbum(self, AlbumID, ArtistID): conn=sqlite3.connect(database) c=conn.cursor() c.execute('UPDATE albums SET status = "Skipped" WHERE AlbumID="%s"' % AlbumID) conn.commit() c.close() raise cherrypy.HTTPRedirect("/artistPage?ArtistID=%s" % ArtistID) unqueueAlbum.exposed = True def upcoming(self): page = [templates._header] page.append(templates._logobar) page.append(templates._nav) page.append(templates._footer) return page upcoming.exposed = True def manage(self): page = [templates._header] page.append(templates._logobar) page.append(templates._nav) page.append('''

Import or Sync Your iTunes Library/Music Folder


Enter the full path to your iTunes XML file or music folder

i.e. /Users/"username"/Music/iTunes/iTunes Music Library.xml
or /Users/"username"/Music/iTunes/iTunes Media/Music

(artists should have their own directories for folder import to work)

note: This process can take a LONG time!

Once you click "Submit" you can navigate away from this page while the process runs.




Force Search


Force Check for Wanted Albums

Force Update Active Artists


''') page.append(templates._footer) return page manage.exposed = True def importItunes(self, path): import itunesimport itunesimport.itunesImport(path) raise cherrypy.HTTPRedirect("/") importItunes.exposed = True def forceUpdate(self): import updater updater.dbUpdate() raise cherrypy.HTTPRedirect("/") forceUpdate.exposed = True def forceSearch(self): import searcher searcher.searchNZB() raise cherrypy.HTTPRedirect("/") forceSearch.exposed = True def history(self): page = [templates._header] page.append(templates._logobar) page.append(templates._nav) page.append(templates._footer) return page history.exposed = True def config(self): page = [templates._header] page.append(templates._logobar) page.append(templates._nav) page.append(config.form) page.append(templates._footer) return page config.exposed = True def configUpdate(self, http_host='127.0.0.1', http_username=None, http_port=8181, http_password=None, launch_browser=0, sab_host=None, sab_username=None, sab_apikey=None, sab_password=None, sab_category=None, music_download_dir=None, usenet_retention=None, nzbmatrix=0, nzbmatrix_username=None, nzbmatrix_apikey=None, newznab=0, newznab_host=None, newznab_apikey=None, nzbsorg=0, nzbsorg_uid=None, nzbsorg_hash=None, include_lossless=0,flac_to_mp3=0, move_to_itunes=0, path_to_itunes=None, rename_mp3s=0, cleanup=0, add_album_art=0): configs = configobj.ConfigObj(config_file) SABnzbd = configs['SABnzbd'] General = configs['General'] NZBMatrix = configs['NZBMatrix'] Newznab = configs['Newznab'] NZBsorg = configs['NZBsorg'] General['http_host'] = http_host General['http_port'] = http_port General['http_username'] = http_username General['http_password'] = http_password General['launch_browser'] = launch_browser SABnzbd['sab_host'] = sab_host SABnzbd['sab_username'] = sab_username SABnzbd['sab_password'] = sab_password SABnzbd['sab_apikey'] = sab_apikey SABnzbd['sab_category'] = sab_category General['music_download_dir'] = music_download_dir General['usenet_retention'] = usenet_retention NZBMatrix['nzbmatrix'] = nzbmatrix NZBMatrix['nzbmatrix_username'] = nzbmatrix_username NZBMatrix['nzbmatrix_apikey'] = nzbmatrix_apikey Newznab['newznab'] = newznab Newznab['newznab_host'] = newznab_host Newznab['newznab_apikey'] = newznab_apikey NZBsorg['nzbsorg'] = nzbsorg NZBsorg['nzbsorg_uid'] = nzbsorg_uid NZBsorg['nzbsorg_hash'] = nzbsorg_hash General['include_lossless'] = include_lossless General['flac_to_mp3'] = flac_to_mp3 General['move_to_itunes'] = move_to_itunes General['path_to_itunes'] = path_to_itunes General['rename_mp3s'] = rename_mp3s General['cleanup'] = cleanup General['add_album_art'] = add_album_art configs.write() reload(config) raise cherrypy.HTTPRedirect("/config") configUpdate.exposed = True def shutdown(self): sys.exit(0) shutdown.exposed = True