Beispiel #1
0
def verifyresult(title, artistterm, term):
    
    title = re.sub('[\.\-\/\_]', ' ', title)
    
    #if artistterm != 'Various Artists':
    #    
    #    if not re.search('^' + re.escape(artistterm), title, re.IGNORECASE):
    #        #logger.info("Removed from results: " + title + " (artist not at string start).")
    #        #return False
    #    elif re.search(re.escape(artistterm) + '\w', title, re.IGNORECASE | re.UNICODE):
    #        logger.info("Removed from results: " + title + " (post substring result).")
    #        return False
    #    elif re.search('\w' + re.escape(artistterm), title, re.IGNORECASE | re.UNICODE):
    #        logger.info("Removed from results: " + title + " (pre substring result).")
    #        return False

    #another attempt to weed out substrings. We don't want "Vol III" when we were looking for "Vol II"
    
    tokens = re.split('\W', term, re.IGNORECASE | re.UNICODE)
    for token in tokens:

        if not token:
            continue
        if token == 'Various' or token == 'Artists' or token == 'VA':
            continue
        if not re.search('(?:\W|^)+' + token + '(?:\W|$)+', title, re.IGNORECASE | re.UNICODE):
            cleantoken = ''.join(c for c in token if c not in string.punctuation)
            if not not re.search('(?:\W|^)+' + cleantoken + '(?:\W|$)+', title, re.IGNORECASE | re.UNICODE):
                dic = {'!':'i', '$':'s'}
                dumbtoken = helpers.replace_all(token, dic)
                if not not re.search('(?:\W|^)+' + dumbtoken + '(?:\W|$)+', title, re.IGNORECASE | re.UNICODE):
                    logger.info("Removed from results: " + title + " (missing tokens: " + token + " and " + cleantoken + ")")
                    return False
                    
    return True
def moveFiles(albumpath, release, tracks):

	try:
		year = release['ReleaseDate'][:4]
	except TypeError:
		year = ''
		
	artist = release['ArtistName'].replace('/', '_')
	album = release['AlbumTitle'].replace('/', '_')
	releasetype = release['Type'].replace('/', '_')

	if release['ArtistName'].startswith('The '):
		sortname = release['ArtistName'][4:]
	else:
		sortname = release['ArtistName']
	
	if sortname.isdigit():
		firstchar = '0-9'
	else:
		firstchar = sortname[0]
		
	lowerfirst = firstchar.lower()
	

	values = {	'artist':	artist,
				'album':	album,
				'year':		year,
				'first':	firstchar,
				'lowerfirst':	lowerfirst,
                                'releasetype':  releasetype
			}
			
	
	folder = helpers.replace_all(headphones.FOLDER_FORMAT, values)
	folder = folder.replace('./', '_/').replace(':','_').replace('?','_')
	
	if folder.endswith('.'):
		folder = folder.replace(folder[len(folder)-1], '_')
	
	destination_path = os.path.normpath(os.path.join(headphones.DESTINATION_DIR, folder)).encode(headphones.SYS_ENCODING)
	
	if os.path.exists(destination_path):
		i = 1
		while True:
			newfolder = folder + '[%i]' % i
			destination_path = os.path.normpath(os.path.join(headphones.DESTINATION_DIR, newfolder)).encode(headphones.SYS_ENCODING)
			if os.path.exists(destination_path):
				i += 1
			else:
				folder = newfolder
				break

	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
Beispiel #3
0
def addAlbumArt(artwork, albumpath, release):
    logger.info('Adding album art to folder')
    
    try:
        year = release['ReleaseDate'][:4]
    except TypeError:
        year = ''
    
    values = {  '$Artist':      release['ArtistName'],
                '$Album':       release['AlbumTitle'],
                '$Year':        year,
                '$artist':      release['ArtistName'].lower(),
                '$album':       release['AlbumTitle'].lower(),
                '$year':        year
                }
    
    album_art_name = helpers.replace_all(headphones.ALBUM_ART_FORMAT.strip(), values) + ".jpg"

    album_art_name = helpers.replace_illegal_chars(album_art_name).encode(headphones.SYS_ENCODING, 'replace')

    if headphones.FILE_UNDERSCORES:
        album_art_name = album_art_name.replace(' ', '_')

    if album_art_name.startswith('.'):
        album_art_name = album_art_name.replace(0, '_')

    try:
        file = open(os.path.join(albumpath, album_art_name), 'wb')
        file.write(artwork)
        file.close()
    except Exception, e:
        logger.error('Error saving album art: %s' % str(e))
        return
Beispiel #4
0
def addAlbumArt(artwork, albumpath, release):
    logger.info('Adding album art to folder')

    try:
        year = release['ReleaseDate'][:4]
    except TypeError:
        year = ''

    values = {
        '$Artist': release['ArtistName'],
        '$Album': release['AlbumTitle'],
        '$Year': year,
        '$artist': release['ArtistName'].lower(),
        '$album': release['AlbumTitle'].lower(),
        '$year': year
    }

    album_art_name = helpers.replace_all(headphones.ALBUM_ART_FORMAT.strip(),
                                         values).replace('/', '_') + ".jpg"

    album_art_name = album_art_name.replace('?', '_').replace(':', '_').encode(
        headphones.SYS_ENCODING, 'replace')

    if album_art_name.startswith('.'):
        album_art_name = album_art_name.replace(0, '_')

    prev = os.umask(headphones.UMASK)
    file = open(os.path.join(albumpath, album_art_name), 'wb')
    file.write(artwork)
    file.close()
    os.umask(prev)
Beispiel #5
0
def verifyresult(title, artistterm, term):
	
	title = re.sub('[\.\-\/\_]', ' ', title)
	
    #if artistterm != 'Various Artists':
    #    
    #    if not re.search('^' + re.escape(artistterm), title, re.IGNORECASE):
    #        #logger.info("Removed from results: " + title + " (artist not at string start).")
    #        #return False
    #    elif re.search(re.escape(artistterm) + '\w', title, re.IGNORECASE | re.UNICODE):
    #        logger.info("Removed from results: " + title + " (post substring result).")
    #        return False
    #    elif re.search('\w' + re.escape(artistterm), title, re.IGNORECASE | re.UNICODE):
    #        logger.info("Removed from results: " + title + " (pre substring result).")
    #        return False

    #another attempt to weed out substrings. We don't want "Vol III" when we were looking for "Vol II"
    
	tokens = re.split('\W', term, re.IGNORECASE | re.UNICODE)
	for token in tokens:

		if not token:
			continue
		if token == 'Various' or token == 'Artists' or token == 'VA':
			continue
		if not re.search('(?:\W|^)+' + token + '(?:\W|$)+', title, re.IGNORECASE | re.UNICODE):
			cleantoken = ''.join(c for c in token if c not in string.punctuation)
			if not not re.search('(?:\W|^)+' + cleantoken + '(?:\W|$)+', title, re.IGNORECASE | re.UNICODE):
				dic = {'!':'i', '$':'s'}
				dumbtoken = helpers.replace_all(token, dic)
				if not not re.search('(?:\W|^)+' + dumbtoken + '(?:\W|$)+', title, re.IGNORECASE | re.UNICODE):
					logger.info("Removed from results: " + title + " (missing tokens: " + token + " and " + cleantoken + ")")
					return False
					
	return True
Beispiel #6
0
def addAlbumArt(artwork, albumpath, release):
    logger.info('Adding album art to folder')
    
    try:
        year = release['ReleaseDate'][:4]
    except TypeError:
        year = ''
    
    values = {  '$Artist':      release['ArtistName'],
                '$Album':       release['AlbumTitle'],
                '$Year':        year,
                '$artist':      release['ArtistName'].lower(),
                '$album':       release['AlbumTitle'].lower(),
                '$year':        year
                }
    
    album_art_name = helpers.replace_all(headphones.ALBUM_ART_FORMAT.strip(), values).replace('/','_') + ".jpg"

    album_art_name = album_art_name.replace('?','_').replace(':', '_').encode(headphones.SYS_ENCODING, 'replace')

    if headphones.FILE_UNDERSCORES:
        album_art_name = album_art_name.replace(' ', '_')

    if album_art_name.startswith('.'):
        album_art_name = album_art_name.replace(0, '_')

    prev = os.umask(headphones.UMASK)
    file = open(os.path.join(albumpath, album_art_name), 'wb')
    file.write(artwork)
    file.close()
    os.umask(prev)
Beispiel #7
0
def update(artist_name,release_groups):
    """ Pretty simple and crude function to find the artist page on metacritic,
    then parse that page to get critic & user scores for albums"""

    # First let's modify the artist name to fit the metacritic convention. 
    # We could just do a search, then take the top result, but at least this will
    # cut down on api calls. If it's ineffective then we'll switch to search

    replacements = {" & " : " ", "." : ""}
    mc_artist_name = helpers.replace_all(artist_name.lower(),replacements)

    mc_artist_name = mc_artist_name.replace(" ","-")

    url = "http://www.metacritic.com/person/" + mc_artist_name + "?filter-options=music&sort_options=date&num_items=100"

    res = request.request_soup(url, parser='html.parser')

    try:
        rows = res.tbody.find_all('tr')
    except:
        logger.info("Unable to get metacritic scores for: %s" % artist_name)
        return

    myDB = db.DBConnection()

    for row in rows:
        title = row.a.string
        for rg in release_groups:
            if rg['title'].lower() == title.lower():
                scores = row.find_all("span")
                critic_score = scores[0].string
                user_score = scores[1].string
                controlValueDict = {"AlbumID": rg['id']}
                newValueDict = {'CriticScore':critic_score,'UserScore':user_score}
                myDB.upsert("albums", newValueDict, controlValueDict)
Beispiel #8
0
def renameFiles(albumpath, downloaded_track_list, release):
    logger.info('Renaming files')
    try:
        year = release['ReleaseDate'][:4]
    except TypeError:
        year = ''
    # Until tagging works better I'm going to rely on the already provided metadata

    for downloaded_track in downloaded_track_list:
        try:
            f = MediaFile(downloaded_track)
        except:
            logger.info("MediaFile couldn't parse: " + downloaded_track)
            continue

        if not f.track:
            tracknumber = ''
        else:
            tracknumber = '%02d' % f.track

        if not f.title:

            basename = unicode(os.path.basename(downloaded_track),
                               headphones.SYS_ENCODING,
                               errors='replace')
            title = os.path.splitext(basename)[0]
            ext = os.path.splitext(basename)[1]

            new_file_name = helpers.cleanTitle(title) + ext

        else:
            title = f.title

            values = {
                'tracknumber': tracknumber,
                'title': title,
                'artist': release['ArtistName'],
                'album': release['AlbumTitle'],
                'year': year
            }

            ext = os.path.splitext(downloaded_track)[1]

            new_file_name = helpers.replace_all(headphones.FILE_FORMAT,
                                                values).replace('/', '_') + ext

        new_file_name = new_file_name.replace('?', '_').replace(
            ':', '_').encode(headphones.SYS_ENCODING)

        new_file = os.path.join(albumpath, new_file_name)

        logger.debug('Renaming %s ---> %s' % (downloaded_track, new_file_name))
        try:
            os.rename(downloaded_track, new_file)
        except Exception, e:
            logger.error('Error renaming file: %s. Error: %s' %
                         (downloaded_track, e))
            continue
Beispiel #9
0
def renameFiles(albumpath, downloaded_track_list, release):
	logger.info('Renaming files')
	try:
		year = release['ReleaseDate'][:4]
	except TypeError:
		year = ''
	# Until tagging works better I'm going to rely on the already provided metadata

	for downloaded_track in downloaded_track_list:
		try:
			f = MediaFile(downloaded_track)
		except:
			logger.info("MediaFile couldn't parse: " + downloaded_track)
			continue
			
		if not f.track:
			tracknumber = ''
		else:
			tracknumber = '%02d' % f.track
		
		if not f.title:
			
			basename = unicode(os.path.basename(downloaded_track), headphones.SYS_ENCODING, errors='replace')
			title = os.path.splitext(basename)[0]
			ext = os.path.splitext(basename)[1]
			
			new_file_name = helpers.cleanTitle(title) + ext
			
		else:
			title = f.title
			
			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
						}
						
			ext = os.path.splitext(downloaded_track)[1]
			
			new_file_name = helpers.replace_all(headphones.FILE_FORMAT, values).replace('/','_') + ext
		
		
		new_file_name = new_file_name.replace('?','_').replace(':', '_').encode(headphones.SYS_ENCODING)

		new_file = os.path.join(albumpath, new_file_name)

		logger.debug('Renaming %s ---> %s' % (downloaded_track, new_file_name))
		try:
			os.rename(downloaded_track, new_file)
		except Exception, e:
			logger.error('Error renaming file: %s. Error: %s' % (downloaded_track, e))
			continue
Beispiel #10
0
def renameFiles(albumpath, downloaded_track_list, release):
    logger.info("Renaming files")
    try:
        year = release["ReleaseDate"][:4]
    except TypeError:
        year = ""
        # Until tagging works better I'm going to rely on the already provided metadata

    for downloaded_track in downloaded_track_list:
        try:
            f = MediaFile(downloaded_track)
        except:
            logger.info("MediaFile couldn't parse: " + downloaded_track)
            continue

        if not f.track:
            tracknumber = ""
        else:
            tracknumber = "%02d" % f.track

        if not f.title:

            basename = unicode(os.path.basename(downloaded_track), headphones.SYS_ENCODING, errors="replace")
            title = os.path.splitext(basename)[0]
            ext = os.path.splitext(basename)[1]

            new_file_name = helpers.cleanTitle(title) + ext

        else:
            title = f.title

            values = {
                "tracknumber": tracknumber,
                "title": title,
                "artist": release["ArtistName"],
                "album": release["AlbumTitle"],
                "year": year,
            }

            ext = os.path.splitext(downloaded_track)[1]

            new_file_name = helpers.replace_all(headphones.FILE_FORMAT, values).replace("/", "_") + ext

        new_file_name = new_file_name.replace("?", "_").replace(":", "_").encode(headphones.SYS_ENCODING)

        new_file = os.path.join(albumpath, new_file_name)

        logger.debug("Renaming %s ---> %s" % (downloaded_track, new_file_name))
        try:
            os.rename(downloaded_track, new_file)
        except Exception, e:
            logger.error("Error renaming file: %s. Error: %s" % (downloaded_track, e))
            continue
Beispiel #11
0
def moveFiles(albumpath, release, tracks):

    try:
        year = release["ReleaseDate"][:4]
    except TypeError:
        year = ""

    values = {"artist": release["ArtistName"], "album": release["AlbumTitle"], "year": year}

    folder = helpers.replace_all(headphones.FOLDER_FORMAT, values)

    destination_path = os.path.join(headphones.DESTINATION_DIR, folder)
    destination_path = destination_path.replace("?", "_")

    if os.path.exists(destination_path):
        i = 1
        while True:
            new_folder_name = destination_path + "[%i]" % i
            if os.path.exists(new_folder_name):
                i += 1
            else:
                destination_path = new_folder_name
                break

    logger.info("Moving files from %s to %s" % (folder, destination_path))

    try:
        os.makedirs(destination_path)

        # Chmod the directories using the folder_format (script courtesy of premiso!)
        folder_list = folder.split("/")
        temp_f = os.path.join(headphones.DESTINATION_DIR)
        for f in folder_list:
            temp_f = os.path.join(temp_f, f)
            os.chmod(temp_f, 0755)

    except Exception, e:
        logger.error("Could not create folder for %s. Not moving" % release["AlbumName"])
        return albumpath
    def test_album_metadata_with_None(self):
        """metadata: check handling of None metadata values"""
        row = _MockDatabaseRow({
            'ArtistName': 'artist',
            'AlbumTitle': 'Album',
            'Type': None,
            'ReleaseDate': None,
        })
        mb = _md.AlbumMetadataBuilder()
        f1 = _MockMediaFile('artist', None, None, None, None, None)
        mb.add_media_file(f1)
        f2 = _MockMediaFile('artist', None, None, 2, 'track2', None)
        mb.add_media_file(f2)
        md = _md.album_metadata("/music/Artist - Album [2002]", row, mb.build())

        # tests don't undergo normal Headphones init, SYS_ENCODING is not set
        if not _h.SYS_ENCODING:
            _h.SYS_ENCODING = 'UTF-8'

        res = _hp.replace_all(
            "/music/$First/$Artist/$Artist - $Album{ [$Year]}", md, True)

        self.assertEqual(res, u"/music/A/artist/artist - Album",
                         "check correct rendering of None via replace_all()")
