- Use: artist, album, year, releasetype and first (first letter in artist name)
- E.g.: first/artist/album [year] = G/Girl Talk/All Day [2010]
+ Use: Artist/artist, Album/album, Year/year, Type/type (release type) and First/first (first letter in artist name)
+ E.g.: Type/First/artist/album [year] = Album/G/girl talk/all day [2010]
@@ -442,7 +442,7 @@
- Use: tracknumber, title, artist, album and year
+ Use: Track/track (track #), Title/title, Artist/artist, Album/album and Year/year
- Use: artist, album, year, releasetype and first (first letter in artist name)
- E.g.: first/artist/album [year] = G/Girl Talk/All Day [2010]
+ Use: Artist/artist, Album/album, Year/year, Type/type (release type) and First/first (first letter in artist name)
+ E.g.: Type/First/artist/album [year] = Album/G/girl talk/all day [2010]
File Format:
- Use: tracknumber, title, artist, album and year
+ Use: Track/track (track #), Title/title, Artist/artist, Album/album and Year/year
- Use: artist, album, year, releasetype and first (first letter in artist name)
- E.g.: first/artist/album [year] = G/Girl Talk/All Day [2010]
+ Use: Artist/artist, Album/album, Year/year, Type/type (release type) and First/first (first letter in artist name)
+ E.g.: Type/First/artist/album [year] = Album/G/girl talk/all day [2010]
File Format:
- Use: tracknumber, title, artist, album and year
+ Use: Track/track (track #), Title/title, Artist/artist, Album/album and Year/year
Miscellaneous:
diff --git a/headphones/__init__.py b/headphones/__init__.py
index 4ea984ea..eb14463f 100644
--- a/headphones/__init__.py
+++ b/headphones/__init__.py
@@ -36,6 +36,7 @@ DATA_DIR = None
CONFIG_FILE = None
CFG = None
+CONFIG_VERSION = None
DB_FILE = None
@@ -203,7 +204,7 @@ def initialize():
with INIT_LOCK:
- global __INITIALIZED__, FULL_PATH, PROG_DIR, VERBOSE, DAEMON, DATA_DIR, CONFIG_FILE, CFG, LOG_DIR, CACHE_DIR, \
+ global __INITIALIZED__, FULL_PATH, PROG_DIR, VERBOSE, DAEMON, DATA_DIR, CONFIG_FILE, CFG, CONFIG_VERSION, LOG_DIR, CACHE_DIR, \
HTTP_PORT, HTTP_HOST, HTTP_USERNAME, HTTP_PASSWORD, HTTP_ROOT, LAUNCH_BROWSER, API_ENABLED, API_KEY, GIT_PATH, \
CURRENT_VERSION, LATEST_VERSION, MUSIC_DIR, DESTINATION_DIR, PREFERRED_QUALITY, PREFERRED_BITRATE, DETECT_BITRATE, \
ADD_ARTISTS, CORRECT_METADATA, MOVE_FILES, RENAME_FILES, FOLDER_FORMAT, FILE_FORMAT, CLEANUP_FILES, INCLUDE_EXTRAS, \
@@ -230,6 +231,8 @@ def initialize():
CheckSection('XBMC')
# Set global variables based on config file or use defaults
+ CONFIG_VERSION = check_setting_str(CFG, 'General', 'config_version', '0')
+
try:
HTTP_PORT = check_setting_int(CFG, 'General', 'http_port', 8181)
except:
@@ -257,8 +260,8 @@ def initialize():
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))
- FOLDER_FORMAT = check_setting_str(CFG, 'General', 'folder_format', 'artist/album [year]')
- FILE_FORMAT = check_setting_str(CFG, 'General', 'file_format', 'tracknumber artist - album [year]- title')
+ FOLDER_FORMAT = check_setting_str(CFG, 'General', 'folder_format', 'Artist/Album [Year]')
+ FILE_FORMAT = check_setting_str(CFG, 'General', 'file_format', 'Track Artist - Album [Year]- Title')
CLEANUP_FILES = bool(check_setting_int(CFG, 'General', 'cleanup_files', 0))
ADD_ALBUM_ART = bool(check_setting_int(CFG, 'General', 'add_album_art', 0))
EMBED_ALBUM_ART = bool(check_setting_int(CFG, 'General', 'embed_album_art', 0))
@@ -338,6 +341,16 @@ def initialize():
HPUSER = check_setting_str(CFG, 'General', 'hpuser', 'username')
HPPASS = check_setting_str(CFG, 'General', 'hppass', 'password')
+ # update folder formats in the config & bump up config version
+ if CONFIG_VERSION == '0':
+ from headphones.helpers import replace_all
+ file_values = { 'tracknumber': 'Track', 'title': 'Title','artist' : 'Artist', 'album' : 'Album', 'year' : 'Year' }
+ folder_values = { 'artist' : 'Artist', 'album':'Album', 'year' : 'Year', 'releasetype' : 'Type', 'first' : 'First', 'lowerfirst' : 'first' }
+ FILE_FORMAT = replace_all(FILE_FORMAT, file_values)
+ FOLDER_FORMAT = replace_all(FOLDER_FORMAT, folder_values)
+
+ CONFIG_VERSION = '1'
+
if not LOG_DIR:
LOG_DIR = os.path.join(DATA_DIR, 'logs')
@@ -351,12 +364,6 @@ def initialize():
# Start the logger, silence console logging if we need to
logger.headphones_log.initLogger(verbose=VERBOSE)
- # Update some old config code:
- if FOLDER_FORMAT == '%artist/%album/%track':
- FOLDER_FORMAT = 'artist/album [year]'
- if FILE_FORMAT == '%tracknumber %artist - %album - %title':
- FILE_FORMAT = 'tracknumber artist - album - title'
-
# Put the cache dir in the data dir for now
CACHE_DIR = os.path.join(DATA_DIR, 'cache')
if not os.path.exists(CACHE_DIR):
@@ -450,6 +457,7 @@ def config_write():
new_config.filename = CONFIG_FILE
new_config['General'] = {}
+ new_config['General']['config_version'] = CONFIG_VERSION
new_config['General']['http_port'] = HTTP_PORT
new_config['General']['http_host'] = HTTP_HOST
new_config['General']['http_username'] = HTTP_USERNAME
diff --git a/headphones/postprocessor.py b/headphones/postprocessor.py
index ed484e32..3246bee9 100644
--- a/headphones/postprocessor.py
+++ b/headphones/postprocessor.py
@@ -323,16 +323,18 @@ def moveFiles(albumpath, release, tracks):
firstchar = '0-9'
else:
firstchar = sortname[0]
-
- lowerfirst = firstchar.lower()
- values = { 'artist': artist,
- 'album': album,
+ values = { 'Artist': artist,
+ 'Album': album,
+ 'Year': year,
+ 'Type': releasetype,
+ 'First': firstchar,
+ 'artist': artist.lower(),
+ 'album': album.lower(),
'year': year,
- 'first': firstchar,
- 'lowerfirst': lowerfirst,
- 'releasetype': releasetype
+ 'type': releasetype.lower(),
+ 'first': firstchar.lower()
}
@@ -344,7 +346,10 @@ def moveFiles(albumpath, release, tracks):
destination_path = os.path.normpath(os.path.join(headphones.DESTINATION_DIR, folder)).encode(headphones.SYS_ENCODING)
- if os.path.exists(destination_path) and 'album' in headphones.FOLDER_FORMAT:
+ last_folder = headphones.FOLDER_FORMAT.split('/')[-1]
+
+ # Only rename the folder if they use the album name, otherwise merge into existing folder
+ if os.path.exists(destination_path) and 'album' in last_folder.lower():
i = 1
while True:
newfolder = folder + '[%i]' % i
@@ -357,15 +362,34 @@ def moveFiles(albumpath, release, tracks):
logger.info('Moving files from %s to %s' % (unicode(albumpath, headphones.SYS_ENCODING, errors="replace"), unicode(destination_path, headphones.SYS_ENCODING, errors="replace")))
- try:
- os.makedirs(destination_path)
-
- except Exception, e:
- logger.error('Could not create folder for %s. Not moving: %s' % (release['AlbumTitle'], e))
- return albumpath
-
+ # Basically check if generic/non-album folders already exist, since we're going to merge
+ if not os.path.exists(destination_path):
+ try:
+ os.makedirs(destination_path)
+ except Exception, e:
+ logger.error('Could not create folder for %s. Not moving: %s' % (release['AlbumTitle'], e))
+ return albumpath
+
+ # Move files to the destination folder, renaming them if they already exist
for r,d,f in os.walk(albumpath):
for files in f:
+ if os.path.isfile(os.path.join(destination_path, files)):
+ logger.info('Destination file exists: %s' % os.path.join(destination_path, files))
+ title = os.path.splitext(files)[0]
+ ext = os.path.splitext(files)[1]
+ i = 1
+ while True:
+ newfile = title + '(' + str(i) + ')' + ext
+ if os.path.isfile(os.path.join(destination_path, newfile)):
+ i += 1
+ else:
+ logger.info('Renaming to %s' % newfile)
+ try:
+ os.rename(os.path.join(r, files), os.path.join(r, newfile))
+ files = newfile
+ except Exception, e:
+ logger.warn('Error renaming %s: %s' % (files, e))
+ break
try:
shutil.move(os.path.join(r, files), destination_path)
except shutil.Error, e:
@@ -379,6 +403,7 @@ def moveFiles(albumpath, release, tracks):
temp_f = os.path.join(temp_f, f)
os.chmod(os.path.normpath(temp_f).encode(headphones.SYS_ENCODING), int(headphones.FOLDER_PERMISSIONS, 8))
+ # If we failed to move all the files out of the directory, this will fail too
try:
shutil.rmtree(albumpath)
except Exception, e:
@@ -475,10 +500,15 @@ def renameFiles(albumpath, downloaded_track_list, release):
else:
title = f.title
- values = { 'tracknumber': tracknumber,
- 'title': title,
- 'artist': release['ArtistName'],
- 'album': release['AlbumTitle'],
+ values = { 'Track': tracknumber,
+ 'Title': title,
+ 'Artist': release['ArtistName'],
+ 'Album': release['AlbumTitle'],
+ 'Year': year,
+ 'track': tracknumber,
+ 'title': title.lower(),
+ 'artist': release['ArtistName'].lower(),
+ 'album': release['AlbumTitle'].lower(),
'year': year
}