Added descriptions from last fm, formatted album page, added retry buttons

This commit is contained in:
Remy
2011-08-07 21:18:42 -07:00
parent 6c235732e2
commit 45563c821c
15 changed files with 306 additions and 92 deletions
+32 -7
View File
@@ -102,15 +102,15 @@ a.blue {
container { }
body { background-color: #EBF4FB; min-width: 907px; }
body { background-color: #EBF4FB; min-width: 930px; }
header { min-height: 68px; width: 100%; min-width: 907px; padding-left: 0px; padding-right: 10px; background-color: #CDC9C9; position: fixed; z-index: 998; }
header { min-height: 68px; width: 100%; min-width: 930px; padding-left: 0px; padding-right: 10px; background-color: #CDC9C9; position: fixed; z-index: 998; }
h1 { font-size: 24px; }
h2 { font-size: 20px; }
h3 { font-size: 16px; }
p.indented { margin-left: 20px; font-size: 14px; }
p.indented { padding-top: 20px; margin-left: 20px; font-size: 14px; }
div#updatebar { text-align: center; min-width: 970px; width: 100%; background-color: light-blue; float: left; }
div#logo { float: left; padding-left: 10px; }
@@ -120,7 +120,7 @@ ul#nav li { margin: 40px 0px auto 10px; display: inline; }
ul#nav li a { padding: 5px; font-size: 16px; font-weight: bold; color: #330000; text-decoration: none; }
ul#nav li a:hover { background-color: #a3e532; }
div#subhead_container { height: 30px; width:100%; min-width: 907px; background-color:#330000; float: left; list-style-type: none; z-index: 998; overflow: hidden; }
div#subhead_container { height: 30px; width:100%; min-width: 930px; background-color:#330000; float: left; list-style-type: none; z-index: 998; overflow: hidden; }
ul#subhead_menu { margin-top: 5px; }
ul#subhead_menu li { width: 100%; height: 100%; display: inline; }
ul#subhead_menu li a { padding: 5px 15px 10px 15px; vertical-align: middle; color: white; font-size: 16px; text-decoration: none; }
@@ -131,6 +131,9 @@ div#searchbar { margin: 24px 30px auto auto; float: right; }
div#main { margin: 0; padding: 80px 0 0 0; }
.table_wrapper { border-radius: 20px; -webkit-border-radius: 20px; -moz-border-radius: 20px; width: 88%; margin: 20px auto 0 auto; padding: 25px; background-color: white; position: relative; min-height: 200px; clear: both; _height: 302px; zoom: 1; }
.manage_wrapper { width: 88%; margin: 20px auto 0 auto; padding: 25px; min-height: 150px; clear: both; _height: 302px; zoom: 1; }
.table_wrapper_left { padding: 25px; background-color: #ffffff; float: left; width: 40%; height: 200px; margin-top: 25px; margin-left: 30px; margin-right: auto; -moz-border-radius: 20px; border-radius: 20px; }
.table_wrapper_right{ padding: 25px; background-color: #ffffff; width: 40%; height: 200px; margin-top: 25px; margin-left: auto; margin-right: 30px; -moz-border-radius: 20px; border-radius: 20px; }
table#artist_table { background-color: white; width: 100%; padding: 20px; }
@@ -144,6 +147,7 @@ table#artist_table td#album { vertical-align: middle; text-align: left; min-widt
table#artist_table td#have { vertical-align: middle; }
div#paddingheader { padding-top: 48px; font-size: 24px; font-weight: bold; text-align: center; }
div#nopaddingheader { font-size: 24px; font-weight: bold; text-align: center; }
table#album_table { background-color: white; }
table#album_table th#select { vertical-align: middle; text-align: left; min-width: 25px; }
@@ -161,15 +165,15 @@ table#album_table td#type { vertical-align: middle; text-align: center; }
table#album_table td#have { vertical-align: middle; }
img.albumArt { float: left; padding-right: 5px; }
div#albumheader { height: 200px; }
div#albumheader { padding-top: 48px; height: 200px; }
div#track_wrapper { padding-top: 20px; text-align: center; font-size: 16px; }
table#track_table th#number { text-align: left; min-width: 50px; }
table#track_table th#number { text-align: right; min-width: 20px; }
table#track_table th#name { text-align: center; min-width: 350px; }
table#track_table th#duration { width: 175px; text-align: center; min-width: 100px; }
table#track_table th#have { width: 175px; text-align: center; min-width: 100px; }
table#track_table td#number { vertical-align: middle; text-align: left; }
table#track_table td#number { vertical-align: middle; text-align: right; }
table#track_table td#name { vertical-align: middle; text-align: center; }
table#track_table td#duration { vertical-align: middle; text-align: center; }
table#track_table td#have { vertical-align: middle; text-align: center; }
@@ -182,6 +186,27 @@ table#log_table th#timestamp { text-align: left; min-width: 165px; }
table#log_table th#level { text-align: left; min-width: 75px; }
table#log_table th#message { text-align: left; min-width: 200px; }
table#upcoming_table th#albumart { text-align: center; min-width: 50px; }
table#upcoming_table th#albumname { text-align: center; min-width: 200px; }
table#upcoming_table th#artistname { text-align: center; min-width: 150px; }
table#upcoming_table th#reldate { text-align: center; min-width: 100px; }
table#upcoming_table th#type { text-align: center; min-width: 75px; }
table#upcoming_table td#albumart { vertical-align: middle; text-align: center; min-width: 50px; }
table#upcoming_table td#albumname { vertical-align: middle; text-align: center; min-width: 200px; }
table#upcoming_table td#artistname { vertical-align: middle; text-align: center; min-width: 150px; }
table#upcoming_table td#reldate { vertical-align: middle; text-align: center; min-width: 100px; }
table#upcoming_table td#type { vertical-align: middle; text-align: center; min-width: 75px; }
table#upcoming_table td#status { vertical-align: middle; text-align: center; }
table#searchresults_table th#albumname { text-align: left; min-width: 225px; }
table#searchresults_table th#artistname { text-align: center; min-width: 325px; }
table#searchresults_table th#score { text-align: center; min-width: 75px; }
table#searchresults_table td#albumname { vertical-align: middle; text-align: left; min-width: 200px; }
table#searchresults_table td#artistname { vertical-align: middle; text-align: left; min-width: 300px; }
table#searchresults_table td#score { vertical-align: middle; text-align: center; min-width: 75px; }
div.progress-container { border: 1px solid #ccc; width: 100px; height: 14px; margin: 2px 5px 2px 0; padding: 1px; float: left; background: white; }
div.progress-container > div { background-color: #a3e532; height: 14px; }
.havetracks { font-size: 13px; margin-left: 36px; padding-bottom: 3px; vertical-align: middle; }
+26 -12
View File
@@ -7,26 +7,36 @@
<%def name="headerIncludes()">
<div id="subhead_container">
<ul id="subhead_menu">
<li><a href="refreshArtist?ArtistID=${album['ArtistID']}">Mark Album as Wanted</a></li>
<li><a href="deleteArtist?ArtistID=${album['ArtistID']}">Delete Artist</a></li>
%if album['Status'] == 'Paused':
<li><a href="resumeArtist?ArtistID=${album['ArtistID']}">Resume Artist</a></li>
%if album['Status'] == 'Skipped':
<li><a href="queueAlbum?AlbumID=${album['AlbumID']}&ArtistID=${album['ArtistID']}&new=False">Mark Album as Wanted</a></li>
%elif album['Status'] == 'Snatched' or 'Downloaded':
<li><a href="queueAlbum?AlbumID=${album['AlbumID']}&ArtistID=${album['ArtistID']}&new=False">Retry Download</a></li>
<li><a href="queueAlbum?AlbumID=${album['AlbumID']}&ArtistID=${album['ArtistID']}&new=True">Try New Version</a></li>
%else:
<li><a href="pauseArtist?ArtistID=${album['ArtistID']}">Pause Artist</a></li>
%endif
<li><a href="getExtras?ArtistID=${album['ArtistID']}">Get Extras</a></li>
<li><a href="unqueueAlbum?AlbumID=${album['AlbumID']}&ArtistID=${album['ArtistID']}&new=False">Mark Album as Skipped</a></li>
%endif
</ul>
</div>
</%def>
<%def name="body()">
<div class="table_wrapper">
<h2><a href="artistPage?ArtistID=${album['ArtistID']}"><- Back to ${album['ArtistName']}</a></h2>
<div id="albumheader">
<img src="http://ec1.images-amazon.com/images/P/${album['AlbumASIN']}.01.LZZZZZZZ.jpg" height="200" width="200" alt="albumart" class="albumArt">
<h1>${album['AlbumTitle']}</h1>
<h2>${album['ArtistName']}</h2>
<br>
<%
totalduration = myDB.action("SELECT SUM(TrackDuration) FROM tracks WHERE AlbumID=?", [album['AlbumID']]).fetchone()[0]
totaltracks = len(myDB.select("SELECT TrackTitle from tracks WHERE AlbumID=?", [album['AlbumID']]))
%>
<h3>Tracks: ${totaltracks}</h3>
<h3>Duration: ${helpers.convert_milliseconds(totalduration)}</h3>
%if description:
<h3>Description: </h3>
${description['Summary']}
%endif
</div>
<div id="track_wrapper">
<table class="display" id="track_table">
@@ -35,14 +45,18 @@
<th id="number">#</th>
<th id="name">Track Title</th>
<th id="duration">Duration</th>
<th id="have">Have</th>
<th id="have"></th>
</tr>
</thead>
<tbody>
<%
i = 0
%>
%for track in tracks:
<%
trackmatch = 'asd'
if len(trackmatch):
i += 1
have = myDB.select('SELECT TrackTitle from have WHERE ArtistName like ? AND AlbumTitle like ? AND TrackTitle like ?', [album['ArtistName'], album['AlbumTitle'], track['TrackTitle']])
if len(have):
grade = 'A'
check = '<img src="images/checkmark.png" alt="checkmark">'
else:
@@ -50,9 +64,9 @@
check = ''
%>
<tr class="grade${grade}">
<td id="number">#</td>
<td id="number">${i}</td>
<td id="name">${track['TrackTitle']}</td>
<td id="duration">${track['TrackDuration']}</td>
<td id="duration">${helpers.convert_milliseconds(track['TrackDuration'])}</td>
<td id="have">${check}</td>
</tr>
%endfor
+11 -2
View File
@@ -26,6 +26,7 @@
<p class="indented">Mark selected albums as
<select name="action">
<option value="Wanted">Wanted</option>
<option value="WantedNew">Wanted (new only)</option>
<option value="Skipped">Skipped</option>
<option value="Downloaded">Downloaded</option>
</select>
@@ -74,7 +75,15 @@
<td id="albumname"><a href="albumPage?AlbumID=${album['AlbumID']}">${album['AlbumTitle']}</a></td>
<td id="reldate">${album['ReleaseDate']}</td>
<td id="type">${album['Type']}</td>
<td id="status">${album['Status']}</td>
<td id="status">${album['Status']}
%if album['Status'] == 'Skipped':
[<a href="queueAlbum?AlbumID=${album['AlbumID']}&ArtistID=${album['ArtistID']}">want</a>]
%elif album['Status'] == 'Wanted':
[<a href="unqueueAlbum?AlbumID=${album['AlbumID']}&ArtistID=${album['ArtistID']}">skip</a>]
%else:
[<a href="queueAlbum?AlbumID=${album['AlbumID']}&ArtistID=${album['ArtistID']}" title="Retry the same download again">retry</a>][<a href="queueAlbum?AlbumID=${album['AlbumID']}&ArtistID=${album['ArtistID']}&new=True" title="Try a new download, skipping all previously tried nzbs">new</a>]
%endif
</td>
<td id="have"><span title="${percent}"><span><div class="progress-container"><div style="width:${percent}%"><div class="havetracks">${havetracks}/${totaltracks}</div></div></div></td>
</tr>
%endfor
@@ -110,7 +119,7 @@
"sInfoEmpty":"Showing 0 to 0 of 0 albums",
"sInfoFiltered":"(filtered from _MAX_ total albums)"},
"bPaginate": false,
"aaSorting": [[3, 'asc'],[2,'desc']]
"aaSorting": [[4, 'asc'],[3,'desc']]
});
});
+1 -1
View File
@@ -49,7 +49,7 @@
<li><a href="config">settings</a></li>
</ul>
<div id="searchbar">
<form action="findArtist" method="get">
<form action="search" method="get">
<input type="text" value="" onfocus="if(this.value==this.defaultValue) this.value='';" name="name" />
<select name="type">
<option value="artist">Artist</option>
+1 -1
View File
@@ -1,5 +1,6 @@
<%inherit file="base.html"/>
<form action="configUpdate" method="post">
<div id="config">
<div class="table_wrapper">
<h1>Web Interface</h1>
<table>
@@ -216,5 +217,4 @@
</p>
</form>
</div>
</div>
<%inherit file="base.html" />
+6 -1
View File
@@ -1,4 +1,7 @@
<%inherit file="base.html"/>
<%!
from headphones import helpers
%>
<%def name="headerIncludes()">
<div id="subhead_container">
@@ -22,6 +25,7 @@
<th id="filename">File Name</th>
<th id="size">Size</th>
<th id="status">Status</th>
<th id="action"></th>
</tr>
</thead>
<tbody>
@@ -39,8 +43,9 @@
<tr class="grade${grade}">
<td id="dateadded">${item['DateAdded']}</td>
<td id="filename"><a href="${item['URL']}">${item['Title']}</a></td>
<td id="size">${item['Size']}</td>
<td id="size">${helpers.bytes_to_mb(item['Size'])}</td>
<td id="status">${item['Status']}</td>
<td id="action">[<a href="queueAlbum?AlbumID=${item['AlbumID']}&redirect=history">retry</a>][<a href="queueAlbum?AlbumID=${item['AlbumID']}&new=True&redirect=history">new</a>]</td>
</tr>
%endfor
</tbody>
+31 -7
View File
@@ -1,4 +1,8 @@
<%inherit file="base.html" />
<%!
import headphones
%>
<%def name="body()">
<div class="table_wrapper">
<h1>Scan Music Library</h1><br />
@@ -10,24 +14,44 @@
as soon as you click 'Submit'
<br /><br />
<form action="musicScan" method="GET" align="center">
%if headphones.MUSIC_DIR:
<input type="text" value="${headphones.MUSIC_DIR}" name="path" size="70" />
%else:
<input type="text" value="Enter a Music Directory to scan" onfocus="if
(this.value==this.defaultValue) this.value='';" name="path" size="70" />
%endif
<input type="submit" /></form>
</div>
<div class="table_wrapper">
<div class="table_wrapper_left">
<h1>Import Last.FM Artists</h1><br />
Enter the username whose artists you want to import:<br /><br />
<form action="importLastFM" method="GET" align="center">
<input type="text" value="%s" onfocus="if
<%
if headphones.LASTFM_USERNAME:
lastfmvalue = headphones.LASTFM_USERNAME
else:
lastfmvalue = 'Last.fm Username'
%>
<input type="text" value="${lastfmvalue}" onfocus="if
(this.value==this.defaultValue) this.value='';" name="username" size="18" />
<input type="submit" /></form><br /><br /></div></div>
<div class="tableright"><div class="config"><h1>Placeholder :-)</h1><br />
<input type="submit" /></form><br /><br />
</div>
<div class="table_wrapper_right">
<h1>Placeholder :-)</h1><br />
<br /><br />
<form action="" method="GET" align="center">
<input type="text" value="" onfocus="if
(this.value==this.defaultValue) this.value='';" name="" size="18" />
<input type="submit" /></form><br /><br /></div></div><br />
<div class="table"><div class="config"><h1>Force Search</h1><br />
<input type="submit" /></form><br /><br />
</div>
<div class="table_wrapper">
<h1>Force Search</h1><br />
<a href="forceSearch">Force Check for Wanted Albums</a><br /><br />
<a href="forceUpdate">Force Update Active Artists</a><br /><br />
<a href="forcePostProcess">Force Post-Process Albums in Download Folder</a><br /><br /><br />
<a href="checkGithub">Check for Headphones Updates</a><br /><br /><br /></div></div>''' % (music_dir_input, lastfm_user_text))
<a href="checkGithub">Check for Headphones Updates</a><br /><br /><br />
</div>
</%def>
@@ -0,0 +1,70 @@
<%inherit file="base.html" />
<%def name="body()">
<div id="paddingheader">
<h1>Search Results<h1>
</div>
<table class="display" id="searchresults_table">
<thead>
<tr>
%if type == 'album':
<th id="albumname">Album Name</th>
%endif
<th id="artistname">Artist Name</th>
<th id="score">Score</th>
<th id="add"></th>
</tr>
</thead>
<tbody>
%if searchresults:
%for result in searchresults:
<%
if result['score'] == 100:
grade = 'A'
else:
grade = 'Z'
%>
<tr class="grade${grade}">
%if type == 'album':
<td id="albumname"><a href="${result['albumurl']}">${result['title']}</a></td>
%endif
<td id="artistname"><a href="${result['url']}">${result['uniquename']}</a></td>
<td id="score">${result['score']}</td>
%if type == 'album':
<td id="add"><a href="addReleaseById?rid=${result['albumid']}">Add this album</a></td>
%else:
<td id="add"><a href="addArtist?artistid=${result['id']}">Add this artist</a></td>
%endif
</tr>
%endfor
%endif
</tbody>
</table>
</%def>
<%def name="headIncludes()">
<link rel="stylesheet" href="css/data_table.css">
</%def>
<%def name="javascriptIncludes()">
<script src="js/libs/jquery.dataTables.min.js"></script>
<script>
$(document).ready(function()
{
$('#searchresults_table').dataTable(
{
"oLanguage": {
"sLengthMenu":"Show _MENU_ results per page",
"sEmptyTable": "No results",
"sInfo":"Showing _TOTAL_ results",
"sInfoEmpty":"Showing 0 to 0 of 0 results",
"sInfoFiltered":"(filtered from _MAX_ total results)"},
"bPaginate": false,
"bFilter": false,
"aaSorting": []
});
});
</script>
</%def>
+1 -1
View File
@@ -6,6 +6,6 @@
<%def name="body()">
<div class="table_wrapper">
Headphones is ${message}
<h1>Headphones is ${message}</h1>
</div>
</%def>
+13 -5
View File
@@ -9,7 +9,7 @@
<th id="artistname">Artist</th>
<th id="albumname">Album Name</th>
<th id="reldate">Release Date</th>
<th id="type">Release Type</th>
<th id="type">Type</th>
<th id="status">Status</th>
</tr>
</thead>
@@ -26,30 +26,38 @@
%endfor
</tbody>
</table>
</div>
<form action="markAlbums" method="get">
<p class="indented">Mark selected albums as
<select name="action">
<option value="Skipped">Skipped</option>
<option value="Downloaded">Downloaded</option>
</select>
<input type="submit" value="Go">
</p>
<div class="table_wrapper">
<h1>Wanted Albums</h1>
<table class="display" id="upcoming_table">
<thead>
<tr>
<th id="select"><input type="checkbox" onClick="toggle(this)" /></th>
<th id="albumart"></th>
<th id="artistname">Artist</th>
<th id="albumname">Album Name</th>
<th id="reldate">Release Date</th>
<th id="type">Release Type</th>
<th id="status">Status</th>
<th id="type">Type</th>
</tr>
</thead>
<tbody>
%for album in wanted:
<tr class="gradeZ">
<td id="select"><input type="checkbox" name="${album['AlbumID']}" class="checkbox" /></th>
<td id="albumart"><img src="http://ec1.images-amazon.com/images/P/${album['AlbumASIN']}.01.MZZZZZZZ.jpg" height="50" width="50"></td>
<td id="artistname">${album['ArtistName']}</td>
<td id="albumname"><a href="albumPage?AlbumID=${album['AlbumID']}">${album['AlbumTitle']}</a></td>
<td id="reldate">${album['ReleaseDate']}</td>
<td id="type">${album['Type']}</td>
<td id="status">${album['Status']}</td>
</tr>
%endfor
</tbody>
+1
View File
@@ -429,6 +429,7 @@ def dbcheck():
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)')
c.execute('CREATE TABLE IF NOT EXISTS lastfmcloud (ArtistName TEXT, ArtistID TEXT, Count INTEGER)')
c.execute('CREATE TABLE IF NOT EXISTS descriptions (ReleaseGroupID TEXT, ReleaseID TEXT, Summary TEXT, Content TEXT)')
try:
c.execute('SELECT IncludeExtras from artists')
+2
View File
@@ -215,6 +215,8 @@ def addArtisttoDB(artistid, extrasonly=False):
myDB.upsert("albums", newValueDict, controlValueDict)
lastfm.getAlbumDescription(rg['id'], release_dict['releaselist'])
# I changed the albumid from releaseid -> rgid, so might need to delete albums that have a releaseid
for release in release_dict['releaselist']:
myDB.action('DELETE from albums WHERE AlbumID=?', [release['releaseid']])
+44 -1
View File
@@ -4,7 +4,7 @@ from collections import defaultdict
import random
import headphones
from headphones import db
from headphones import db, logger
api_key = '395e6ec6bb557382fc41fde867bce66f'
@@ -91,4 +91,47 @@ def getArtists():
for artistid in artistlist:
importer.addArtisttoDB(artistid)
def getAlbumDescription(rgid, releaselist):
myDB = db.DBConnection()
result = myDB.select('SELECT Summary from descriptions WHERE ReleaseGroupID=?', [rgid])
if result:
return
for release in releaselist:
mbid = release['releaseid']
url = 'http://ws.audioscrobbler.com/2.0/?method=album.getInfo&mbid=%s&api_key=%s' % (mbid, api_key)
logger.info('Checking last.fm for: ' + mbid)
data = urllib.urlopen(url).read()
if data == 'Album not found':
logger.info('Release id not on last fm, skipping')
continue
try:
d = minidom.parseString(data)
albuminfo = d.getElementsByTagName("album")
for item in albuminfo:
summarynode = item.getElementsByTagName("summary")[0].childNodes
contentnode = item.getElementsByTagName("content")[0].childNodes
for node in summarynode:
summary = node.data
for node in contentnode:
content = node.data
controlValueDict = {'ReleaseGroupID': rgid}
newValueDict = {'ReleaseID': mbid,
'Summary': summary,
'Content': content}
myDB.upsert("descriptions", newValueDict, controlValueDict)
logger.info('Inserted description')
break
except:
continue
+41
View File
@@ -66,6 +66,47 @@ def findArtist(name, limit=1):
})
return artistlist
def findRelease(name, limit=1):
with mb_lock:
releaselist = []
attempt = 0
releaseResults = None
chars = set('!?')
if any((c in chars) for c in name):
name = '"'+name+'"'
while attempt < 5:
try:
releaseResults = q.getReleases(ws.ReleaseFilter(query=name, limit=limit))
break
except WebServiceError, e:
logger.warn('Attempt to query MusicBrainz for %s failed: %s' % (name, e))
attempt += 1
time.sleep(5)
time.sleep(1)
if not releaseResults:
return False
for result in releaseResults:
releaselist.append({
'uniquename': result.release.artist.name,
'title': result.release.title,
'id': u.extractUuid(result.release.artist.id),
'albumid': u.extractUuid(result.release.id),
'url': result.release.artist.id,
'albumurl': result.release.id,
'score': result.score
})
return releaselist
def getArtist(artistid, extrasonly=False):
+26 -54
View File
@@ -10,7 +10,7 @@ import threading
import headphones
from headphones import logger, searcher, db, importer, lastfm
from headphones import logger, searcher, db, importer, mb, lastfm
from headphones.helpers import checked, radio
@@ -50,140 +50,112 @@ class WebInterface(object):
myDB = db.DBConnection()
album = myDB.action('SELECT * from albums WHERE AlbumID=?', [AlbumID]).fetchone()
tracks = myDB.select('SELECT * from tracks WHERE AlbumID=?', [AlbumID])
description = myDB.action('SELECT * from descriptions WHERE ReleaseGroupID=?', [AlbumID]).fetchone()
title = album['ArtistName'] + ' - ' + album['AlbumTitle']
return serve_template(templatename="album.html", title=title, album=album, tracks=tracks)
return serve_template(templatename="album.html", title=title, album=album, tracks=tracks, description=description)
albumPage.exposed = True
def search(self, name, type):
if len(name) == 0:
raise cherrypy.HTTPRedirect("home")
if type == 'artist':
searchresults = mb.findArtist(name, limit=10)
searchresults = mb.findArtist(name, limit=20)
else:
searchresults = mb.findRelease(name, limit=10)
findArtist.exposed = True
def artistInfo(self, artistid):
page = [templates._header]
page.append(templates._logobar)
page.append(templates._nav)
artist = mb.getArtist(artistid)
if artist['artist_begindate']:
begindate = artist['artist_begindate']
else:
begindate = ''
if artist['artist_enddate']:
enddate = artist['artist_enddate']
else:
enddate = ''
page.append('''<div class="table"><p class="center">Artist Information:</p>''')
page.append('''<p class="mediumtext">Artist Name: %s (%s)</br> ''' % (artist['artist_name'], artist['artist_type']))
page.append('''<p class="mediumtext">Years Active: %s - %s <br /><br />''' % (begindate, enddate))
page.append('''MusicBrainz Link: <a class="external" href="http://www.musicbrainz.org/artist/%s">http://www.musicbrainz.org/artist/%s</a></br></br><b>Albums:</b><br />''' % (artistid, artistid))
for rg in artist['releasegroups']:
page.append('''%s <br />''' % rg['title'])
page.append('''<div class="center"><a href="addArtist?artistid=%s">Add this artist!</a></div>''' % artistid)
return page
artistInfo.exposed = True
searchresults = mb.findRelease(name, limit=20)
return serve_template(templatename="searchresults.html", title='Search Results for: "' + name + '"', searchresults=searchresults, type=type)
search.exposed = True
def addArtist(self, artistid):
threading.Thread(target=importer.addArtisttoDB, args=[artistid]).start()
time.sleep(5)
threading.Thread(target=lastfm.getSimilar).start()
raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % artistid)
addArtist.exposed = True
def getExtras(self, ArtistID):
myDB = db.DBConnection()
controlValueDict = {'ArtistID': ArtistID}
newValueDict = {'IncludeExtras': 1}
myDB.upsert("artists", newValueDict, controlValueDict)
threading.Thread(target=importer.addArtisttoDB, args=[ArtistID, True]).start()
time.sleep(10)
raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID)
getExtras.exposed = True
def pauseArtist(self, ArtistID):
logger.info(u"Pausing artist: " + ArtistID)
myDB = db.DBConnection()
controlValueDict = {'ArtistID': ArtistID}
newValueDict = {'Status': 'Paused'}
myDB.upsert("artists", newValueDict, controlValueDict)
raise cherrypy.HTTPRedirect("home")
raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID)
pauseArtist.exposed = True
def resumeArtist(self, ArtistID):
logger.info(u"Resuming artist: " + ArtistID)
myDB = db.DBConnection()
controlValueDict = {'ArtistID': ArtistID}
newValueDict = {'Status': 'Active'}
myDB.upsert("artists", newValueDict, controlValueDict)
raise cherrypy.HTTPRedirect("home")
raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID)
resumeArtist.exposed = True
def deleteArtist(self, ArtistID):
logger.info(u"Deleting all traces of artist: " + ArtistID)
myDB = db.DBConnection()
myDB.action('DELETE from artists WHERE ArtistID=?', [ArtistID])
myDB.action('DELETE from albums WHERE ArtistID=?', [ArtistID])
myDB.action('DELETE from tracks WHERE ArtistID=?', [ArtistID])
raise cherrypy.HTTPRedirect("home")
deleteArtist.exposed = True
def refreshArtist(self, ArtistID):
importer.addArtisttoDB(ArtistID)
raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID)
refreshArtist.exposed=True
def markAlbums(self, ArtistID=None, action=None, **args):
myDB = db.DBConnection()
if action == 'WantedNew':
newaction = 'Wanted'
else:
newaction = action
for mbid in args:
controlValueDict = {'AlbumID': mbid}
newValueDict = {'Status': action}
newValueDict = {'Status': newaction}
myDB.upsert("albums", newValueDict, controlValueDict)
if action == 'Wanted':
searcher.searchNZB(mbid, new=False)
raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID)
if action == 'WantedNew':
searcher.searchNZB(mbid, new=True)
if ArtistID:
raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID)
else:
raise cherrypy.HTTPRedirect("upcoming")
markAlbums.exposed = True
def queueAlbum(self, AlbumID, ArtistID, new=False):
def queueAlbum(self, AlbumID, ArtistID=None, new=False, redirect=None):
logger.info(u"Marking album: " + AlbumID + "as wanted...")
myDB = db.DBConnection()
controlValueDict = {'AlbumID': AlbumID}
newValueDict = {'Status': 'Wanted'}
myDB.upsert("albums", newValueDict, controlValueDict)
searcher.searchNZB(AlbumID, new)
raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID)
if ArtistID:
raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID)
else:
raise cherrypy.HTTPRedirect(redirect)
queueAlbum.exposed = True
def unqueueAlbum(self, AlbumID, ArtistID):
logger.info(u"Marking album: " + AlbumID + "as skipped...")
myDB = db.DBConnection()
controlValueDict = {'AlbumID': AlbumID}
newValueDict = {'Status': 'Skipped'}
myDB.upsert("albums", newValueDict, controlValueDict)
raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID)
unqueueAlbum.exposed = True
def upcoming(self):