Beispiel #13
0
def initialize():

    with INIT_LOCK:

        global __INITIALIZED__, FULL_PATH, PROG_DIR, VERBOSE, DAEMON, SYS_PLATFORM, DATA_DIR, CONFIG_FILE, CFG, CONFIG_VERSION, LOG_DIR, CACHE_DIR, \
                HTTP_PORT, HTTP_HOST, HTTP_USERNAME, HTTP_PASSWORD, HTTP_ROOT, HTTP_PROXY, LAUNCH_BROWSER, API_ENABLED, API_KEY, GIT_PATH, GIT_USER, GIT_BRANCH, \
                CURRENT_VERSION, LATEST_VERSION, CHECK_GITHUB, CHECK_GITHUB_ON_STARTUP, CHECK_GITHUB_INTERVAL, MUSIC_DIR, DESTINATION_DIR, \
                LOSSLESS_DESTINATION_DIR, PREFERRED_QUALITY, PREFERRED_BITRATE, DETECT_BITRATE, ADD_ARTISTS, CORRECT_METADATA, MOVE_FILES, \
                RENAME_FILES, FOLDER_FORMAT, FILE_FORMAT, FILE_UNDERSCORES, CLEANUP_FILES, INCLUDE_EXTRAS, EXTRAS, AUTOWANT_UPCOMING, AUTOWANT_ALL, KEEP_TORRENT_FILES, \
                ADD_ALBUM_ART, ALBUM_ART_FORMAT, EMBED_ALBUM_ART, EMBED_LYRICS, DOWNLOAD_DIR, BLACKHOLE, BLACKHOLE_DIR, USENET_RETENTION, SEARCH_INTERVAL, \
                TORRENTBLACKHOLE_DIR, NUMBEROFSEEDERS, ISOHUNT, KAT, PIRATEBAY, PIRATEBAY_PROXY_URL, MININOVA, WAFFLES, WAFFLES_UID, WAFFLES_PASSKEY, \
                RUTRACKER, RUTRACKER_USER, RUTRACKER_PASSWORD, WHATCD, WHATCD_USERNAME, WHATCD_PASSWORD, DOWNLOAD_TORRENT_DIR, \
                LIBRARYSCAN, LIBRARYSCAN_INTERVAL, DOWNLOAD_SCAN_INTERVAL, SAB_HOST, SAB_USERNAME, SAB_PASSWORD, SAB_APIKEY, SAB_CATEGORY, \
                NZBGET_USERNAME, NZBGET_PASSWORD, NZBGET_CATEGORY, NZBGET_HOST, HEADPHONES_INDEXER, NZBMATRIX, TRANSMISSION_HOST, TRANSMISSION_USERNAME, TRANSMISSION_PASSWORD, \
                UTORRENT_HOST, UTORRENT_USERNAME, UTORRENT_PASSWORD, NEWZNAB, NEWZNAB_HOST, NEWZNAB_APIKEY, NEWZNAB_ENABLED, EXTRA_NEWZNABS, \
                NZBSORG, NZBSORG_UID, NZBSORG_HASH, NZBSRUS, NZBSRUS_UID, NZBSRUS_APIKEY, OMGWTFNZBS, OMGWTFNZBS_UID, OMGWTFNZBS_APIKEY, \
		NZB_DOWNLOADER, TORRENT_DOWNLOADER, PREFERRED_WORDS, REQUIRED_WORDS, IGNORED_WORDS, LASTFM_USERNAME, \
                INTERFACE, FOLDER_PERMISSIONS, FILE_PERMISSIONS, ENCODERFOLDER, ENCODER_PATH, ENCODER, XLDPROFILE, BITRATE, SAMPLINGFREQUENCY, \
                MUSIC_ENCODER, ADVANCEDENCODER, ENCODEROUTPUTFORMAT, ENCODERQUALITY, ENCODERVBRCBR, ENCODERLOSSLESS, DELETE_LOSSLESS_FILES, \
                PROWL_ENABLED, PROWL_PRIORITY, PROWL_KEYS, PROWL_ONSNATCH, PUSHOVER_ENABLED, PUSHOVER_PRIORITY, PUSHOVER_KEYS, PUSHOVER_ONSNATCH, MIRRORLIST, \
                MIRROR, CUSTOMHOST, CUSTOMPORT, CUSTOMSLEEP, HPUSER, HPPASS, XBMC_ENABLED, XBMC_HOST, XBMC_USERNAME, XBMC_PASSWORD, XBMC_UPDATE, \
                XBMC_NOTIFY, NMA_ENABLED, NMA_APIKEY, NMA_PRIORITY, NMA_ONSNATCH, SYNOINDEX_ENABLED, ALBUM_COMPLETION_PCT, PREFERRED_BITRATE_HIGH_BUFFER, \
                PREFERRED_BITRATE_LOW_BUFFER, PREFERRED_BITRATE_ALLOW_LOSSLESS, CACHE_SIZEMB, JOURNAL_MODE, UMASK, ENABLE_HTTPS, HTTPS_CERT, HTTPS_KEY

        if __INITIALIZED__:
            return False

        # Make sure all the config sections exist
        CheckSection('General')
        CheckSection('SABnzbd')
        CheckSection('NZBget')
        CheckSection('Transmission')
        CheckSection('uTorrent')
        CheckSection('Headphones')
        CheckSection('Newznab')
        CheckSection('NZBsorg')
        CheckSection('NZBsRus')
        CheckSection('omgwtfnzbs')
        CheckSection('Waffles')
        CheckSection('Rutracker')
        CheckSection('What.cd')
        CheckSection('Prowl')
        CheckSection('Pushover')
        CheckSection('XBMC')
        CheckSection('NMA')
        CheckSection('Synoindex')
        CheckSection('Advanced')

        # 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:
            HTTP_PORT = 8181

        if HTTP_PORT < 21 or HTTP_PORT > 65535:
            HTTP_PORT = 8181

        HTTP_HOST = check_setting_str(CFG, 'General', 'http_host', '0.0.0.0')
        HTTP_USERNAME = check_setting_str(CFG, 'General', 'http_username', '')
        HTTP_PASSWORD = check_setting_str(CFG, 'General', 'http_password', '')
        HTTP_ROOT = check_setting_str(CFG, 'General', 'http_root', '/')
        HTTP_PROXY = bool(check_setting_int(CFG, 'General', 'http_proxy', 0))
        ENABLE_HTTPS = bool(check_setting_int(CFG, 'General', 'enable_https', 0))
        HTTPS_CERT = check_setting_str(CFG, 'General', 'https_cert', os.path.join(DATA_DIR, 'server.crt'))
        HTTPS_KEY = check_setting_str(CFG, 'General', 'https_key', os.path.join(DATA_DIR, 'server.key'))
        LAUNCH_BROWSER = bool(check_setting_int(CFG, 'General', 'launch_browser', 1))
        API_ENABLED = bool(check_setting_int(CFG, 'General', 'api_enabled', 0))
        API_KEY = check_setting_str(CFG, 'General', 'api_key', '')
        GIT_PATH = check_setting_str(CFG, 'General', 'git_path', '')
        GIT_USER = check_setting_str(CFG, 'General', 'git_user', 'rembo10')
        GIT_BRANCH = check_setting_str(CFG, 'General', 'git_branch', 'master')
        LOG_DIR = check_setting_str(CFG, 'General', 'log_dir', '')
        CACHE_DIR = check_setting_str(CFG, 'General', 'cache_dir', '')

        CHECK_GITHUB = bool(check_setting_int(CFG, 'General', 'check_github', 1))
        CHECK_GITHUB_ON_STARTUP = bool(check_setting_int(CFG, 'General', 'check_github_on_startup', 1))
        CHECK_GITHUB_INTERVAL = check_setting_int(CFG, 'General', 'check_github_interval', 360)

        MUSIC_DIR = check_setting_str(CFG, 'General', 'music_dir', '')
        DESTINATION_DIR = check_setting_str(CFG, 'General', 'destination_dir', '')
        LOSSLESS_DESTINATION_DIR = check_setting_str(CFG, 'General', 'lossless_destination_dir', '')
        PREFERRED_QUALITY = check_setting_int(CFG, 'General', 'preferred_quality', 0)
        PREFERRED_BITRATE = check_setting_str(CFG, 'General', 'preferred_bitrate', '')
        PREFERRED_BITRATE_HIGH_BUFFER = check_setting_int(CFG, 'General', 'preferred_bitrate_high_buffer', '')
        PREFERRED_BITRATE_LOW_BUFFER = check_setting_int(CFG, 'General', 'preferred_bitrate_low_buffer', '')
        PREFERRED_BITRATE_ALLOW_LOSSLESS = bool(check_setting_int(CFG, 'General', 'preferred_bitrate_allow_lossless', 0))
        DETECT_BITRATE = bool(check_setting_int(CFG, 'General', 'detect_bitrate', 0))
        ADD_ARTISTS = bool(check_setting_int(CFG, 'General', 'auto_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))
        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')
        FILE_UNDERSCORES = bool(check_setting_int(CFG, 'General', 'file_underscores', 0))
        CLEANUP_FILES = bool(check_setting_int(CFG, 'General', 'cleanup_files', 0))
        ADD_ALBUM_ART = bool(check_setting_int(CFG, 'General', 'add_album_art', 0))
        ALBUM_ART_FORMAT = check_setting_str(CFG, 'General', 'album_art_format', 'folder')
        EMBED_ALBUM_ART = bool(check_setting_int(CFG, 'General', 'embed_album_art', 0))
        EMBED_LYRICS = bool(check_setting_int(CFG, 'General', 'embed_lyrics', 0))
        NZB_DOWNLOADER = check_setting_int(CFG, 'General', 'nzb_downloader', 0)
        TORRENT_DOWNLOADER = check_setting_int(CFG, 'General', 'torrent_downloader', 0)
        DOWNLOAD_DIR = check_setting_str(CFG, 'General', 'download_dir', '')
        BLACKHOLE = bool(check_setting_int(CFG, 'General', 'blackhole', 0))
        BLACKHOLE_DIR = check_setting_str(CFG, 'General', 'blackhole_dir', '')
        USENET_RETENTION = check_setting_int(CFG, 'General', 'usenet_retention', '1500')
        INCLUDE_EXTRAS = bool(check_setting_int(CFG, 'General', 'include_extras', 0))
        EXTRAS = check_setting_str(CFG, 'General', 'extras', '')
        AUTOWANT_UPCOMING = bool(check_setting_int(CFG, 'General', 'autowant_upcoming', 1))
        AUTOWANT_ALL = bool(check_setting_int(CFG, 'General', 'autowant_all', 0))
        KEEP_TORRENT_FILES = bool(check_setting_int(CFG, 'General', 'keep_torrent_files', 0))

        SEARCH_INTERVAL = check_setting_int(CFG, 'General', 'search_interval', 1440)
        LIBRARYSCAN = bool(check_setting_int(CFG, 'General', 'libraryscan', 1))
        LIBRARYSCAN_INTERVAL = check_setting_int(CFG, 'General', 'libraryscan_interval', 300)
        DOWNLOAD_SCAN_INTERVAL = check_setting_int(CFG, 'General', 'download_scan_interval', 5)

        TORRENTBLACKHOLE_DIR = check_setting_str(CFG, 'General', 'torrentblackhole_dir', '')
        NUMBEROFSEEDERS = check_setting_str(CFG, 'General', 'numberofseeders', '10')
        ISOHUNT = bool(check_setting_int(CFG, 'General', 'isohunt', 0))
        KAT = bool(check_setting_int(CFG, 'General', 'kat', 0))
        PIRATEBAY = bool(check_setting_int(CFG, 'General', 'piratebay', 0))
        PIRATEBAY_PROXY_URL = check_setting_str(CFG, 'General', 'piratebay_proxy_url', '')
        MININOVA = bool(check_setting_int(CFG, 'General', 'mininova', 0))
        DOWNLOAD_TORRENT_DIR = check_setting_str(CFG, 'General', 'download_torrent_dir', '')

        WAFFLES = bool(check_setting_int(CFG, 'Waffles', 'waffles', 0))
        WAFFLES_UID = check_setting_str(CFG, 'Waffles', 'waffles_uid', '')
        WAFFLES_PASSKEY = check_setting_str(CFG, 'Waffles', 'waffles_passkey', '')

        RUTRACKER = bool(check_setting_int(CFG, 'Rutracker', 'rutracker', 0))
        RUTRACKER_USER = check_setting_str(CFG, 'Rutracker', 'rutracker_user', '')
        RUTRACKER_PASSWORD = check_setting_str(CFG, 'Rutracker', 'rutracker_password', '')

        WHATCD = bool(check_setting_int(CFG, 'What.cd', 'whatcd', 0))
        WHATCD_USERNAME = check_setting_str(CFG, 'What.cd', 'whatcd_username', '')
        WHATCD_PASSWORD = check_setting_str(CFG, 'What.cd', 'whatcd_password', '')

        SAB_HOST = check_setting_str(CFG, 'SABnzbd', 'sab_host', '')
        SAB_USERNAME = check_setting_str(CFG, 'SABnzbd', 'sab_username', '')
        SAB_PASSWORD = check_setting_str(CFG, 'SABnzbd', 'sab_password', '')
        SAB_APIKEY = check_setting_str(CFG, 'SABnzbd', 'sab_apikey', '')
        SAB_CATEGORY = check_setting_str(CFG, 'SABnzbd', 'sab_category', '')

        NZBGET_USERNAME = check_setting_str(CFG, 'NZBget', 'nzbget_username', 'nzbget')
        NZBGET_PASSWORD = check_setting_str(CFG, 'NZBget', 'nzbget_password', '')
        NZBGET_CATEGORY = check_setting_str(CFG, 'NZBget', 'nzbget_category', '')
        NZBGET_HOST = check_setting_str(CFG, 'NZBget', 'nzbget_host', '')

        HEADPHONES_INDEXER = bool(check_setting_int(CFG, 'Headphones', 'headphones_indexer', 0))
        
        TRANSMISSION_HOST = check_setting_str(CFG, 'Transmission', 'transmission_host', '')
        TRANSMISSION_USERNAME = check_setting_str(CFG, 'Transmission', 'transmission_username', '')
        TRANSMISSION_PASSWORD = check_setting_str(CFG, 'Transmission', 'transmission_password', '')
        
        UTORRENT_HOST = check_setting_str(CFG, 'uTorrent', 'utorrent_host', '')
        UTORRENT_USERNAME = check_setting_str(CFG, 'uTorrent', 'utorrent_username', '')
        UTORRENT_PASSWORD = check_setting_str(CFG, 'uTorrent', 'utorrent_password', '')

        NEWZNAB = bool(check_setting_int(CFG, 'Newznab', 'newznab', 0))
        NEWZNAB_HOST = check_setting_str(CFG, 'Newznab', 'newznab_host', '')
        NEWZNAB_APIKEY = check_setting_str(CFG, 'Newznab', 'newznab_apikey', '')
        NEWZNAB_ENABLED = bool(check_setting_int(CFG, 'Newznab', 'newznab_enabled', 1))

        # Need to pack the extra newznabs back into a list of tuples
        flattened_newznabs = check_setting_str(CFG, 'Newznab', 'extra_newznabs', [], log=False)
        EXTRA_NEWZNABS = list(itertools.izip(*[itertools.islice(flattened_newznabs, i, None, 3) for i in range(3)]))

        NZBSORG = bool(check_setting_int(CFG, 'NZBsorg', 'nzbsorg', 0))
        NZBSORG_UID = check_setting_str(CFG, 'NZBsorg', 'nzbsorg_uid', '')
        NZBSORG_HASH = check_setting_str(CFG, 'NZBsorg', 'nzbsorg_hash', '')

        NZBSRUS = bool(check_setting_int(CFG, 'NZBsRus', 'nzbsrus', 0))
        NZBSRUS_UID = check_setting_str(CFG, 'NZBsRus', 'nzbsrus_uid', '')
        NZBSRUS_APIKEY = check_setting_str(CFG, 'NZBsRus', 'nzbsrus_apikey', '')

        OMGWTFNZBS = bool(check_setting_int(CFG, 'omgwtfnzbs', 'omgwtfnzbs', 0))
        OMGWTFNZBS_UID = check_setting_str(CFG, 'omgwtfnzbs', 'omgwtfnzbs_uid', '')
        OMGWTFNZBS_APIKEY = check_setting_str(CFG, 'omgwtfnzbs', 'omgwtfnzbs_apikey', '')

        PREFERRED_WORDS = check_setting_str(CFG, 'General', 'preferred_words', '')
        IGNORED_WORDS = check_setting_str(CFG, 'General', 'ignored_words', '')
        REQUIRED_WORDS = check_setting_str(CFG, 'General', 'required_words', '')

        LASTFM_USERNAME = check_setting_str(CFG, 'General', 'lastfm_username', '')

        INTERFACE = check_setting_str(CFG, 'General', 'interface', 'default')
        FOLDER_PERMISSIONS = check_setting_str(CFG, 'General', 'folder_permissions', '0755')
        FILE_PERMISSIONS = check_setting_str(CFG, 'General', 'file_permissions', '0644')

        ENCODERFOLDER = check_setting_str(CFG, 'General', 'encoderfolder', '')
        ENCODER_PATH = check_setting_str(CFG, 'General', 'encoder_path', '')
        ENCODER = check_setting_str(CFG, 'General', 'encoder', 'ffmpeg')
        XLDPROFILE = check_setting_str(CFG, 'General', 'xldprofile', '')
        BITRATE = check_setting_int(CFG, 'General', 'bitrate', 192)
        SAMPLINGFREQUENCY= check_setting_int(CFG, 'General', 'samplingfrequency', 44100)
        MUSIC_ENCODER = bool(check_setting_int(CFG, 'General', 'music_encoder', 0))
        ADVANCEDENCODER = check_setting_str(CFG, 'General', 'advancedencoder', '')
        ENCODEROUTPUTFORMAT = check_setting_str(CFG, 'General', 'encoderoutputformat', 'mp3')
        ENCODERQUALITY = check_setting_int(CFG, 'General', 'encoderquality', 2)
        ENCODERVBRCBR = check_setting_str(CFG, 'General', 'encodervbrcbr', 'cbr')
        ENCODERLOSSLESS = bool(check_setting_int(CFG, 'General', 'encoderlossless', 1))
        DELETE_LOSSLESS_FILES = bool(check_setting_int(CFG, 'General', 'delete_lossless_files', 1))

        PROWL_ENABLED = bool(check_setting_int(CFG, 'Prowl', 'prowl_enabled', 0))
        PROWL_KEYS = check_setting_str(CFG, 'Prowl', 'prowl_keys', '')
        PROWL_ONSNATCH = bool(check_setting_int(CFG, 'Prowl', 'prowl_onsnatch', 0))
        PROWL_PRIORITY = check_setting_int(CFG, 'Prowl', 'prowl_priority', 0)

        XBMC_ENABLED = bool(check_setting_int(CFG, 'XBMC', 'xbmc_enabled', 0))
        XBMC_HOST = check_setting_str(CFG, 'XBMC', 'xbmc_host', '')
        XBMC_USERNAME = check_setting_str(CFG, 'XBMC', 'xbmc_username', '')
        XBMC_PASSWORD = check_setting_str(CFG, 'XBMC', 'xbmc_password', '')
        XBMC_UPDATE = bool(check_setting_int(CFG, 'XBMC', 'xbmc_update', 0))
        XBMC_NOTIFY = bool(check_setting_int(CFG, 'XBMC', 'xbmc_notify', 0))

        NMA_ENABLED = bool(check_setting_int(CFG, 'NMA', 'nma_enabled', 0))
        NMA_APIKEY = check_setting_str(CFG, 'NMA', 'nma_apikey', '')
        NMA_PRIORITY = check_setting_int(CFG, 'NMA', 'nma_priority', 0)
        NMA_ONSNATCH = bool(check_setting_int(CFG, 'NMA', 'nma_onsnatch', 0))

        SYNOINDEX_ENABLED = bool(check_setting_int(CFG, 'Synoindex', 'synoindex_enabled', 0))

        PUSHOVER_ENABLED = bool(check_setting_int(CFG, 'Pushover', 'pushover_enabled', 0))
        PUSHOVER_KEYS = check_setting_str(CFG, 'Pushover', 'pushover_keys', '')
        PUSHOVER_ONSNATCH = bool(check_setting_int(CFG, 'Pushover', 'pushover_onsnatch', 0))
        PUSHOVER_PRIORITY = check_setting_int(CFG, 'Pushover', 'pushover_priority', 0)

        MIRROR = check_setting_str(CFG, 'General', 'mirror', 'musicbrainz.org')
        CUSTOMHOST = check_setting_str(CFG, 'General', 'customhost', 'localhost')
        CUSTOMPORT = check_setting_int(CFG, 'General', 'customport', 5000)
        CUSTOMSLEEP = check_setting_int(CFG, 'General', 'customsleep', 1)
        HPUSER = check_setting_str(CFG, 'General', 'hpuser', '')
        HPPASS = check_setting_str(CFG, 'General', 'hppass', '')

        CACHE_SIZEMB = check_setting_int(CFG,'Advanced','cache_sizemb',32)
        JOURNAL_MODE = check_setting_int(CFG,'Advanced', 'journal_mode', 'wal')

        ALBUM_COMPLETION_PCT = check_setting_int(CFG, 'Advanced', 'album_completion_pct', 80)

        # 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 CONFIG_VERSION == '1':

            from headphones.helpers import replace_all

            file_values = { 'Track':        '$Track',
                            'Title':        '$Title',
                            'Artist':       '$Artist',
                            'Album':        '$Album',
                            'Year':         '$Year',
                            'track':        '$track',
                            'title':        '$title',
                            'artist':       '$artist',
                            'album':        '$album',
                            'year':         '$year'
                            }
            folder_values = {   'Artist':   '$Artist',
                                'Album':    '$Album',
                                'Year':     '$Year',
                                'Type':     '$Type',
                                'First':    '$First',
                                'artist':   '$artist',
                                'album':    '$album',
                                'year':     '$year',
                                'type':     '$type',
                                'first':    '$first'
                            }
            FILE_FORMAT = replace_all(FILE_FORMAT, file_values)
            FOLDER_FORMAT = replace_all(FOLDER_FORMAT, folder_values)

            CONFIG_VERSION = '2'

        if CONFIG_VERSION == '2':

            # Update the config to use direct path to the encoder rather than the encoder folder
            if ENCODERFOLDER:
                ENCODER_PATH = os.path.join(ENCODERFOLDER, ENCODER)
            CONFIG_VERSION = '3'

        if CONFIG_VERSION == '3':
			#Update the BLACKHOLE option to the NZB_DOWNLOADER format
			if BLACKHOLE:
				NZB_DOWNLOADER = 2
			CONFIG_VERSION = '4'
            
        # Enable Headphones Indexer if they have a VIP account
        if CONFIG_VERSION == '4':
            if HPUSER and HPPASS:
                HEADPHONES_INDEXER = True
            CONFIG_VERSION = '5'

        if not LOG_DIR:
            LOG_DIR = os.path.join(DATA_DIR, 'logs')

        if not os.path.exists(LOG_DIR):
            try:
                os.makedirs(LOG_DIR)
            except OSError:
                if VERBOSE:
                    print 'Unable to create the log directory. Logging to screen only.'

        # Start the logger, silence console logging if we need to
        logger.headphones_log.initLogger(verbose=VERBOSE)

        if not CACHE_DIR:
            # 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):
            try:
                os.makedirs(CACHE_DIR)
            except OSError:
                logger.error('Could not create cache dir. Check permissions of datadir: ' + DATA_DIR)

        # Sanity check for search interval. Set it to at least 6 hours
        if SEARCH_INTERVAL < 360:
            logger.info("Search interval too low. Resetting to 6 hour minimum")
            SEARCH_INTERVAL = 360

        # Initialize the database
        logger.info('Checking to see if the database has all tables....')
        try:
            dbcheck()
        except Exception, e:
            logger.error("Can't connect to the database: %s" % e)

        # Get the currently installed version - returns None, 'win32' or the git hash
        # Also sets INSTALL_TYPE variable to 'win', 'git' or 'source'
        CURRENT_VERSION = versioncheck.getVersion()

        # Check for new versions
        if CHECK_GITHUB_ON_STARTUP:
            try:
                LATEST_VERSION = versioncheck.checkGithub()
            except:
                LATEST_VERSION = CURRENT_VERSION
        else:
            LATEST_VERSION = CURRENT_VERSION

        # Store the original umask
        UMASK = os.umask(0)
        os.umask(UMASK)

        __INITIALIZED__ = True
        return True
Beispiel #14
0
def renameFiles(albumpath, downloaded_track_list, release):
    logger.info('Renaming files')
    try:
        year = release['ReleaseDate'][:4]
    except TypeError:
        year = ''
    # Until tagging works better I'm going to rely on the already provided metadata

    for downloaded_track in downloaded_track_list:
        try:
            f = MediaFile(downloaded_track)
        except:
            logger.info("MediaFile couldn't parse: " + downloaded_track.decode(headphones.SYS_ENCODING, 'replace'))
            continue

        if not f.disc:
            discnumber = ''
        else:
            discnumber = '%d' % f.disc

        if not f.track:
            tracknumber = ''
        else:
            tracknumber = '%02d' % f.track
        
        if not f.title:
            
            basename = os.path.basename(downloaded_track.decode(headphones.SYS_ENCODING, 'replace'))
            title = os.path.splitext(basename)[0]
            ext = os.path.splitext(basename)[1]
            
            new_file_name = helpers.cleanTitle(title) + ext
            
        else:
            title = f.title
            
            if release['ArtistName'] == "Various Artists" and f.artist:
                artistname = f.artist
            else:
                artistname = release['ArtistName']
                
            if artistname.startswith('The '):
                sortname = artistname[4:] + ", The"
            else:
                sortname = artistname
            
            values = {  '$Disc':        discnumber,
                        '$Track':       tracknumber,
                        '$Title':       title,
                        '$Artist':      artistname,
                        '$SortArtist':  sortname,
                        '$Album':       release['AlbumTitle'],
                        '$Year':        year,
                        '$disc':        discnumber,
                        '$track':       tracknumber,
                        '$title':       title.lower(),
                        '$artist':      artistname.lower(),
                        '$sortartist':  sortname.lower(),
                        '$album':       release['AlbumTitle'].lower(),
                        '$year':        year
                        }
                        
            ext = os.path.splitext(downloaded_track)[1]
            
            new_file_name = helpers.replace_all(headphones.FILE_FORMAT.strip(), values).replace('/','_') + ext
        
        
        new_file_name = new_file_name.replace('?','_').replace(':', '_').encode(headphones.SYS_ENCODING, 'replace')

        if headphones.FILE_UNDERSCORES:
            new_file_name = new_file_name.replace(' ', '_')

        if new_file_name.startswith('.'):
            new_file_name = new_file_name.replace(0, '_')
        
        new_file = os.path.join(albumpath, new_file_name)
        
        if downloaded_track == new_file_name:
            logger.debug("Renaming for: " + downloaded_track.decode(headphones.SYS_ENCODING, 'replace') + " is not neccessary")
            continue

        logger.debug('Renaming %s ---> %s' % (downloaded_track.decode(headphones.SYS_ENCODING,'replace'), new_file_name.decode(headphones.SYS_ENCODING,'replace')))
        try:
            os.rename(downloaded_track, new_file)
        except Exception, e:
            logger.error('Error renaming file: %s. Error: %s' % (downloaded_track.decode(headphones.SYS_ENCODING, 'replace'), e))
            continue
Beispiel #15
0
def searchNZB(albumid=None, new=False, losslessOnly=False):

    myDB = db.DBConnection()
    
    if albumid:
        results = myDB.select('SELECT ArtistName, AlbumTitle, AlbumID, ReleaseDate from albums WHERE AlbumID=?', [albumid])
    else:
        results = myDB.select('SELECT ArtistName, AlbumTitle, AlbumID, ReleaseDate from albums WHERE Status="Wanted" OR Status="Wanted Lossless"')
        new = True
        
    for albums in results:
        
        albumid = albums[2]
        reldate = albums[3]
        
        try:
            year = reldate[:4]
        except TypeError:
            year = ''
        
        dic = {'...':'', ' & ':' ', ' = ': ' ', '?':'', '$':'s', ' + ':' ', '"':'', ',':'', '*':'', '.':'', ':':''}

        cleanalbum = helpers.latinToAscii(helpers.replace_all(albums[1], dic))
        cleanartist = helpers.latinToAscii(helpers.replace_all(albums[0], dic))

        # FLAC usually doesn't have a year for some reason so I'll leave it out
        # Various Artist albums might be listed as VA, so I'll leave that out too
        # Only use the year if the term could return a bunch of different albums, i.e. self-titled albums
        if albums[0] in albums[1] or len(albums[0]) < 4 or len(albums[1]) < 4:
            term = cleanartist + ' ' + cleanalbum + ' ' + year
        elif albums[0] == 'Various Artists':
        	term = cleanalbum + ' ' + year
        else:
        	term = cleanartist + ' ' + cleanalbum
            
        # Replace bad characters in the term and unicode it
        term = re.sub('[\.\-\/]', ' ', term).encode('utf-8')
        artistterm = re.sub('[\.\-\/]', ' ', cleanartist).encode('utf-8')
        
        logger.info("Searching for %s since it was marked as wanted" % term)
        
        resultlist = []
        
        if headphones.NZBMATRIX:
            provider = "nzbmatrix"
            if headphones.PREFERRED_QUALITY == 3 or losslessOnly:
                categories = "23"
                maxsize = 10000000000    
            elif headphones.PREFERRED_QUALITY:
                categories = "23,22"
                maxsize = 2000000000
            else:
                categories = "22"
                maxsize = 300000000
                
            # For some reason NZBMatrix is erroring out/timing out when the term starts with a "The" right now
            # so we'll strip it out for the time being. This may get fixed on their end, it may not, but
            # hopefully this will fix it for now. If you notice anything else it gets stuck on, please post it
            # on Github so it can be added
            if term.lower().startswith("the "):
            	term = term[4:]
            
            
            params = {    "page": "download",
                        "username": headphones.NZBMATRIX_USERNAME,
                        "apikey": headphones.NZBMATRIX_APIKEY,
                        "subcat": categories,
                        "maxage": headphones.USENET_RETENTION,
                        "english": 1,
                        "ssl": 1,
                        "scenename": 1,
                        "term": term
                        }
                        
            searchURL = "http://rss.nzbmatrix.com/rss.php?" + urllib.urlencode(params)
            logger.info(u'Parsing results from <a href="%s">NZBMatrix</a>' % searchURL)
            try:
            	data = urllib2.urlopen(searchURL, timeout=20).read()
            except urllib2.URLError, e:
            	logger.warn('Error fetching data from NZBMatrix: %s' % e)
            	data = False   
            	
            if data:
            
				d = feedparser.parse(data)
				
				for item in d.entries:
					try:
						url = item.link
						title = item.title
						size = int(item.links[1]['length'])
						if size < maxsize:
							resultlist.append((title, size, url, provider))
							logger.info('Found %s. Size: %s' % (title, helpers.bytes_to_mb(size)))
						else:
							logger.info('%s is larger than the maxsize for this category, skipping. (Size: %i bytes)' % (title, size))    
					
					except AttributeError, e:
						logger.info(u"No results found from NZBMatrix for %s" % term)
Beispiel #16
0
def renameFiles(albumpath, downloaded_track_list, release):
    logger.info("Renaming files")
    try:
        year = release["ReleaseDate"][:4]
    except TypeError:
        year = ""
    # Until tagging works better I'm going to rely on the already provided metadata

    for downloaded_track in downloaded_track_list:
        try:
            f = MediaFile(downloaded_track)
        except:
            logger.info("MediaFile couldn't parse: " + downloaded_track.decode(headphones.SYS_ENCODING, "replace"))
            continue

        if not f.track:
            tracknumber = ""
        else:
            tracknumber = "%02d" % f.track

        if not f.title:

            basename = os.path.basename(downloaded_track.decode(headphones.SYS_ENCODING, "replace"))
            title = os.path.splitext(basename)[0]
            ext = os.path.splitext(basename)[1]

            new_file_name = helpers.cleanTitle(title) + ext

        else:
            title = f.title

            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,
            }

            ext = os.path.splitext(downloaded_track)[1]

            new_file_name = helpers.replace_all(headphones.FILE_FORMAT.strip(), values).replace("/", "_") + ext

        new_file_name = new_file_name.replace("?", "_").replace(":", "_").encode(headphones.SYS_ENCODING, "replace")

        if new_file_name.startswith("."):
            new_file_name = new_file_name.replace(0, "_")

        new_file = os.path.join(albumpath, new_file_name)

        if downloaded_track == new_file_name:
            logger.debug(
                "Renaming for: " + downloaded_track.decode(headphones.SYS_ENCODING, "replace") + " is not neccessary"
            )
            continue

        logger.debug(
            "Renaming %s ---> %s"
            % (
                downloaded_track.decode(headphones.SYS_ENCODING, "replace"),
                new_file_name.decode(headphones.SYS_ENCODING, "replace"),
            )
        )
        try:
            os.rename(downloaded_track, new_file)
        except Exception, e:
            logger.error(
                "Error renaming file: %s. Error: %s" % (downloaded_track.decode(headphones.SYS_ENCODING, "replace"), e)
            )
            continue
Beispiel #17
0
def moveFiles(albumpath, release, tracks):

    try:
        year = release['ReleaseDate'][:4]
    except TypeError:
        year = ''

    artist = release['ArtistName'].replace('/', '_')
    album = release['AlbumTitle'].replace('/', '_')
    releasetype = release['Type'].replace('/', '_')

    if release['ArtistName'].startswith('The '):
        sortname = release['ArtistName'][4:] + ", The"
    else:
        sortname = release['ArtistName']

    if sortname[0].isdigit():
        firstchar = '0-9'
    else:
        firstchar = sortname[0]

    values = {
        '$Artist': artist,
        '$SortArtist': sortname,
        '$Album': album,
        '$Year': year,
        '$Type': releasetype,
        '$First': firstchar.upper(),
        '$artist': artist.lower(),
        '$sortartist': sortname.lower(),
        '$album': album.lower(),
        '$year': year,
        '$type': releasetype.lower(),
        '$first': firstchar.lower()
    }

    folder = helpers.replace_all(headphones.FOLDER_FORMAT.strip(), values)
    folder = folder.replace('./', '_/').replace(':', '_').replace(
        '?', '_').replace('/.', '/_').replace('<', '_').replace('>', '_')

    if folder.endswith('.'):
        folder = folder.replace(folder[len(folder) - 1], '_')

    if folder.startswith('.'):
        folder = folder.replace(0, '_')

    # Grab our list of files early on so we can determine if we need to create
    # the lossy_dest_dir, lossless_dest_dir, or both
    files_to_move = []
    lossy_media = False
    lossless_media = False

    for r, d, f in os.walk(albumpath):
        for files in f:
            files_to_move.append(os.path.join(r, files))
            if any(files.lower().endswith('.' + x.lower())
                   for x in headphones.LOSSY_MEDIA_FORMATS):
                lossy_media = True
            if any(files.lower().endswith('.' + x.lower())
                   for x in headphones.LOSSLESS_MEDIA_FORMATS):
                lossless_media = True

    # Do some sanity checking to see what directories we need to create:
    make_lossy_folder = False
    make_lossless_folder = False

    lossy_destination_path = os.path.normpath(
        os.path.join(headphones.DESTINATION_DIR,
                     folder)).encode(headphones.SYS_ENCODING, 'replace')
    lossless_destination_path = os.path.normpath(
        os.path.join(headphones.LOSSLESS_DESTINATION_DIR,
                     folder)).encode(headphones.SYS_ENCODING, 'replace')

    # If they set a destination dir for lossless media, only create the lossy folder if there is lossy media
    if headphones.LOSSLESS_DESTINATION_DIR:
        if lossy_media:
            make_lossy_folder = True
        if lossless_media:
            make_lossless_folder = True
    # If they haven't set a lossless dest_dir, just create the "lossy" folder
    else:
        make_lossy_folder = True

    last_folder = headphones.FOLDER_FORMAT.strip().split('/')[-1]

    if make_lossless_folder:
        # Only rename the folder if they use the album name, otherwise merge into existing folder
        if os.path.exists(
                lossless_destination_path) and 'album' in last_folder.lower():

            temp_folder = folder

            i = 1
            while True:
                newfolder = temp_folder + '[%i]' % i
                lossless_destination_path = os.path.normpath(
                    os.path.join(headphones.LOSSLESS_DESTINATION_DIR,
                                 newfolder)).encode(headphones.SYS_ENCODING,
                                                    'replace')
                if os.path.exists(lossless_destination_path):
                    i += 1
                else:
                    temp_folder = newfolder
                    break

        if not os.path.exists(lossless_destination_path):
            try:
                os.makedirs(lossless_destination_path)
            except Exception, e:
                logger.error(
                    'Could not create lossless folder for %s. (Error: %s)' %
                    (release['AlbumTitle'], e))
                if not make_lossy_folder:
                    return [albumpath]
Beispiel #18
0
def update(artistid, artist_name, release_groups):
    """ Pretty simple and crude function to find the artist page on metacritic,
    then parse that page to get critic & user scores for albums"""

    # First let's modify the artist name to fit the metacritic convention.
    # We could just do a search, then take the top result, but at least this will
    # cut down on api calls. If it's ineffective then we'll switch to search

    replacements = {" & ": " ", ".": ""}
    mc_artist_name = helpers.replace_all(artist_name.lower(), replacements)

    mc_artist_name = mc_artist_name.replace(" ", "-")

    headers = {
        'User-Agent':
        'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2243.2 Safari/537.36'
    }

    url = "http://www.metacritic.com/person/" + mc_artist_name + "?filter-options=music&sort_options=date&num_items=100"

    res = request.request_soup(url, headers=headers)

    rows = None

    try:
        table = res.find("table", class_="credits person_credits")
        rows = table.tbody.find_all('tr')
    except:
        logger.info("Unable to get metacritic scores for: %s" % artist_name)

    myDB = db.DBConnection()
    artist = myDB.action('SELECT * FROM artists WHERE ArtistID=?',
                         [artistid]).fetchone()

    score_list = []

    # If we couldn't get anything from MetaCritic for whatever reason,
    # let's try to load scores from the db
    if not rows:
        if artist['MetaCritic']:
            score_list = json.loads(artist['MetaCritic'])
        else:
            return

    # If we did get scores, let's update the db with them
    else:
        for row in rows:
            title = row.a.string
            scores = row.find_all("span")
            critic_score = scores[0].string
            user_score = scores[1].string
            score_dict = {
                'title': title,
                'critic_score': critic_score,
                'user_score': user_score
            }
            score_list.append(score_dict)

        # Save scores to the database
        controlValueDict = {"ArtistID": artistid}
        newValueDict = {'MetaCritic': json.dumps(score_list)}
        myDB.upsert("artists", newValueDict, controlValueDict)

    for score in score_list:
        title = score['title']
        # Iterate through the release groups we got passed to see if we can find
        # a match
        for rg in release_groups:
            if rg['title'].lower() == title.lower():
                critic_score = score['critic_score']
                user_score = score['user_score']
                controlValueDict = {"AlbumID": rg['id']}
                newValueDict = {
                    'CriticScore': critic_score,
                    'UserScore': user_score
                }
                myDB.upsert("albums", newValueDict, controlValueDict)
Beispiel #19
0
def update(artistid, artist_name,release_groups):
    """ Pretty simple and crude function to find the artist page on metacritic,
    then parse that page to get critic & user scores for albums"""

    # First let's modify the artist name to fit the metacritic convention.
    # We could just do a search, then take the top result, but at least this will
    # cut down on api calls. If it's ineffective then we'll switch to search

    replacements = {" & " : " ", "." : ""}
    mc_artist_name = helpers.replace_all(artist_name.lower(),replacements)

    mc_artist_name = mc_artist_name.replace(" ","-")

    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2243.2 Safari/537.36'}

    url = "http://www.metacritic.com/person/" + mc_artist_name + "?filter-options=music&sort_options=date&num_items=100"

    res = request.request_soup(url, headers=headers, parser='html.parser')

    rows = None

    try:
        rows = res.tbody.find_all('tr')
    except:
        logger.info("Unable to get metacritic scores for: %s" % artist_name)

    myDB = db.DBConnection()
    artist = myDB.action('SELECT * FROM artists WHERE ArtistID=?', [artistid]).fetchone()

    score_list = []

    # If we couldn't get anything from MetaCritic for whatever reason,
    # let's try to load scores from the db
    if not rows:
        if artist['MetaCritic']:
            score_list = json.loads(artist['MetaCritic'])
        else:
            return

    # If we did get scores, let's update the db with them
    else:
        for row in rows:
            title = row.a.string
            scores = row.find_all("span")
            critic_score = scores[0].string
            user_score = scores[1].string
            score_dict = {'title':title,'critic_score':critic_score,'user_score':user_score}
            score_list.append(score_dict)

        # Save scores to the database
        controlValueDict = {"ArtistID": artistid}
        newValueDict = {'MetaCritic':json.dumps(score_list)}
        myDB.upsert("artists", newValueDict, controlValueDict)

    for score in score_list:
        title = score['title']
        # Iterate through the release groups we got passed to see if we can find
        # a match
        for rg in release_groups:
            if rg['title'].lower() == title.lower():
                critic_score = score['critic_score']
                user_score = score['user_score']
                controlValueDict = {"AlbumID": rg['id']}
                newValueDict = {'CriticScore':critic_score,'UserScore':user_score}
                myDB.upsert("albums", newValueDict, controlValueDict)
def moveFiles(albumpath, release, tracks):

	try:
		year = release['ReleaseDate'][:4]
	except TypeError:
		year = ''
		
	artist = release['ArtistName'].replace('/', '_')
	album = release['AlbumTitle'].replace('/', '_')

	if release['ArtistName'].startswith('The '):
		sortname = release['ArtistName'][4:]
	else:
		sortname = release['ArtistName']
	
	if sortname.isdigit():
		firstchar = '0-9'
	else:
		firstchar = sortname[0]
	

	values = {	'artist':	artist,
				'album':	album,
				'year':		year,
				'first':	firstchar,
			}
			
	
	folder = helpers.replace_all(headphones.FOLDER_FORMAT, values)
	folder = folder.replace('./', '_/').replace(':','_').replace('?','_')
	
	if folder.endswith('.'):
		folder = folder.replace(folder[len(folder)-1], '_')
	
	destination_path = os.path.normpath(os.path.join(headphones.DESTINATION_DIR, folder))
	
	if os.path.exists(destination_path):
		i = 1
		while True:
			new_folder_name = destination_path + '[%i]' % i
			if os.path.exists(new_folder_name):
				i += 1
			else:
				destination_path = new_folder_name
				break
	
	logger.info('Moving files from %s to %s' % (albumpath, destination_path))
	
	try:
		os.makedirs(destination_path)
		
		# Chmod the directories using the folder_format (script courtesy of premiso!)
		folder_list = folder.split('/')
		
		
		temp_f = os.path.join(headphones.DESTINATION_DIR);
		for f in folder_list:
			temp_f = os.path.join(temp_f, f)
			os.chmod(temp_f, int(headphones.FOLDER_PERMISSIONS, 8))
	
	except Exception, e:
		logger.error('Could not create folder for %s. Not moving: %s' % (release['AlbumTitle'], e))
		return albumpath
Beispiel #21
0
def moveFiles(albumpath, release, tracks):

	try:
		year = release['ReleaseDate'][:4]
	except TypeError:
		year = ''
		
	artist = release['ArtistName'].replace('/', '_')
	album = release['AlbumTitle'].replace('/', '_')
	releasetype = release['Type'].replace('/', '_')

	if release['ArtistName'].startswith('The '):
		sortname = release['ArtistName'][4:]
	else:
		sortname = release['ArtistName']
	
	if sortname.isdigit():
		firstchar = '0-9'
	else:
		firstchar = sortname[0]
	

	values = {	'$Artist':	artist,
				'$Album':	album,
				'$Year':		year,
				'$Type':  releasetype,
				'$First':	firstchar,
				'$artist':	artist.lower(),
				'$album':	album.lower(),
				'$year':		year,
				'$type':  releasetype.lower(),
				'$first':	firstchar.lower()
			}
			
	
	folder = helpers.replace_all(headphones.FOLDER_FORMAT, values)
	folder = folder.replace('./', '_/').replace(':','_').replace('?','_').replace('/.','/_')
	
	if folder.endswith('.'):
		folder = folder.replace(folder[len(folder)-1], '_')
		
	if folder.startswith('.'):
		folder = folder.replace(0, '_')
	
	destination_path = os.path.normpath(os.path.join(headphones.DESTINATION_DIR, folder)).encode(headphones.SYS_ENCODING)
	
	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
			destination_path = os.path.normpath(os.path.join(headphones.DESTINATION_DIR, newfolder)).encode(headphones.SYS_ENCODING)
			if os.path.exists(destination_path):
				i += 1
			else:
				folder = newfolder
				break

	logger.info('Moving files from %s to %s' % (unicode(albumpath, headphones.SYS_ENCODING, errors="replace"), unicode(destination_path, headphones.SYS_ENCODING, errors="replace")))
	
	# 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
Beispiel #22
0
def getReleaseGroup(rgid):
    """
	Returns a dictionary of the best stuff from a release group
	"""
    with mb_lock:

        releaselist = []

        inc = ws.ReleaseGroupIncludes(releases=True, artist=True)
        releaseGroup = None
        attempt = 0

        while attempt < 5:

            try:
                releaseGroup = q.getReleaseGroupById(rgid, inc)
                break
            except WebServiceError, e:
                logger.warn(
                    'Attempt to retrieve information from MusicBrainz for release group "%s" failed. Sleeping 5 seconds'
                    % rgid)
                attempt += 1
                time.sleep(5)

        if not releaseGroup:
            return False

        time.sleep(1)
        # I think for now we have to make separate queries for each release, in order
        # to get more detailed release info (ASIN, track count, etc.)
        for release in releaseGroup.releases:

            inc = ws.ReleaseIncludes(tracks=True, releaseEvents=True)
            releaseResult = None
            attempt = 0

            while attempt < 5:

                try:
                    releaseResult = q.getReleaseById(release.id, inc)
                    break
                except WebServiceError, e:
                    logger.warn(
                        'Attempt to retrieve release information for %s from MusicBrainz failed: %s. Sleeping 5 seconds'
                        % (releaseResult.title, e))
                    attempt += 1
                    time.sleep(5)

            if not releaseResult:
                continue

            # Release filter for non-official live albums
            types = releaseResult.getTypes()
            if any('Live' in type for type in types):
                if not any('Official' in type for type in types):
                    logger.debug('%s is not an official live album. Skipping' %
                                 releaseResult.name)
                    continue

            time.sleep(1)

            formats = {
                '2xVinyl': '2',
                'Vinyl': '2',
                'CD': '0',
                'Cassette': '3',
                '2xCD': '1',
                'Digital Media': '0'
            }

            country = {
                'US': '0',
                'GB': '1',
                'JP': '2',
            }

            try:
                format = int(
                    replace_all(
                        u.extractFragment(
                            releaseResult.releaseEvents[0].format), formats))
            except:
                format = 3

            try:
                country = int(
                    replace_all(releaseResult.releaseEvents[0].country,
                                country))
            except:
                country = 3

            release_dict = {
                'hasasin': bool(releaseResult.asin),
                'asin': releaseResult.asin,
                'trackscount': len(releaseResult.getTracks()),
                'releaseid': u.extractUuid(releaseResult.id),
                'releasedate': releaseResult.getEarliestReleaseDate(),
                'format': format,
                'country': country
            }

            tracks = []

            i = 1
            for track in releaseResult.tracks:

                tracks.append({
                    'number': i,
                    'title': track.title,
                    'id': u.extractUuid(track.id),
                    'url': track.id,
                    'duration': track.duration
                })
                i += 1

            release_dict['tracks'] = tracks

            releaselist.append(release_dict)
Beispiel #23
0
def libraryScan(dir=None):

	if not dir:
		dir = headphones.MUSIC_DIR
		
	try:
		dir = str(dir)
	except UnicodeEncodeError:
		dir = unicode(dir).encode('unicode_escape')
		
	if not os.path.isdir(dir):
		logger.warn('Cannot find directory: %s. Not scanning' % dir)
		return

	myDB = db.DBConnection()
	
	# 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'].encode(headphones.SYS_ENCODING)):
			myDB.action('UPDATE tracks SET Location=?, BitRate=?, Format=? WHERE TrackID=?', [None, None, None, track['TrackID']])

	logger.info('Scanning music directory: %s' % dir)

	new_artists = []
	bitrates = []

	myDB.action('DELETE from have')
	
	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.lower().endswith('.' + x.lower()) for x in headphones.MEDIA_FORMATS):

				song = os.path.join(r, files)
				file = unicode(os.path.join(r, files), headphones.SYS_ENCODING, errors='replace')

				# Try to read the metadata
				try:
					f = MediaFile(song)

				except:
					logger.error('Cannot read file: ' + file)
					continue
					
				# Grab the bitrates for the auto detect bit rate option
				if f.bitrate:
					bitrates.append(f.bitrate)
				
				# 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()
					
					if track:
						myDB.action('UPDATE tracks SET Location=?, BitRate=?, Format=? WHERE TrackID=?', [file, f.bitrate, f.format, track['TrackID']])
						continue		
				
				# Try to match on mbid if available and we couldn't find a match based on metadata
				if 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 track:
						myDB.action('UPDATE tracks SET Location=?, BitRate=?, Format=? WHERE TrackID=?', [file, f.bitrate, f.format, 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 (ArtistName, AlbumTitle, TrackNumber, TrackTitle, TrackLength, BitRate, Genre, Date, TrackID, Location, CleanName, Format) 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), f.format])

	logger.info('Completed scanning of directory: %s' % dir)
	logger.info('Checking filepaths to see if we can find any matches')

	# 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 IS NULL')
	for track in tracks:
	
		release = myDB.action('SELECT * from albums WHERE AlbumID=?', [track['AlbumID']]).fetchone()

		try:
			year = release['ReleaseDate'][:4]
		except TypeError:
			year = ''
			
		artist = release['ArtistName'].replace('/', '_')
		album = release['AlbumTitle'].replace('/', '_')
	
		if release['ArtistName'].startswith('The '):
			sortname = release['ArtistName'][4:]
		else:
			sortname = release['ArtistName']
		
		if sortname.isdigit():
			firstchar = '0-9'
		else:
			firstchar = sortname[0]
			
		lowerfirst = firstchar.lower()
		
		albumvalues = {	'artist':	artist,
						'album':	album,
						'year':		year,
						'first':	firstchar,
						'lowerfirst':	lowerfirst
					}
				
		
		folder = helpers.replace_all(headphones.FOLDER_FORMAT, albumvalues)
		folder = folder.replace('./', '_/').replace(':','_').replace('?','_')
		
		if folder.endswith('.'):
			folder = folder.replace(folder[len(folder)-1], '_')

		if not track['TrackNumber']:
			tracknumber = ''
		else:
			tracknumber = '%02d' % track['TrackNumber']
			
		trackvalues = {	'tracknumber':	tracknumber,
						'title':		track['TrackTitle'],
						'artist':		release['ArtistName'],
						'album':		release['AlbumTitle'],
						'year':			year
						}
		
		new_file_name = helpers.replace_all(headphones.FILE_FORMAT, trackvalues).replace('/','_') + '.*'
		
		new_file_name = new_file_name.replace('?','_').replace(':', '_')
		
		full_path_to_file = os.path.normpath(os.path.join(headphones.MUSIC_DIR, folder, new_file_name)).encode(headphones.SYS_ENCODING, 'replace')

		match = glob.glob(full_path_to_file)
		
		if match:

			logger.info('Found a match: %s. Writing MBID to metadata' % match[0])
			
			unipath = unicode(match[0], headphones.SYS_ENCODING, errors='replace')

			myDB.action('UPDATE tracks SET Location=? WHERE TrackID=?', [unipath, track['TrackID']])
			myDB.action('DELETE from have WHERE Location=?', [unipath])
			
			# 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']
				f.save()
				myDB.action('UPDATE tracks SET BitRate=?, Format=? WHERE TrackID=?', [f.bitrate, f.format, track['TrackID']])

				logger.debug('Wrote mbid to track: %s' % match[0])

			except:
				logger.error('Error embedding track id into: %s' % match[0])
				continue

	logger.info('Done checking empty filepaths')
	logger.info('Done syncing library with directory: %s' % dir)
	
	# Clean up the new artist list
	unique_artists = {}.fromkeys(new_artists).keys()
	current_artists = myDB.select('SELECT ArtistName, ArtistID from artists')
	
	artist_list = [f for f in unique_artists if f.lower() not in [x[0].lower() for x in current_artists]]
	
	# Update track counts
	logger.info('Updating track counts')

	for artist in current_artists:
		havetracks = len(myDB.select('SELECT TrackTitle from tracks WHERE ArtistID like ? AND Location IS NOT NULL', [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']])
		
	logger.info('Found %i new artists' % len(artist_list))

	if len(artist_list):
		if headphones.ADD_ARTISTS:
			logger.info('Importing %i new artists' % len(artist_list))
			importer.artistlist_to_mbids(artist_list)
		else:
			logger.info('To add these artists, go to Manage->Manage New Artists')
			headphones.NEW_ARTISTS = artist_list
	
	if headphones.DETECT_BITRATE:
		headphones.PREFERRED_BITRATE = sum(bitrates)/len(bitrates)/1000
Beispiel #24
0
    def _upgrade(self):
        """ Update folder formats in the config & bump up config version """
        if self.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",
            }
            self.FILE_FORMAT = replace_all(self.FILE_FORMAT, file_values)
            self.FOLDER_FORMAT = replace_all(self.FOLDER_FORMAT, folder_values)

            self.CONFIG_VERSION = "1"

        if self.CONFIG_VERSION == "1":
            from headphones.helpers import replace_all

            file_values = {
                "Track": "$Track",
                "Title": "$Title",
                "Artist": "$Artist",
                "Album": "$Album",
                "Year": "$Year",
                "track": "$track",
                "title": "$title",
                "artist": "$artist",
                "album": "$album",
                "year": "$year",
            }
            folder_values = {
                "Artist": "$Artist",
                "Album": "$Album",
                "Year": "$Year",
                "Type": "$Type",
                "First": "$First",
                "artist": "$artist",
                "album": "$album",
                "year": "$year",
                "type": "$type",
                "first": "$first",
            }
            self.FILE_FORMAT = replace_all(self.FILE_FORMAT, file_values)
            self.FOLDER_FORMAT = replace_all(self.FOLDER_FORMAT, folder_values)
            self.CONFIG_VERSION = "2"

        if self.CONFIG_VERSION == "2":
            # Update the config to use direct path to the encoder rather than the encoder folder
            if self.ENCODERFOLDER:
                self.ENCODER_PATH = os.path.join(self.ENCODERFOLDER, self.ENCODER)
            self.CONFIG_VERSION = "3"

        if self.CONFIG_VERSION == "3":
            # Update the BLACKHOLE option to the NZB_DOWNLOADER format
            if self.BLACKHOLE:
                self.NZB_DOWNLOADER = 2
            self.CONFIG_VERSION = "4"

        # Enable Headphones Indexer if they have a VIP account
        if self.CONFIG_VERSION == "4":
            if self.HPUSER and self.HPPASS:
                self.HEADPHONES_INDEXER = True
            self.CONFIG_VERSION = "5"

        if self.CONFIG_VERSION == "5":
            if self.OPEN_MAGNET_LINKS:
                self.MAGNET_LINKS = 2
            self.CONFIG_VERSION = "5"
Beispiel #25
0
def searchNZB(albumid=None, new=False):

    myDB = db.DBConnection()
    
    if albumid:
        results = myDB.select('SELECT ArtistName, AlbumTitle, AlbumID, ReleaseDate from albums WHERE Status="Wanted" AND AlbumID=?', [albumid])
    else:
        results = myDB.select('SELECT ArtistName, AlbumTitle, AlbumID, ReleaseDate from albums WHERE Status="Wanted"')
        new = True
        
    for albums in results:
        
        albumid = albums[2]
        reldate = albums[3]
        
        try:
            year = reldate[:4]
        except TypeError:
            year = ''
        
        dic = {'...':'', ' & ':' ', ' = ': ' ', '?':'', '$':'s', ' + ':' ', '"':'', ',':''}

        cleanartistalbum = helpers.latinToAscii(helpers.replace_all(albums[0]+' '+albums[1], dic))

        # FLAC usually doesn't have a year for some reason so I'll leave it out:
        term = re.sub('[\.\-\/]', ' ', '%s' % (cleanartistalbum)).encode('utf-8')
        altterm = re.sub('[\.\-\/]', ' ', '%s %s' % (cleanartistalbum, year)).encode('utf-8')
        
        # Only use the year if the term could return a bunch of different albums, i.e. self-titled albums
        if albums[0] in albums[1] or len(albums[0]) < 4 or len(albums[1]) < 4:
            term = altterm    
        
        logger.info("Searching for %s since it was marked as wanted" % term)
        
        resultlist = []
        
        if headphones.NZBMATRIX:
            provider = "nzbmatrix"
            if headphones.PREFERRED_QUALITY == 3:
                categories = "23"
                maxsize = 10000000000    
            elif headphones.PREFERRED_QUALITY:
                categories = "23,22"
                maxsize = 2000000000
            else:
                categories = "22"
                maxsize = 300000000
            
            
            params = {    "page": "download",
                        "username": headphones.NZBMATRIX_USERNAME,
                        "apikey": headphones.NZBMATRIX_APIKEY,
                        "subcat": categories,
                        "age": headphones.USENET_RETENTION,
                        "english": 1,
                        "ssl": 1,
                        "scenename": 1,
                        "term": term
                        }
                        
            searchURL = "http://rss.nzbmatrix.com/rss.php?" + urllib.urlencode(params)
            logger.info(u"Parsing results from "+searchURL)
            try:
            	data = urllib2.urlopen(searchURL, timeout=20).read()
            except urllib2.URLError, e:
            	logger.warn('Error fetching data from NZBMatrix: %s' % e)
            	data = False   
            	
            if data:
            
				d = feedparser.parse(data)
				
				for item in d.entries:
					try:
						url = item.link
						title = item.title
						size = int(item.links[1]['length'])
						if size < maxsize:
							resultlist.append((title, size, url, provider))
							logger.info('Found %s. Size: %s' % (title, helpers.bytes_to_mb(size)))
						else:
							logger.info('%s is larger than the maxsize for this category, skipping. (Size: %i bytes)' % (title, size))    
					
					except AttributeError, e:
						logger.info(u"No results found from NZBMatrix for %s" % term)
Beispiel #26
0
def initialize():

    with INIT_LOCK:

        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, HTTP_PROXY, LAUNCH_BROWSER, API_ENABLED, API_KEY, GIT_PATH, CURRENT_VERSION, LATEST_VERSION, CHECK_GITHUB, CHECK_GITHUB_ON_STARTUP, CHECK_GITHUB_INTERVAL, MUSIC_DIR, DESTINATION_DIR, LOSSLESS_DESTINATION_DIR, PREFERRED_QUALITY, PREFERRED_BITRATE, DETECT_BITRATE, ADD_ARTISTS, CORRECT_METADATA, MOVE_FILES, RENAME_FILES, FOLDER_FORMAT, FILE_FORMAT, CLEANUP_FILES, INCLUDE_EXTRAS, EXTRAS, AUTOWANT_UPCOMING, AUTOWANT_ALL, ADD_ALBUM_ART, EMBED_ALBUM_ART, EMBED_LYRICS, DOWNLOAD_DIR, BLACKHOLE, BLACKHOLE_DIR, USENET_RETENTION, SEARCH_INTERVAL, TORRENTBLACKHOLE_DIR, NUMBEROFSEEDERS, ISOHUNT, KAT, MININOVA, WAFFLES, WAFFLES_UID, WAFFLES_PASSKEY, WHATCD, WHATCD_USERNAME, WHATCD_PASSWORD, DOWNLOAD_TORRENT_DIR, 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, NEWZNAB_ENABLED, EXTRA_NEWZNABS, NZBSORG, NZBSORG_UID, NZBSORG_HASH, NEWZBIN, NEWZBIN_UID, NEWZBIN_PASSWORD, LASTFM_USERNAME, INTERFACE, FOLDER_PERMISSIONS, ENCODERFOLDER, ENCODER, BITRATE, SAMPLINGFREQUENCY, MUSIC_ENCODER, ADVANCEDENCODER, ENCODEROUTPUTFORMAT, ENCODERQUALITY, ENCODERVBRCBR, ENCODERLOSSLESS, DELETE_LOSSLESS_FILES, PROWL_ENABLED, PROWL_PRIORITY, PROWL_KEYS, PROWL_ONSNATCH, MIRRORLIST, MIRROR, CUSTOMHOST, CUSTOMPORT, CUSTOMSLEEP, HPUSER, HPPASS, XBMC_ENABLED, XBMC_HOST, XBMC_USERNAME, XBMC_PASSWORD, XBMC_UPDATE, XBMC_NOTIFY, NMA_ENABLED, NMA_APIKEY, NMA_PRIORITY, NMA_ONSNATCH, SYNOINDEX_ENABLED, ALBUM_COMPLETION_PCT, PREFERRED_BITRATE_HIGH_BUFFER, PREFERRED_BITRATE_LOW_BUFFER, CACHE_SIZEMB

        if __INITIALIZED__:
            return False

        # Make sure all the config sections exist
        CheckSection("General")
        CheckSection("SABnzbd")
        CheckSection("NZBMatrix")
        CheckSection("Newznab")
        CheckSection("NZBsorg")
        CheckSection("Newzbin")
        CheckSection("Waffles")
        CheckSection("What.cd")
        CheckSection("Prowl")
        CheckSection("XBMC")
        CheckSection("NMA")
        CheckSection("Synoindex")
        CheckSection("Advanced")

        # 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:
            HTTP_PORT = 8181

        if HTTP_PORT < 21 or HTTP_PORT > 65535:
            HTTP_PORT = 8181

        HTTP_HOST = check_setting_str(CFG, "General", "http_host", "0.0.0.0")
        HTTP_USERNAME = check_setting_str(CFG, "General", "http_username", "")
        HTTP_PASSWORD = check_setting_str(CFG, "General", "http_password", "")
        HTTP_ROOT = check_setting_str(CFG, "General", "http_root", "/")
        HTTP_PROXY = bool(check_setting_int(CFG, "General", "http_proxy", 0))
        LAUNCH_BROWSER = bool(check_setting_int(CFG, "General", "launch_browser", 1))
        API_ENABLED = bool(check_setting_int(CFG, "General", "api_enabled", 0))
        API_KEY = check_setting_str(CFG, "General", "api_key", "")
        GIT_PATH = check_setting_str(CFG, "General", "git_path", "")
        LOG_DIR = check_setting_str(CFG, "General", "log_dir", "")

        CHECK_GITHUB = bool(check_setting_int(CFG, "General", "check_github", 1))
        CHECK_GITHUB_ON_STARTUP = bool(check_setting_int(CFG, "General", "check_github_on_startup", 1))
        CHECK_GITHUB_INTERVAL = check_setting_int(CFG, "General", "check_github_interval", 360)

        MUSIC_DIR = check_setting_str(CFG, "General", "music_dir", "")
        DESTINATION_DIR = check_setting_str(CFG, "General", "destination_dir", "")
        LOSSLESS_DESTINATION_DIR = check_setting_str(CFG, "General", "lossless_destination_dir", "")
        PREFERRED_QUALITY = check_setting_int(CFG, "General", "preferred_quality", 0)
        PREFERRED_BITRATE = check_setting_int(CFG, "General", "preferred_bitrate", "")
        PREFERRED_BITRATE_HIGH_BUFFER = check_setting_int(CFG, "General", "preferred_bitrate_high_buffer", "")
        PREFERRED_BITRATE_LOW_BUFFER = check_setting_int(CFG, "General", "preferred_bitrate_low_buffer", "")
        DETECT_BITRATE = bool(check_setting_int(CFG, "General", "detect_bitrate", 0))
        ADD_ARTISTS = bool(check_setting_int(CFG, "General", "auto_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))
        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))
        EMBED_LYRICS = bool(check_setting_int(CFG, "General", "embed_lyrics", 0))
        DOWNLOAD_DIR = check_setting_str(CFG, "General", "download_dir", "")
        BLACKHOLE = bool(check_setting_int(CFG, "General", "blackhole", 0))
        BLACKHOLE_DIR = check_setting_str(CFG, "General", "blackhole_dir", "")
        USENET_RETENTION = check_setting_int(CFG, "General", "usenet_retention", "1500")
        INCLUDE_EXTRAS = bool(check_setting_int(CFG, "General", "include_extras", 0))
        EXTRAS = check_setting_str(CFG, "General", "extras", "")
        AUTOWANT_UPCOMING = bool(check_setting_int(CFG, "General", "autowant_upcoming", 1))
        AUTOWANT_ALL = bool(check_setting_int(CFG, "General", "autowant_all", 0))

        SEARCH_INTERVAL = check_setting_int(CFG, "General", "search_interval", 360)
        LIBRARYSCAN_INTERVAL = check_setting_int(CFG, "General", "libraryscan_interval", 300)
        DOWNLOAD_SCAN_INTERVAL = check_setting_int(CFG, "General", "download_scan_interval", 5)

        TORRENTBLACKHOLE_DIR = check_setting_str(CFG, "General", "torrentblackhole_dir", "")
        NUMBEROFSEEDERS = check_setting_str(CFG, "General", "numberofseeders", "10")
        ISOHUNT = bool(check_setting_int(CFG, "General", "isohunt", 0))
        KAT = bool(check_setting_int(CFG, "General", "kat", 0))
        MININOVA = bool(check_setting_int(CFG, "General", "mininova", 0))
        DOWNLOAD_TORRENT_DIR = check_setting_str(CFG, "General", "download_torrent_dir", "")

        WAFFLES = bool(check_setting_int(CFG, "Waffles", "waffles", 0))
        WAFFLES_UID = check_setting_str(CFG, "Waffles", "waffles_uid", "")
        WAFFLES_PASSKEY = check_setting_str(CFG, "Waffles", "waffles_passkey", "")

        WHATCD = bool(check_setting_int(CFG, "What.cd", "whatcd", 0))
        WHATCD_USERNAME = check_setting_str(CFG, "What.cd", "whatcd_username", "")
        WHATCD_PASSWORD = check_setting_str(CFG, "What.cd", "whatcd_password", "")

        SAB_HOST = check_setting_str(CFG, "SABnzbd", "sab_host", "")
        SAB_USERNAME = check_setting_str(CFG, "SABnzbd", "sab_username", "")
        SAB_PASSWORD = check_setting_str(CFG, "SABnzbd", "sab_password", "")
        SAB_APIKEY = check_setting_str(CFG, "SABnzbd", "sab_apikey", "")
        SAB_CATEGORY = check_setting_str(CFG, "SABnzbd", "sab_category", "")

        NZBMATRIX = bool(check_setting_int(CFG, "NZBMatrix", "nzbmatrix", 0))
        NZBMATRIX_USERNAME = check_setting_str(CFG, "NZBMatrix", "nzbmatrix_username", "")
        NZBMATRIX_APIKEY = check_setting_str(CFG, "NZBMatrix", "nzbmatrix_apikey", "")

        NEWZNAB = bool(check_setting_int(CFG, "Newznab", "newznab", 0))
        NEWZNAB_HOST = check_setting_str(CFG, "Newznab", "newznab_host", "")
        NEWZNAB_APIKEY = check_setting_str(CFG, "Newznab", "newznab_apikey", "")
        NEWZNAB_ENABLED = bool(check_setting_int(CFG, "Newznab", "newznab_enabled", 1))

        # Need to pack the extra newznabs back into a list of tuples
        flattened_newznabs = check_setting_str(CFG, "Newznab", "extra_newznabs", [], log=False)
        EXTRA_NEWZNABS = list(itertools.izip(*[itertools.islice(flattened_newznabs, i, None, 3) for i in range(3)]))

        NZBSORG = bool(check_setting_int(CFG, "NZBsorg", "nzbsorg", 0))
        NZBSORG_UID = check_setting_str(CFG, "NZBsorg", "nzbsorg_uid", "")
        NZBSORG_HASH = check_setting_str(CFG, "NZBsorg", "nzbsorg_hash", "")

        NEWZBIN = bool(check_setting_int(CFG, "Newzbin", "newzbin", 0))
        NEWZBIN_UID = check_setting_str(CFG, "Newzbin", "newzbin_uid", "")
        NEWZBIN_PASSWORD = check_setting_str(CFG, "Newzbin", "newzbin_password", "")

        LASTFM_USERNAME = check_setting_str(CFG, "General", "lastfm_username", "")

        INTERFACE = check_setting_str(CFG, "General", "interface", "default")
        FOLDER_PERMISSIONS = check_setting_str(CFG, "General", "folder_permissions", "0755")

        ENCODERFOLDER = check_setting_str(CFG, "General", "encoderfolder", "")
        ENCODER = check_setting_str(CFG, "General", "encoder", "ffmpeg")
        BITRATE = check_setting_int(CFG, "General", "bitrate", 192)
        SAMPLINGFREQUENCY = check_setting_int(CFG, "General", "samplingfrequency", 44100)
        MUSIC_ENCODER = bool(check_setting_int(CFG, "General", "music_encoder", 0))
        ADVANCEDENCODER = check_setting_str(CFG, "General", "advancedencoder", "")
        ENCODEROUTPUTFORMAT = check_setting_str(CFG, "General", "encoderoutputformat", "mp3")
        ENCODERQUALITY = check_setting_int(CFG, "General", "encoderquality", 2)
        ENCODERVBRCBR = check_setting_str(CFG, "General", "encodervbrcbr", "cbr")
        ENCODERLOSSLESS = bool(check_setting_int(CFG, "General", "encoderlossless", 1))
        DELETE_LOSSLESS_FILES = bool(check_setting_int(CFG, "General", "delete_lossless_files", 1))

        PROWL_ENABLED = bool(check_setting_int(CFG, "Prowl", "prowl_enabled", 0))
        PROWL_KEYS = check_setting_str(CFG, "Prowl", "prowl_keys", "")
        PROWL_ONSNATCH = bool(check_setting_int(CFG, "Prowl", "prowl_onsnatch", 0))
        PROWL_PRIORITY = check_setting_int(CFG, "Prowl", "prowl_priority", 0)

        XBMC_ENABLED = bool(check_setting_int(CFG, "XBMC", "xbmc_enabled", 0))
        XBMC_HOST = check_setting_str(CFG, "XBMC", "xbmc_host", "")
        XBMC_USERNAME = check_setting_str(CFG, "XBMC", "xbmc_username", "")
        XBMC_PASSWORD = check_setting_str(CFG, "XBMC", "xbmc_password", "")
        XBMC_UPDATE = bool(check_setting_int(CFG, "XBMC", "xbmc_update", 0))
        XBMC_NOTIFY = bool(check_setting_int(CFG, "XBMC", "xbmc_notify", 0))

        NMA_ENABLED = bool(check_setting_int(CFG, "NMA", "nma_enabled", 0))
        NMA_APIKEY = check_setting_str(CFG, "NMA", "nma_apikey", "")
        NMA_PRIORITY = check_setting_int(CFG, "NMA", "nma_priority", 0)
        NMA_ONSNATCH = bool(check_setting_int(CFG, "NMA", "nma_onsnatch", 0))

        SYNOINDEX_ENABLED = bool(check_setting_int(CFG, "Synoindex", "synoindex_enabled", 0))

        MIRROR = check_setting_str(CFG, "General", "mirror", "musicbrainz.org")
        CUSTOMHOST = check_setting_str(CFG, "General", "customhost", "localhost")
        CUSTOMPORT = check_setting_int(CFG, "General", "customport", 5000)
        CUSTOMSLEEP = check_setting_int(CFG, "General", "customsleep", 1)
        HPUSER = check_setting_str(CFG, "General", "hpuser", "")
        HPPASS = check_setting_str(CFG, "General", "hppass", "")

        CACHE_SIZEMB = check_setting_int(CFG, "Advanced", "cache_sizemb", 32)

        ALBUM_COMPLETION_PCT = check_setting_int(CFG, "Advanced", "album_completion_pct", 80)

        # 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 CONFIG_VERSION == "1":

            from headphones.helpers import replace_all

            file_values = {
                "Track": "$Track",
                "Title": "$Title",
                "Artist": "$Artist",
                "Album": "$Album",
                "Year": "$Year",
                "track": "$track",
                "title": "$title",
                "artist": "$artist",
                "album": "$album",
                "year": "$year",
            }
            folder_values = {
                "Artist": "$Artist",
                "Album": "$Album",
                "Year": "$Year",
                "Type": "$Type",
                "First": "$First",
                "artist": "$artist",
                "album": "$album",
                "year": "$year",
                "type": "$type",
                "first": "$first",
            }
            FILE_FORMAT = replace_all(FILE_FORMAT, file_values)
            FOLDER_FORMAT = replace_all(FOLDER_FORMAT, folder_values)

            CONFIG_VERSION = "2"

        if not LOG_DIR:
            LOG_DIR = os.path.join(DATA_DIR, "logs")

        if not os.path.exists(LOG_DIR):
            try:
                os.makedirs(LOG_DIR)
            except OSError:
                if VERBOSE:
                    print "Unable to create the log directory. Logging to screen only."

        # Start the logger, silence console logging if we need to
        logger.headphones_log.initLogger(verbose=VERBOSE)

        # 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):
            try:
                os.makedirs(CACHE_DIR)
            except OSError:
                logger.error("Could not create cache dir. Check permissions of datadir: " + DATA_DIR)

        # Initialize the database
        logger.info("Checking to see if the database has all tables....")
        try:
            dbcheck()
        except Exception, e:
            logger.error("Can't connect to the database: %s" % e)

        # Get the currently installed version - returns None, 'win32' or the git hash
        # Also sets INSTALL_TYPE variable to 'win', 'git' or 'source'
        CURRENT_VERSION = versioncheck.getVersion()

        # Check for new versions
        if CHECK_GITHUB_ON_STARTUP:
            try:
                LATEST_VERSION = versioncheck.checkGithub()
            except:
                LATEST_VERSION = CURRENT_VERSION
        else:
            LATEST_VERSION = CURRENT_VERSION

        __INITIALIZED__ = True
        return True
Beispiel #27
0
def moveFiles(albumpath, release, tracks):

	try:
		year = release['ReleaseDate'][:4]
	except TypeError:
		year = ''
		
	artist = release['ArtistName'].replace('/', '_')
	album = release['AlbumTitle'].replace('/', '_')
	releasetype = release['Type'].replace('/', '_')

	if release['ArtistName'].startswith('The '):
		sortname = release['ArtistName'][4:]
	else:
		sortname = release['ArtistName']
	
	if sortname.isdigit():
		firstchar = '0-9'
	else:
		firstchar = sortname[0]
	

	values = {	'Artist':	artist,
				'Album':	album,
				'Year':		year,
				'Type':  releasetype,
				'First':	firstchar,
				'artist':	artist.lower(),
				'album':	album.lower(),
				'year':		year,
				'type':  releasetype.lower(),
				'first':	firstchar.lower()
			}
			
	
	folder = helpers.replace_all(headphones.FOLDER_FORMAT, values)
	folder = folder.replace('./', '_/').replace(':','_').replace('?','_')
	
	if folder.endswith('.'):
		folder = folder.replace(folder[len(folder)-1], '_')
	
	destination_path = os.path.normpath(os.path.join(headphones.DESTINATION_DIR, folder)).encode(headphones.SYS_ENCODING)
	
	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
			destination_path = os.path.normpath(os.path.join(headphones.DESTINATION_DIR, newfolder)).encode(headphones.SYS_ENCODING)
			if os.path.exists(destination_path):
				i += 1
			else:
				folder = newfolder
				break

	logger.info('Moving files from %s to %s' % (unicode(albumpath, headphones.SYS_ENCODING, errors="replace"), unicode(destination_path, headphones.SYS_ENCODING, errors="replace")))
	
	# 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
Beispiel #28
0
def searchNZB(albumid=None, new=False, losslessOnly=False):

    myDB = db.DBConnection()
    
    if albumid:
        results = myDB.select('SELECT ArtistName, AlbumTitle, AlbumID, ReleaseDate, Type from albums WHERE AlbumID=?', [albumid])
    else:
        results = myDB.select('SELECT ArtistName, AlbumTitle, AlbumID, ReleaseDate, Type from albums WHERE Status="Wanted" OR Status="Wanted Lossless"')
        new = True
        
    for albums in results:
        
        albumid = albums[2]
        reldate = albums[3]
        
        try:
            year = reldate[:4]
        except TypeError:
            year = ''
        
        dic = {'...':'', ' & ':' ', ' = ': ' ', '?':'', '$':'s', ' + ':' ', '"':'', ',':'', '*':'', '.':'', ':':''}

        cleanalbum = helpers.latinToAscii(helpers.replace_all(albums[1], dic))
        cleanartist = helpers.latinToAscii(helpers.replace_all(albums[0], dic))

        # FLAC usually doesn't have a year for some reason so I'll leave it out
        # Various Artist albums might be listed as VA, so I'll leave that out too
        # Only use the year if the term could return a bunch of different albums, i.e. self-titled albums
        if albums[0] in albums[1] or len(albums[0]) < 4 or len(albums[1]) < 4:
            term = cleanartist + ' ' + cleanalbum + ' ' + year
        elif albums[0] == 'Various Artists':
            term = cleanalbum + ' ' + year
        else:
            term = cleanartist + ' ' + cleanalbum
            
        # Replace bad characters in the term and unicode it
        term = re.sub('[\.\-\/]', ' ', term).encode('utf-8')
        artistterm = re.sub('[\.\-\/]', ' ', cleanartist).encode('utf-8')
        
        logger.info("Searching for %s since it was marked as wanted" % term)
        
        resultlist = []
        
        if headphones.NZBMATRIX:
            provider = "nzbmatrix"
            if headphones.PREFERRED_QUALITY == 3 or losslessOnly:
                categories = "23" 
            elif headphones.PREFERRED_QUALITY:
                categories = "23,22"
            else:
                categories = "22"
                
            # Search Audiobooks/Singles/etc
            if albums['Type'] == "Other":
                categories = "49"
                logger.info("Album type is audiobook/spokenword. Using audiobook category")
            if albums['Type'] == "Single":
                categories = "47"
                logger.info("Album type is 'Single'. Using singles category")
                
            # For some reason NZBMatrix is erroring out/timing out when the term starts with a "The" right now
            # so we'll strip it out for the time being. This may get fixed on their end, it may not, but
            # hopefully this will fix it for now. If you notice anything else it gets stuck on, please post it
            # on Github so it can be added
            if term.lower().startswith("the "):
                term = term[4:]
            
            
            params = {    "page": "download",
                        "username": headphones.NZBMATRIX_USERNAME,
                        "apikey": headphones.NZBMATRIX_APIKEY,
                        "subcat": categories,
                        "maxage": headphones.USENET_RETENTION,
                        "english": 1,
                        "ssl": 1,
                        "scenename": 1,
                        "term": term
                        }
                        
            searchURL = "http://rss.nzbmatrix.com/rss.php?" + urllib.urlencode(params)
            logger.info(u'Parsing results from <a href="%s">NZBMatrix</a>' % searchURL)
            try:
                data = urllib2.urlopen(searchURL, timeout=20).read()
            except urllib2.URLError, e:
                logger.warn('Error fetching data from NZBMatrix: %s' % e)
                data = False   
                
            if data:
            
                d = feedparser.parse(data)
                
                for item in d.entries:
                    try:
                        url = item.link
                        title = item.title
                        size = int(item.links[1]['length'])
                        
                        resultlist.append((title, size, url, provider))
                        logger.info('Found %s. Size: %s' % (title, helpers.bytes_to_mb(size)))
                    
                    except AttributeError, e:
                        logger.info(u"No results found from NZBMatrix for %s" % term)
Beispiel #29
0
    def _upgrade(self):
        """ Update folder formats in the config & bump up config version """
        if self.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'
            }
            self.FILE_FORMAT = replace_all(self.FILE_FORMAT, file_values)
            self.FOLDER_FORMAT = replace_all(self.FOLDER_FORMAT, folder_values)

            self.CONFIG_VERSION = '1'

        if self.CONFIG_VERSION == '1':
            from headphones.helpers import replace_all
            file_values = {
                'Track': '$Track',
                'Title': '$Title',
                'Artist': '$Artist',
                'Album': '$Album',
                'Year': '$Year',
                'track': '$track',
                'title': '$title',
                'artist': '$artist',
                'album': '$album',
                'year': '$year'
            }
            folder_values = {
                'Artist': '$Artist',
                'Album': '$Album',
                'Year': '$Year',
                'Type': '$Type',
                'First': '$First',
                'artist': '$artist',
                'album': '$album',
                'year': '$year',
                'type': '$type',
                'first': '$first'
            }
            self.FILE_FORMAT = replace_all(self.FILE_FORMAT, file_values)
            self.FOLDER_FORMAT = replace_all(self.FOLDER_FORMAT, folder_values)
            self.CONFIG_VERSION = '2'

        if self.CONFIG_VERSION == '2':
            # Update the config to use direct path to the encoder rather than the encoder folder
            if self.ENCODERFOLDER:
                self.ENCODER_PATH = os.path.join(self.ENCODERFOLDER,
                                                 self.ENCODER)
            self.CONFIG_VERSION = '3'

        if self.CONFIG_VERSION == '3':
            # Update the BLACKHOLE option to the NZB_DOWNLOADER format
            if self.BLACKHOLE:
                self.NZB_DOWNLOADER = 2
            self.CONFIG_VERSION = '4'

        # Enable Headphones Indexer if they have a VIP account
        if self.CONFIG_VERSION == '4':
            if self.HPUSER and self.HPPASS:
                self.HEADPHONES_INDEXER = True
            self.CONFIG_VERSION = '5'

        if self.CONFIG_VERSION == '5':
            if self.OPEN_MAGNET_LINKS:
                self.MAGNET_LINKS = 2
            self.CONFIG_VERSION = '5'
Beispiel #30
0
def getReleaseGroup(rgid):
    """
	Returns a dictionary of the best stuff from a release group
	"""
    with mb_lock:

        releaselist = []

        inc = ws.ReleaseGroupIncludes(releases=True, artist=True)
        releaseGroup = None
        attempt = 0

        while attempt < 5:

            try:
                releaseGroup = q.getReleaseGroupById(rgid, inc)
                break
            except WebServiceError, e:
                logger.warn(
                    'Attempt to retrieve information from MusicBrainz for release group "%s" failed. Sleeping 5 seconds'
                    % rgid
                )
                attempt += 1
                time.sleep(5)

        if not releaseGroup:
            return False

        time.sleep(1)
        # I think for now we have to make separate queries for each release, in order
        # to get more detailed release info (ASIN, track count, etc.)
        for release in releaseGroup.releases:

            inc = ws.ReleaseIncludes(tracks=True, releaseEvents=True)
            releaseResult = None
            attempt = 0

            while attempt < 5:

                try:
                    releaseResult = q.getReleaseById(release.id, inc)
                    break
                except WebServiceError, e:
                    logger.warn(
                        "Attempt to retrieve release information for %s from MusicBrainz failed: %s. Sleeping 5 seconds"
                        % (releaseResult.title, e)
                    )
                    attempt += 1
                    time.sleep(5)

            if not releaseResult:
                continue

                # Release filter for non-official live albums
            types = releaseResult.getTypes()
            if any("Live" in type for type in types):
                if not any("Official" in type for type in types):
                    logger.debug("%s is not an official live album. Skipping" % releaseResult.name)
                    continue

            time.sleep(1)

            formats = {"2xVinyl": "2", "Vinyl": "2", "CD": "0", "Cassette": "3", "2xCD": "1", "Digital Media": "0"}

            country = {"US": "0", "GB": "1", "JP": "2"}

            try:
                format = int(replace_all(u.extractFragment(releaseResult.releaseEvents[0].format), formats))
            except:
                format = 3

            try:
                country = int(replace_all(releaseResult.releaseEvents[0].country, country))
            except:
                country = 3

            release_dict = {
                "hasasin": bool(releaseResult.asin),
                "asin": releaseResult.asin,
                "trackscount": len(releaseResult.getTracks()),
                "releaseid": u.extractUuid(releaseResult.id),
                "releasedate": releaseResult.getEarliestReleaseDate(),
                "format": format,
                "country": country,
            }

            tracks = []

            i = 1
            for track in releaseResult.tracks:

                tracks.append(
                    {
                        "number": i,
                        "title": track.title,
                        "id": u.extractUuid(track.id),
                        "url": track.id,
                        "duration": track.duration,
                    }
                )
                i += 1

            release_dict["tracks"] = tracks

            releaselist.append(release_dict)
Beispiel #31
0
def getReleaseGroup(rgid):
	"""
	Returns a dictionary of the best stuff from a release group
	"""
	with mb_lock:
	
		releaselist = []
		
		inc = ws.ReleaseGroupIncludes(releases=True, artist=True)
		releaseGroup = None
		attempt = 0
		
		q, sleepytime = startmb()
		
		while attempt < 5:
		
			try:
				releaseGroup = q.getReleaseGroupById(rgid, inc)
				break
			except WebServiceError, e:
				logger.warn('Attempt to retrieve information from MusicBrainz for release group "%s" failed (%s)' % (rgid, str(e)))
				attempt += 1
				time.sleep(5)
	
		if not releaseGroup:
			return False
			
		time.sleep(sleepytime)
		# I think for now we have to make separate queries for each release, in order
		# to get more detailed release info (ASIN, track count, etc.)
		for release in releaseGroup.releases:
	
			inc = ws.ReleaseIncludes(tracks=True, releaseEvents=True)	
			releaseResult = None
			attempt = 0
			
			while attempt < 5:
			
				try:
					releaseResult = q.getReleaseById(release.id, inc)
					break
				except WebServiceError, e:
					logger.warn('Attempt to retrieve release information for %s from MusicBrainz failed (%s)' % (releaseResult.title, str(e)))
					attempt += 1
					time.sleep(5)		
			
			if not releaseResult:
				continue
			
			# Release filter for non-official live albums
			types = releaseResult.getTypes()
			if any('Live' in type for type in types):
				if not any('Official' in type for type in types):
					logger.debug('%s is not an official live album. Skipping' % releaseResult.name)
					continue
				
			time.sleep(sleepytime)
			
			formats = {
				'2xVinyl':			'2',
				'Vinyl':			'2',
				'CD':				'0',
				'Cassette':			'3',			
				'2xCD':				'1',
				'Digital Media':	'0'
				}
				
			country = {
				'US':	'0',
				'GB':	'1',
				'JP':	'2',
				}

			
			try:
				format = int(replace_all(u.extractFragment(releaseResult.releaseEvents[0].format), formats))
			except:
				format = 3
				
			try:
				country = int(replace_all(releaseResult.releaseEvents[0].country, country))
			except:
				country = 3
			
			release_dict = {
				'hasasin':		bool(releaseResult.asin),
				'asin':			releaseResult.asin,
				'trackscount':	len(releaseResult.getTracks()),
				'releaseid':	u.extractUuid(releaseResult.id),
				'releasedate':	releaseResult.getEarliestReleaseDate(),
				'format':		format,
				'country':		country
				}
			
			tracks = []
			
			i = 1
			for track in releaseResult.tracks:
				
				tracks.append({
						'number':		i,
						'title':		track.title,
						'id':			u.extractUuid(track.id),
						'url':			track.id,
						'duration':		track.duration
						})
				i += 1
			
			release_dict['tracks'] = tracks		
			
			releaselist.append(release_dict)
Beispiel #32
0
def searchTorrent(albumid=None, new=False, losslessOnly=False):

    myDB = db.DBConnection()
    
    if albumid:
        results = myDB.select('SELECT ArtistName, AlbumTitle, AlbumID, ReleaseDate from albums WHERE AlbumID=?', [albumid])
    else:
        results = myDB.select('SELECT ArtistName, AlbumTitle, AlbumID, ReleaseDate from albums WHERE Status="Wanted" OR Status="Wanted Lossless"')
        new = True
        
    for albums in results:
        
        albumid = albums[2]
        reldate = albums[3]
        
        try:
            year = reldate[:4]
        except TypeError:
            year = ''
        
        dic = {'...':'', ' & ':' ', ' = ': ' ', '?':'', '$':'s', ' + ':' ', '"':'', ',':'', '*':''}

        cleanalbum = helpers.latinToAscii(helpers.replace_all(albums[1], dic))
        cleanartist = helpers.latinToAscii(helpers.replace_all(albums[0], dic))

        # FLAC usually doesn't have a year for some reason so I'll leave it out
        # Various Artist albums might be listed as VA, so I'll leave that out too
        # Only use the year if the term could return a bunch of different albums, i.e. self-titled albums
        if albums[0] in albums[1] or len(albums[0]) < 4 or len(albums[1]) < 4:
            term = cleanartist + ' ' + cleanalbum + ' ' + year
        elif albums[0] == 'Various Artists':
            term = cleanalbum + ' ' + year
        else:
            term = cleanartist + ' ' + cleanalbum
            
        # Replace bad characters in the term and unicode it
        term = re.sub('[\.\-\/]', ' ', term).encode('utf-8')
        artistterm = re.sub('[\.\-\/]', ' ', cleanartist).encode('utf-8')
        albumterm  = re.sub('[\.\-\/]', ' ', cleanalbum).encode('utf-8')

        logger.info("Searching torrents for %s since it was marked as wanted" % term)
        
        resultlist = []
        minimumseeders = int(headphones.NUMBEROFSEEDERS) - 1

        if headphones.KAT:
            provider = "Kick Ass Torrent"
            providerurl = url_fix("http://www.kat.ph/search/" + term)
            if headphones.PREFERRED_QUALITY == 3 or losslessOnly:
                categories = "7"        #music
                format = "2"             #flac
                maxsize = 10000000000
            elif headphones.PREFERRED_QUALITY:
                categories = "7"        #music
                format = "10"            #mp3+flac
                maxsize = 10000000000
            else:
                categories = "7"        #music
                format = "8"            #mp3
                maxsize = 300000000        

            params = {   
                        "categories[0]": "music",
                        "field": "seeders",
                        "sorder": "desc",
                        "rss": "1"
                      }
            searchURL = providerurl + "/?%s" % urllib.urlencode(params)
            
            try:
                data = urllib2.urlopen(searchURL, timeout=20).read()
            except urllib2.URLError, e:
                logger.warn('Error fetching data from %s: %s' % (provider, e))
                data = False
            
            if data:
            
                logger.info(u'Parsing results from <a href="%s">KAT</a>' % searchURL)
                
                d = feedparser.parse(data)
                if not len(d.entries):
                    logger.info(u"No results found from %s for %s" % (provider, term))
                    pass
                
                else:
                    for item in d.entries:
                        try:
                            rightformat = True
                            title = item.title
                            seeders = item.seeds
                            url = item.links[1]['url']
                            size = int(item.links[1]['length'])
                            try:
                                if format == "2":
                                    request = urllib2.Request(url)
                                    request.add_header('Accept-encoding', 'gzip')
                                    request.add_header('Referer', 'http://kat.ph/')
                                    response = urllib2.urlopen(request)
                                    if response.info().get('Content-Encoding') == 'gzip':
                                        buf = StringIO( response.read())
                                        f = gzip.GzipFile(fileobj=buf)
                                        torrent = f.read()
                                    else:
                                        torrent = response.read()
                                    if int(torrent.find(".mp3")) > 0 and int(torrent.find(".flac")) < 1:
                                        rightformat = False
                            except Exception, e:
                                rightformat = False
                            if rightformat == True and size < maxsize and minimumseeders < int(seeders):
                                resultlist.append((title, size, url, provider))
                                logger.info('Found %s. Size: %s' % (title, helpers.bytes_to_mb(size)))
                            else:
                                logger.info('%s is larger than the maxsize, the wrong format or has too little seeders for this category, skipping. (Size: %i bytes, Seeders: %i, Format: %s)' % (title, size, int(seeders), rightformat))    
                        
                        except Exception, e:
                            logger.error(u"An unknown error occurred in the KAT parser: %s" % e)
Beispiel #33
0
def renameFiles(albumpath, downloaded_track_list, release):
    logger.info('Renaming files')
    try:
        year = release['ReleaseDate'][:4]
    except TypeError:
        year = ''
    # Until tagging works better I'm going to rely on the already provided metadata

    for downloaded_track in downloaded_track_list:
        try:
            f = MediaFile(downloaded_track)
        except:
            logger.info(
                "MediaFile couldn't parse: " +
                downloaded_track.decode(headphones.SYS_ENCODING, 'replace'))
            continue

        if not f.disc:
            discnumber = ''
        else:
            discnumber = '%d' % f.disc

        if not f.track:
            tracknumber = ''
        else:
            tracknumber = '%02d' % f.track

        if not f.title:

            basename = os.path.basename(
                downloaded_track.decode(headphones.SYS_ENCODING, 'replace'))
            title = os.path.splitext(basename)[0]
            ext = os.path.splitext(basename)[1]

            new_file_name = helpers.cleanTitle(title) + ext

        else:
            title = f.title

            if release['ArtistName'] == "Various Artists" and f.artist:
                artistname = f.artist
            else:
                artistname = release['ArtistName']

            if artistname.startswith('The '):
                sortname = artistname[4:] + ", The"
            else:
                sortname = artistname

            values = {
                '$Disc': discnumber,
                '$Track': tracknumber,
                '$Title': title,
                '$Artist': artistname,
                '$SortArtist': sortname,
                '$Album': release['AlbumTitle'],
                '$Year': year,
                '$disc': discnumber,
                '$track': tracknumber,
                '$title': title.lower(),
                '$artist': artistname.lower(),
                '$sortartist': sortname.lower(),
                '$album': release['AlbumTitle'].lower(),
                '$year': year
            }

            ext = os.path.splitext(downloaded_track)[1]

            new_file_name = helpers.replace_all(headphones.FILE_FORMAT.strip(),
                                                values).replace('/', '_') + ext

        new_file_name = new_file_name.replace('?', '_').replace(
            ':', '_').encode(headphones.SYS_ENCODING, 'replace')

        if new_file_name.startswith('.'):
            new_file_name = new_file_name.replace(0, '_')

        new_file = os.path.join(albumpath, new_file_name)

        if downloaded_track == new_file_name:
            logger.debug(
                "Renaming for: " +
                downloaded_track.decode(headphones.SYS_ENCODING, 'replace') +
                " is not neccessary")
            continue

        logger.debug(
            'Renaming %s ---> %s' %
            (downloaded_track.decode(headphones.SYS_ENCODING, 'replace'),
             new_file_name.decode(headphones.SYS_ENCODING, 'replace')))
        try:
            os.rename(downloaded_track, new_file)
        except Exception, e:
            logger.error('Error renaming file: %s. Error: %s' %
                         (downloaded_track.decode(headphones.SYS_ENCODING,
                                                  'replace'), e))
            continue
Beispiel #34
0
def libraryScan(dir=None):

    if not dir:
        dir = headphones.MUSIC_DIR

    try:
        dir = str(dir)
    except UnicodeEncodeError:
        dir = unicode(dir).encode('unicode_escape')

    if not os.path.isdir(dir):
        logger.warn('Cannot find directory: %s. Not scanning' % dir)
        return

    myDB = db.DBConnection()

    # 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'].encode(
                headphones.SYS_ENCODING)):
            myDB.action(
                'UPDATE tracks SET Location=?, BitRate=?, Format=? WHERE TrackID=?',
                [None, None, None, track['TrackID']])

    logger.info('Scanning music directory: %s' % dir)

    new_artists = []
    bitrates = []

    myDB.action('DELETE from have')

    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.lower().endswith('.' + x.lower())
                   for x in headphones.MEDIA_FORMATS):

                song = os.path.join(r, files)
                file = unicode(os.path.join(r, files),
                               headphones.SYS_ENCODING,
                               errors='replace')

                # Try to read the metadata
                try:
                    f = MediaFile(song)

                except:
                    logger.error('Cannot read file: ' + file)
                    continue

                # Grab the bitrates for the auto detect bit rate option
                if f.bitrate:
                    bitrates.append(f.bitrate)

                # 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()

                    if track:
                        myDB.action(
                            'UPDATE tracks SET Location=?, BitRate=?, Format=? WHERE TrackID=?',
                            [file, f.bitrate, f.format, track['TrackID']])
                        continue

                # Try to match on mbid if available and we couldn't find a match based on metadata
                if 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 track:
                        myDB.action(
                            'UPDATE tracks SET Location=?, BitRate=?, Format=? WHERE TrackID=?',
                            [file, f.bitrate, f.format, 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 (ArtistName, AlbumTitle, TrackNumber, TrackTitle, TrackLength, BitRate, Genre, Date, TrackID, Location, CleanName, Format) 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), f.format
                    ])

    logger.info('Completed scanning of directory: %s' % dir)
    logger.info('Checking filepaths to see if we can find any matches')

    # 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 IS NULL')
    for track in tracks:

        release = myDB.action('SELECT * from albums WHERE AlbumID=?',
                              [track['AlbumID']]).fetchone()

        try:
            year = release['ReleaseDate'][:4]
        except TypeError:
            year = ''

        artist = release['ArtistName'].replace('/', '_')
        album = release['AlbumTitle'].replace('/', '_')
        releasetype = release['Type'].replace('/', '_')

        if release['ArtistName'].startswith('The '):
            sortname = release['ArtistName'][4:]
        else:
            sortname = release['ArtistName']

        if sortname.isdigit():
            firstchar = '0-9'
        else:
            firstchar = sortname[0]

        albumvalues = {
            '$Artist': artist,
            '$Album': album,
            '$Year': year,
            '$Type': releasetype,
            '$First': firstchar,
            '$artist': artist.lower(),
            '$album': album.lower(),
            '$year': year,
            '$type': releasetype.lower(),
            '$first': firstchar.lower()
        }

        folder = helpers.replace_all(headphones.FOLDER_FORMAT, albumvalues)
        folder = folder.replace('./', '_/').replace(':', '_').replace('?', '_')

        if folder.endswith('.'):
            folder = folder.replace(folder[len(folder) - 1], '_')

        if not track['TrackNumber']:
            tracknumber = ''
        else:
            tracknumber = '%02d' % track['TrackNumber']

        title = track['TrackTitle']

        trackvalues = {
            '$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
        }

        new_file_name = helpers.replace_all(
            headphones.FILE_FORMAT, trackvalues).replace('/', '_') + '.*'

        new_file_name = new_file_name.replace('?', '_').replace(':', '_')

        full_path_to_file = os.path.normpath(
            os.path.join(headphones.MUSIC_DIR, folder,
                         new_file_name)).encode(headphones.SYS_ENCODING,
                                                'replace')

        match = glob.glob(full_path_to_file)

        if match:

            logger.info('Found a match: %s. Writing MBID to metadata' %
                        match[0])

            unipath = unicode(match[0],
                              headphones.SYS_ENCODING,
                              errors='replace')

            myDB.action('UPDATE tracks SET Location=? WHERE TrackID=?',
                        [unipath, track['TrackID']])
            myDB.action('DELETE from have WHERE Location=?', [unipath])

            # 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']
                f.save()
                myDB.action(
                    'UPDATE tracks SET BitRate=?, Format=? WHERE TrackID=?',
                    [f.bitrate, f.format, track['TrackID']])

                logger.debug('Wrote mbid to track: %s' % match[0])

            except:
                logger.error('Error embedding track id into: %s' % match[0])
                continue

    logger.info('Done checking empty filepaths')
    logger.info('Done syncing library with directory: %s' % dir)

    # Clean up the new artist list
    unique_artists = {}.fromkeys(new_artists).keys()
    current_artists = myDB.select('SELECT ArtistName, ArtistID from artists')

    artist_list = [
        f for f in unique_artists
        if f.lower() not in [x[0].lower() for x in current_artists]
    ]

    # Update track counts
    logger.info('Updating track counts')

    for artist in current_artists:
        havetracks = len(
            myDB.select(
                'SELECT TrackTitle from tracks WHERE ArtistID like ? AND Location IS NOT NULL',
                [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']])

    logger.info('Found %i new artists' % len(artist_list))

    if len(artist_list):
        if headphones.ADD_ARTISTS:
            logger.info('Importing %i new artists' % len(artist_list))
            importer.artistlist_to_mbids(artist_list)
        else:
            logger.info(
                'To add these artists, go to Manage->Manage New Artists')
            headphones.NEW_ARTISTS = artist_list

    if headphones.DETECT_BITRATE:
        headphones.PREFERRED_BITRATE = sum(bitrates) / len(bitrates) / 1000
Beispiel #35
0
def searchTorrent(albumid=None, new=False, losslessOnly=False):

    myDB = db.DBConnection()
    
    if albumid:
        results = myDB.select('SELECT ArtistName, AlbumTitle, AlbumID, ReleaseDate from albums WHERE AlbumID=?', [albumid])
    else:
        results = myDB.select('SELECT ArtistName, AlbumTitle, AlbumID, ReleaseDate from albums WHERE Status="Wanted" OR Status="Wanted Lossless"')
        new = True
        
    for albums in results:
        
        albumid = albums[2]
        reldate = albums[3]
        
        try:
            year = reldate[:4]
        except TypeError:
            year = ''
        
        dic = {'...':'', ' & ':' ', ' = ': ' ', '?':'', '$':'s', ' + ':' ', '"':'', ',':'', '*':''}

        cleanalbum = helpers.latinToAscii(helpers.replace_all(albums[1], dic))
        cleanartist = helpers.latinToAscii(helpers.replace_all(albums[0], dic))

        # FLAC usually doesn't have a year for some reason so I'll leave it out
        # Various Artist albums might be listed as VA, so I'll leave that out too
        # Only use the year if the term could return a bunch of different albums, i.e. self-titled albums
        if albums[0] in albums[1] or len(albums[0]) < 4 or len(albums[1]) < 4:
            term = cleanartist + ' ' + cleanalbum + ' ' + year
        elif albums[0] == 'Various Artists':
        	term = cleanalbum + ' ' + year
        else:
        	term = cleanartist + ' ' + cleanalbum
            
        # Replace bad characters in the term and unicode it
        term = re.sub('[\.\-\/]', ' ', term).encode('utf-8')
        artistterm = re.sub('[\.\-\/]', ' ', cleanartist).encode('utf-8')
        
        logger.info("Searching torrents for %s since it was marked as wanted" % term)
        
        resultlist = []
        minimumseeders = int(headphones.NUMBEROFSEEDERS) - 1

        if headphones.KAT:
            provider = "Kick Ass Torrent"
            providerurl = url_fix("http://www.kat.ph/search/" + term)
            if headphones.PREFERRED_QUALITY == 3 or losslessOnly:
                categories = "7"        #music
                format = "2"             #flac
                maxsize = 10000000000
            elif headphones.PREFERRED_QUALITY:
                categories = "7"        #music
                format = "10"            #mp3+flac
                maxsize = 10000000000
            else:
                categories = "7"        #music
                format = "8"            #mp3
                maxsize = 300000000        

            params = {   
                        "categories[0]": "music",
                        "field": "seeders",
                        "sorder": "desc",
                        "rss": "1"
                      }
            searchURL = providerurl + "/?%s" % urllib.urlencode(params)
            
            try:
            	data = urllib2.urlopen(searchURL, timeout=20).read()
            except urllib2.URLError, e:
            	logger.warn('Error fetching data from %s: %s' % (provider, e))
            	data = False
            
            if data:
			
				d = feedparser.parse(data)
				if not len(d.entries):
					logger.info(u"No results found from %s for %s" % (provider, term))
					pass
				
				else:
					for item in d.entries:
						try:
							rightformat = True
							title = item.title
							seeders = item.seeds
							url = item.links[1]['url']
							size = int(item.links[1]['length'])
							try:
								if format == "2":
                                                                        request = urllib2.Request(url)
                                                                        request.add_header('Accept-encoding', 'gzip')
                                                                        response = urllib2.urlopen(request)
                                                                        if response.info().get('Content-Encoding') == 'gzip':
                                                                            buf = StringIO( response.read())
                                                                            f = gzip.GzipFile(fileobj=buf)
                                                                            torrent = f.read()
                                                                        else:
                                                                            torrent = response.read()
									if int(torrent.find(".mp3")) > 0 and int(torrent.find(".flac")) < 1:
										rightformat = False
							except Exception, e:
								rightformat = False
							if rightformat == True and size < maxsize and minimumseeders < int(seeders):
								resultlist.append((title, size, url, provider))
								logger.info('Found %s. Size: %s' % (title, helpers.bytes_to_mb(size)))
							else:
								logger.info('%s is larger than the maxsize, the wrong format or has to little seeders for this category, skipping. (Size: %i bytes, Seeders: %i, Format: %s)' % (title, size, int(seeders), rightformat))    
						
						except Exception, e:
							logger.error(u"An unknown error occured in the KAT parser: %s" % e)
Beispiel #36
0
def libraryScan(dir=None):

    if not dir:
        dir = headphones.MUSIC_DIR

    try:
        dir = str(dir)
    except UnicodeEncodeError:
        dir = unicode(dir).encode("unicode_escape")

    if not os.path.isdir(dir):
        logger.warn("Cannot find directory: %s. Not scanning" % dir)
        return

    myDB = db.DBConnection()

    # 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"].encode(headphones.SYS_ENCODING)):
            myDB.action(
                "UPDATE tracks SET Location=?, BitRate=?, Format=? WHERE TrackID=?",
                [None, None, None, track["TrackID"]],
            )

    logger.info("Scanning music directory: %s" % dir)

    new_artists = []
    bitrates = []

    myDB.action("DELETE from have")

    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.lower().endswith("." + x.lower()) for x in headphones.MEDIA_FORMATS):

                song = os.path.join(r, files)
                file = unicode(os.path.join(r, files), headphones.SYS_ENCODING, errors="replace")

                # Try to read the metadata
                try:
                    f = MediaFile(song)

                except:
                    logger.error("Cannot read file: " + file)
                    continue

                    # Grab the bitrates for the auto detect bit rate option
                if f.bitrate:
                    bitrates.append(f.bitrate)

                    # 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()

                    if track:
                        myDB.action(
                            "UPDATE tracks SET Location=?, BitRate=?, Format=? WHERE TrackID=?",
                            [file, f.bitrate, f.format, track["TrackID"]],
                        )
                        continue

                        # Try to match on mbid if available and we couldn't find a match based on metadata
                if 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 track:
                        myDB.action(
                            "UPDATE tracks SET Location=?, BitRate=?, Format=? WHERE TrackID=?",
                            [file, f.bitrate, f.format, 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 (ArtistName, AlbumTitle, TrackNumber, TrackTitle, TrackLength, BitRate, Genre, Date, TrackID, Location, CleanName, Format) 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),
                        f.format,
                    ],
                )

    logger.info("Completed scanning of directory: %s" % dir)
    logger.info("Checking filepaths to see if we can find any matches")

    # 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 IS NULL")
    for track in tracks:

        release = myDB.action("SELECT * from albums WHERE AlbumID=?", [track["AlbumID"]]).fetchone()

        try:
            year = release["ReleaseDate"][:4]
        except TypeError:
            year = ""

        artist = release["ArtistName"].replace("/", "_")
        album = release["AlbumTitle"].replace("/", "_")
        releasetype = release["Type"].replace("/", "_")

        if release["ArtistName"].startswith("The "):
            sortname = release["ArtistName"][4:]
        else:
            sortname = release["ArtistName"]

        if sortname.isdigit():
            firstchar = "0-9"
        else:
            firstchar = sortname[0]

        albumvalues = {
            "$Artist": artist,
            "$Album": album,
            "$Year": year,
            "$Type": releasetype,
            "$First": firstchar,
            "$artist": artist.lower(),
            "$album": album.lower(),
            "$year": year,
            "$type": releasetype.lower(),
            "$first": firstchar.lower(),
        }

        folder = helpers.replace_all(headphones.FOLDER_FORMAT, albumvalues)
        folder = folder.replace("./", "_/").replace(":", "_").replace("?", "_")

        if folder.endswith("."):
            folder = folder.replace(folder[len(folder) - 1], "_")

        if not track["TrackNumber"]:
            tracknumber = ""
        else:
            tracknumber = "%02d" % track["TrackNumber"]

        title = track["TrackTitle"]

        trackvalues = {
            "$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,
        }

        new_file_name = helpers.replace_all(headphones.FILE_FORMAT, trackvalues).replace("/", "_") + ".*"

        new_file_name = new_file_name.replace("?", "_").replace(":", "_")

        full_path_to_file = os.path.normpath(os.path.join(headphones.MUSIC_DIR, folder, new_file_name)).encode(
            headphones.SYS_ENCODING, "replace"
        )

        match = glob.glob(full_path_to_file)

        if match:

            logger.info("Found a match: %s. Writing MBID to metadata" % match[0])

            unipath = unicode(match[0], headphones.SYS_ENCODING, errors="replace")

            myDB.action("UPDATE tracks SET Location=? WHERE TrackID=?", [unipath, track["TrackID"]])
            myDB.action("DELETE from have WHERE Location=?", [unipath])

            # 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"]
                f.save()
                myDB.action(
                    "UPDATE tracks SET BitRate=?, Format=? WHERE TrackID=?", [f.bitrate, f.format, track["TrackID"]]
                )

                logger.debug("Wrote mbid to track: %s" % match[0])

            except:
                logger.error("Error embedding track id into: %s" % match[0])
                continue

    logger.info("Done checking empty filepaths")
    logger.info("Done syncing library with directory: %s" % dir)

    # Clean up the new artist list
    unique_artists = {}.fromkeys(new_artists).keys()
    current_artists = myDB.select("SELECT ArtistName, ArtistID from artists")

    artist_list = [f for f in unique_artists if f.lower() not in [x[0].lower() for x in current_artists]]

    # Update track counts
    logger.info("Updating track counts")

    for artist in current_artists:
        havetracks = len(
            myDB.select(
                "SELECT TrackTitle from tracks WHERE ArtistID like ? AND Location IS NOT NULL", [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"]])

    logger.info("Found %i new artists" % len(artist_list))

    if len(artist_list):
        if headphones.ADD_ARTISTS:
            logger.info("Importing %i new artists" % len(artist_list))
            importer.artistlist_to_mbids(artist_list)
        else:
            logger.info("To add these artists, go to Manage->Manage New Artists")
            headphones.NEW_ARTISTS = artist_list

    if headphones.DETECT_BITRATE:
        headphones.PREFERRED_BITRATE = sum(bitrates) / len(bitrates) / 1000
Beispiel #37
0
def moveFiles(albumpath, release, tracks):

    try:
        year = release["ReleaseDate"][:4]
    except TypeError:
        year = ""

    artist = release["ArtistName"].replace("/", "_")
    album = release["AlbumTitle"].replace("/", "_")
    releasetype = release["Type"].replace("/", "_")

    if release["ArtistName"].startswith("The "):
        sortname = release["ArtistName"][4:]
    else:
        sortname = release["ArtistName"]

    if sortname.isdigit():
        firstchar = "0-9"
    else:
        firstchar = sortname[0]

    values = {
        "$Artist": artist,
        "$Album": album,
        "$Year": year,
        "$Type": releasetype,
        "$First": firstchar.upper(),
        "$artist": artist.lower(),
        "$album": album.lower(),
        "$year": year,
        "$type": releasetype.lower(),
        "$first": firstchar.lower(),
    }

    folder = helpers.replace_all(headphones.FOLDER_FORMAT.strip(), values)
    folder = (
        folder.replace("./", "_/")
        .replace(":", "_")
        .replace("?", "_")
        .replace("/.", "/_")
        .replace("<", "_")
        .replace(">", "_")
    )

    if folder.endswith("."):
        folder = folder.replace(folder[len(folder) - 1], "_")

    if folder.startswith("."):
        folder = folder.replace(0, "_")

    # Grab our list of files early on so we can determine if we need to create
    # the lossy_dest_dir, lossless_dest_dir, or both
    files_to_move = []
    lossy_media = False
    lossless_media = False

    for r, d, f in os.walk(albumpath):
        for files in f:
            files_to_move.append(os.path.join(r, files))
            if any(files.lower().endswith("." + x.lower()) for x in headphones.LOSSY_MEDIA_FORMATS):
                lossy_media = True
            if any(files.lower().endswith("." + x.lower()) for x in headphones.LOSSLESS_MEDIA_FORMATS):
                lossless_media = True

    # Do some sanity checking to see what directories we need to create:
    make_lossy_folder = False
    make_lossless_folder = False

    lossy_destination_path = os.path.normpath(os.path.join(headphones.DESTINATION_DIR, folder)).encode(
        headphones.SYS_ENCODING, "replace"
    )
    lossless_destination_path = os.path.normpath(os.path.join(headphones.LOSSLESS_DESTINATION_DIR, folder)).encode(
        headphones.SYS_ENCODING, "replace"
    )

    # If they set a destination dir for lossless media, only create the lossy folder if there is lossy media
    if headphones.LOSSLESS_DESTINATION_DIR:
        if lossy_media:
            make_lossy_folder = True
        if lossless_media:
            make_lossless_folder = True
    # If they haven't set a lossless dest_dir, just create the "lossy" folder
    else:
        make_lossy_folder = True

    last_folder = headphones.FOLDER_FORMAT.strip().split("/")[-1]

    if make_lossless_folder:
        # Only rename the folder if they use the album name, otherwise merge into existing folder
        if os.path.exists(lossless_destination_path) and "album" in last_folder.lower():

            temp_folder = folder

            i = 1
            while True:
                newfolder = temp_folder + "[%i]" % i
                lossless_destination_path = os.path.normpath(
                    os.path.join(headphones.LOSSLESS_DESTINATION_DIR, newfolder)
                ).encode(headphones.SYS_ENCODING, "replace")
                if os.path.exists(lossless_destination_path):
                    i += 1
                else:
                    temp_folder = newfolder
                    break

        if not os.path.exists(lossless_destination_path):
            try:
                os.makedirs(lossless_destination_path)
            except Exception, e:
                logger.error("Could not create lossless folder for %s. (Error: %s)" % (release["AlbumTitle"], e))
                if not make_lossy_folder:
                    return [albumpath]
Beispiel #38
0
def moveFiles(albumpath, release, tracks):

    try:
        year = release['ReleaseDate'][:4]
    except TypeError:
        year = ''

    artist = release['ArtistName'].replace('/', '_')
    album = release['AlbumTitle'].replace('/', '_')
    releasetype = release['Type'].replace('/', '_')

    if release['ArtistName'].startswith('The '):
        sortname = release['ArtistName'][4:]
    else:
        sortname = release['ArtistName']

    if sortname.isdigit():
        firstchar = '0-9'
    else:
        firstchar = sortname[0]

    lowerfirst = firstchar.lower()

    values = {
        'artist': artist,
        'album': album,
        'year': year,
        'first': firstchar,
        'lowerfirst': lowerfirst,
        'releasetype': releasetype
    }

    folder = helpers.replace_all(headphones.FOLDER_FORMAT, values)
    folder = folder.replace('./', '_/').replace(':', '_').replace('?', '_')

    if folder.endswith('.'):
        folder = folder.replace(folder[len(folder) - 1], '_')

    destination_path = os.path.normpath(
        os.path.join(headphones.DESTINATION_DIR,
                     folder)).encode(headphones.SYS_ENCODING)

    if os.path.exists(destination_path):
        i = 1
        while True:
            newfolder = folder + '[%i]' % i
            destination_path = os.path.normpath(
                os.path.join(headphones.DESTINATION_DIR,
                             newfolder)).encode(headphones.SYS_ENCODING)
            if os.path.exists(destination_path):
                i += 1
            else:
                folder = newfolder
                break

    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
Beispiel #39
0
def getReleaseGroup(rgid):
	"""
	Returns the best release out of any given release group
	"""
	with mb_lock:
	
		releaselist = []
		
		inc = ws.ReleaseGroupIncludes(releases=True)
		releaseGroup = None
		attempt = 0
		
		while attempt < 5:
		
			try:
				releaseGroup = q.getReleaseGroupById(rgid, inc)
				break
			except WebServiceError, e:
				logger.warn('Attempt to retrieve information from MusicBrainz for release group "%s" failed. Sleeping 5 seconds' % rgid)
				attempt += 1
				time.sleep(5)
	
		if not releaseGroup:
			return False
			
		time.sleep(1)
		# I think for now we have to make separate queries for each release, in order
		# to get more detailed release info (ASIN, track count, etc.)
		for release in releaseGroup.releases:
	
			inc = ws.ReleaseIncludes(tracks=True, releaseEvents=True)		
			releaseResult = None
			attempt = 0
			
			while attempt < 5:
			
				try:
					releaseResult = q.getReleaseById(release.id, inc)
					break
				except WebServiceError, e:
					logger.warn('Attempt to retrieve release information for %s from MusicBrainz failed: %s. Sleeping 5 seconds' % (releaseResult.title, e))
					attempt += 1
					time.sleep(5)		
			
			if not releaseResult:
				continue
				
			if releaseResult.title.lower() != releaseGroup.title.lower():
				continue
				
			time.sleep(1)
			
			formats = {
				'2xVinyl':			'2',
				'Vinyl':			'2',
				'CD':				'0',
				'Cassette':			'3',			
				'2xCD':				'1',
				'Digital Media':	'0'
				}
				
			country = {
				'US':	'0',
				'GB':	'1',
				'JP':	'1',
				}

			
			try:
				format = int(replace_all(u.extractFragment(releaseResult.releaseEvents[0].format), formats))
			except:
				format = 3
				
			try:
				country = int(replace_all(releaseResult.releaseEvents[0].country, country))
			except:
				country = 2
			
			release_dict = {
				'hasasin':		bool(releaseResult.asin),
				'asin':			releaseResult.asin,
				'trackscount':	len(releaseResult.getTracks()),
				'releaseid':	u.extractUuid(releaseResult.id),
				'releasedate':	releaseResult.getEarliestReleaseDate(),
				'format':		format,
				'country':		country
				}
			
			tracks = []
			
			i = 1
			for track in releaseResult.tracks:
				
				tracks.append({
						'number':		i,
						'title':		track.title,
						'id':			u.extractUuid(track.id),
						'url':			track.id,
						'duration':		track.duration
						})
				i += 1
			
			release_dict['tracks'] = tracks		
			
			releaselist.append(release_dict)
  def fileSystemScan(self):
    # 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 IS NULL')

    for track in tracks:
      release = myDB.action('SELECT * from albums WHERE AlbumID=?', [track['AlbumID']]).fetchone()

      try:
        year = release['ReleaseDate'][:4]
      except TypeError:
        year = ''

      artist = release['ArtistName'].replace('/', '_')
      album = release['AlbumTitle'].replace('/', '_')

      if release['ArtistName'].startswith('The '):
        sortname = release['ArtistName'][4:]
      else:
        sortname = release['ArtistName']

      if sortname.isdigit():
        firstchar = '0-9'
      else:
        firstchar = sortname[0]

      lowerfirst = firstchar.lower()
      albumvalues = { 'artist': artist,
        'album':  album,
        'year':   year,
        'first':  firstchar,
        'lowerfirst': lowerfirst
      }

      folder = helpers.replace_all(headphones.FOLDER_FORMAT, albumvalues)
      folder = folder.replace('./', '_/').replace(':','_').replace('?','_')

      if folder.endswith('.'):
        folder = folder.replace(folder[len(folder)-1], '_')

      if not track['TrackNumber']:
        tracknumber = ''
      else:
        tracknumber = '%02d' % track['TrackNumber']

      trackvalues = { 'tracknumber':  tracknumber,
        'title':    track['TrackTitle'],
        'artist':   release['ArtistName'],
        'album':    release['AlbumTitle'],
        'year':     year
      }

      new_file_name = helpers.replace_all(headphones.FILE_FORMAT, trackvalues).replace('/','_') + '.*'
      new_file_name = new_file_name.replace('?','_').replace(':', '_')
      full_path_to_file = os.path.normpath(os.path.join(headphones.MUSIC_DIR, folder, new_file_name)).encode(headphones.SYS_ENCODING, 'replace')
      match = glob.glob(full_path_to_file)

      if match:
        logger.info('Found a match: %s. Writing MBID to metadata' % match[0])

        unipath = unicode(match[0], headphones.SYS_ENCODING, errors='replace')

        myDB.action('UPDATE tracks SET Location=? WHERE TrackID=?', [unipath, track['TrackID']])
        myDB.action('DELETE from have WHERE Location=?', [unipath])

        # 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']
          f.save()
          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
Beispiel #41
0
def initialize():

    with INIT_LOCK:

        global __INITIALIZED__, FULL_PATH, PROG_DIR, VERBOSE, DAEMON, SYS_PLATFORM, DATA_DIR, CONFIG_FILE, CFG, CONFIG_VERSION, LOG_DIR, CACHE_DIR, \
                HTTP_PORT, HTTP_HOST, HTTP_USERNAME, HTTP_PASSWORD, HTTP_ROOT, HTTP_PROXY, LAUNCH_BROWSER, API_ENABLED, API_KEY, GIT_PATH, GIT_USER, GIT_BRANCH, \
                CURRENT_VERSION, LATEST_VERSION, CHECK_GITHUB, CHECK_GITHUB_ON_STARTUP, CHECK_GITHUB_INTERVAL, MUSIC_DIR, DESTINATION_DIR, \
                LOSSLESS_DESTINATION_DIR, PREFERRED_QUALITY, PREFERRED_BITRATE, DETECT_BITRATE, ADD_ARTISTS, CORRECT_METADATA, MOVE_FILES, \
                RENAME_FILES, FOLDER_FORMAT, FILE_FORMAT, CLEANUP_FILES, INCLUDE_EXTRAS, EXTRAS, AUTOWANT_UPCOMING, AUTOWANT_ALL, KEEP_TORRENT_FILES, \
                ADD_ALBUM_ART, ALBUM_ART_FORMAT, EMBED_ALBUM_ART, EMBED_LYRICS, DOWNLOAD_DIR, BLACKHOLE, BLACKHOLE_DIR, USENET_RETENTION, SEARCH_INTERVAL, \
                TORRENTBLACKHOLE_DIR, NUMBEROFSEEDERS, ISOHUNT, KAT, MININOVA, WAFFLES, WAFFLES_UID, WAFFLES_PASSKEY, \
                RUTRACKER, RUTRACKER_USER, RUTRACKER_PASSWORD, WHATCD, WHATCD_USERNAME, WHATCD_PASSWORD, DOWNLOAD_TORRENT_DIR, \
                LIBRARYSCAN, LIBRARYSCAN_INTERVAL, DOWNLOAD_SCAN_INTERVAL, SAB_HOST, SAB_USERNAME, SAB_PASSWORD, SAB_APIKEY, SAB_CATEGORY, \
                NZBGET_USERNAME, NZBGET_PASSWORD, NZBGET_CATEGORY, NZBGET_HOST, NZBMATRIX, NZBMATRIX_USERNAME, NZBMATRIX_APIKEY, NEWZNAB, NEWZNAB_HOST, NEWZNAB_APIKEY, NEWZNAB_ENABLED, EXTRA_NEWZNABS, \
                NZBSORG, NZBSORG_UID, NZBSORG_HASH, NEWZBIN, NEWZBIN_UID, NEWZBIN_PASSWORD, NZBSRUS, NZBSRUS_UID, NZBSRUS_APIKEY, NZBX, \
                NZB_DOWNLOADER, PREFERRED_WORDS, REQUIRED_WORDS, IGNORED_WORDS, \
                LASTFM_USERNAME, INTERFACE, FOLDER_PERMISSIONS, ENCODERFOLDER, ENCODER_PATH, ENCODER, XLDPROFILE, BITRATE, SAMPLINGFREQUENCY, \
                MUSIC_ENCODER, ADVANCEDENCODER, ENCODEROUTPUTFORMAT, ENCODERQUALITY, ENCODERVBRCBR, ENCODERLOSSLESS, DELETE_LOSSLESS_FILES, \
                PROWL_ENABLED, PROWL_PRIORITY, PROWL_KEYS, PROWL_ONSNATCH, PUSHOVER_ENABLED, PUSHOVER_PRIORITY, PUSHOVER_KEYS, PUSHOVER_ONSNATCH, MIRRORLIST, \
                MIRROR, CUSTOMHOST, CUSTOMPORT, CUSTOMSLEEP, HPUSER, HPPASS, XBMC_ENABLED, XBMC_HOST, XBMC_USERNAME, XBMC_PASSWORD, XBMC_UPDATE, \
                XBMC_NOTIFY, NMA_ENABLED, NMA_APIKEY, NMA_PRIORITY, NMA_ONSNATCH, SYNOINDEX_ENABLED, ALBUM_COMPLETION_PCT, PREFERRED_BITRATE_HIGH_BUFFER, \
                PREFERRED_BITRATE_LOW_BUFFER, PREFERRED_BITRATE_ALLOW_LOSSLESS, CACHE_SIZEMB, \
                UMASK

        if __INITIALIZED__:
            return False

        # Make sure all the config sections exist
        CheckSection('General')
        CheckSection('SABnzbd')
        CheckSection('NZBget')
        CheckSection('NZBMatrix')
        CheckSection('Newznab')
        CheckSection('NZBsorg')
        CheckSection('NZBsRus')
        CheckSection('nzbX')
        CheckSection('Newzbin')
        CheckSection('Waffles')
        CheckSection('Rutracker')
        CheckSection('What.cd')
        CheckSection('Prowl')
        CheckSection('Pushover')
        CheckSection('XBMC')
        CheckSection('NMA')
        CheckSection('Synoindex')
        CheckSection('Advanced')

        # 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:
            HTTP_PORT = 8181

        if HTTP_PORT < 21 or HTTP_PORT > 65535:
            HTTP_PORT = 8181

        HTTP_HOST = check_setting_str(CFG, 'General', 'http_host', '0.0.0.0')
        HTTP_USERNAME = check_setting_str(CFG, 'General', 'http_username', '')
        HTTP_PASSWORD = check_setting_str(CFG, 'General', 'http_password', '')
        HTTP_ROOT = check_setting_str(CFG, 'General', 'http_root', '/')
        HTTP_PROXY = bool(check_setting_int(CFG, 'General', 'http_proxy', 0))
        LAUNCH_BROWSER = bool(
            check_setting_int(CFG, 'General', 'launch_browser', 1))
        API_ENABLED = bool(check_setting_int(CFG, 'General', 'api_enabled', 0))
        API_KEY = check_setting_str(CFG, 'General', 'api_key', '')
        GIT_PATH = check_setting_str(CFG, 'General', 'git_path', '')
        GIT_USER = check_setting_str(CFG, 'General', 'git_user', 'rembo10')
        GIT_BRANCH = check_setting_str(CFG, 'General', 'git_branch', 'master')
        LOG_DIR = check_setting_str(CFG, 'General', 'log_dir', '')
        CACHE_DIR = check_setting_str(CFG, 'General', 'cache_dir', '')

        CHECK_GITHUB = bool(
            check_setting_int(CFG, 'General', 'check_github', 1))
        CHECK_GITHUB_ON_STARTUP = bool(
            check_setting_int(CFG, 'General', 'check_github_on_startup', 1))
        CHECK_GITHUB_INTERVAL = check_setting_int(CFG, 'General',
                                                  'check_github_interval', 360)

        MUSIC_DIR = check_setting_str(CFG, 'General', 'music_dir', '')
        DESTINATION_DIR = check_setting_str(CFG, 'General', 'destination_dir',
                                            '')
        LOSSLESS_DESTINATION_DIR = check_setting_str(
            CFG, 'General', 'lossless_destination_dir', '')
        PREFERRED_QUALITY = check_setting_int(CFG, 'General',
                                              'preferred_quality', 0)
        PREFERRED_BITRATE = check_setting_str(CFG, 'General',
                                              'preferred_bitrate', '')
        PREFERRED_BITRATE_HIGH_BUFFER = check_setting_int(
            CFG, 'General', 'preferred_bitrate_high_buffer', '')
        PREFERRED_BITRATE_LOW_BUFFER = check_setting_int(
            CFG, 'General', 'preferred_bitrate_low_buffer', '')
        PREFERRED_BITRATE_ALLOW_LOSSLESS = bool(
            check_setting_int(CFG, 'General',
                              'preferred_bitrate_allow_lossless', 0))
        DETECT_BITRATE = bool(
            check_setting_int(CFG, 'General', 'detect_bitrate', 0))
        ADD_ARTISTS = bool(
            check_setting_int(CFG, 'General', 'auto_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))
        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))
        ALBUM_ART_FORMAT = check_setting_str(CFG, 'General',
                                             'album_art_format', 'folder')
        EMBED_ALBUM_ART = bool(
            check_setting_int(CFG, 'General', 'embed_album_art', 0))
        EMBED_LYRICS = bool(
            check_setting_int(CFG, 'General', 'embed_lyrics', 0))
        NZB_DOWNLOADER = check_setting_int(CFG, 'General', 'nzb_downloader', 0)
        DOWNLOAD_DIR = check_setting_str(CFG, 'General', 'download_dir', '')
        BLACKHOLE = bool(check_setting_int(CFG, 'General', 'blackhole', 0))
        BLACKHOLE_DIR = check_setting_str(CFG, 'General', 'blackhole_dir', '')
        USENET_RETENTION = check_setting_int(CFG, 'General',
                                             'usenet_retention', '1500')
        INCLUDE_EXTRAS = bool(
            check_setting_int(CFG, 'General', 'include_extras', 0))
        EXTRAS = check_setting_str(CFG, 'General', 'extras', '')
        AUTOWANT_UPCOMING = bool(
            check_setting_int(CFG, 'General', 'autowant_upcoming', 1))
        AUTOWANT_ALL = bool(
            check_setting_int(CFG, 'General', 'autowant_all', 0))
        KEEP_TORRENT_FILES = bool(
            check_setting_int(CFG, 'General', 'keep_torrent_files', 0))

        SEARCH_INTERVAL = check_setting_int(CFG, 'General', 'search_interval',
                                            1440)
        LIBRARYSCAN = bool(check_setting_int(CFG, 'General', 'libraryscan', 1))
        LIBRARYSCAN_INTERVAL = check_setting_int(CFG, 'General',
                                                 'libraryscan_interval', 300)
        DOWNLOAD_SCAN_INTERVAL = check_setting_int(CFG, 'General',
                                                   'download_scan_interval', 5)

        TORRENTBLACKHOLE_DIR = check_setting_str(CFG, 'General',
                                                 'torrentblackhole_dir', '')
        NUMBEROFSEEDERS = check_setting_str(CFG, 'General', 'numberofseeders',
                                            '10')
        ISOHUNT = bool(check_setting_int(CFG, 'General', 'isohunt', 0))
        KAT = bool(check_setting_int(CFG, 'General', 'kat', 0))
        MININOVA = bool(check_setting_int(CFG, 'General', 'mininova', 0))
        DOWNLOAD_TORRENT_DIR = check_setting_str(CFG, 'General',
                                                 'download_torrent_dir', '')

        WAFFLES = bool(check_setting_int(CFG, 'Waffles', 'waffles', 0))
        WAFFLES_UID = check_setting_str(CFG, 'Waffles', 'waffles_uid', '')
        WAFFLES_PASSKEY = check_setting_str(CFG, 'Waffles', 'waffles_passkey',
                                            '')

        RUTRACKER = bool(check_setting_int(CFG, 'Rutracker', 'rutracker', 0))
        RUTRACKER_USER = check_setting_str(CFG, 'Rutracker', 'rutracker_user',
                                           '')
        RUTRACKER_PASSWORD = check_setting_str(CFG, 'Rutracker',
                                               'rutracker_password', '')

        WHATCD = bool(check_setting_int(CFG, 'What.cd', 'whatcd', 0))
        WHATCD_USERNAME = check_setting_str(CFG, 'What.cd', 'whatcd_username',
                                            '')
        WHATCD_PASSWORD = check_setting_str(CFG, 'What.cd', 'whatcd_password',
                                            '')

        SAB_HOST = check_setting_str(CFG, 'SABnzbd', 'sab_host', '')
        SAB_USERNAME = check_setting_str(CFG, 'SABnzbd', 'sab_username', '')
        SAB_PASSWORD = check_setting_str(CFG, 'SABnzbd', 'sab_password', '')
        SAB_APIKEY = check_setting_str(CFG, 'SABnzbd', 'sab_apikey', '')
        SAB_CATEGORY = check_setting_str(CFG, 'SABnzbd', 'sab_category', '')

        NZBGET_USERNAME = check_setting_str(CFG, 'NZBget', 'nzbget_username',
                                            'nzbget')
        NZBGET_PASSWORD = check_setting_str(CFG, 'NZBget', 'nzbget_password',
                                            '')
        NZBGET_CATEGORY = check_setting_str(CFG, 'NZBget', 'nzbget_category',
                                            '')
        NZBGET_HOST = check_setting_str(CFG, 'NZBget', 'nzbget_host', '')

        NZBMATRIX = bool(check_setting_int(CFG, 'NZBMatrix', 'nzbmatrix', 0))
        NZBMATRIX_USERNAME = check_setting_str(CFG, 'NZBMatrix',
                                               'nzbmatrix_username', '')
        NZBMATRIX_APIKEY = check_setting_str(CFG, 'NZBMatrix',
                                             'nzbmatrix_apikey', '')

        NEWZNAB = bool(check_setting_int(CFG, 'Newznab', 'newznab', 0))
        NEWZNAB_HOST = check_setting_str(CFG, 'Newznab', 'newznab_host', '')
        NEWZNAB_APIKEY = check_setting_str(CFG, 'Newznab', 'newznab_apikey',
                                           '')
        NEWZNAB_ENABLED = bool(
            check_setting_int(CFG, 'Newznab', 'newznab_enabled', 1))

        # Need to pack the extra newznabs back into a list of tuples
        flattened_newznabs = check_setting_str(CFG,
                                               'Newznab',
                                               'extra_newznabs', [],
                                               log=False)
        EXTRA_NEWZNABS = list(
            itertools.izip(*[
                itertools.islice(flattened_newznabs, i, None, 3)
                for i in range(3)
            ]))

        NZBSORG = bool(check_setting_int(CFG, 'NZBsorg', 'nzbsorg', 0))
        NZBSORG_UID = check_setting_str(CFG, 'NZBsorg', 'nzbsorg_uid', '')
        NZBSORG_HASH = check_setting_str(CFG, 'NZBsorg', 'nzbsorg_hash', '')

        NEWZBIN = bool(check_setting_int(CFG, 'Newzbin', 'newzbin', 0))
        NEWZBIN_UID = check_setting_str(CFG, 'Newzbin', 'newzbin_uid', '')
        NEWZBIN_PASSWORD = check_setting_str(CFG, 'Newzbin',
                                             'newzbin_password', '')

        NZBSRUS = bool(check_setting_int(CFG, 'NZBsRus', 'nzbsrus', 0))
        NZBSRUS_UID = check_setting_str(CFG, 'NZBsRus', 'nzbsrus_uid', '')
        NZBSRUS_APIKEY = check_setting_str(CFG, 'NZBsRus', 'nzbsrus_apikey',
                                           '')

        NZBX = bool(check_setting_int(CFG, 'nzbX', 'nzbx', 0))

        PREFERRED_WORDS = check_setting_str(CFG, 'General', 'preferred_words',
                                            '')
        IGNORED_WORDS = check_setting_str(CFG, 'General', 'ignored_words', '')
        REQUIRED_WORDS = check_setting_str(CFG, 'General', 'required_words',
                                           '')

        LASTFM_USERNAME = check_setting_str(CFG, 'General', 'lastfm_username',
                                            '')

        INTERFACE = check_setting_str(CFG, 'General', 'interface', 'default')
        FOLDER_PERMISSIONS = check_setting_str(CFG, 'General',
                                               'folder_permissions', '0755')

        ENCODERFOLDER = check_setting_str(CFG, 'General', 'encoderfolder', '')
        ENCODER_PATH = check_setting_str(CFG, 'General', 'encoder_path', '')
        ENCODER = check_setting_str(CFG, 'General', 'encoder', 'ffmpeg')
        XLDPROFILE = check_setting_str(CFG, 'General', 'xldprofile', '')
        BITRATE = check_setting_int(CFG, 'General', 'bitrate', 192)
        SAMPLINGFREQUENCY = check_setting_int(CFG, 'General',
                                              'samplingfrequency', 44100)
        MUSIC_ENCODER = bool(
            check_setting_int(CFG, 'General', 'music_encoder', 0))
        ADVANCEDENCODER = check_setting_str(CFG, 'General', 'advancedencoder',
                                            '')
        ENCODEROUTPUTFORMAT = check_setting_str(CFG, 'General',
                                                'encoderoutputformat', 'mp3')
        ENCODERQUALITY = check_setting_int(CFG, 'General', 'encoderquality', 2)
        ENCODERVBRCBR = check_setting_str(CFG, 'General', 'encodervbrcbr',
                                          'cbr')
        ENCODERLOSSLESS = bool(
            check_setting_int(CFG, 'General', 'encoderlossless', 1))
        DELETE_LOSSLESS_FILES = bool(
            check_setting_int(CFG, 'General', 'delete_lossless_files', 1))

        PROWL_ENABLED = bool(
            check_setting_int(CFG, 'Prowl', 'prowl_enabled', 0))
        PROWL_KEYS = check_setting_str(CFG, 'Prowl', 'prowl_keys', '')
        PROWL_ONSNATCH = bool(
            check_setting_int(CFG, 'Prowl', 'prowl_onsnatch', 0))
        PROWL_PRIORITY = check_setting_int(CFG, 'Prowl', 'prowl_priority', 0)

        XBMC_ENABLED = bool(check_setting_int(CFG, 'XBMC', 'xbmc_enabled', 0))
        XBMC_HOST = check_setting_str(CFG, 'XBMC', 'xbmc_host', '')
        XBMC_USERNAME = check_setting_str(CFG, 'XBMC', 'xbmc_username', '')
        XBMC_PASSWORD = check_setting_str(CFG, 'XBMC', 'xbmc_password', '')
        XBMC_UPDATE = bool(check_setting_int(CFG, 'XBMC', 'xbmc_update', 0))
        XBMC_NOTIFY = bool(check_setting_int(CFG, 'XBMC', 'xbmc_notify', 0))

        NMA_ENABLED = bool(check_setting_int(CFG, 'NMA', 'nma_enabled', 0))
        NMA_APIKEY = check_setting_str(CFG, 'NMA', 'nma_apikey', '')
        NMA_PRIORITY = check_setting_int(CFG, 'NMA', 'nma_priority', 0)
        NMA_ONSNATCH = bool(check_setting_int(CFG, 'NMA', 'nma_onsnatch', 0))

        SYNOINDEX_ENABLED = bool(
            check_setting_int(CFG, 'Synoindex', 'synoindex_enabled', 0))

        PUSHOVER_ENABLED = bool(
            check_setting_int(CFG, 'Pushover', 'pushover_enabled', 0))
        PUSHOVER_KEYS = check_setting_str(CFG, 'Pushover', 'pushover_keys', '')
        PUSHOVER_ONSNATCH = bool(
            check_setting_int(CFG, 'Pushover', 'pushover_onsnatch', 0))
        PUSHOVER_PRIORITY = check_setting_int(CFG, 'Pushover',
                                              'pushover_priority', 0)

        MIRROR = check_setting_str(CFG, 'General', 'mirror', 'musicbrainz.org')
        CUSTOMHOST = check_setting_str(CFG, 'General', 'customhost',
                                       'localhost')
        CUSTOMPORT = check_setting_int(CFG, 'General', 'customport', 5000)
        CUSTOMSLEEP = check_setting_int(CFG, 'General', 'customsleep', 1)
        HPUSER = check_setting_str(CFG, 'General', 'hpuser', '')
        HPPASS = check_setting_str(CFG, 'General', 'hppass', '')

        CACHE_SIZEMB = check_setting_int(CFG, 'Advanced', 'cache_sizemb', 32)

        ALBUM_COMPLETION_PCT = check_setting_int(CFG, 'Advanced',
                                                 'album_completion_pct', 80)

        # 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 CONFIG_VERSION == '1':

            from headphones.helpers import replace_all

            file_values = {
                'Track': '$Track',
                'Title': '$Title',
                'Artist': '$Artist',
                'Album': '$Album',
                'Year': '$Year',
                'track': '$track',
                'title': '$title',
                'artist': '$artist',
                'album': '$album',
                'year': '$year'
            }
            folder_values = {
                'Artist': '$Artist',
                'Album': '$Album',
                'Year': '$Year',
                'Type': '$Type',
                'First': '$First',
                'artist': '$artist',
                'album': '$album',
                'year': '$year',
                'type': '$type',
                'first': '$first'
            }
            FILE_FORMAT = replace_all(FILE_FORMAT, file_values)
            FOLDER_FORMAT = replace_all(FOLDER_FORMAT, folder_values)

            CONFIG_VERSION = '2'

        if CONFIG_VERSION == '2':

            # Update the config to use direct path to the encoder rather than the encoder folder
            if ENCODERFOLDER:
                ENCODER_PATH = os.path.join(ENCODERFOLDER, ENCODER)
            CONFIG_VERSION = '3'

        if CONFIG_VERSION == '3':
            #Update the BLACKHOLE option to the NZB_DOWNLOADER format
            if BLACKHOLE:
                NZB_DOWNLOADER = 2
            CONFIG_VERSION = '4'

        if not LOG_DIR:
            LOG_DIR = os.path.join(DATA_DIR, 'logs')

        if not os.path.exists(LOG_DIR):
            try:
                os.makedirs(LOG_DIR)
            except OSError:
                if VERBOSE:
                    print 'Unable to create the log directory. Logging to screen only.'

        # Start the logger, silence console logging if we need to
        logger.headphones_log.initLogger(verbose=VERBOSE)

        if not CACHE_DIR:
            # 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):
            try:
                os.makedirs(CACHE_DIR)
            except OSError:
                logger.error(
                    'Could not create cache dir. Check permissions of datadir: '
                    + DATA_DIR)

        # Sanity check for search interval. Set it to at least 6 hours
        if SEARCH_INTERVAL < 360:
            logger.info("Search interval too low. Resetting to 6 hour minimum")
            SEARCH_INTERVAL = 360

        # Initialize the database
        logger.info('Checking to see if the database has all tables....')
        try:
            dbcheck()
        except Exception, e:
            logger.error("Can't connect to the database: %s" % e)

        # Get the currently installed version - returns None, 'win32' or the git hash
        # Also sets INSTALL_TYPE variable to 'win', 'git' or 'source'
        CURRENT_VERSION = versioncheck.getVersion()

        # Check for new versions
        if CHECK_GITHUB_ON_STARTUP:
            try:
                LATEST_VERSION = versioncheck.checkGithub()
            except:
                LATEST_VERSION = CURRENT_VERSION
        else:
            LATEST_VERSION = CURRENT_VERSION

        # Store the original umask
        UMASK = os.umask(0)
        os.umask(UMASK)

        __INITIALIZED__ = True
        return True
Beispiel #42
0
def initialize():

    with INIT_LOCK:

        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, CHECK_GITHUB, CHECK_GITHUB_ON_STARTUP, CHECK_GITHUB_INTERVAL, 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, AUTOWANT_UPCOMING, AUTOWANT_ALL, \
                ADD_ALBUM_ART, EMBED_ALBUM_ART, EMBED_LYRICS, DOWNLOAD_DIR, BLACKHOLE, BLACKHOLE_DIR, USENET_RETENTION, SEARCH_INTERVAL, \
                TORRENTBLACKHOLE_DIR, NUMBEROFSEEDERS, ISOHUNT, KAT, MININOVA, DOWNLOAD_TORRENT_DIR, \
                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, \
                NZBSORG, NZBSORG_UID, NZBSORG_HASH, NEWZBIN, NEWZBIN_UID, NEWZBIN_PASSWORD, LASTFM_USERNAME, INTERFACE, FOLDER_PERMISSIONS, \
                ENCODERFOLDER, ENCODER, BITRATE, SAMPLINGFREQUENCY, MUSIC_ENCODER, ADVANCEDENCODER, ENCODEROUTPUTFORMAT, ENCODERQUALITY, ENCODERVBRCBR, \
                ENCODERLOSSLESS, PROWL_ENABLED, PROWL_PRIORITY, PROWL_KEYS, PROWL_ONSNATCH, MIRRORLIST, MIRROR, CUSTOMHOST, CUSTOMPORT, \
                CUSTOMSLEEP, HPUSER, HPPASS, XBMC_ENABLED, XBMC_HOST, XBMC_USERNAME, XBMC_PASSWORD, XBMC_UPDATE, XBMC_NOTIFY, NMA_ENABLED, NMA_APIKEY, NMA_PRIORITY

        if __INITIALIZED__:
            return False

        # Make sure all the config sections exist
        CheckSection('General')
        CheckSection('SABnzbd')
        CheckSection('NZBMatrix')
        CheckSection('Newznab')
        CheckSection('NZBsorg')
        CheckSection('Newzbin')
        CheckSection('Prowl')
        CheckSection('XBMC')
        CheckSection('NMA')

        # 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:
            HTTP_PORT = 8181

        if HTTP_PORT < 21 or HTTP_PORT > 65535:
            HTTP_PORT = 8181

        HTTP_HOST = check_setting_str(CFG, 'General', 'http_host', '0.0.0.0')
        HTTP_USERNAME = check_setting_str(CFG, 'General', 'http_username', '')
        HTTP_PASSWORD = check_setting_str(CFG, 'General', 'http_password', '')
        HTTP_ROOT = check_setting_str(CFG, 'General', 'http_root', '/')
        LAUNCH_BROWSER = bool(
            check_setting_int(CFG, 'General', 'launch_browser', 1))
        API_ENABLED = bool(check_setting_int(CFG, 'General', 'api_enabled', 0))
        API_KEY = check_setting_str(CFG, 'General', 'api_key', '')
        GIT_PATH = check_setting_str(CFG, 'General', 'git_path', '')
        LOG_DIR = check_setting_str(CFG, 'General', 'log_dir', '')

        CHECK_GITHUB = bool(
            check_setting_int(CFG, 'General', 'check_github', 1))
        CHECK_GITHUB_ON_STARTUP = bool(
            check_setting_int(CFG, 'General', 'check_github_on_startup', 1))
        CHECK_GITHUB_INTERVAL = check_setting_int(CFG, 'General',
                                                  'check_github_interval', 360)

        MUSIC_DIR = check_setting_str(CFG, 'General', 'music_dir', '')
        DESTINATION_DIR = check_setting_str(CFG, 'General', 'destination_dir',
                                            '')
        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', 'auto_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))
        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))
        EMBED_LYRICS = bool(
            check_setting_int(CFG, 'General', 'embed_lyrics', 0))
        DOWNLOAD_DIR = check_setting_str(CFG, 'General', 'download_dir', '')
        BLACKHOLE = bool(check_setting_int(CFG, 'General', 'blackhole', 0))
        BLACKHOLE_DIR = check_setting_str(CFG, 'General', 'blackhole_dir', '')
        USENET_RETENTION = check_setting_int(CFG, 'General',
                                             'usenet_retention', '')
        INCLUDE_EXTRAS = bool(
            check_setting_int(CFG, 'General', 'include_extras', 0))
        AUTOWANT_UPCOMING = bool(
            check_setting_int(CFG, 'General', 'autowant_upcoming', 1))
        AUTOWANT_ALL = bool(
            check_setting_int(CFG, 'General', 'autowant_all', 0))

        SEARCH_INTERVAL = check_setting_int(CFG, 'General', 'search_interval',
                                            360)
        LIBRARYSCAN_INTERVAL = check_setting_int(CFG, 'General',
                                                 'libraryscan_interval', 300)
        DOWNLOAD_SCAN_INTERVAL = check_setting_int(CFG, 'General',
                                                   'download_scan_interval', 5)

        TORRENTBLACKHOLE_DIR = check_setting_str(CFG, 'General',
                                                 'torrentblackhole_dir', '')
        NUMBEROFSEEDERS = check_setting_str(CFG, 'General', 'numberofseeders',
                                            '10')
        ISOHUNT = bool(check_setting_int(CFG, 'General', 'isohunt', 0))
        KAT = bool(check_setting_int(CFG, 'General', 'kat', 0))
        MININOVA = bool(check_setting_int(CFG, 'General', 'mininova', 0))
        DOWNLOAD_TORRENT_DIR = check_setting_str(CFG, 'General',
                                                 'download_torrent_dir', '')

        SAB_HOST = check_setting_str(CFG, 'SABnzbd', 'sab_host', '')
        SAB_USERNAME = check_setting_str(CFG, 'SABnzbd', 'sab_username', '')
        SAB_PASSWORD = check_setting_str(CFG, 'SABnzbd', 'sab_password', '')
        SAB_APIKEY = check_setting_str(CFG, 'SABnzbd', 'sab_apikey', '')
        SAB_CATEGORY = check_setting_str(CFG, 'SABnzbd', 'sab_category', '')

        NZBMATRIX = bool(check_setting_int(CFG, 'NZBMatrix', 'nzbmatrix', 0))
        NZBMATRIX_USERNAME = check_setting_str(CFG, 'NZBMatrix',
                                               'nzbmatrix_username', '')
        NZBMATRIX_APIKEY = check_setting_str(CFG, 'NZBMatrix',
                                             'nzbmatrix_apikey', '')

        NEWZNAB = bool(check_setting_int(CFG, 'Newznab', 'newznab', 0))
        NEWZNAB_HOST = check_setting_str(CFG, 'Newznab', 'newznab_host', '')
        NEWZNAB_APIKEY = check_setting_str(CFG, 'Newznab', 'newznab_apikey',
                                           '')

        NZBSORG = bool(check_setting_int(CFG, 'NZBsorg', 'nzbsorg', 0))
        NZBSORG_UID = check_setting_str(CFG, 'NZBsorg', 'nzbsorg_uid', '')
        NZBSORG_HASH = check_setting_str(CFG, 'NZBsorg', 'nzbsorg_hash', '')

        NEWZBIN = bool(check_setting_int(CFG, 'Newzbin', 'newzbin', 0))
        NEWZBIN_UID = check_setting_str(CFG, 'Newzbin', 'newzbin_uid', '')
        NEWZBIN_PASSWORD = check_setting_str(CFG, 'Newzbin',
                                             'newzbin_password', '')

        LASTFM_USERNAME = check_setting_str(CFG, 'General', 'lastfm_username',
                                            '')

        INTERFACE = check_setting_str(CFG, 'General', 'interface', 'default')
        FOLDER_PERMISSIONS = check_setting_str(CFG, 'General',
                                               'folder_permissions', '0755')

        ENCODERFOLDER = check_setting_str(CFG, 'General', 'encoderfolder', '')
        ENCODER = check_setting_str(CFG, 'General', 'encoder', 'ffmpeg')
        BITRATE = check_setting_int(CFG, 'General', 'bitrate', 192)
        SAMPLINGFREQUENCY = check_setting_int(CFG, 'General',
                                              'samplingfrequency', 44100)
        MUSIC_ENCODER = bool(
            check_setting_int(CFG, 'General', 'music_encoder', 0))
        ADVANCEDENCODER = check_setting_str(CFG, 'General', 'advancedencoder',
                                            '')
        ENCODEROUTPUTFORMAT = check_setting_str(CFG, 'General',
                                                'encoderoutputformat', 'mp3')
        ENCODERQUALITY = check_setting_int(CFG, 'General', 'encoderquality', 2)
        ENCODERVBRCBR = check_setting_str(CFG, 'General', 'encodervbrcbr',
                                          'cbr')
        ENCODERLOSSLESS = bool(
            check_setting_int(CFG, 'General', 'encoderlossless', 1))

        PROWL_ENABLED = bool(
            check_setting_int(CFG, 'Prowl', 'prowl_enabled', 0))
        PROWL_KEYS = check_setting_str(CFG, 'Prowl', 'prowl_keys', '')
        PROWL_ONSNATCH = bool(
            check_setting_int(CFG, 'Prowl', 'prowl_onsnatch', 0))
        PROWL_PRIORITY = check_setting_int(CFG, 'Prowl', 'prowl_priority', 0)

        XBMC_ENABLED = bool(check_setting_int(CFG, 'XBMC', 'xbmc_enabled', 0))
        XBMC_HOST = check_setting_str(CFG, 'XBMC', 'xbmc_host', '')
        XBMC_USERNAME = check_setting_str(CFG, 'XBMC', 'xbmc_username', '')
        XBMC_PASSWORD = check_setting_str(CFG, 'XBMC', 'xbmc_password', '')
        XBMC_UPDATE = bool(check_setting_int(CFG, 'XBMC', 'xbmc_update', 0))
        XBMC_NOTIFY = bool(check_setting_int(CFG, 'XBMC', 'xbmc_notify', 0))

        NMA_ENABLED = bool(check_setting_int(CFG, 'NMA', 'nma_enabled', 0))
        NMA_APIKEY = check_setting_str(CFG, 'NMA', 'nma_apikey', '')
        NMA_PRIORITY = check_setting_int(CFG, 'NMA', 'nma_priority', 0)

        MIRROR = check_setting_str(CFG, 'General', 'mirror', 'musicbrainz.org')
        CUSTOMHOST = check_setting_str(CFG, 'General', 'customhost',
                                       'localhost')
        CUSTOMPORT = check_setting_int(CFG, 'General', 'customport', 5000)
        CUSTOMSLEEP = check_setting_int(CFG, 'General', 'customsleep', 1)
        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 CONFIG_VERSION == '1':

            from headphones.helpers import replace_all

            file_values = {
                'Track': '$Track',
                'Title': '$Title',
                'Artist': '$Artist',
                'Album': '$Album',
                'Year': '$Year',
                'track': '$track',
                'title': '$title',
                'artist': '$artist',
                'album': '$album',
                'year': '$year'
            }
            folder_values = {
                'Artist': '$Artist',
                'Album': '$Album',
                'Year': '$Year',
                'Type': '$Type',
                'First': '$First',
                'artist': '$artist',
                'album': '$album',
                'year': '$year',
                'type': '$type',
                'first': '$first'
            }
            FILE_FORMAT = replace_all(FILE_FORMAT, file_values)
            FOLDER_FORMAT = replace_all(FOLDER_FORMAT, folder_values)

            CONFIG_VERSION = '2'

        if not LOG_DIR:
            LOG_DIR = os.path.join(DATA_DIR, 'logs')

        if not os.path.exists(LOG_DIR):
            try:
                os.makedirs(LOG_DIR)
            except OSError:
                if VERBOSE:
                    print 'Unable to create the log directory. Logging to screen only.'

        # Start the logger, silence console logging if we need to
        logger.headphones_log.initLogger(verbose=VERBOSE)

        # 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):
            try:
                os.makedirs(CACHE_DIR)
            except OSError:
                logger.error(
                    'Could not create cache dir. Check permissions of datadir: '
                    + DATA_DIR)

        # Initialize the database
        logger.info('Checking to see if the database has all tables....')
        try:
            dbcheck()
        except Exception, e:
            logger.error("Can't connect to the database: %s" % e)

        # Get the currently installed version - returns None, 'win32' or the git hash
        # Also sets INSTALL_TYPE variable to 'win', 'git' or 'source'
        CURRENT_VERSION = versioncheck.getVersion()

        # Check for new versions
        if CHECK_GITHUB_ON_STARTUP:
            try:
                LATEST_VERSION = versioncheck.checkGithub()
            except:
                LATEST_VERSION = CURRENT_VERSION
        else:
            LATEST_VERSION = CURRENT_VERSION

        __INITIALIZED__ = True
        return True
