Added manage new artists page, fixed some bugs in the importer

This commit is contained in:
Remy
2011-08-16 13:07:17 -07:00
parent b4663b39df
commit 10b334f29e
9 changed files with 125 additions and 63 deletions

View File

@@ -177,19 +177,25 @@ img.albumArt { float: left; padding-right: 5px; }
div#albumheader { padding-top: 48px; height: 200px; }
div#track_wrapper { margin-left: -50px; padding-top: 20px; font-size: 16px; width: 100%; }
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#number { text-align: right; min-width: 10px; }
table#track_table th#name { text-align: center; min-width: 320px; }
table#track_table th#duration { width: 175px; text-align: center; min-width: 100px; }
table#track_table th#location { text-align: center; min-width: 200px; }
table#track_table th#bitrate { text-align: center; min-width: 75px; }
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#name { vertical-align: middle; text-align: center; font-size: 15px; }
table#track_table td#duration { vertical-align: middle; text-align: center; }
table#track_table td#location { vertical-align: middle; text-align: center; font-size: 11px; }
table#track_table td#bitrate { vertical-align: middle; text-align: center; font-size: 12px; }
table#history_table { background-color: white; width: 100%; }
table#history_table { background-color: white; width: 100%; font-size: 13px; }
table#history_table td#dateadded { vertical-align: middle; text-align: center; min-width: 150px; font-size: 14px; }
table#history_table td#filename { vertical-align: middle; text-align: center; min-width: 100px; font-size: 15px; }
table#history_table td#size { vertical-align: middle; text-align: center; min-width: 75px; font-size: 14px; }
table#history_table td#status { vertical-align: middle; text-align: center; font-size: 14px; }
table#history_table td#action { vertical-align: middle; text-align: center; font-size: 14px; }
table#log_table { background-color: white; }

View File

@@ -42,7 +42,7 @@
%>
<tr class="grade${grade}">
<td id="dateadded">${item['DateAdded']}</td>
<td id="filename"><a href="${item['URL']}">${item['Title']}</a> <a href="albumPage?AlbumID=?${item['AlbumID']}">[album page]</a></td>
<td id="filename">${item['Title']} [<a href="${item['URL']}">nzb</a>]<a href="albumPage?AlbumID=${item['AlbumID']}">[album page]</a></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>

View File

@@ -5,7 +5,10 @@
<%def name="headerIncludes()">
<div id="subhead_container">
<ul id="subhead_menu">
<li><a href="manageArtists">Manage Artists</a></li>
<li><a href="manageArtists">Manage Artists</a></li>
%if not headphones.ADD_ARTISTS:
<li><a href="manageNew">Manage New Artists</a></li>
%endif
</ul>
</div>
</%def>

View File

@@ -1,18 +1,14 @@
<%inherit file="base.html" />
<%!
import headphones
%>
<%def name="body()">
<div id="paddingheader">
<h1>Manage Artists<h1>
<h1>Manage New Artists<h1>
</div>
<form action="markArtists" method="get">
<form action="addArtists" method="get">
<p class="indented">
<select name="action">
<option value="pause">Pause</option>
<option value="resume">Resume</option>
<option value="refresh">Refresh</option>
<option value="delete">Delete</option>
</select>
selected artists
Add selected artists
<input type="submit" value="Go">
</p>
<table class="display" id="artist_table">
@@ -20,23 +16,13 @@
<tr>
<th id="select"><input type="checkbox" onClick="toggle(this)" /></th>
<th id="name">Artist Name</th>
<th id="status">Status</th>
</tr>
</thead>
<tbody>
%for artist in artists:
<%
if artist['Status'] == 'Paused':
grade = 'X'
elif artist['Status'] == 'Loading':
grade = 'C'
else:
grade = 'Z'
%>
<tr class="grade${grade}">
%for artist in headphones.NEW_ARTISTS:
<tr class="gradeZ">
<td id="select"><input type="checkbox" name="${artist['ArtistID']}" class="checkbox" /></td>
<td id="name"><span title="${artist['ArtistSortName']}"></span><a href="artistPage?ArtistID=${artist['ArtistID']}">${artist['ArtistName']}</a></td>
<td id="status">${artist['Status']}</td>
</tr>
%endfor
</tbody>
@@ -58,7 +44,6 @@
"aoColumns": [
null,
{ "sType": "title-string"},
null
],
"bStateSave": true,
"bPaginate": false

View File

