Add decorators for exposing.

This commit is contained in:
Bas Stottelaar
2014-12-13 17:49:09 +01:00
parent 997c78a08b
commit e1bd9eabe7
+90 -116
View File
@@ -23,15 +23,17 @@ from mako import exceptions
from operator import itemgetter from operator import itemgetter
import cherrypy
import headphones import headphones
import json
import os
import sys
import time
import urllib
import urllib2
import threading import threading
import cherrypy
import urllib2
import hashlib
import random
import urllib
import json
import time
import sys
import os
try: try:
# pylint:disable=E0611 # pylint:disable=E0611
@@ -59,16 +61,17 @@ def serve_template(templatename, **kwargs):
class WebInterface(object): class WebInterface(object):
@cherrypy.expose
def index(self): def index(self):
raise cherrypy.HTTPRedirect("home") raise cherrypy.HTTPRedirect("home")
index.exposed = True
@cherrypy.expose
def home(self): def home(self):
myDB = db.DBConnection() myDB = db.DBConnection()
artists = myDB.select('SELECT * from artists order by ArtistSortName COLLATE NOCASE') artists = myDB.select('SELECT * from artists order by ArtistSortName COLLATE NOCASE')
return serve_template(templatename="index.html", title="Home", artists=artists) return serve_template(templatename="index.html", title="Home", artists=artists)
home.exposed = True
@cherrypy.expose
def artistPage(self, ArtistID): def artistPage(self, ArtistID):
myDB = db.DBConnection() myDB = db.DBConnection()
artist = myDB.action('SELECT * FROM artists WHERE ArtistID=?', [ArtistID]).fetchone() artist = myDB.action('SELECT * FROM artists WHERE ArtistID=?', [ArtistID]).fetchone()
@@ -105,8 +108,8 @@ class WebInterface(object):
i += 1 i += 1
return serve_template(templatename="artist.html", title=artist['ArtistName'], artist=artist, albums=albums, extras=extras_dict) return serve_template(templatename="artist.html", title=artist['ArtistName'], artist=artist, albums=albums, extras=extras_dict)
artistPage.exposed = True
@cherrypy.expose
def albumPage(self, AlbumID): def albumPage(self, AlbumID):
myDB = db.DBConnection() myDB = db.DBConnection()
album = myDB.action('SELECT * from albums WHERE AlbumID=?', [AlbumID]).fetchone() album = myDB.action('SELECT * from albums WHERE AlbumID=?', [AlbumID]).fetchone()
@@ -135,8 +138,8 @@ class WebInterface(object):
else: else:
title = title + album['AlbumTitle'] title = title + album['AlbumTitle']
return serve_template(templatename="album.html", title=title, album=album, tracks=tracks, description=description) return serve_template(templatename="album.html", title=title, album=album, tracks=tracks, description=description)
albumPage.exposed = True
@cherrypy.expose
def search(self, name, type): def search(self, name, type):
if len(name) == 0: if len(name) == 0:
raise cherrypy.HTTPRedirect("home") raise cherrypy.HTTPRedirect("home")
@@ -145,15 +148,15 @@ class WebInterface(object):
else: else:
searchresults = mb.findRelease(name, limit=100) searchresults = mb.findRelease(name, limit=100)
return serve_template(templatename="searchresults.html", title='Search Results for: "' + name + '"', searchresults=searchresults, name=name, type=type) return serve_template(templatename="searchresults.html", title='Search Results for: "' + name + '"', searchresults=searchresults, name=name, type=type)
search.exposed = True
@cherrypy.expose
def addArtist(self, artistid): def addArtist(self, artistid):
thread = threading.Thread(target=importer.addArtisttoDB, args=[artistid]) thread = threading.Thread(target=importer.addArtisttoDB, args=[artistid])
thread.start() thread.start()
thread.join(1) thread.join(1)
raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % artistid) raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % artistid)
addArtist.exposed = True
@cherrypy.expose
def getExtras(self, ArtistID, newstyle=False, **kwargs): def getExtras(self, ArtistID, newstyle=False, **kwargs):
# if calling this function without the newstyle, they're using the old format # if calling this function without the newstyle, they're using the old format
# which doesn't separate extras, so we'll grab all of them # which doesn't separate extras, so we'll grab all of them
@@ -179,8 +182,8 @@ class WebInterface(object):
thread.start() thread.start()
thread.join(1) thread.join(1)
raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID) raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID)
getExtras.exposed = True
@cherrypy.expose
def removeExtras(self, ArtistID, ArtistName): def removeExtras(self, ArtistID, ArtistName):
myDB = db.DBConnection() myDB = db.DBConnection()
controlValueDict = {'ArtistID': ArtistID} controlValueDict = {'ArtistID': ArtistID}
@@ -198,8 +201,8 @@ class WebInterface(object):
c.remove_from_cache(AlbumID=album['AlbumID']) c.remove_from_cache(AlbumID=album['AlbumID'])
importer.finalize_update(ArtistID, ArtistName) importer.finalize_update(ArtistID, ArtistName)
raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID) raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID)
removeExtras.exposed = True
@cherrypy.expose
def pauseArtist(self, ArtistID): def pauseArtist(self, ArtistID):
logger.info(u"Pausing artist: " + ArtistID) logger.info(u"Pausing artist: " + ArtistID)
myDB = db.DBConnection() myDB = db.DBConnection()
@@ -207,8 +210,8 @@ class WebInterface(object):
newValueDict = {'Status': 'Paused'} newValueDict = {'Status': 'Paused'}
myDB.upsert("artists", newValueDict, controlValueDict) myDB.upsert("artists", newValueDict, controlValueDict)
raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID) raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID)
pauseArtist.exposed = True
@cherrypy.expose
def resumeArtist(self, ArtistID): def resumeArtist(self, ArtistID):
logger.info(u"Resuming artist: " + ArtistID) logger.info(u"Resuming artist: " + ArtistID)
myDB = db.DBConnection() myDB = db.DBConnection()
@@ -216,7 +219,6 @@ class WebInterface(object):
newValueDict = {'Status': 'Active'} newValueDict = {'Status': 'Active'}
myDB.upsert("artists", newValueDict, controlValueDict) myDB.upsert("artists", newValueDict, controlValueDict)
raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID) raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID)
resumeArtist.exposed = True
def removeArtist(self, ArtistID): def removeArtist(self, ArtistID):
logger.info(u"Deleting all traces of artist: " + ArtistID) logger.info(u"Deleting all traces of artist: " + ArtistID)
@@ -247,26 +249,27 @@ class WebInterface(object):
myDB.action('DELETE from descriptions WHERE ArtistID=?', [ArtistID]) myDB.action('DELETE from descriptions WHERE ArtistID=?', [ArtistID])
myDB.action('INSERT OR REPLACE into blacklist VALUES (?)', [ArtistID]) myDB.action('INSERT OR REPLACE into blacklist VALUES (?)', [ArtistID])
@cherrypy.expose
def deleteArtist(self, ArtistID): def deleteArtist(self, ArtistID):
self.removeArtist(ArtistID) self.removeArtist(ArtistID)
raise cherrypy.HTTPRedirect("home") raise cherrypy.HTTPRedirect("home")
deleteArtist.exposed = True
@cherrypy.expose
def deleteEmptyArtists(self): def deleteEmptyArtists(self):
logger.info(u"Deleting all empty artists") logger.info(u"Deleting all empty artists")
myDB = db.DBConnection() myDB = db.DBConnection()
emptyArtistIDs = [row['ArtistID'] for row in myDB.select("SELECT ArtistID FROM artists WHERE LatestAlbum IS NULL")] emptyArtistIDs = [row['ArtistID'] for row in myDB.select("SELECT ArtistID FROM artists WHERE LatestAlbum IS NULL")]
for ArtistID in emptyArtistIDs: for ArtistID in emptyArtistIDs:
self.removeArtist(ArtistID) self.removeArtist(ArtistID)
deleteEmptyArtists.exposed = True
@cherrypy.expose
def refreshArtist(self, ArtistID): def refreshArtist(self, ArtistID):
thread = threading.Thread(target=importer.addArtisttoDB, args=[ArtistID, False, True]) thread = threading.Thread(target=importer.addArtisttoDB, args=[ArtistID, False, True])
thread.start() thread.start()
thread.join(1) thread.join(1)
raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID) raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID)
refreshArtist.exposed = True
@cherrypy.expose
def markAlbums(self, ArtistID=None, action=None, **args): def markAlbums(self, ArtistID=None, action=None, **args):
myDB = db.DBConnection() myDB = db.DBConnection()
if action == 'WantedNew' or action == 'WantedLossless': if action == 'WantedNew' or action == 'WantedLossless':
@@ -293,8 +296,8 @@ class WebInterface(object):
raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID) raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID)
else: else:
raise cherrypy.HTTPRedirect("upcoming") raise cherrypy.HTTPRedirect("upcoming")
markAlbums.exposed = True
@cherrypy.expose
def addArtists(self, action=None, **args): def addArtists(self, action=None, **args):
if action == "add": if action == "add":
threading.Thread(target=importer.artistlist_to_mbids, args=[args, True]).start() threading.Thread(target=importer.artistlist_to_mbids, args=[args, True]).start()
@@ -305,8 +308,8 @@ class WebInterface(object):
myDB.action('UPDATE have SET Matched="Ignored" WHERE ArtistName=?', [artist.decode(headphones.SYS_ENCODING, 'replace')]) myDB.action('UPDATE have SET Matched="Ignored" WHERE ArtistName=?', [artist.decode(headphones.SYS_ENCODING, 'replace')])
logger.info("Artist %s removed from new artist list and set to ignored" % artist) logger.info("Artist %s removed from new artist list and set to ignored" % artist)
raise cherrypy.HTTPRedirect("home") raise cherrypy.HTTPRedirect("home")
addArtists.exposed = True
@cherrypy.expose
def queueAlbum(self, AlbumID, ArtistID=None, new=False, redirect=None, lossless=False): def queueAlbum(self, AlbumID, ArtistID=None, new=False, redirect=None, lossless=False):
logger.info(u"Marking album: " + AlbumID + " as wanted...") logger.info(u"Marking album: " + AlbumID + " as wanted...")
myDB = db.DBConnection() myDB = db.DBConnection()
@@ -321,8 +324,8 @@ class WebInterface(object):
if ArtistID: if ArtistID:
redirect = "artistPage?ArtistID=%s" % ArtistID redirect = "artistPage?ArtistID=%s" % ArtistID
raise cherrypy.HTTPRedirect(redirect) raise cherrypy.HTTPRedirect(redirect)
queueAlbum.exposed = True
@cherrypy.expose
def choose_specific_download(self, AlbumID): def choose_specific_download(self, AlbumID):
results = searcher.searchforalbum(AlbumID, choose_specific_download=True) results = searcher.searchforalbum(AlbumID, choose_specific_download=True)
@@ -342,8 +345,7 @@ class WebInterface(object):
cherrypy.response.headers['Content-type'] = 'application/json' cherrypy.response.headers['Content-type'] = 'application/json'
return s return s
choose_specific_download.exposed = True @cherrypy.expose
def download_specific_release(self, AlbumID, title, size, url, provider, kind, **kwargs): def download_specific_release(self, AlbumID, title, size, url, provider, kind, **kwargs):
# Handle situations where the torrent url contains arguments that are parsed # Handle situations where the torrent url contains arguments that are parsed
if kwargs: if kwargs:
@@ -361,8 +363,7 @@ class WebInterface(object):
album = myDB.action('SELECT * from albums WHERE AlbumID=?', [AlbumID]).fetchone() album = myDB.action('SELECT * from albums WHERE AlbumID=?', [AlbumID]).fetchone()
searcher.send_to_downloader(data, bestqual, album) searcher.send_to_downloader(data, bestqual, album)
download_specific_release.exposed = True @cherrypy.expose
def unqueueAlbum(self, AlbumID, ArtistID): def unqueueAlbum(self, AlbumID, ArtistID):
logger.info(u"Marking album: " + AlbumID + "as skipped...") logger.info(u"Marking album: " + AlbumID + "as skipped...")
myDB = db.DBConnection() myDB = db.DBConnection()
@@ -370,8 +371,8 @@ class WebInterface(object):
newValueDict = {'Status': 'Skipped'} newValueDict = {'Status': 'Skipped'}
myDB.upsert("albums", newValueDict, controlValueDict) myDB.upsert("albums", newValueDict, controlValueDict)
raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID) raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID)
unqueueAlbum.exposed = True
@cherrypy.expose
def deleteAlbum(self, AlbumID, ArtistID=None): def deleteAlbum(self, AlbumID, ArtistID=None):
logger.info(u"Deleting all traces of album: " + AlbumID) logger.info(u"Deleting all traces of album: " + AlbumID)
myDB = db.DBConnection() myDB = db.DBConnection()
@@ -397,8 +398,8 @@ class WebInterface(object):
raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID) raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID)
else: else:
raise cherrypy.HTTPRedirect("home") raise cherrypy.HTTPRedirect("home")
deleteAlbum.exposed = True
@cherrypy.expose
def switchAlbum(self, AlbumID, ReleaseID): def switchAlbum(self, AlbumID, ReleaseID):
""" """
Take the values from allalbums/alltracks (based on the ReleaseID) and Take the values from allalbums/alltracks (based on the ReleaseID) and
@@ -407,8 +408,8 @@ class WebInterface(object):
from headphones import albumswitcher from headphones import albumswitcher
albumswitcher.switch(AlbumID, ReleaseID) albumswitcher.switch(AlbumID, ReleaseID)
raise cherrypy.HTTPRedirect("albumPage?AlbumID=%s" % AlbumID) raise cherrypy.HTTPRedirect("albumPage?AlbumID=%s" % AlbumID)
switchAlbum.exposed = True
@cherrypy.expose
def editSearchTerm(self, AlbumID, SearchTerm): def editSearchTerm(self, AlbumID, SearchTerm):
logger.info(u"Updating search term for albumid: " + AlbumID) logger.info(u"Updating search term for albumid: " + AlbumID)
myDB = db.DBConnection() myDB = db.DBConnection()
@@ -416,27 +417,27 @@ class WebInterface(object):
newValueDict = {'SearchTerm': SearchTerm} newValueDict = {'SearchTerm': SearchTerm}
myDB.upsert("albums", newValueDict, controlValueDict) myDB.upsert("albums", newValueDict, controlValueDict)
raise cherrypy.HTTPRedirect("albumPage?AlbumID=%s" % AlbumID) raise cherrypy.HTTPRedirect("albumPage?AlbumID=%s" % AlbumID)
editSearchTerm.exposed = True
@cherrypy.expose
def upcoming(self): def upcoming(self):
myDB = db.DBConnection() myDB = db.DBConnection()
upcoming = myDB.select("SELECT * from albums WHERE ReleaseDate > date('now') order by ReleaseDate ASC") upcoming = myDB.select("SELECT * from albums WHERE ReleaseDate > date('now') order by ReleaseDate ASC")
wanted = myDB.select("SELECT * from albums WHERE Status='Wanted'") wanted = myDB.select("SELECT * from albums WHERE Status='Wanted'")
return serve_template(templatename="upcoming.html", title="Upcoming", upcoming=upcoming, wanted=wanted) return serve_template(templatename="upcoming.html", title="Upcoming", upcoming=upcoming, wanted=wanted)
upcoming.exposed = True
@cherrypy.expose
def manage(self): def manage(self):
myDB = db.DBConnection() myDB = db.DBConnection()
emptyArtists = myDB.select("SELECT * FROM artists WHERE LatestAlbum IS NULL") emptyArtists = myDB.select("SELECT * FROM artists WHERE LatestAlbum IS NULL")
return serve_template(templatename="manage.html", title="Manage", emptyArtists=emptyArtists) return serve_template(templatename="manage.html", title="Manage", emptyArtists=emptyArtists)
manage.exposed = True
@cherrypy.expose
def manageArtists(self): def manageArtists(self):
myDB = db.DBConnection() myDB = db.DBConnection()
artists = myDB.select('SELECT * from artists order by ArtistSortName COLLATE NOCASE') artists = myDB.select('SELECT * from artists order by ArtistSortName COLLATE NOCASE')
return serve_template(templatename="manageartists.html", title="Manage Artists", artists=artists) return serve_template(templatename="manageartists.html", title="Manage Artists", artists=artists)
manageArtists.exposed = True
@cherrypy.expose
def manageAlbums(self, Status=None): def manageAlbums(self, Status=None):
myDB = db.DBConnection() myDB = db.DBConnection()
if Status == "Upcoming": if Status == "Upcoming":
@@ -446,14 +447,14 @@ class WebInterface(object):
else: else:
albums = myDB.select('SELECT * from albums') albums = myDB.select('SELECT * from albums')
return serve_template(templatename="managealbums.html", title="Manage Albums", albums=albums) return serve_template(templatename="managealbums.html", title="Manage Albums", albums=albums)
manageAlbums.exposed = True
@cherrypy.expose
def manageNew(self): def manageNew(self):
myDB = db.DBConnection() myDB = db.DBConnection()
newartists = myDB.select('SELECT * from newartists') newartists = myDB.select('SELECT * from newartists')
return serve_template(templatename="managenew.html", title="Manage New Artists", newartists=newartists) return serve_template(templatename="managenew.html", title="Manage New Artists", newartists=newartists)
manageNew.exposed = True
@cherrypy.expose
def manageUnmatched(self): def manageUnmatched(self):
myDB = db.DBConnection() myDB = db.DBConnection()
have_album_dictionary = [] have_album_dictionary = []
@@ -479,8 +480,8 @@ class WebInterface(object):
unmatchedalbums = [d for d in have_album_dictionary if (cleanName(d['ArtistName']).lower(), cleanName(d['AlbumTitle']).lower()) not in check] unmatchedalbums = [d for d in have_album_dictionary if (cleanName(d['ArtistName']).lower(), cleanName(d['AlbumTitle']).lower()) not in check]
return serve_template(templatename="manageunmatched.html", title="Manage Unmatched Items", unmatchedalbums=unmatchedalbums) return serve_template(templatename="manageunmatched.html", title="Manage Unmatched Items", unmatchedalbums=unmatchedalbums)
manageUnmatched.exposed = True
@cherrypy.expose
def markUnmatched(self, action=None, existing_artist=None, existing_album=None, new_artist=None, new_album=None): def markUnmatched(self, action=None, existing_artist=None, existing_album=None, new_artist=None, new_album=None):
myDB = db.DBConnection() myDB = db.DBConnection()
@@ -566,8 +567,7 @@ class WebInterface(object):
else: else:
logger.info("Artist %s / Album %s already named appropriately; nothing to modify" % (existing_artist, existing_album)) logger.info("Artist %s / Album %s already named appropriately; nothing to modify" % (existing_artist, existing_album))
markUnmatched.exposed = True @cherrypy.expose
def manageManual(self): def manageManual(self):
myDB = db.DBConnection() myDB = db.DBConnection()
manual_albums = [] manual_albums = []
@@ -586,8 +586,8 @@ class WebInterface(object):
manual_albums_sorted = sorted(manual_albums, key=itemgetter('ArtistName', 'AlbumTitle')) manual_albums_sorted = sorted(manual_albums, key=itemgetter('ArtistName', 'AlbumTitle'))
return serve_template(templatename="managemanual.html", title="Manage Manual Items", manualalbums=manual_albums_sorted) return serve_template(templatename="managemanual.html", title="Manage Manual Items", manualalbums=manual_albums_sorted)
manageManual.exposed = True
@cherrypy.expose
def markManual(self, action=None, existing_artist=None, existing_album=None): def markManual(self, action=None, existing_artist=None, existing_album=None):
myDB = db.DBConnection() myDB = db.DBConnection()
if action == "unignoreArtist": if action == "unignoreArtist":
@@ -638,8 +638,7 @@ class WebInterface(object):
librarysync.update_album_status(album_id) librarysync.update_album_status(album_id)
logger.info("Album: %s successfully restored to unmatched list" % album) logger.info("Album: %s successfully restored to unmatched list" % album)
markManual.exposed = True @cherrypy.expose
def markArtists(self, action=None, **args): def markArtists(self, action=None, **args):
myDB = db.DBConnection() myDB = db.DBConnection()
artistsToAdd = [] artistsToAdd = []
@@ -660,20 +659,20 @@ class WebInterface(object):
logger.debug("Refreshing artists: %s" % artistsToAdd) logger.debug("Refreshing artists: %s" % artistsToAdd)
threading.Thread(target=importer.addArtistIDListToDB, args=[artistsToAdd]).start() threading.Thread(target=importer.addArtistIDListToDB, args=[artistsToAdd]).start()
raise cherrypy.HTTPRedirect("home") raise cherrypy.HTTPRedirect("home")
markArtists.exposed = True
@cherrypy.expose
def importLastFM(self, username): def importLastFM(self, username):
headphones.CONFIG.LASTFM_USERNAME = username headphones.CONFIG.LASTFM_USERNAME = username
headphones.CONFIG.write() headphones.CONFIG.write()
threading.Thread(target=lastfm.getArtists).start() threading.Thread(target=lastfm.getArtists).start()
raise cherrypy.HTTPRedirect("home") raise cherrypy.HTTPRedirect("home")
importLastFM.exposed = True
@cherrypy.expose
def importLastFMTag(self, tag, limit): def importLastFMTag(self, tag, limit):
threading.Thread(target=lastfm.getTagTopArtists, args=(tag, limit)).start() threading.Thread(target=lastfm.getTagTopArtists, args=(tag, limit)).start()
raise cherrypy.HTTPRedirect("home") raise cherrypy.HTTPRedirect("home")
importLastFMTag.exposed = True
@cherrypy.expose
def importItunes(self, path): def importItunes(self, path):
headphones.CONFIG.PATH_TO_XML = path headphones.CONFIG.PATH_TO_XML = path
headphones.CONFIG.write() headphones.CONFIG.write()
@@ -681,8 +680,8 @@ class WebInterface(object):
thread.start() thread.start()
thread.join(10) thread.join(10)
raise cherrypy.HTTPRedirect("home") raise cherrypy.HTTPRedirect("home")
importItunes.exposed = True
@cherrypy.expose
def musicScan(self, path, scan=0, redirect=None, autoadd=0, libraryscan=0): def musicScan(self, path, scan=0, redirect=None, autoadd=0, libraryscan=0):
headphones.CONFIG.LIBRARYSCAN = libraryscan headphones.CONFIG.LIBRARYSCAN = libraryscan
headphones.CONFIG.AUTO_ADD_ARTISTS = autoadd headphones.CONFIG.AUTO_ADD_ARTISTS = autoadd
@@ -697,54 +696,54 @@ class WebInterface(object):
raise cherrypy.HTTPRedirect(redirect) raise cherrypy.HTTPRedirect(redirect)
else: else:
raise cherrypy.HTTPRedirect("home") raise cherrypy.HTTPRedirect("home")
musicScan.exposed = True
@cherrypy.expose
def forceUpdate(self): def forceUpdate(self):
from headphones import updater from headphones import updater
threading.Thread(target=updater.dbUpdate, args=[False]).start() threading.Thread(target=updater.dbUpdate, args=[False]).start()
raise cherrypy.HTTPRedirect("home") raise cherrypy.HTTPRedirect("home")
forceUpdate.exposed = True
@cherrypy.expose
def forceFullUpdate(self): def forceFullUpdate(self):
from headphones import updater from headphones import updater
threading.Thread(target=updater.dbUpdate, args=[True]).start() threading.Thread(target=updater.dbUpdate, args=[True]).start()
raise cherrypy.HTTPRedirect("home") raise cherrypy.HTTPRedirect("home")
forceFullUpdate.exposed = True
@cherrypy.expose
def forceSearch(self): def forceSearch(self):
from headphones import searcher from headphones import searcher
threading.Thread(target=searcher.searchforalbum).start() threading.Thread(target=searcher.searchforalbum).start()
raise cherrypy.HTTPRedirect("home") raise cherrypy.HTTPRedirect("home")
forceSearch.exposed = True
@cherrypy.expose
def forcePostProcess(self, dir=None, album_dir=None): def forcePostProcess(self, dir=None, album_dir=None):
from headphones import postprocessor from headphones import postprocessor
threading.Thread(target=postprocessor.forcePostProcess, kwargs={'dir': dir, 'album_dir': album_dir}).start() threading.Thread(target=postprocessor.forcePostProcess, kwargs={'dir': dir, 'album_dir': album_dir}).start()
raise cherrypy.HTTPRedirect("home") raise cherrypy.HTTPRedirect("home")
forcePostProcess.exposed = True
@cherrypy.expose
def checkGithub(self): def checkGithub(self):
from headphones import versioncheck from headphones import versioncheck
versioncheck.checkGithub() versioncheck.checkGithub()
raise cherrypy.HTTPRedirect("home") raise cherrypy.HTTPRedirect("home")
checkGithub.exposed = True
@cherrypy.expose
def history(self): def history(self):
myDB = db.DBConnection() myDB = db.DBConnection()
history = myDB.select('''SELECT * from snatched WHERE Status NOT LIKE "Seed%" order by DateAdded DESC''') history = myDB.select('''SELECT * from snatched WHERE Status NOT LIKE "Seed%" order by DateAdded DESC''')
return serve_template(templatename="history.html", title="History", history=history) return serve_template(templatename="history.html", title="History", history=history)
history.exposed = True
@cherrypy.expose
def logs(self): def logs(self):
return serve_template(templatename="logs.html", title="Log", lineList=headphones.LOG_LIST) return serve_template(templatename="logs.html", title="Log", lineList=headphones.LOG_LIST)
logs.exposed = True
@cherrypy.expose
def clearLogs(self): def clearLogs(self):
headphones.LOG_LIST = [] headphones.LOG_LIST = []
logger.info("Web logs cleared") logger.info("Web logs cleared")
raise cherrypy.HTTPRedirect("logs") raise cherrypy.HTTPRedirect("logs")
clearLogs.exposed = True
@cherrypy.expose
def toggleVerbose(self): def toggleVerbose(self):
headphones.VERBOSE = not headphones.VERBOSE headphones.VERBOSE = not headphones.VERBOSE
logger.initLogger(console=not headphones.QUIET, logger.initLogger(console=not headphones.QUIET,
@@ -752,10 +751,9 @@ class WebInterface(object):
logger.info("Verbose toggled, set to %s", headphones.VERBOSE) logger.info("Verbose toggled, set to %s", headphones.VERBOSE)
logger.debug("If you read this message, debug logging is available") logger.debug("If you read this message, debug logging is available")
raise cherrypy.HTTPRedirect("logs") raise cherrypy.HTTPRedirect("logs")
toggleVerbose.exposed = True
@cherrypy.expose
def getLog(self, iDisplayStart=0, iDisplayLength=100, iSortCol_0=0, sSortDir_0="desc", sSearch="", **kwargs): def getLog(self, iDisplayStart=0, iDisplayLength=100, iSortCol_0=0, sSortDir_0="desc", sSearch="", **kwargs):
iDisplayStart = int(iDisplayStart) iDisplayStart = int(iDisplayStart)
iDisplayLength = int(iDisplayLength) iDisplayLength = int(iDisplayLength)
@@ -780,8 +778,8 @@ class WebInterface(object):
'iTotalRecords': len(headphones.LOG_LIST), 'iTotalRecords': len(headphones.LOG_LIST),
'aaData': rows, 'aaData': rows,
}) })
getLog.exposed = True
@cherrypy.expose
def getArtists_json(self, iDisplayStart=0, iDisplayLength=100, sSearch="", iSortCol_0='0', sSortDir_0='asc', **kwargs): def getArtists_json(self, iDisplayStart=0, iDisplayLength=100, sSearch="", iSortCol_0='0', sSortDir_0='asc', **kwargs):
iDisplayStart = int(iDisplayStart) iDisplayStart = int(iDisplayStart)
iDisplayLength = int(iDisplayLength) iDisplayLength = int(iDisplayLength)
@@ -852,8 +850,8 @@ class WebInterface(object):
s = json.dumps(dict) s = json.dumps(dict)
cherrypy.response.headers['Content-type'] = 'application/json' cherrypy.response.headers['Content-type'] = 'application/json'
return s return s
getArtists_json.exposed = True
@cherrypy.expose
def getAlbumsByArtist_json(self, artist=None): def getAlbumsByArtist_json(self, artist=None):
myDB = db.DBConnection() myDB = db.DBConnection()
album_json = {} album_json = {}
@@ -866,7 +864,6 @@ class WebInterface(object):
cherrypy.response.headers['Content-type'] = 'application/json' cherrypy.response.headers['Content-type'] = 'application/json'
return json_albums return json_albums
getAlbumsByArtist_json.exposed = True
def getArtistjson(self, ArtistID, **kwargs): def getArtistjson(self, ArtistID, **kwargs):
myDB = db.DBConnection() myDB = db.DBConnection()
@@ -876,8 +873,8 @@ class WebInterface(object):
'Status': artist['Status'] 'Status': artist['Status']
}) })
return artist_json return artist_json
getArtistjson.exposed = True
@cherrypy.expose
def getAlbumjson(self, AlbumID, **kwargs): def getAlbumjson(self, AlbumID, **kwargs):
myDB = db.DBConnection() myDB = db.DBConnection()
album = myDB.action('SELECT * from albums WHERE AlbumID=?', [AlbumID]).fetchone() album = myDB.action('SELECT * from albums WHERE AlbumID=?', [AlbumID]).fetchone()
@@ -887,8 +884,8 @@ class WebInterface(object):
'Status': album['Status'] 'Status': album['Status']
}) })
return album_json return album_json
getAlbumjson.exposed = True
@cherrypy.expose
def clearhistory(self, type=None, date_added=None, title=None): def clearhistory(self, type=None, date_added=None, title=None):
myDB = db.DBConnection() myDB = db.DBConnection()
if type: if type:
@@ -902,19 +899,14 @@ class WebInterface(object):
logger.info(u"Deleting '%s' from history" % title) logger.info(u"Deleting '%s' from history" % title)
myDB.action('DELETE from snatched WHERE Status NOT LIKE "Seed%" AND Title=? AND DateAdded=?', [title, date_added]) myDB.action('DELETE from snatched WHERE Status NOT LIKE "Seed%" AND Title=? AND DateAdded=?', [title, date_added])
raise cherrypy.HTTPRedirect("history") raise cherrypy.HTTPRedirect("history")
clearhistory.exposed = True
@cherrypy.expose
def generateAPI(self): def generateAPI(self):
import hashlib
import random
apikey = hashlib.sha224(str(random.getrandbits(256))).hexdigest()[0:32] apikey = hashlib.sha224(str(random.getrandbits(256))).hexdigest()[0:32]
logger.info("New API generated") logger.info("New API generated")
return apikey return apikey
generateAPI.exposed = True @cherrypy.expose
def forceScan(self, keepmatched=None): def forceScan(self, keepmatched=None):
myDB = db.DBConnection() myDB = db.DBConnection()
######################################### #########################################
@@ -933,10 +925,9 @@ class WebInterface(object):
except Exception as e: except Exception as e:
logger.error('Unable to complete the scan: %s' % e) logger.error('Unable to complete the scan: %s' % e)
raise cherrypy.HTTPRedirect("home") raise cherrypy.HTTPRedirect("home")
forceScan.exposed = True
@cherrypy.expose
def config(self): def config(self):
interface_dir = os.path.join(headphones.PROG_DIR, 'data/interfaces/') interface_dir = os.path.join(headphones.PROG_DIR, 'data/interfaces/')
interface_list = [name for name in os.listdir(interface_dir) if os.path.isdir(os.path.join(interface_dir, name))] interface_list = [name for name in os.listdir(interface_dir) if os.path.isdir(os.path.join(interface_dir, name))]
@@ -1174,8 +1165,8 @@ class WebInterface(object):
config["extras"] = extras_dict config["extras"] = extras_dict
return serve_template(templatename="config.html", title="Settings", config=config) return serve_template(templatename="config.html", title="Settings", config=config)
config.exposed = True
@cherrypy.expose
def configUpdate(self, **kwargs): def configUpdate(self, **kwargs):
# Handle the variable config options. Note - keys with False values aren't getting passed # Handle the variable config options. Note - keys with False values aren't getting passed
@@ -1263,61 +1254,54 @@ class WebInterface(object):
raise cherrypy.HTTPRedirect("config") raise cherrypy.HTTPRedirect("config")
configUpdate.exposed = True @cherrypy.expose
def do_state_change(self, signal, title, timer): def do_state_change(self, signal, title, timer):
headphones.SIGNAL = signal headphones.SIGNAL = signal
message = title + '...' message = title + '...'
return serve_template(templatename="shutdown.html", title=title, return serve_template(templatename="shutdown.html", title=title,
message=message, timer=timer) message=message, timer=timer)
@cherrypy.expose
def shutdown(self): def shutdown(self):
return self.do_state_change('shutdown', 'Shutting Down', 15) return self.do_state_change('shutdown', 'Shutting Down', 15)
shutdown.exposed = True
@cherrypy.expose
def restart(self): def restart(self):
return self.do_state_change('restart', 'Restarting', 30) return self.do_state_change('restart', 'Restarting', 30)
restart.exposed = True
@cherrypy.expose
def update(self): def update(self):
return self.do_state_change('update', 'Updating', 120) return self.do_state_change('update', 'Updating', 120)
update.exposed = True
@cherrypy.expose
def extras(self): def extras(self):
myDB = db.DBConnection() myDB = db.DBConnection()
cloudlist = myDB.select('SELECT * from lastfmcloud') cloudlist = myDB.select('SELECT * from lastfmcloud')
return serve_template(templatename="extras.html", title="Extras", cloudlist=cloudlist) return serve_template(templatename="extras.html", title="Extras", cloudlist=cloudlist)
extras.exposed = True
@cherrypy.expose
def addReleaseById(self, rid, rgid=None): def addReleaseById(self, rid, rgid=None):
threading.Thread(target=importer.addReleaseById, args=[rid, rgid]).start() threading.Thread(target=importer.addReleaseById, args=[rid, rgid]).start()
if rgid: if rgid:
raise cherrypy.HTTPRedirect("albumPage?AlbumID=%s" % rgid) raise cherrypy.HTTPRedirect("albumPage?AlbumID=%s" % rgid)
else: else:
raise cherrypy.HTTPRedirect("home") raise cherrypy.HTTPRedirect("home")
addReleaseById.exposed = True
@cherrypy.expose
def updateCloud(self): def updateCloud(self):
lastfm.getSimilar() lastfm.getSimilar()
raise cherrypy.HTTPRedirect("extras") raise cherrypy.HTTPRedirect("extras")
updateCloud.exposed = True @cherrypy.expose
def api(self, *args, **kwargs): def api(self, *args, **kwargs):
from headphones.api import Api from headphones.api import Api
a = Api() a = Api()
a.checkParams(*args, **kwargs) a.checkParams(*args, **kwargs)
data = a.fetchData() return a.fetchData()
return data
api.exposed = True
@cherrypy.expose
def getInfo(self, ArtistID=None, AlbumID=None): def getInfo(self, ArtistID=None, AlbumID=None):
from headphones import cache from headphones import cache
@@ -1325,25 +1309,22 @@ class WebInterface(object):
return json.dumps(info_dict) return json.dumps(info_dict)
getInfo.exposed = True @cherrypy.expose
def getArtwork(self, ArtistID=None, AlbumID=None): def getArtwork(self, ArtistID=None, AlbumID=None):
from headphones import cache from headphones import cache
return cache.getArtwork(ArtistID, AlbumID) return cache.getArtwork(ArtistID, AlbumID)
getArtwork.exposed = True @cherrypy.expose
def getThumb(self, ArtistID=None, AlbumID=None): def getThumb(self, ArtistID=None, AlbumID=None):
from headphones import cache from headphones import cache
return cache.getThumb(ArtistID, AlbumID) return cache.getThumb(ArtistID, AlbumID)
getThumb.exposed = True # If you just want to get the last.fm image links for an album, make sure
# to pass a releaseid and not a releasegroupid
# If you just want to get the last.fm image links for an album, make sure to pass a releaseid and not a releasegroupid @cherrypy.expose
def getImageLinks(self, ArtistID=None, AlbumID=None): def getImageLinks(self, ArtistID=None, AlbumID=None):
from headphones import cache from headphones import cache
image_dict = cache.getImageLinks(ArtistID, AlbumID) image_dict = cache.getImageLinks(ArtistID, AlbumID)
@@ -1360,14 +1341,13 @@ class WebInterface(object):
return json.dumps(image_dict) return json.dumps(image_dict)
getImageLinks.exposed = True @cherrypy.expose
def twitterStep1(self): def twitterStep1(self):
cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store" cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"
tweet = notifiers.TwitterNotifier() tweet = notifiers.TwitterNotifier()
return tweet._get_authorization() return tweet._get_authorization()
twitterStep1.exposed = True
@cherrypy.expose
def twitterStep2(self, key): def twitterStep2(self, key):
cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store" cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"
tweet = notifiers.TwitterNotifier() tweet = notifiers.TwitterNotifier()
@@ -1377,8 +1357,8 @@ class WebInterface(object):
return "Key verification successful" return "Key verification successful"
else: else:
return "Unable to verify key" return "Unable to verify key"
twitterStep2.exposed = True
@cherrypy.expose
def testTwitter(self): def testTwitter(self):
cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store" cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"
tweet = notifiers.TwitterNotifier() tweet = notifiers.TwitterNotifier()
@@ -1387,8 +1367,8 @@ class WebInterface(object):
return "Tweet successful, check your twitter to make sure it worked" return "Tweet successful, check your twitter to make sure it worked"
else: else:
return "Error sending tweet" return "Error sending tweet"
testTwitter.exposed = True
@cherrypy.expose
def osxnotifyregister(self, app): def osxnotifyregister(self, app):
cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store" cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"
from osxnotify import registerapp as osxnotify from osxnotify import registerapp as osxnotify
@@ -1400,14 +1380,13 @@ class WebInterface(object):
else: else:
logger.warn(msg) logger.warn(msg)
return msg return msg
osxnotifyregister.exposed = True
class Artwork(object): class Artwork(object):
@cherrypy.expose
def index(self): def index(self):
return "Artwork" return "Artwork"
index.exposed = True
@cherrypy.expose
def default(self, ArtistOrAlbum="", ID=None): def default(self, ArtistOrAlbum="", ID=None):
from headphones import cache from headphones import cache
ArtistID = None ArtistID = None
@@ -1432,16 +1411,15 @@ class Artwork(object):
cherrypy.response.headers['Content-type'] = 'image/' + fileext cherrypy.response.headers['Content-type'] = 'image/' + fileext
cherrypy.response.headers['Cache-Control'] = 'max-age=31556926' cherrypy.response.headers['Cache-Control'] = 'max-age=31556926'
path = os.path.normpath(path) with open(os.path.normpath(path), "rb") as fp:
f = open(path, 'rb') return fp.read()
return f.read()
default.exposed = True
class Thumbs(object): class Thumbs(object):
@cherrypy.expose
def index(self): def index(self):
return "Here be thumbs" return "Here be thumbs"
index.exposed = True
@cherrypy.expose
def default(self, ArtistOrAlbum="", ID=None): def default(self, ArtistOrAlbum="", ID=None):
from headphones import cache from headphones import cache
ArtistID = None ArtistID = None
@@ -1466,12 +1444,8 @@ class Artwork(object):
cherrypy.response.headers['Content-type'] = 'image/' + fileext cherrypy.response.headers['Content-type'] = 'image/' + fileext
cherrypy.response.headers['Cache-Control'] = 'max-age=31556926' cherrypy.response.headers['Cache-Control'] = 'max-age=31556926'
path = os.path.normpath(path) with open(os.path.normpath(path), "rb") as fp:
f = open(path, 'rb') return fp.read()
return f.read()
default.exposed = True
thumbs = Thumbs() thumbs = Thumbs()
WebInterface.artwork = Artwork() WebInterface.artwork = Artwork()