Beispiel #43
0
def moveFiles(albumpath, release, tracks):

    try:
        year = release['ReleaseDate'][:4]
    except TypeError:
        year = ''
        
    artist = release['ArtistName'].replace('/', '_')
    album = release['AlbumTitle'].replace('/', '_')
    releasetype = release['Type'].replace('/', '_')

    if release['ArtistName'].startswith('The '):
        sortname = release['ArtistName'][4:]
    else:
        sortname = release['ArtistName']
    
    if sortname.isdigit():
        firstchar = '0-9'
    else:
        firstchar = sortname[0]
    

    values = {  '$Artist':  artist,
                '$Album':   album,
                '$Year':        year,
                '$Type':  releasetype,
                '$First':   firstchar,
                '$artist':  artist.lower(),
                '$album':   album.lower(),
                '$year':        year,
                '$type':  releasetype.lower(),
                '$first':   firstchar.lower()
            }
            
    
    folder = helpers.replace_all(headphones.FOLDER_FORMAT, values)
    folder = folder.replace('./', '_/').replace(':','_').replace('?','_').replace('/.','/_')
    
    if folder.endswith('.'):
        folder = folder.replace(folder[len(folder)-1], '_')
        
    if folder.startswith('.'):
        folder = folder.replace(0, '_')
        
    # Grab our list of files early on so we can determine if we need to create
    # the lossy_dest_dir, lossless_dest_dir, or both
    files_to_move = []
    lossy_media = False
    lossless_media = False
    
    for r,d,f in os.walk(albumpath):
        for files in f:
            files_to_move.append(os.path.join(r, files))
            if any(files.lower().endswith('.' + x.lower()) for x in headphones.LOSSY_MEDIA_FORMATS):
                lossy_media = True
            if any(files.lower().endswith('.' + x.lower()) for x in headphones.LOSSLESS_MEDIA_FORMATS):
                lossless_media = True

    # Do some sanity checking to see what directories we need to create:
    make_lossy_folder = False
    make_lossless_folder = False
    
    lossy_destination_path = os.path.normpath(os.path.join(headphones.DESTINATION_DIR, folder)).encode(headphones.SYS_ENCODING)
    lossless_destination_path = os.path.normpath(os.path.join(headphones.LOSSLESS_DESTINATION_DIR, folder)).encode(headphones.SYS_ENCODING)
    
    # If they set a destination dir for lossless media, only create the lossy folder if there is lossy media
    if headphones.LOSSLESS_DESTINATION_DIR:
        if lossy_media:
            make_lossy_folder = True
        if lossless_media:
            make_lossless_folder = True
    # If they haven't set a lossless dest_dir, just create the "lossy" folder
    else:
        make_lossy_folder = True

    last_folder = headphones.FOLDER_FORMAT.split('/')[-1]
    
    if make_lossless_folder:
        # Only rename the folder if they use the album name, otherwise merge into existing folder
        if os.path.exists(lossless_destination_path) and 'album' in last_folder.lower():
            
            temp_folder = folder
            
            i = 1
            while True:
                newfolder = temp_folder + '[%i]' % i
                lossless_destination_path = os.path.normpath(os.path.join(headphones.LOSSLESS_DESTINATION_DIR, newfolder)).encode(headphones.SYS_ENCODING)
                if os.path.exists(lossless_destination_path):
                    i += 1
                else:
                    temp_folder = newfolder
                    break
                    
        if not os.path.exists(lossless_destination_path):
            try:
                os.makedirs(lossless_destination_path)
            except Exception, e:
                logger.error('Could not create lossless folder for %s. (Error: %s)' % (release['AlbumTitle'], e))
                if not make_lossy_folder:
                    return albumpath