@@ -0,0 +1,51 @@
<%inherit file="base.html" />
<%!
import headphones
%>
<%def name="body()">
<div id="paddingheader">
<h1>Manage New Artists<h1>
</div>
<form action="addArtists" method="get">
<p class="indented">
Add selected artists
<input type="submit" value="Go">
</p>
<table class="display" id="artist_table">
<thead>
<tr>
<th id="select"><input type="checkbox" onClick="toggle(this)" /></th>
<th id="name">Artist Name</th>
</tr>
</thead>
<tbody>
%for artist in headphones.NEW_ARTISTS:
<tr class="gradeZ">
<td id="select"><input type="checkbox" name="${artist}" class="checkbox" /></td>
<td id="name">${artist}</a></td>
</tr>
%endfor
</tbody>
</table>
</form>
</%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()
{
$('#artist_table').dataTable(
{
"aaSorting": [[1, 'asc']],
"bStateSave": false,
"bPaginate": false
});
});
</script>
</%def>

View File

@@ -63,7 +63,7 @@ PREFERRED_QUALITY = None
PREFERRED_BITRATE = None
DETECT_BITRATE = False
ADD_ARTISTS = False
NEW_ARTISTS = None
NEW_ARTISTS = []
CORRECT_METADATA = False
MOVE_FILES = False
RENAME_FILES = False
@@ -432,7 +432,7 @@ def start():
SCHED.add_interval_job(librarysync.libraryScan, minutes=LIBRARYSCAN_INTERVAL)
SCHED.add_interval_job(versioncheck.checkGithub, minutes=300)
SCHED.add_interval_job(postprocessor.checkFolder, minutes=DOWNLOAD_SCAN_INTERVAL)
librarysync.libraryScan()
SCHED.start()
started = True

View File

@@ -141,7 +141,6 @@ def addArtisttoDB(artistid, extrasonly=False):
myDB.action('DELETE from albums WHERE AlbumID=?', [release['releaseid']])
myDB.action('DELETE from tracks WHERE AlbumID=?', [release['releaseid']])
myDB.action('DELETE from tracks WHERE AlbumID=?', [rg['id']])
for track in release_dict['tracks']:
cleanname = helpers.cleanName(artist['artist_name'] + ' ' + rg['title'] + ' ' + track['title'])
@@ -158,18 +157,16 @@ def addArtisttoDB(artistid, extrasonly=False):
"CleanName": cleanname
}
location = myDB.action('SELECT Location, BitRate from have WHERE TrackID=?', [track['id']]).fetchone()
if not location:
location = myDB.action('SELECT Location, BitRate from have WHERE CleanName=?', [cleanname]).fetchone()
match = myDB.action('SELECT Location, BitRate from have WHERE TrackID=?', [track['id']]).fetchone()
if not location:
location = myDB.action('SELECT Location, BitRate from have WHERE ArtistName LIKE ? AND AlbumTitle LIKE ? AND TrackTitle LIKE ?', [artist['artist_name'], rg['title'], track['title']]).fetchone()
if location:
newValueDict['Location'] = location['Location']
newValueDict['BitRate'] = location['BitRate']
myDB.action('DELETE from have WHERE Location=?', [location['location']])
if not match:
match = myDB.action('SELECT Location, BitRate from have WHERE CleanName=?', [cleanname]).fetchone()
if not match:
match = myDB.action('SELECT Location, BitRate from have WHERE ArtistName LIKE ? AND AlbumTitle LIKE ? AND TrackTitle LIKE ?', [artist['artist_name'], rg['title'], track['title']]).fetchone()
if match:
newValueDict['Location'] = match['Location']
newValueDict['BitRate'] = match['BitRate']
myDB.action('DELETE from have WHERE Location=?', [match['Location']])
myDB.upsert("tracks", newValueDict, controlValueDict)
@@ -187,7 +184,9 @@ def addArtisttoDB(artistid, extrasonly=False):
"TotalTracks": totaltracks,
"HaveTracks": havetracks}
else:
newValueDict = {"Status": "Active"}
newValueDict = {"Status": "Active",
"TotalTracks": totaltracks,
"HaveTracks": havetracks}
myDB.upsert("artists", newValueDict, controlValueDict)
logger.info(u"Updating complete for: " + artist['artist_name'])
@@ -284,17 +283,17 @@ def addReleaseById(rid):
"CleanName": cleanname
}
location = myDB.action('SELECT Location, BitRate from have WHERE TrackID=?', [track['id']]).fetchone()
match = myDB.action('SELECT Location, BitRate from have WHERE TrackID=?', [track['id']]).fetchone()
if not location:
location = myDB.action('SELECT Location, BitRate from have WHERE CleanName=?', [cleanname]).fetchone()
if not match:
match = myDB.action('SELECT Location, BitRate from have WHERE CleanName=?', [cleanname]).fetchone()
if not location:
location = myDB.action('SELECT Location, BitRate from have WHERE ArtistName LIKE ? AND AlbumTitle LIKE ? AND TrackTitle LIKE ?', [release_dict['artist_name'], release_dict['rg_title'], track['title']]).fetchone()
if not match:
match = myDB.action('SELECT Location, BitRate from have WHERE ArtistName LIKE ? AND AlbumTitle LIKE ? AND TrackTitle LIKE ?', [release_dict['artist_name'], release_dict['rg_title'], track['title']]).fetchone()
if location:
newValueDict['Location'] = location['Location']
newValueDict['BitRate'] = location['BitRate']
if match:
newValueDict['Location'] = match['Location']
newValueDict['BitRate'] = match['BitRate']
myDB.upsert("tracks", newValueDict, controlValueDict)

