Merge remote-tracking branch 'theguardian/master' into develop

This commit is contained in:
rembo10
2013-11-25 11:53:37 +01:00
16 changed files with 1187 additions and 425 deletions
+1 -1
View File
@@ -138,7 +138,7 @@
</tr>
%endfor
<%
unmatched = myDB.select('SELECT * from have WHERE ArtistName LIKE ? AND AlbumTitle LIKE ?', [album['ArtistName'], album['AlbumTitle']])
unmatched = myDB.select('SELECT * from have WHERE ArtistName LIKE ? AND AlbumTitle LIKE ? AND Matched is null ORDER BY CAST(TrackNumber AS INTEGER)', [album['ArtistName'], album['AlbumTitle']])
%>
%if unmatched:
%for track in unmatched:
+1 -1
View File
@@ -93,7 +93,7 @@
myDB = db.DBConnection()
totaltracks = len(myDB.select('SELECT TrackTitle from tracks WHERE AlbumID=?', [album['AlbumID']]))
havetracks = len(myDB.select('SELECT TrackTitle from tracks WHERE AlbumID=? AND Location IS NOT NULL', [album['AlbumID']])) + len(myDB.select('SELECT TrackTitle from have WHERE ArtistName like ? AND AlbumTitle LIKE ?', [album['ArtistName'], album['AlbumTitle']]))
havetracks = len(myDB.select('SELECT TrackTitle from tracks WHERE AlbumID=? AND Location IS NOT NULL', [album['AlbumID']])) + len(myDB.select('SELECT TrackTitle from have WHERE ArtistName like ? AND AlbumTitle LIKE ? AND Matched IS NULL', [album['ArtistName'], album['AlbumTitle']]))
try:
percent = (havetracks*100.0)/totaltracks
+8
View File
@@ -97,6 +97,14 @@
<label>Library Scan Interval</label>
<input type="text" name="libraryscan_interval" value="${config['libraryscan_interval']}" size="4">mins
</div>
<div class="row">
<label>MusicBrainz Update Interval</label>
<input type="text" name="update_db_interval" value="${config['update_db_interval']}" size="4">hours
</div>
<div class="row">
<label>Ignore Album Updates</label>
<input type="text" name="mb_ignore_age" value="${config['mb_ignore_age']}" size="4">days
</div>
</fieldset>
</td>
</tr>
+1
View File
@@ -315,6 +315,7 @@ function doAjaxCall(url,elem,reload,form) {
console.log('refresh'); refreshTable();
}
if ( reload == "tabs") refreshTab();
if ( reload == "page") location.reload();
if ( form ) {
// Change the option to 'choose...'
$(formID + " select").children('option[disabled=disabled]').attr('selected','selected');
+23 -1
View File
@@ -22,6 +22,7 @@
%if not headphones.ADD_ARTISTS:
<a class="menu_link_edit" href="manageNew">Manage New Artists</a>
%endif
<a class="menu_link_edit" href="manageUnmatched">Manage Unmatched</a>
</div>
</div>
</%def>
@@ -35,6 +36,7 @@
<li><a href="#tabs-1">Scan Music Library</a></li>
<li><a href="#tabs-2">Imports</a></li>
<li><a href="#tabs-3">Force Actions</a></li>
<li><a href="#tabs-4">Force Legacy</a></li>
</ul>
<div id="tabs-1" class="configtable">
<fieldset>
@@ -119,7 +121,7 @@
<legend>Force Search</legend>
<div class="links">
<a href="#" onclick="doAjaxCall('forceSearch',$(this))" data-success="Checking for wanted albums successful" data-error="Error checking wanted albums"><span class="ui-icon ui-icon-search"></span>Force Check for Wanted Albums</a>
<a href="#" onclick="doAjaxCall('forceUpdate',$(this))" data-success="Update active artists successful" data-error="Error forcing update artists"><span class="ui-icon ui-icon-heart"></span>Force Update Active Artists</a>
<a href="#" onclick="doAjaxCall('forceUpdate',$(this))" data-success="Update active artists successful" data-error="Error forcing update artists"><span class="ui-icon ui-icon-heart"></span>Force Update Active Artists [Fast]</a>
<a href="#" onclick="doAjaxCall('forcePostProcess',$(this))" data-success="Post-Processor is being loaded" data-error="Error during Post-Processing"><span class="ui-icon ui-icon-wrench"></span>Force Post-Process Albums in Download Folder</a>
<a href="#" onclick="doAjaxCall('checkGithub',$(this))" data-success="Checking for update successful" data-error="Error checking for update"><span class="ui-icon ui-icon-refresh"></span>Check for Headphones Updates</a>
<a href="#" id="delete_empty_artists"><span class="ui-icon ui-icon-trash"></span>Delete empty Artists</a>
@@ -139,6 +141,26 @@
</fieldset>
</div>
<div id="tabs-4" class="configtable">
<fieldset>
<legend>Force Legacy</legend>
<p>Please note that these functions will take a significant amount of time to complete.</p>
<div class="links">
<a href="#" onclick="doAjaxCall('forceFullUpdate',$(this))" data-success="Update active artists successful" data-error="Error forcing update artists"><span class="ui-icon ui-icon-heart"></span>Force Update Active Artists [Comprehensive]</a>
<BR>
<a href="#" onclick="doAjaxCall('forceScan',$(this))" data-success="Library scan successful" data-error="Error forcing library scan"><span class="ui-icon ui-icon-refresh"></span>Force Re-scan Library [Comprehensive]</a>
<BR>
<small>*Warning: If you choose [Force Re-scan Library], any manually ignored/matched artists/albums will be reset to "unmatched".</small>
</div>
</fieldset>
</div>
</div>
</%def>
<%def name="javascriptIncludes()">
+1 -1
View File
@@ -57,7 +57,7 @@
myDB = db.DBConnection()
totaltracks = len(myDB.select('SELECT TrackTitle from tracks WHERE AlbumID=?', [album['AlbumID']]))
havetracks = len(myDB.select('SELECT TrackTitle from tracks WHERE AlbumID=? AND Location IS NOT NULL', [album['AlbumID']])) + len(myDB.select('SELECT TrackTitle from have WHERE ArtistName like ? AND AlbumTitle LIKE ?', [album['ArtistName'], album['AlbumTitle']]))
havetracks = len(myDB.select('SELECT TrackTitle from tracks WHERE AlbumID=? AND Location IS NOT NULL', [album['AlbumID']])) + len(myDB.select('SELECT TrackTitle from have WHERE ArtistName like ? AND AlbumTitle LIKE ? AND Matched IS NULL', [album['ArtistName'], album['AlbumTitle']]))
try:
percent = (havetracks*100.0)/totaltracks
+121
View File
@@ -0,0 +1,121 @@
<%inherit file="base.html" />
<%!
import headphones
from headphones import db, helpers
myDB = db.DBConnection()
%>
<%def name="headerIncludes()">
<div id="subhead_container">
<div id="subhead_menu">
</div>
</div>
<a href="manageUnmatched" class="back">&laquo; Back to Unmatched Albums</a>
</%def>
<%def name="body()">
<div class="table_wrapper">
<div id="manageheader" class="title">
<h1 class="clearfix"><img src="interfaces/default/images/icon_manage.png" alt="manage"/>Manage Manually Changed Albums</h1>
</div>
<table class="display" id="artist_table">
<thead>
<tr>
<th id="artist">Local Artist</th>
<th id="album">Local Album</th>
<th id="status">Previous Action</th>
</tr>
</thead>
<tbody>
<% count_albums=0 %>
%for album in manualalbums:
<tr class="gradeZ">
<%
old_artist_clean = album['ArtistName'].replace('&','%26').replace('+', '%2B').replace("'","%27")
old_album_clean = album['AlbumTitle'].replace('&','%26').replace('+', '%2B').replace("'","%27")
%>
<td id="artist">${album['ArtistName']}<BR>
<button id="restore_artist${count_albums}" onClick="restore_Artist(this.id)">(<-) Restore Artist</button>
<div id="restore_artist_dialog${count_albums}" title="Restore Artist" style="display:none">
<table>
<tr><td>Are you sure you want to restore Local Artist: ${album['ArtistName']} to unmatched?</td></tr>
<tr><td align="right"><BR>
%if album['AlbumStatus'] == "Ignored":
<button href="#" onclick="doAjaxCall('markManual?action=unignoreArtist&existing_artist=${old_artist_clean}', $(this), 'page');" data-success="Successfully restored ${album['ArtistName']} to unmatched">Restore Artist</button>
%elif album['AlbumStatus'] == "Matched":
<button href="#" onclick="doAjaxCall('markManual?action=unmatchArtist&existing_artist=${old_artist_clean}', $(this), 'page');" data-success="Successfully restored ${album['ArtistName']} to unmatched">Restore Artist</button>
%endif
</td></tr>
</table>
</div>
</td>
<td id="album">${album['AlbumTitle']}<BR>
<button id="restore_album${count_albums}" onClick="restore_Album(this.id)">(<-) Restore Album</button>
<div id="restore_album_dialog${count_albums}" title="Restore Album" style="display:none">
<table>
<tr><td>Are you sure you want to restore Local Album: ${album['AlbumTitle']} to unmatched?</td></tr>
<tr><td align="right"><BR>
%if album['AlbumStatus'] == "Ignored":
<button href="#" onclick="doAjaxCall('markManual?action=unignoreAlbum&existing_artist=${old_artist_clean}&existing_album=${old_album_clean}', $(this), 'page');" data-success="Successfully restored ${album['AlbumTitle']} to unmatched">Restore Album</button>
%elif album['AlbumStatus'] == "Matched":
<button href="#" onclick="doAjaxCall('markManual?action=unmatchAlbum&existing_artist=${old_artist_clean}&existing_album=${old_album_clean}', $(this), 'page');" data-success="Successfully restored ${album['AlbumTitle']} to unmatched">Restore Album</button>
%endif
</td></tr>
</table>
</div>
</td>
<td id="status">${album['AlbumStatus']}
</td>
</tr>
<% count_albums+=1 %>
%endfor
</tbody>
</table>
</div>
</%def>
<%def name="headIncludes()">
<link rel="stylesheet" href="interfaces/default/css/data_table.css">
</%def>
<%def name="javascriptIncludes()">
<script src="js/libs/jquery.dataTables.min.js"></script>
<script>
$(document).ready(function()
{
$('#artist_table').dataTable(
{
"bStateSave": true,
"bPaginate": true,
"oLanguage": {
"sSearch": "",
"sLengthMenu":"Show _MENU_ albums per page",
"sInfo":"Showing _START_ to _END_ of _TOTAL_ albums",
"sInfoEmpty":"Showing 0 to 0 of 0 albums",
"sInfoFiltered":"(filtered from _MAX_ total albums)",
"sEmptyTable": " ",
},
"sPaginationType": "full_numbers",
});
initActions();
});
function restore_Artist(clicked_id) {
n=clicked_id.replace("restore_artist","");
$("#restore_artist_dialog"+n).dialog();
return false;
}
function restore_Album(clicked_id) {
n=clicked_id.replace("restore_album","");
$("#restore_album_dialog"+n).dialog();
return false;
}
</script>
</%def>
+4 -1
View File
@@ -20,7 +20,10 @@
</div>
<form action="addArtists" method="get">
<div id="markalbum">
Add selected artists
<select name="action">
<option value="add">(+) ADD Selected Artists</option>
<option value="ignore">(-) IGNORE Selected Artists</option>
</select>
<input type="submit" value="Go">
</div>
<table class="display" id="artist_table">
@@ -0,0 +1,259 @@
<%inherit file="base.html" />
<%!
import headphones
import json
from headphones import db, helpers
myDB = db.DBConnection()
artist_json = {}
counter = 0
artist_list = myDB.action("SELECT ArtistName from artists ORDER BY ArtistName COLLATE NOCASE")
for artist in artist_list:
artist_json[counter] = artist['ArtistName']
counter+=1
json_artists = json.dumps(artist_json)
%>
<%def name="headerIncludes()">
<div id="subhead_container">
<div id="subhead_menu">
<a class="menu_link_edit" href="manageManual">Manage Manually Matched & Ignored</a>
</div>
</div>
<a href="manage" class="back">&laquo; Back to manage overview</a>
</%def>
<%def name="body()">
<div class="table_wrapper">
<div id="manageheader" class="title">
<h1 class="clearfix"><img src="interfaces/default/images/icon_manage.png" alt="manage"/>Manage Unmatched Albums</h1>
</div>
<table class="display" id="artist_table">
<thead>
<tr>
<th id="artist">Local Artist</th>
<th id="album">Local Album</th>
</tr>
</thead>
<tbody>
<% count_albums=0 %>
%for album in unmatchedalbums:
<tr class="gradeZ">
<%
old_artist_clean = album['ArtistName'].replace('&','%26').replace("'","%27")
old_album_clean = album['AlbumTitle'].replace('&','%26').replace("'","%27")
old_artist_js = album['ArtistName'].replace("'","\\'").replace('"','\\"')
old_album_js = album['AlbumTitle'].replace("'","\\'").replace('"','\\"')
%>
<td id="artist">${album['ArtistName']}<BR>
<button id="ignore_artists${count_albums}" onClick="ignore_Artist(this.id)">(-) Ignore Artist</button>
<div id="ignore_artist_dialog${count_albums}" title="Ignore Artist" style="display:none">
<table>
<tr><td>Are you sure you want to ignore Local Artist: ${album['ArtistName']} from future matching?</td></tr>
<tr><td align="right"><BR>
<button href="#" onclick="doAjaxCall('markUnmatched?action=ignoreArtist&existing_artist=${old_artist_clean}', $(this), 'page');" data-success="Successfully ignored ${album['ArtistName']} from future matching">Ignore Artist</button>
</td></tr>
</table>
</div>
<button id="match_artists${count_albums}" onClick="load_Artist(this.id)">(->) Match Artist</button>
<div id="artist_dialog${count_albums}" title="Match Artist" style="display:none">
<table width=400>
<tr><td>Local Artist:</td><td>${album['ArtistName']}</td></tr>
<tr><td>Match Artist</td><td>
<select id="artist_options${count_albums}" name="new_artist">
</select>
</td></tr>
<tr><td></td><td align="right"><BR>
<button href="#" onclick="artist_matcher(${count_albums}, '${old_artist_js}')">Match Artist</button>
</td></tr>
</table>
</div>
</td>
<td id="album">${album['AlbumTitle']}<BR>
<button id="ignore_albums${count_albums}" onClick="ignore_Album(this.id)">(-) Ignore Album</button>
<div id="ignore_album_dialog${count_albums}" title="Ignore Album" style="display:none">
<table>
<tr><td>Are you sure you want to ignore Local Album: ${album['AlbumTitle']} from future matching?</td></tr>
<tr><td align="right"><BR>
<button href="#" onclick="doAjaxCall('markUnmatched?action=ignoreAlbum&existing_artist=${old_artist_clean}&existing_album=${old_album_clean}', $(this), 'page');" data-success="Successfully ignored ${album['AlbumTitle']} from future matching">Ignore Album</button>
</td></tr>
</table>
</div>
<button id="match_albums${count_albums}" onClick="load_AlbumArtist(this.id)">(->) Match Album</button>
<div id="album_dialog${count_albums}" title="Match Album" style="display:none">
<table width=650>
<tr><td>Local Artist:</td><td>${album['ArtistName']}</td></tr>
<tr><td>Local Album:</td><td>${album['AlbumTitle']}</td></tr>
<tr><td>Match Artist</td><td>
<select id="album_artist_options${count_albums}" name="new_artist">
</select>
</td></tr>
<tr><td>Match Album</td><td>
<select id="album_options${count_albums}" name="new_album">
</select>
</td></tr>
<tr><td></td><td align="right"><BR>
<button href="#" onclick="album_matcher(${count_albums}, '${old_artist_js}', '${old_album_js}')">Match Album</button>
</td></tr>
</table>
</div>
</td>
</tr>
<% count_albums+=1 %>
%endfor
</tbody>
</table>
</div>
</%def>
<%def name="headIncludes()">
<link rel="stylesheet" href="interfaces/default/css/data_table.css">
</%def>
<%def name="javascriptIncludes()">
<script src="js/libs/jquery.dataTables.min.js"></script>
<script>
$(document).ready(function()
{
$('#artist_table').dataTable(
{
"bStateSave": true,
"bPaginate": true,
"oLanguage": {
"sSearch": "",
"sLengthMenu":"Show _MENU_ albums per page",
"sInfo":"Showing _START_ to _END_ of _TOTAL_ albums",
"sInfoEmpty":"Showing 0 to 0 of 0 albums",
"sInfoFiltered":"(filtered from _MAX_ total albums)",
"sEmptyTable": " ",
},
"sPaginationType": "full_numbers",
});
initActions();
});
function ignore_Artist(clicked_id) {
n=clicked_id.replace("ignore_artists","");
$("#ignore_artist_dialog"+n).dialog();
return false;
}
function ignore_Album(clicked_id) {
n=clicked_id.replace("ignore_albums","");
$("#ignore_album_dialog"+n).dialog();
return false;
}
function load_Artist(clicked_id) {
n=clicked_id.replace("match_artists","");
var d = $("#artist_dialog"+n).dialog();
d.dialog("option", "width", 450);
d.dialog("option", "position", "center");
$('#artist_options'+n).html('');
$.each(${json_artists}, function(key, value) {
$('#artist_options'+n).append($("<option/>", {
value: value,
text: value
}));
});
change_artist(n)
return false;
}
function change_artist(n) {
selected_artist = $("#artist_options"+n).find("option:selected").text();
selected_artist_clean = selected_artist.replace('&', '%26').replace('+', '%2B');
$("#artist_options"+n).change(function() {
selected_artist = $("#artist_options"+n).find("option:selected").text();
selected_artist_clean = selected_artist.replace('&', '%26').replace('+', '%2B');
});
}
function artist_matcher(n, existing_artist) {
var existing_artist = existing_artist.toString();
var existing_artist_clean = existing_artist.replace('&', '%26').replace('+', '%2B');
$('#match_artists'+n).attr('data-success', 'Successfully matched '+existing_artist+' with '+selected_artist);
doAjaxCall('markUnmatched?action=matchArtist&existing_artist='+existing_artist_clean+'&new_artist='+selected_artist_clean, $('#match_artists'+n), 'page');
}
function load_AlbumArtist(clicked_id) {
n=clicked_id.replace("match_albums","");
var d = $("#album_dialog"+n).dialog();
d.dialog("option", "width", 700);
d.dialog("option", "position", "center");
$('#album_artist_options'+n).html('');
$.each(${json_artists}, function(key, value) {
$('#album_artist_options'+n).append($("<option/>", {
value: value,
text: value
}));
});
load_json_albums(n)
return false;
}
function load_json_albums(n) {
selected_album_artist = $("#album_artist_options"+n).find("option:selected").text();
selected_album_artist_clean = selected_album_artist.replace('&', '%26').replace('+', '%2B');
$('#album_options'+n).html('')
$.getJSON("getAlbumsByArtist_json?artist="+selected_album_artist_clean, function( data ) {
$.each( data, function( key, value ) {
$('#album_options'+n).append($("<option/>", {
value: value,
text: value
}));
});
selected_album= $("#album_options"+n).find("option:selected").text();
selected_album_clean = selected_album.replace('&', '%26').replace('+', '%2B');
});
change_json_albums(n)
change_album(n)
}
function change_json_albums(n) {
$("#album_artist_options"+n).change(function(){
selected_album_artist = $("#album_artist_options"+n).find("option:selected").text();
selected_album_artist_clean = selected_album_artist.replace('&', '%26').replace('+', '%2B');
$('#album_options'+n).html('')
$.getJSON("getAlbumsByArtist_json?artist="+selected_album_artist_clean, function( data ) {
$.each( data, function( key, value ) {
$('#album_options'+n).append($("<option/>", {
value: value,
text: value
}));
});
selected_album= $("#album_options"+n).find("option:selected").text();
selected_album_clean = selected_album.replace('&', '%26').replace('+', '%2B');
});
change_album(n)
});
}
function change_album(n) {
$("#album_options"+n).change(function() {
selected_album= $("#album_options"+n).find("option:selected").text();
selected_album_clean = selected_album.replace('&', '%26').replace('+', '%2B');
});
}
function album_matcher(n, existing_artist, existing_album) {
var existing_artist = existing_artist.toString();
var existing_artist_clean = existing_artist.replace('&', '%26').replace('+', '%2B');
var existing_album = existing_album.toString();
var existing_album_clean = existing_album.replace('&', '%26').replace('+', '%2B');
$('#match_albums'+n).attr('data-success', 'Successfully matched '+existing_album+' with '+selected_album);
doAjaxCall('markUnmatched?action=matchAlbum&existing_artist='+existing_artist_clean+'&new_artist='+selected_album_artist_clean+'&existing_album='+existing_album_clean+'&new_album='+selected_album_clean, $('#match_albums'+n), 'page');
}
</script>
</%def>