Beispiel #44
0
    def _upgrade(self):
        """ Update folder formats in the config & bump up config version """
        if self.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'
            }
            self.FILE_FORMAT = replace_all(self.FILE_FORMAT, file_values)
            self.FOLDER_FORMAT = replace_all(self.FOLDER_FORMAT, folder_values)

            self.CONFIG_VERSION = '1'

        if self.CONFIG_VERSION == '1':
            from headphones.helpers import replace_all
            file_values = {
                'Track': '$Track',
                'Title': '$Title',
                'Artist': '$Artist',
                'Album': '$Album',
                'Year': '$Year',
                'track': '$track',
                'title': '$title',
                'artist': '$artist',
                'album': '$album',
                'year': '$year'
            }
            folder_values = {
                'Artist': '$Artist',
                'Album': '$Album',
                'Year': '$Year',
                'Type': '$Type',
                'First': '$First',
                'artist': '$artist',
                'album': '$album',
                'year': '$year',
                'type': '$type',
                'first': '$first'
            }
            self.FILE_FORMAT = replace_all(self.FILE_FORMAT, file_values)
            self.FOLDER_FORMAT = replace_all(self.FOLDER_FORMAT, folder_values)
            self.CONFIG_VERSION = '2'

        if self.CONFIG_VERSION == '2':
            # Update the config to use direct path to the encoder rather than the encoder folder
            if self.ENCODERFOLDER:
                self.ENCODER_PATH = os.path.join(self.ENCODERFOLDER, self.ENCODER)
            self.CONFIG_VERSION = '3'

        if self.CONFIG_VERSION == '3':
            # Update the BLACKHOLE option to the NZB_DOWNLOADER format
            if self.BLACKHOLE:
                self.NZB_DOWNLOADER = 2
            self.CONFIG_VERSION = '4'

        # Enable Headphones Indexer if they have a VIP account
        if self.CONFIG_VERSION == '4':
            if self.HPUSER and self.HPPASS:
                self.HEADPHONES_INDEXER = True
            self.CONFIG_VERSION = '5'

        if self.CONFIG_VERSION == '5':
            if self.OPEN_MAGNET_LINKS:
                self.MAGNET_LINKS = 2
            self.CONFIG_VERSION = '5'