View File

@@ -6,10 +6,17 @@ from lib.beets.mediafile import MediaFile
import headphones
from headphones import db, logger, helpers, importer
def libraryScan():
def libraryScan(dir=None):
if not headphones.MUSIC_DIR:
return
if not dir:
dir = headphones.MUSIC_DIR
try:
dir = str(dir)
except UnicodeEncodeError:
dir = unicode(dir).encode('unicode_escape')
logger.info('Scanning music directory: %s' % dir)
new_artists = []
bitrates = []
@@ -17,7 +24,7 @@ def libraryScan():
myDB = db.DBConnection()
myDB.action('''DELETE from have''')
for r,d,f in os.walk(headphones.MUSIC_DIR):
for r,d,f in os.walk(dir):
for files in f:
# MEDIA_FORMATS = music file extensions, e.g. mp3, flac, etc
if any(files.endswith('.' + x) for x in headphones.MEDIA_FORMATS):
@@ -132,17 +139,19 @@ def libraryScan():
if match:
myDB.action('UPDATE tracks SET Location=? WHERE TrackID=?', [match[0], track['TrackID']])
myDB.action('DELETE from have WHERE Location=?', [match[0]])
# Try to insert the appropriate track id so we don't have to keep doing this
try:
f = MediaFile(match[0])
f.mb_trackid = track['TrackID']
myDB.action('UPDATE tracks SET BitRate=? WHERE TrackID=?', [f.bitrate, track['TrackID']])
f.save()
logger.info('Wrote mbid to track: %s' % match[0])
myDB.action('UPDATE tracks SET BitRate=? WHERE TrackID=?', [f.bitrate, track['TrackID']])
logger.debug('Wrote mbid to track: %s' % match[0])
except:
logger.error('Error embedding track id into: %s' % match[0])
continue
# Clean up bad filepaths
tracks = myDB.select('SELECT Location, TrackID from tracks WHERE Location IS NOT NULL')
@@ -168,4 +177,4 @@ def libraryScan():
headphones.NEW_ARTISTS = artist_list
if headphones.DETECT_BITRATE:
headphones.PREFERRED_BITRATE = round(sum(bitrates))/len(bitrates)/1000
headphones.PREFERRED_BITRATE = sum(bitrates)/len(bitrates)/1000

View File

@@ -10,7 +10,7 @@ import threading
import headphones
from headphones import logger, searcher, db, importer, mb, lastfm
from headphones import logger, searcher, db, importer, mb, lastfm, librarysync
from headphones.helpers import checked, radio
@@ -148,7 +148,12 @@ class WebInterface(object):
else:
raise cherrypy.HTTPRedirect("upcoming")
markAlbums.exposed = True
def addArtists(self, **args):
threading.Thread(target=importer.artistlist_to_mbids, args=[args]).start()
time.sleep(5)
raise cherrypy.HTTPRedirect("home")
addArtists.exposed = True
def queueAlbum(self, AlbumID, ArtistID=None, new=False, redirect=None):
logger.info(u"Marking album: " + AlbumID + "as wanted...")
@@ -189,6 +194,10 @@ class WebInterface(object):
return serve_template(templatename="manageartists.html", title="Manage Artists", artists=artists)
manageArtists.exposed = True
def manageNew(self):
return serve_template(templatename="managenew.html", title="Manage New Artists")
manageNew.exposed = True
def markArtists(self, action=None, **args):
myDB = db.DBConnection()
for ArtistID in args:
@@ -231,7 +240,7 @@ class WebInterface(object):
headphones.MUSIC_DIR = path
headphones.config_write()
try:
threading.Thread(target=importer.scanMusic, args=[path]).start()
threading.Thread(target=librarysync.libraryScan).start()
except Exception, e:
logger.error('Unable to complete the scan: %s' % e)
time.sleep(10)