mirror of
https://github.com/rembo10/headphones.git
synced 2026-05-14 23:59:30 +01:00
Moved everything over to the new library scan - needs cleanup
This commit is contained in:
@@ -157,19 +157,21 @@ div#paddingheader { padding-top: 48px; font-size: 24px; font-weight: bold; text-
|
||||
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; }
|
||||
table#album_table th#select { vertical-align: middle; text-align: left; min-width: 10px; }
|
||||
table#album_table th#albumart { text-align: left; min-width: 50px; }
|
||||
table#album_table th#albumname { text-align: center; min-width: 150px; }
|
||||
table#album_table th#reldate { width: 175px; text-align: center; min-width: 100px; }
|
||||
table#album_table th#status { width: 175px; text-align: center; min-width: 100px; }
|
||||
table#album_table th#reldate { width: 175px; text-align: center; min-width: 70px; }
|
||||
table#album_table th#status { width: 175px; text-align: center; min-width: 80px; }
|
||||
table#album_table th#type { width: 175px; text-align: center; min-width: 100px; }
|
||||
table#album_table th#bitrate { text-align: center; min-width: 60px; }
|
||||
table#album_table td#select { vertical-align: middle; text-align: left; }
|
||||
table#album_table td#albumart { vertical-align: middle; text-align: left; }
|
||||
table#album_table td#albumname { vertical-align: middle; text-align: center; }
|
||||
table#album_table td#reldate { vertical-align: middle; text-align: center; }
|
||||
table#album_table td#status { vertical-align: middle; text-align: center; }
|
||||
table#album_table td#status { vertical-align: middle; text-align: center; font-size: 13px; }
|
||||
table#album_table td#type { vertical-align: middle; text-align: center; }
|
||||
table#album_table td#have { vertical-align: middle; }
|
||||
table#album_table td#bitrate { vertical-align: middle; text-align: center; font-size: 13px; }
|
||||
|
||||
img.albumArt { float: left; padding-right: 5px; }
|
||||
div#albumheader { padding-top: 48px; height: 200px; }
|
||||
@@ -185,7 +187,7 @@ 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#location { vertical-align: middle; text-align: center; font-size: 11px; }
|
||||
table#track_table td#location { vertical-align: middle; text-align: center; }
|
||||
table#track_table td#bitrate { vertical-align: middle; text-align: center; font-size: 12px; }
|
||||
|
||||
table#history_table { background-color: white; width: 100%; }
|
||||
|
||||
|
||||
@@ -85,6 +85,33 @@
|
||||
%endfor
|
||||
</tbody>
|
||||
</table>
|
||||
<%
|
||||
unmatched = myDB.select('SELECT * from have WHERE ArtistName LIKE ? AND AlbumTitle LIKE ?', [album['ArtistName'], album['AlbumTitle']])
|
||||
%>
|
||||
%if unmatched:
|
||||
<table class="display" id="track_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th id="number">#</th>
|
||||
<th id="name">Track Title</th>
|
||||
<th id="duration">Duration</th>
|
||||
<th id="location">Local File</th>
|
||||
<th id="bitrate">Bit Rate</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
%for track in unmatched:
|
||||
<tr class="gradeZ">
|
||||
<td id="number">${track['TrackNumber']}</td>
|
||||
<td id="name">${track['TrackTitle']}</td>
|
||||
<td id="duration">${track['TrackLength']}</td>
|
||||
<td id="location">${track['Location']}</td>
|
||||
<td id="bitrate">${track['BitRate']}</td>
|
||||
</tr>
|
||||
%endfor
|
||||
</tbody>
|
||||
</table>
|
||||
%endif
|
||||
</div>
|
||||
</div>
|
||||
</%def>
|
||||
|
||||
@@ -41,11 +41,12 @@
|
||||
<tr>
|
||||
<th id="select"><input type="checkbox" onClick="toggle(this)" /></th>
|
||||
<th id="albumart"></th>
|
||||
<th id="albumname">Album Name</th>
|
||||
<th id="reldate">Release Date</th>
|
||||
<th id="type">Release Type</th>
|
||||
<th id="albumname">Name</th>
|
||||
<th id="reldate">Date</th>
|
||||
<th id="type">Type</th>
|
||||
<th id="status">Status</th>
|
||||
<th id="have">Have</th>
|
||||
<th id="bitrate">Bitrate</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -62,7 +63,7 @@
|
||||
|
||||
myDB = db.DBConnection()
|
||||
totaltracks = len(myDB.select('SELECT TrackTitle from tracks WHERE AlbumID=?', [album['AlbumID']]))
|
||||
havetracks = 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']]))
|
||||
|
||||
try:
|
||||
percent = (havetracks*100.0)/totaltracks
|
||||
@@ -71,6 +72,12 @@
|
||||
except (ZeroDivisionError, TypeError):
|
||||
percent = 0
|
||||
totaltracks = '?'
|
||||
|
||||
avgbitrate = myDB.action("SELECT AVG(BitRate) FROM tracks WHERE AlbumID=?", [album['AlbumID']]).fetchone()[0]
|
||||
if avgbitrate:
|
||||
bitrate = str(int(avgbitrate)/1000) + ' kbps'
|
||||
else:
|
||||
bitrate = ''
|
||||
|
||||
%>
|
||||
<tr class="grade${grade}">
|
||||
@@ -89,6 +96,7 @@
|
||||
%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>
|
||||
<td id="bitrate">${bitrate}</td>
|
||||
</tr>
|
||||
%endfor
|
||||
</tbody>
|
||||
@@ -114,7 +122,8 @@
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
{ "sType": "title-numeric"}
|
||||
{ "sType": "title-numeric"},
|
||||
null
|
||||
],
|
||||
"oLanguage": {
|
||||
"sLengthMenu":"Show _MENU_ albums per page",
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
%>
|
||||
<tr class="grade${grade}">
|
||||
<td id="dateadded">${item['DateAdded']}</td>
|
||||
<td id="filename"><a href="${item['URL']}">${item['Title']}</a></td>
|
||||
<td id="filename"><a href="${item['URL']}">${item['Title']}</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>
|
||||
|
||||
@@ -62,6 +62,8 @@ PATH_TO_XML = None
|
||||
PREFERRED_QUALITY = None
|
||||
PREFERRED_BITRATE = None
|
||||
DETECT_BITRATE = False
|
||||
ADD_ARTISTS = False
|
||||
NEW_ARTISTS = None
|
||||
CORRECT_METADATA = False
|
||||
MOVE_FILES = False
|
||||
RENAME_FILES = False
|
||||
@@ -160,7 +162,7 @@ def initialize():
|
||||
global __INITIALIZED__, FULL_PATH, PROG_DIR, QUIET, DAEMON, DATA_DIR, CONFIG_FILE, CFG, LOG_DIR, CACHE_DIR, \
|
||||
HTTP_PORT, HTTP_HOST, HTTP_USERNAME, HTTP_PASSWORD, HTTP_ROOT, LAUNCH_BROWSER, GIT_PATH, \
|
||||
CURRENT_VERSION, LATEST_VERSION, MUSIC_DIR, DESTINATION_DIR, PREFERRED_QUALITY, PREFERRED_BITRATE, DETECT_BITRATE, \
|
||||
CORRECT_METADATA, MOVE_FILES, RENAME_FILES, FOLDER_FORMAT, FILE_FORMAT, CLEANUP_FILES, INCLUDE_EXTRAS, \
|
||||
ADD_ARTISTS, CORRECT_METADATA, MOVE_FILES, RENAME_FILES, FOLDER_FORMAT, FILE_FORMAT, CLEANUP_FILES, INCLUDE_EXTRAS, \
|
||||
ADD_ALBUM_ART, EMBED_ALBUM_ART, DOWNLOAD_DIR, BLACKHOLE, BLACKHOLE_DIR, USENET_RETENTION, NZB_SEARCH_INTERVAL, \
|
||||
LIBRARYSCAN_INTERVAL, DOWNLOAD_SCAN_INTERVAL, SAB_HOST, SAB_USERNAME, SAB_PASSWORD, SAB_APIKEY, SAB_CATEGORY, \
|
||||
NZBMATRIX, NZBMATRIX_USERNAME, NZBMATRIX_APIKEY, NEWZNAB, NEWZNAB_HOST, NEWZNAB_APIKEY, \
|
||||
@@ -199,6 +201,7 @@ def initialize():
|
||||
PREFERRED_QUALITY = check_setting_int(CFG, 'General', 'preferred_quality', 0)
|
||||
PREFERRED_BITRATE = check_setting_int(CFG, 'General', 'preferred_bitrate', '')
|
||||
DETECT_BITRATE = bool(check_setting_int(CFG, 'General', 'detect_bitrate', 0))
|
||||
ADD_ARTISTS = bool(check_setting_int(CFG, 'General', 'add_artists', 1))
|
||||
CORRECT_METADATA = bool(check_setting_int(CFG, 'General', 'correct_metadata', 0))
|
||||
MOVE_FILES = bool(check_setting_int(CFG, 'General', 'move_files', 0))
|
||||
RENAME_FILES = bool(check_setting_int(CFG, 'General', 'rename_files', 0))
|
||||
@@ -363,6 +366,7 @@ def config_write():
|
||||
new_config['General']['preferred_quality'] = PREFERRED_QUALITY
|
||||
new_config['General']['preferred_bitrate'] = PREFERRED_BITRATE
|
||||
new_config['General']['detect_bitrate'] = int(DETECT_BITRATE)
|
||||
new_config['General']['add_artists'] = int(ADD_ARTISTS)
|
||||
new_config['General']['correct_metadata'] = int(CORRECT_METADATA)
|
||||
new_config['General']['move_files'] = int(MOVE_FILES)
|
||||
new_config['General']['rename_files'] = int(RENAME_FILES)
|
||||
@@ -425,10 +429,10 @@ def start():
|
||||
|
||||
SCHED.add_cron_job(updater.dbUpdate, hour=4, minute=0, second=0)
|
||||
SCHED.add_interval_job(searcher.searchNZB, minutes=NZB_SEARCH_INTERVAL)
|
||||
SCHED.add_interval_job(importer.scanMusic, minutes=LIBRARYSCAN_INTERVAL)
|
||||
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
|
||||
@@ -439,9 +443,9 @@ def dbcheck():
|
||||
c=conn.cursor()
|
||||
c.execute('CREATE TABLE IF NOT EXISTS artists (ArtistID TEXT UNIQUE, ArtistName TEXT, ArtistSortName TEXT, DateAdded TEXT, Status TEXT, IncludeExtras INTEGER, LatestAlbum TEXT, ReleaseDate TEXT, AlbumID TEXT, HaveTracks INTEGER, TotalTracks INTEGER)')
|
||||
c.execute('CREATE TABLE IF NOT EXISTS albums (ArtistID TEXT, ArtistName TEXT, AlbumTitle TEXT, AlbumASIN TEXT, ReleaseDate TEXT, DateAdded TEXT, AlbumID TEXT UNIQUE, Status TEXT, Type TEXT)')
|
||||
c.execute('CREATE TABLE IF NOT EXISTS tracks (ArtistID TEXT, ArtistName TEXT, AlbumTitle TEXT, AlbumASIN TEXT, AlbumID TEXT, TrackTitle TEXT, TrackDuration, TrackID TEXT, TrackNumber INTEGER, Location TEXT, BitRate INTEGER)')
|
||||
c.execute('CREATE TABLE IF NOT EXISTS tracks (ArtistID TEXT, ArtistName TEXT, AlbumTitle TEXT, AlbumASIN TEXT, AlbumID TEXT, TrackTitle TEXT, TrackDuration, TrackID TEXT, TrackNumber INTEGER, Location TEXT, BitRate INTEGER, CleanName TEXT)')
|
||||
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 have (ArtistName TEXT, AlbumTitle TEXT, TrackNumber TEXT, TrackTitle TEXT, TrackLength TEXT, BitRate TEXT, Genre TEXT, Date TEXT, TrackID TEXT, Location TEXT, CleanName 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)')
|
||||
c.execute('CREATE TABLE IF NOT EXISTS releases (ReleaseID TEXT, ReleaseGroupID TEXT, UNIQUE(ReleaseID, ReleaseGroupID))')
|
||||
@@ -495,11 +499,26 @@ def dbcheck():
|
||||
c.execute('SELECT Location from tracks')
|
||||
except sqlite3.OperationalError:
|
||||
c.execute('ALTER TABLE tracks ADD COLUMN Location TEXT')
|
||||
|
||||
try:
|
||||
c.execute('SELECT Location from have')
|
||||
except sqlite3.OperationalError:
|
||||
c.execute('ALTER TABLE have ADD COLUMN Location TEXT')
|
||||
|
||||
try:
|
||||
c.execute('SELECT BitRate from tracks')
|
||||
except sqlite3.OperationalError:
|
||||
c.execute('ALTER TABLE tracks ADD COLUMN BitRate INTEGER')
|
||||
|
||||
try:
|
||||
c.execute('SELECT CleanName from tracks')
|
||||
except sqlite3.OperationalError:
|
||||
c.execute('ALTER TABLE tracks ADD COLUMN CleanName TEXT')
|
||||
|
||||
try:
|
||||
c.execute('SELECT CleanName from have')
|
||||
except sqlite3.OperationalError:
|
||||
c.execute('ALTER TABLE have ADD COLUMN CleanName TEXT')
|
||||
|
||||
conn.commit()
|
||||
c.close()
|
||||
|
||||
@@ -104,6 +104,13 @@ def replace_all(text, dic):
|
||||
text = text.replace(i, j)
|
||||
return text
|
||||
|
||||
def cleanName(string):
|
||||
|
||||
pass1 = latinToAscii(string).lower()
|
||||
out_string = re.sub('[\.\-\/\!\@\#\$\%\^\&\*\(\)\+\-\"\'\,\;\:\[\]\{\}\<\>\=\_]', '', pass1).encode('utf-8')
|
||||
|
||||
return out_string
|
||||
|
||||
def extract_data(s):
|
||||
|
||||
from headphones import logger
|
||||
|
||||
@@ -7,89 +7,6 @@ import headphones
|
||||
from headphones import logger, helpers, db, mb, albumart, lastfm
|
||||
|
||||
various_artists_mbid = '89ad4ac3-39f7-470e-963a-56509c546377'
|
||||
|
||||
def scanMusic(dir=None):
|
||||
|
||||
if not dir:
|
||||
dir = headphones.MUSIC_DIR
|
||||
|
||||
try:
|
||||
dir = str(dir)
|
||||
except UnicodeEncodeError:
|
||||
dir = unicode(dir).encode('unicode_escape')
|
||||
|
||||
logger.info('Starting Music Scan with directory: %s' % dir)
|
||||
|
||||
results = []
|
||||
|
||||
for r,d,f in os.walk(dir):
|
||||
for files in f:
|
||||
if any(files.endswith('.' + x) for x in headphones.MEDIA_FORMATS):
|
||||
results.append(os.path.join(r, files))
|
||||
|
||||
logger.info(u'%i music files found. Reading metadata....' % len(results))
|
||||
|
||||
if results:
|
||||
|
||||
myDB = db.DBConnection()
|
||||
myDB.action('''DELETE from have''')
|
||||
|
||||
for song in results:
|
||||
try:
|
||||
f = MediaFile(song)
|
||||
except:
|
||||
logger.warn('Could not read file: %s' % song)
|
||||
continue
|
||||
else:
|
||||
if f.albumartist:
|
||||
artist = f.albumartist
|
||||
elif f.artist:
|
||||
artist = f.artist
|
||||
else:
|
||||
continue
|
||||
|
||||
if not f.album:
|
||||
album = None
|
||||
else:
|
||||
album = f.album
|
||||
|
||||
myDB.action('INSERT INTO have VALUES( ?, ?, ?, ?, ?, ?, ?, ?, ?)', [artist, album, f.track, f.title, f.length, f.bitrate, f.genre, f.date, f.mb_trackid])
|
||||
|
||||
# Get the average bitrate if the option is selected
|
||||
if headphones.DETECT_BITRATE:
|
||||
try:
|
||||
avgbitrate = myDB.action("SELECT AVG(BitRate) FROM have").fetchone()[0]
|
||||
headphones.PREFERRED_BITRATE = int(avgbitrate)/1000
|
||||
|
||||
except Exception, e:
|
||||
logger.error('Error detecting preferred bitrate:' + str(e))
|
||||
|
||||
artistlist = myDB.action('SELECT DISTINCT ArtistName FROM have').fetchall()
|
||||
logger.info(u"Preparing to import %i artists" % len(artistlist))
|
||||
|
||||
artistlist_to_mbids(artistlist)
|
||||
|
||||
def itunesImport(pathtoxml):
|
||||
|
||||
if os.path.splitext(pathtoxml)[1] == '.xml':
|
||||
logger.info(u"Loading xml file from"+ pathtoxml)
|
||||
pl = XMLLibraryParser(pathtoxml)
|
||||
l = Library(pl.dictionary)
|
||||
lst = []
|
||||
for song in l.songs:
|
||||
lst.append(song.artist)
|
||||
rawlist = {}.fromkeys(lst).keys()
|
||||
artistlist = [f for f in rawlist if f != None]
|
||||
|
||||
else:
|
||||
rawlist = os.listdir(pathtoxml)
|
||||
logger.info(u"Loading artists from directory:" +pathtoxml)
|
||||
exclude = ['.ds_store', 'various artists', 'untitled folder', 'va']
|
||||
artistlist = [f for f in rawlist if f.lower() not in exclude]
|
||||
|
||||
logger.info('Starting directory/xml import...')
|
||||
artistlist_to_mbids(artistlist)
|
||||
|
||||
|
||||
def is_exists(artistid):
|
||||
|
||||
@@ -109,7 +26,7 @@ def artistlist_to_mbids(artistlist):
|
||||
|
||||
for artist in artistlist:
|
||||
|
||||
results = mb.findArtist(artist['ArtistName'], limit=1)
|
||||
results = mb.findArtist(artist, limit=1)
|
||||
|
||||
if not results:
|
||||
continue
|
||||
@@ -124,16 +41,12 @@ def artistlist_to_mbids(artistlist):
|
||||
# Add to database if it doesn't exist
|
||||
if artistid != various_artists_mbid and not is_exists(artistid):
|
||||
addArtisttoDB(artistid)
|
||||
|
||||
# Update track count regardless of whether it already exists
|
||||
if artistid != various_artists_mbid:
|
||||
|
||||
|
||||
# Just update the tracks if it does
|
||||
else:
|
||||
myDB = db.DBConnection()
|
||||
havetracks = len(myDB.select('SELECT TrackTitle from have WHERE ArtistName like ?', [artist['ArtistName']]))
|
||||
|
||||
controlValueDict = {"ArtistID": artistid}
|
||||
newValueDict = {"HaveTracks": havetracks}
|
||||
myDB.upsert("artists", newValueDict, controlValueDict)
|
||||
havetracks = len(myDB.select('SELECT TrackTitle from tracks WHERE ArtistID=?', [artistid])) + len(myDB.select('SELECT TrackTitle from have WHERE ArtistName like ?', [artist['ArtistName']]))
|
||||
myDB.action('UPDATE artists SET HaveTracks=? WHERE ArtistID=?', [havetracks, artistid])
|
||||
|
||||
# Update the similar artist tag cloud:
|
||||
logger.info('Updating artist information from Last.fm')
|
||||
@@ -231,6 +144,8 @@ def addArtisttoDB(artistid, extrasonly=False):
|
||||
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'])
|
||||
|
||||
controlValueDict = {"TrackID": track['id'],
|
||||
"AlbumID": rg['id']}
|
||||
newValueDict = {"ArtistID": artistid,
|
||||
@@ -239,14 +154,29 @@ def addArtisttoDB(artistid, extrasonly=False):
|
||||
"AlbumASIN": release_dict['asin'],
|
||||
"TrackTitle": track['title'],
|
||||
"TrackDuration": track['duration'],
|
||||
"TrackNumber": track['number']
|
||||
"TrackNumber": track['number'],
|
||||
"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()
|
||||
|
||||
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']])
|
||||
|
||||
myDB.upsert("tracks", newValueDict, controlValueDict)
|
||||
|
||||
latestalbum = myDB.action('SELECT AlbumTitle, ReleaseDate, AlbumID from albums WHERE ArtistID=? order by ReleaseDate DESC', [artistid]).fetchone()
|
||||
totaltracks = len(myDB.select('SELECT TrackTitle from tracks WHERE ArtistID=?', [artistid]))
|
||||
|
||||
havetracks = len(myDB.select('SELECT TrackTitle from tracks WHERE ArtistID=? AND Location IS NOT NULL', [artistid])) + len(myDB.select('SELECT TrackTitle from have WHERE ArtistName like ?', [artist['artist_name']]))
|
||||
|
||||
controlValueDict = {"ArtistID": artistid}
|
||||
|
||||
if latestalbum:
|
||||
@@ -254,7 +184,8 @@ def addArtisttoDB(artistid, extrasonly=False):
|
||||
"LatestAlbum": latestalbum['AlbumTitle'],
|
||||
"ReleaseDate": latestalbum['ReleaseDate'],
|
||||
"AlbumID": latestalbum['AlbumID'],
|
||||
"TotalTracks": totaltracks}
|
||||
"TotalTracks": totaltracks,
|
||||
"HaveTracks": havetracks}
|
||||
else:
|
||||
newValueDict = {"Status": "Active"}
|
||||
|
||||
@@ -339,6 +270,8 @@ def addReleaseById(rid):
|
||||
|
||||
for track in release_dict['tracks']:
|
||||
|
||||
cleanname = helpers.cleanName(release_dict['artist_name'] + ' ' + release_dict['rg_title'] + ' ' + track['title'])
|
||||
|
||||
controlValueDict = {"TrackID": track['id'],
|
||||
"AlbumID": rgid}
|
||||
newValueDict = {"ArtistID": release_dict['artist_id'],
|
||||
@@ -347,8 +280,21 @@ def addReleaseById(rid):
|
||||
"AlbumASIN": release_dict['asin'],
|
||||
"TrackTitle": track['title'],
|
||||
"TrackDuration": track['duration'],
|
||||
"TrackNumber": track['number']
|
||||
"TrackNumber": track['number'],
|
||||
"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()
|
||||
|
||||
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 location:
|
||||
newValueDict['Location'] = location['Location']
|
||||
newValueDict['BitRate'] = location['BitRate']
|
||||
|
||||
myDB.upsert("tracks", newValueDict, controlValueDict)
|
||||
|
||||
|
||||
@@ -4,17 +4,18 @@ import glob
|
||||
from lib.beets.mediafile import MediaFile
|
||||
|
||||
import headphones
|
||||
from headphones import db, logger
|
||||
from headphones import db, logger, helpers, importer
|
||||
|
||||
def LibraryScan():
|
||||
def libraryScan():
|
||||
|
||||
if not headphones.MUSIC_DIR:
|
||||
return
|
||||
|
||||
unmatched_files = []
|
||||
new_artists = []
|
||||
bitrates = []
|
||||
|
||||
myDB = db.DBConnection()
|
||||
myDB.action('''DELETE from have''')
|
||||
|
||||
for r,d,f in os.walk(headphones.MUSIC_DIR):
|
||||
for files in f:
|
||||
@@ -22,63 +23,58 @@ def LibraryScan():
|
||||
if any(files.endswith('.' + x) for x in headphones.MEDIA_FORMATS):
|
||||
|
||||
file = unicode(os.path.join(r, files), "utf-8")
|
||||
print repr(file)
|
||||
|
||||
# Try to read the metadata
|
||||
try:
|
||||
f = MediaFile(file)
|
||||
except:
|
||||
logger.error('Cannot read file: ' + file)
|
||||
continue
|
||||
continue
|
||||
|
||||
# Grab the bitrates for the auto detect bit rate option
|
||||
if f.bitrate:
|
||||
bitrates.append(f.bitrate)
|
||||
|
||||
# Try to match on metadata first,
|
||||
# Try to match on metadata first, starting with the track id
|
||||
if f.mb_trackid:
|
||||
print 'has track id:' + repr(f.mb_trackid)
|
||||
|
||||
# Wondering if theres a better way to do this -> do one thing if the row exists,
|
||||
# do something else if it doesn't
|
||||
track = myDB.action('SELECT TrackID from tracks WHERE TrackID=?', [f.mb_trackid]).fetchone()
|
||||
|
||||
if not track:
|
||||
if f.albumartist:
|
||||
new_artists.append(f.albumartist)
|
||||
elif f.artist:
|
||||
new_artists.append(f.artist)
|
||||
else:
|
||||
unmatched_files.append(file)
|
||||
|
||||
else:
|
||||
if track:
|
||||
myDB.action('UPDATE tracks SET Location=?, BitRate=? WHERE TrackID=?', [file, f.bitrate, track['TrackID']])
|
||||
continue
|
||||
|
||||
elif f.albumartist and f.album and f.title:
|
||||
|
||||
track = myDB.action('SELECT TrackID from tracks WHERE ArtistName LIKE ? AND AlbumTitle LIKE ? AND TrackTitle LIKE ?', [f.albumartist, f.album, f.title]).fetchone()
|
||||
|
||||
if not track:
|
||||
new_artists.append(f.albumartist)
|
||||
|
||||
else:
|
||||
myDB.action('UPDATE tracks SET Location=?, BitRate=? WHERE TrackID=?', [file, f.bitrate, track['TrackID']])
|
||||
|
||||
elif f.artist and f.album and f.title:
|
||||
|
||||
track = myDB.action('SELECT TrackID from tracks WHERE ArtistName LIKE ? AND AlbumTitle LIKE ? AND TrackTitle LIKE ?', [f.artist, f.album, f.title]).fetchone()
|
||||
|
||||
if not track:
|
||||
new_artists.append(file)
|
||||
else:
|
||||
myDB.action('UPDATE tracks SET Location=?, BitRate=? WHERE TrackID=?', [file, f.bitrate, track['TrackID']])
|
||||
|
||||
# Try to find a match based on artist/album/tracktitle
|
||||
if f.albumartist:
|
||||
f_artist = f.albumartist
|
||||
elif f.artist:
|
||||
f_artist = f.artist
|
||||
else:
|
||||
continue
|
||||
|
||||
if f_artist and f.album and f.title:
|
||||
|
||||
track = myDB.action('SELECT TrackID from tracks WHERE CleanName LIKE ?', [helpers.cleanName(f_artist +' '+f.album+' '+f.title)]).fetchone()
|
||||
|
||||
if not track:
|
||||
track = myDB.action('SELECT TrackID from tracks WHERE ArtistName LIKE ? AND AlbumTitle LIKE ? AND TrackTitle LIKE ?', [f_artist, f.album, f.title]).fetchone()
|
||||
|
||||
# Try to parse the unmatched files based on the folder & file formats in the config
|
||||
for file in unmatched_files:
|
||||
# Will do later
|
||||
pass
|
||||
if track:
|
||||
myDB.action('UPDATE tracks SET Location=?, BitRate=? WHERE TrackID=?', [file, f.bitrate, track['TrackID']])
|
||||
continue
|
||||
|
||||
# if we can't find a match in the database on a track level, it might be a new artist or it might be on a non-mb release
|
||||
new_artists.append(f_artist)
|
||||
|
||||
# The have table will become the new database for unmatched tracks (i.e. tracks with no associated links in the database
|
||||
myDB.action('INSERT INTO have VALUES( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [f_artist, f.album, f.track, f.title, f.length, f.bitrate, f.genre, f.date, f.mb_trackid, file, helpers.cleanName(f_artist+' '+f.album+' '+f.title)])
|
||||
|
||||
# Now check empty file paths to see if we can find a match based on their folder format
|
||||
tracks = myDB.select('SELECT * from tracks WHERE Location=NULL')
|
||||
tracks = myDB.select('SELECT * from tracks WHERE Location IS NULL')
|
||||
for track in tracks:
|
||||
|
||||
release = myDB.action('SELECT * from albums WHERE AlbumID=?', [track['AlbumID']]).fetchone()
|
||||
|
||||
try:
|
||||
@@ -129,32 +125,48 @@ def LibraryScan():
|
||||
|
||||
new_file_name = new_file_name.replace('?','_').replace(':', '_')
|
||||
|
||||
full_path_to_file = os.path.join(headphones.MUSIC_DIR, folder, new_file_name)
|
||||
full_path_to_file = os.path.normpath(os.path.join(headphones.MUSIC_DIR, folder, new_file_name))
|
||||
|
||||
match = glob.glob(full_path_to_file)
|
||||
|
||||
print 'Full path to file is: ' + repr(full_path_to_file)
|
||||
|
||||
if glob.glob(full_path_to_file):
|
||||
myDB.action('UPDATE tracks SET Location=? WHERE TrackID=?', [full_path_to_file, track['TrackID']])
|
||||
if match:
|
||||
|
||||
myDB.action('UPDATE tracks SET Location=? WHERE TrackID=?', [match[0], track['TrackID']])
|
||||
|
||||
# Try to insert the appropriate track id so we don't have to keep doing this
|
||||
try:
|
||||
f = MediaFile(full_path_to_file)
|
||||
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])
|
||||
except:
|
||||
logger.error('Error embedding track id into: %s' % full_path_to_file)
|
||||
logger.error('Error embedding track id into: %s' % match[0])
|
||||
|
||||
# Lastly, clean up any old paths that don't exist
|
||||
# Clean up bad filepaths
|
||||
tracks = myDB.select('SELECT Location, TrackID from tracks WHERE Location IS NOT NULL')
|
||||
|
||||
for track in tracks:
|
||||
if not os.path.isfile(track['Location']):
|
||||
myDB.action('UPDATE tracks SET Location=? WHERE TrackID=?', [None, track['TrackID']])
|
||||
|
||||
|
||||
# Clean up the new artist list
|
||||
unique_artists = {}.fromkeys(new_artists).keys()
|
||||
current_artists = myDB.action('SELECT ArtistName from artists').fetchall()
|
||||
current_artists = myDB.select('SELECT ArtistName from artists')
|
||||
|
||||
artist_list = [f for f in unique_artists if f not in current_artists]
|
||||
artist_list = [f for f in unique_artists if f.lower() not in [x[0].lower() for x in current_artists]]
|
||||
|
||||
logger.info('Found %i artists to import: ' % len(artist_list))
|
||||
logger.info('Found %i new artists to import.' % len(artist_list))
|
||||
|
||||
# Update track counts
|
||||
for artist in current_artists:
|
||||
havetracks = len(myDB.select('SELECT TrackTitle from tracks WHERE ArtistID like ?', [artist['ArtistID']])) + len(myDB.select('SELECT TrackTitle from have WHERE ArtistName like ?', [artist['ArtistName']]))
|
||||
myDB.action('UPDATE artists SET HaveTracks=? WHERE ArtistID=?', [havetracks, artist['ArtistID']])
|
||||
|
||||
if headphones.ADD_ARTISTS:
|
||||
importer.artistlist_to_mbids(artist_list)
|
||||
else:
|
||||
headphones.NEW_ARTISTS = artist_list
|
||||
|
||||
if headphones.DETECT_BITRATE:
|
||||
headphones.PREFERRED_BITRATE = float(sum(bitrates))/len(bitrates)/1000
|
||||
Reference in New Issue
Block a user