Beispiel #45
0
def initialize():

    with INIT_LOCK:
    
        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, CHECK_GITHUB, CHECK_GITHUB_ON_STARTUP, CHECK_GITHUB_INTERVAL, 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, AUTOWANT_UPCOMING, AUTOWANT_ALL, \
                ADD_ALBUM_ART, EMBED_ALBUM_ART, EMBED_LYRICS, DOWNLOAD_DIR, BLACKHOLE, BLACKHOLE_DIR, USENET_RETENTION, SEARCH_INTERVAL, \
                TORRENTBLACKHOLE_DIR, NUMBEROFSEEDERS, ISOHUNT, KAT, MININOVA, DOWNLOAD_TORRENT_DIR, \
                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, \
                NZBSORG, NZBSORG_UID, NZBSORG_HASH, NEWZBIN, NEWZBIN_UID, NEWZBIN_PASSWORD, LASTFM_USERNAME, INTERFACE, FOLDER_PERMISSIONS, \
                ENCODERFOLDER, ENCODER, BITRATE, SAMPLINGFREQUENCY, MUSIC_ENCODER, ADVANCEDENCODER, ENCODEROUTPUTFORMAT, ENCODERQUALITY, ENCODERVBRCBR, \
                ENCODERLOSSLESS, PROWL_ENABLED, PROWL_PRIORITY, PROWL_KEYS, PROWL_ONSNATCH, MIRRORLIST, MIRROR, CUSTOMHOST, CUSTOMPORT, \
                CUSTOMSLEEP, HPUSER, HPPASS, XBMC_ENABLED, XBMC_HOST, XBMC_USERNAME, XBMC_PASSWORD, XBMC_UPDATE, XBMC_NOTIFY, NMA_ENABLED, NMA_APIKEY, NMA_PRIORITY
                
        if __INITIALIZED__:
            return False
                
        # Make sure all the config sections exist
        CheckSection('General')
        CheckSection('SABnzbd')
        CheckSection('NZBMatrix')
        CheckSection('Newznab')
        CheckSection('NZBsorg')
        CheckSection('Newzbin')
        CheckSection('Prowl')
        CheckSection('XBMC')
        CheckSection('NMA')
        
        # 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:
            HTTP_PORT = 8181
            
        if HTTP_PORT < 21 or HTTP_PORT > 65535:
            HTTP_PORT = 8181
            
        HTTP_HOST = check_setting_str(CFG, 'General', 'http_host', '0.0.0.0')
        HTTP_USERNAME = check_setting_str(CFG, 'General', 'http_username', '')
        HTTP_PASSWORD = check_setting_str(CFG, 'General', 'http_password', '')
        HTTP_ROOT = check_setting_str(CFG, 'General', 'http_root', '/')
        LAUNCH_BROWSER = bool(check_setting_int(CFG, 'General', 'launch_browser', 1))
        API_ENABLED = bool(check_setting_int(CFG, 'General', 'api_enabled', 0))
        API_KEY = check_setting_str(CFG, 'General', 'api_key', '')
        GIT_PATH = check_setting_str(CFG, 'General', 'git_path', '')
        LOG_DIR = check_setting_str(CFG, 'General', 'log_dir', '')
        
        CHECK_GITHUB = bool(check_setting_int(CFG, 'General', 'check_github', 1))
        CHECK_GITHUB_ON_STARTUP = bool(check_setting_int(CFG, 'General', 'check_github_on_startup', 1))
        CHECK_GITHUB_INTERVAL = check_setting_int(CFG, 'General', 'check_github_interval', 360)
        
        MUSIC_DIR = check_setting_str(CFG, 'General', 'music_dir', '')
        DESTINATION_DIR = check_setting_str(CFG, 'General', 'destination_dir', '')
        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', 'auto_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))
        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))
        EMBED_LYRICS = bool(check_setting_int(CFG, 'General', 'embed_lyrics', 0))
        DOWNLOAD_DIR = check_setting_str(CFG, 'General', 'download_dir', '')
        BLACKHOLE = bool(check_setting_int(CFG, 'General', 'blackhole', 0))
        BLACKHOLE_DIR = check_setting_str(CFG, 'General', 'blackhole_dir', '')
        USENET_RETENTION = check_setting_int(CFG, 'General', 'usenet_retention', '')
        INCLUDE_EXTRAS = bool(check_setting_int(CFG, 'General', 'include_extras', 0))
        AUTOWANT_UPCOMING = bool(check_setting_int(CFG, 'General', 'autowant_upcoming', 1))
        AUTOWANT_ALL = bool(check_setting_int(CFG, 'General', 'autowant_all', 0))
        
        SEARCH_INTERVAL = check_setting_int(CFG, 'General', 'search_interval', 360)
        LIBRARYSCAN_INTERVAL = check_setting_int(CFG, 'General', 'libraryscan_interval', 300)
        DOWNLOAD_SCAN_INTERVAL = check_setting_int(CFG, 'General', 'download_scan_interval', 5)
        
        TORRENTBLACKHOLE_DIR = check_setting_str(CFG, 'General', 'torrentblackhole_dir', '')
        NUMBEROFSEEDERS = check_setting_str(CFG, 'General', 'numberofseeders', '10')
        ISOHUNT = bool(check_setting_int(CFG, 'General', 'isohunt', 0))
        KAT = bool(check_setting_int(CFG, 'General', 'kat', 0))
        MININOVA = bool(check_setting_int(CFG, 'General', 'mininova', 0))
        DOWNLOAD_TORRENT_DIR = check_setting_str(CFG, 'General', 'download_torrent_dir', '')
        
        SAB_HOST = check_setting_str(CFG, 'SABnzbd', 'sab_host', '')
        SAB_USERNAME = check_setting_str(CFG, 'SABnzbd', 'sab_username', '')
        SAB_PASSWORD = check_setting_str(CFG, 'SABnzbd', 'sab_password', '')
        SAB_APIKEY = check_setting_str(CFG, 'SABnzbd', 'sab_apikey', '')
        SAB_CATEGORY = check_setting_str(CFG, 'SABnzbd', 'sab_category', '')
        
        NZBMATRIX = bool(check_setting_int(CFG, 'NZBMatrix', 'nzbmatrix', 0))
        NZBMATRIX_USERNAME = check_setting_str(CFG, 'NZBMatrix', 'nzbmatrix_username', '')
        NZBMATRIX_APIKEY = check_setting_str(CFG, 'NZBMatrix', 'nzbmatrix_apikey', '')
        
        NEWZNAB = bool(check_setting_int(CFG, 'Newznab', 'newznab', 0))
        NEWZNAB_HOST = check_setting_str(CFG, 'Newznab', 'newznab_host', '')
        NEWZNAB_APIKEY = check_setting_str(CFG, 'Newznab', 'newznab_apikey', '')
        
        NZBSORG = bool(check_setting_int(CFG, 'NZBsorg', 'nzbsorg', 0))
        NZBSORG_UID = check_setting_str(CFG, 'NZBsorg', 'nzbsorg_uid', '')
        NZBSORG_HASH = check_setting_str(CFG, 'NZBsorg', 'nzbsorg_hash', '')

        NEWZBIN = bool(check_setting_int(CFG, 'Newzbin', 'newzbin', 0))
        NEWZBIN_UID = check_setting_str(CFG, 'Newzbin', 'newzbin_uid', '')
        NEWZBIN_PASSWORD = check_setting_str(CFG, 'Newzbin', 'newzbin_password', '')

        LASTFM_USERNAME = check_setting_str(CFG, 'General', 'lastfm_username', '')
        
        INTERFACE = check_setting_str(CFG, 'General', 'interface', 'default')
        FOLDER_PERMISSIONS = check_setting_str(CFG, 'General', 'folder_permissions', '0755')
		
        ENCODERFOLDER = check_setting_str(CFG, 'General', 'encoderfolder', '')        
        ENCODER = check_setting_str(CFG, 'General', 'encoder', 'ffmpeg')
        BITRATE = check_setting_int(CFG, 'General', 'bitrate', 192)
        SAMPLINGFREQUENCY= check_setting_int(CFG, 'General', 'samplingfrequency', 44100)
        MUSIC_ENCODER = bool(check_setting_int(CFG, 'General', 'music_encoder', 0))
        ADVANCEDENCODER = check_setting_str(CFG, 'General', 'advancedencoder', '')
        ENCODEROUTPUTFORMAT = check_setting_str(CFG, 'General', 'encoderoutputformat', 'mp3')
        ENCODERQUALITY = check_setting_int(CFG, 'General', 'encoderquality', 2)
        ENCODERVBRCBR = check_setting_str(CFG, 'General', 'encodervbrcbr', 'cbr')
        ENCODERLOSSLESS = bool(check_setting_int(CFG, 'General', 'encoderlossless', 1))

        PROWL_ENABLED = bool(check_setting_int(CFG, 'Prowl', 'prowl_enabled', 0))
        PROWL_KEYS = check_setting_str(CFG, 'Prowl', 'prowl_keys', '')
        PROWL_ONSNATCH = bool(check_setting_int(CFG, 'Prowl', 'prowl_onsnatch', 0)) 
        PROWL_PRIORITY = check_setting_int(CFG, 'Prowl', 'prowl_priority', 0)
        
        XBMC_ENABLED = bool(check_setting_int(CFG, 'XBMC', 'xbmc_enabled', 0))
        XBMC_HOST = check_setting_str(CFG, 'XBMC', 'xbmc_host', '')
        XBMC_USERNAME = check_setting_str(CFG, 'XBMC', 'xbmc_username', '')
        XBMC_PASSWORD = check_setting_str(CFG, 'XBMC', 'xbmc_password', '')
        XBMC_UPDATE = bool(check_setting_int(CFG, 'XBMC', 'xbmc_update', 0))
        XBMC_NOTIFY = bool(check_setting_int(CFG, 'XBMC', 'xbmc_notify', 0))
        
        NMA_ENABLED = bool(check_setting_int(CFG, 'NMA', 'nma_enabled', 0))
        NMA_APIKEY = check_setting_str(CFG, 'NMA', 'nma_apikey', '')
        NMA_PRIORITY = check_setting_int(CFG, 'NMA', 'nma_priority', 0)
        
        MIRROR = check_setting_str(CFG, 'General', 'mirror', 'musicbrainz.org')
        CUSTOMHOST = check_setting_str(CFG, 'General', 'customhost', 'localhost')
        CUSTOMPORT = check_setting_int(CFG, 'General', 'customport', 5000)
        CUSTOMSLEEP = check_setting_int(CFG, 'General', 'customsleep', 1)
        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 CONFIG_VERSION == '1':

			from headphones.helpers import replace_all

			file_values = {	'Track':		'$Track',
							'Title':		'$Title',
							'Artist':		'$Artist',
							'Album':		'$Album',
							'Year':			'$Year',
							'track':		'$track',
							'title':		'$title',
							'artist':		'$artist',
							'album':		'$album',
							'year':			'$year'
							}
			folder_values = { 	'Artist':	'$Artist',
								'Album':	'$Album',
								'Year':		'$Year',
								'Type':  	'$Type',
								'First':	'$First',
								'artist':	'$artist',
								'album':	'$album',
								'year':		'$year',
								'type':  	'$type',
								'first':	'$first'
							}	
			FILE_FORMAT = replace_all(FILE_FORMAT, file_values)
			FOLDER_FORMAT = replace_all(FOLDER_FORMAT, folder_values)
			
			CONFIG_VERSION = '2'
        
        if not LOG_DIR:
            LOG_DIR = os.path.join(DATA_DIR, 'logs')
        
        if not os.path.exists(LOG_DIR):
            try:
                os.makedirs(LOG_DIR)
            except OSError:
                if VERBOSE:
                    print 'Unable to create the log directory. Logging to screen only.'
        
        # Start the logger, silence console logging if we need to
        logger.headphones_log.initLogger(verbose=VERBOSE)
        
        # 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):
            try:
                os.makedirs(CACHE_DIR)
            except OSError:
                logger.error('Could not create cache dir. Check permissions of datadir: ' + DATA_DIR)
        
        # Initialize the database
        logger.info('Checking to see if the database has all tables....')
        try:
            dbcheck()
        except Exception, e:
            logger.error("Can't connect to the database: %s" % e)
            
        # Get the currently installed version - returns None, 'win32' or the git hash
        # Also sets INSTALL_TYPE variable to 'win', 'git' or 'source'
        CURRENT_VERSION = versioncheck.getVersion()
        
        # Check for new versions
        if CHECK_GITHUB_ON_STARTUP:
        	try:
        	    LATEST_VERSION = versioncheck.checkGithub()
        	except:
        	    LATEST_VERSION = CURRENT_VERSION
        else:
        	LATEST_VERSION = CURRENT_VERSION

        __INITIALIZED__ = True
        return True
Beispiel #46
0
def searchNZB(albumid=None, new=False):

    myDB = db.DBConnection()

    if albumid:
        results = myDB.select(
            'SELECT ArtistName, AlbumTitle, AlbumID, ReleaseDate from albums WHERE Status="Wanted" AND AlbumID=?',
            [albumid])
    else:
        results = myDB.select(
            'SELECT ArtistName, AlbumTitle, AlbumID, ReleaseDate from albums WHERE Status="Wanted"'
        )
        new = True

    for albums in results:

        albumid = albums[2]
        reldate = albums[3]

        try:
            year = reldate[:4]
        except TypeError:
            year = ''

        dic = {
            '...': '',
            ' & ': ' ',
            ' = ': ' ',
            '?': '',
            '$': 's',
            ' + ': ' ',
            '"': '',
            ',': '',
            '*': ''
        }

        cleanalbum = helpers.latinToAscii(helpers.replace_all(albums[1], dic))
        cleanartist = helpers.latinToAscii(helpers.replace_all(albums[0], dic))

        # FLAC usually doesn't have a year for some reason so I'll leave it out
        # Various Artist albums might be listed as VA, so I'll leave that out too
        # Only use the year if the term could return a bunch of different albums, i.e. self-titled albums
        if albums[0] in albums[1] or len(albums[0]) < 4 or len(albums[1]) < 4:
            term = cleanartist + ' ' + cleanalbum + ' ' + year
        elif albums[0] == 'Various Artists':
            term = cleanalbum + ' ' + year
        else:
            term = cleanartist + ' ' + cleanalbum

        # Replace bad characters in the term and unicode it
        term = re.sub('[\.\-\/]', ' ', term).encode('utf-8')
        artistterm = re.sub('[\.\-\/]', ' ', cleanartist).encode('utf-8')

        logger.info("Searching for %s since it was marked as wanted" % term)

        resultlist = []

        if headphones.NZBMATRIX:
            provider = "nzbmatrix"
            if headphones.PREFERRED_QUALITY == 3:
                categories = "23"
                maxsize = 10000000000
            elif headphones.PREFERRED_QUALITY:
                categories = "23,22"
                maxsize = 2000000000
            else:
                categories = "22"
                maxsize = 300000000

            params = {
                "page": "download",
                "username": headphones.NZBMATRIX_USERNAME,
                "apikey": headphones.NZBMATRIX_APIKEY,
                "subcat": categories,
                "age": headphones.USENET_RETENTION,
                "english": 1,
                "ssl": 1,
                "scenename": 1,
                "term": term
            }

            searchURL = "http://rss.nzbmatrix.com/rss.php?" + urllib.urlencode(
                params)
            logger.info(u'Parsing results from <a href="%s">NZBMatrix</a>' %
                        searchURL)
            try:
                data = urllib2.urlopen(searchURL, timeout=20).read()
            except urllib2.URLError, e:
                logger.warn('Error fetching data from NZBMatrix: %s' % e)
                data = False

            if data:

                d = feedparser.parse(data)

                for item in d.entries:
                    try:
                        url = item.link
                        title = item.title
                        size = int(item.links[1]['length'])
                        if size < maxsize:
                            resultlist.append((title, size, url, provider))
                            logger.info('Found %s. Size: %s' %
                                        (title, helpers.bytes_to_mb(size)))
                        else:
                            logger.info(
                                '%s is larger than the maxsize for this category, skipping. (Size: %i bytes)'
                                % (title, size))

                    except AttributeError, e:
                        logger.info(u"No results found from NZBMatrix for %s" %
                                    term)