Files
headphones/headphones/__init__.py
2012-07-10 00:56:25 -07:00

855 lines
34 KiB
Python

# This file is part of Headphones.
#
# Headphones is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Headphones is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Headphones. If not, see <http://www.gnu.org/licenses/>.
from __future__ import with_statement
import os, sys, subprocess
import threading
import webbrowser
import sqlite3
from lib.apscheduler.scheduler import Scheduler
from lib.configobj import ConfigObj
import cherrypy
from headphones import versioncheck, logger, version
from headphones.common import *
FULL_PATH = None
PROG_DIR = None
ARGS = None
SIGNAL = None
SYS_ENCODING = None
VERBOSE = 1
DAEMON = False
PIDFILE= None
SCHED = Scheduler()
INIT_LOCK = threading.Lock()
__INITIALIZED__ = False
started = False
DATA_DIR = None
CONFIG_FILE = None
CFG = None
CONFIG_VERSION = None
DB_FILE = None
LOG_DIR = None
LOG_LIST = []
CACHE_DIR = None
HTTP_PORT = None
HTTP_HOST = None
HTTP_USERNAME = None
HTTP_PASSWORD = None
HTTP_ROOT = None
LAUNCH_BROWSER = False
API_ENABLED = False
API_KEY = None
GIT_PATH = None
INSTALL_TYPE = None
CURRENT_VERSION = None
LATEST_VERSION = None
COMMITS_BEHIND = None
CHECK_GITHUB = False
CHECK_GITHUB_ON_STARTUP = False
CHECK_GITHUB_INTERVAL = None
MUSIC_DIR = None
DESTINATION_DIR = None
FOLDER_FORMAT = None
FILE_FORMAT = None
PATH_TO_XML = None
PREFERRED_QUALITY = None
PREFERRED_BITRATE = None
DETECT_BITRATE = False
ADD_ARTISTS = False
NEW_ARTISTS = []
CORRECT_METADATA = False
MOVE_FILES = False
RENAME_FILES = False
CLEANUP_FILES = False
ADD_ALBUM_ART = False
EMBED_ALBUM_ART = False
EMBED_LYRICS = False
DOWNLOAD_DIR = None
BLACKHOLE = None
BLACKHOLE_DIR = None
USENET_RETENTION = None
INCLUDE_EXTRAS = False
AUTOWANT_UPCOMING = False
AUTOWANT_ALL = False
SEARCH_INTERVAL = 360
LIBRARYSCAN_INTERVAL = 300
DOWNLOAD_SCAN_INTERVAL = 5
SAB_HOST = None
SAB_USERNAME = None
SAB_PASSWORD = None
SAB_APIKEY = None
SAB_CATEGORY = None
NZBMATRIX = False
NZBMATRIX_USERNAME = None
NZBMATRIX_APIKEY = None
NEWZNAB = False
NEWZNAB_HOST = None
NEWZNAB_APIKEY = None
NZBSORG = False
NZBSORG_UID = None
NZBSORG_HASH = None
NEWZBIN = False
NEWZBIN_UID = None
NEWZBIN_PASSWORD = None
LASTFM_USERNAME = None
LOSSY_MEDIA_FORMATS = ["mp3", "aac", "ogg", "ape", "m4a"]
LOSSLESS_MEDIA_FORMATS = ["flac"]
MEDIA_FORMATS = LOSSY_MEDIA_FORMATS + LOSSLESS_MEDIA_FORMATS
TORRENTBLACKHOLE_DIR = None
NUMBEROFSEEDERS = 10
ISOHUNT = None
KAT = None
MININOVA = None
WAFFLES = None
WAFFLES_UID = None
WAFFLES_PASSKEY = None
DOWNLOAD_TORRENT_DIR = None
INTERFACE = None
FOLDER_PERMISSIONS = None
MUSIC_ENCODER = False
ENCODERFOLDER = None
ENCODER = None
BITRATE = None
SAMPLINGFREQUENCY = None
ADVANCEDENCODER = None
ENCODEROUTPUTFORMAT = None
ENCODERQUALITY = None
ENCODERVBRCBR = None
ENCODERLOSSLESS = False
PROWL_ENABLED = True
PROWL_PRIORITY = 1
PROWL_KEYS = None
PROWL_ONSNATCH = True
XBMC_ENABLED = False
XBMC_HOST = None
XBMC_USERNAME = None
XBMC_PASSWORD = None
XBMC_UPDATE = False
XBMC_NOTIFY = False
NMA_ENABLED = False
NMA_APIKEY = None
NMA_PRIORITY = None
SYNOINDEX_ENABLED = False
MIRRORLIST = ["musicbrainz.org","headphones","custom"]
MIRROR = None
CUSTOMHOST = None
CUSTOMPORT = None
CUSTOMSLEEP = None
HPUSER = None
HPPASS = None
def CheckSection(sec):
""" Check if INI section exists, if not create it """
try:
CFG[sec]
return True
except:
CFG[sec] = {}
return False
################################################################################
# Check_setting_int #
################################################################################
def check_setting_int(config, cfg_name, item_name, def_val):
try:
my_val = int(config[cfg_name][item_name])
except:
my_val = def_val
try:
config[cfg_name][item_name] = my_val
except:
config[cfg_name] = {}
config[cfg_name][item_name] = my_val
logger.debug(item_name + " -> " + str(my_val))
return my_val
################################################################################
# Check_setting_str #
################################################################################
def check_setting_str(config, cfg_name, item_name, def_val, log=True):
try:
my_val = config[cfg_name][item_name]
except:
my_val = def_val
try:
config[cfg_name][item_name] = my_val
except:
config[cfg_name] = {}
config[cfg_name][item_name] = my_val
if log:
logger.debug(item_name + " -> " + my_val)
else:
logger.debug(item_name + " -> ******")
return my_val
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, WAFFLES, WAFFLES_UID, WAFFLES_PASSKEY, 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, SYNOINDEX_ENABLED
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('Prowl')
CheckSection('XBMC')
CheckSection('NMA')
CheckSection('Synoindex')
# 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', '1500')
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', '')
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', '')
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
def daemonize():
if threading.activeCount() != 1:
logger.warn('There are %r active threads. Daemonizing may cause \
strange behavior.' % threading.enumerate())
sys.stdout.flush()
sys.stderr.flush()
# Do first fork
try:
pid = os.fork()
if pid == 0:
pass
else:
# Exit the parent process
logger.debug('Forking once...')
os._exit(0)
except OSError, e:
sys.exit("1st fork failed: %s [%d]" % (e.strerror, e.errno))
os.setsid()
# Do second fork
try:
pid = os.fork()
if pid > 0:
logger.debug('Forking twice...')
os._exit(0) # Exit second parent process
except OSError, e:
sys.exit("2nd fork failed: %s [%d]" % (e.strerror, e.errno))
os.chdir("/")
os.umask(0)
si = open('/dev/null', "r")
so = open('/dev/null', "a+")
se = open('/dev/null', "a+")
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
pid = os.getpid()
logger.info('Daemonized to PID: %s' % pid)
if PIDFILE:
logger.info('Writing PID %s to %s' % (pid, PIDFILE))
file(PIDFILE, 'w').write("%s\n" % pid)
def launch_browser(host, port, root):
if host == '0.0.0.0':
host = 'localhost'
try:
webbrowser.open('http://%s:%i%s' % (host, port, root))
except Exception, e:
logger.error('Could not launch browser: %s' % e)
def config_write():
new_config = ConfigObj()
new_config.filename = CONFIG_FILE
new_config['General'] = {}
new_config['General']['config_version'] = CONFIG_VERSION
new_config['General']['http_port'] = HTTP_PORT
new_config['General']['http_host'] = HTTP_HOST
new_config['General']['http_username'] = HTTP_USERNAME
new_config['General']['http_password'] = HTTP_PASSWORD
new_config['General']['http_root'] = HTTP_ROOT
new_config['General']['launch_browser'] = int(LAUNCH_BROWSER)
new_config['General']['api_enabled'] = int(API_ENABLED)
new_config['General']['api_key'] = API_KEY
new_config['General']['log_dir'] = LOG_DIR
new_config['General']['git_path'] = GIT_PATH
new_config['General']['check_github'] = int(CHECK_GITHUB)
new_config['General']['check_github_on_startup'] = int(CHECK_GITHUB_ON_STARTUP)
new_config['General']['check_github_interval'] = CHECK_GITHUB_INTERVAL
new_config['General']['music_dir'] = MUSIC_DIR
new_config['General']['destination_dir'] = DESTINATION_DIR
new_config['General']['preferred_quality'] = PREFERRED_QUALITY
new_config['General']['preferred_bitrate'] = PREFERRED_BITRATE
new_config['General']['detect_bitrate'] = int(DETECT_BITRATE)
new_config['General']['auto_add_artists'] = int(ADD_ARTISTS)
new_config['General']['correct_metadata'] = int(CORRECT_METADATA)
new_config['General']['move_files'] = int(MOVE_FILES)
new_config['General']['rename_files'] = int(RENAME_FILES)
new_config['General']['folder_format'] = FOLDER_FORMAT
new_config['General']['file_format'] = FILE_FORMAT
new_config['General']['cleanup_files'] = int(CLEANUP_FILES)
new_config['General']['add_album_art'] = int(ADD_ALBUM_ART)
new_config['General']['embed_album_art'] = int(EMBED_ALBUM_ART)
new_config['General']['embed_lyrics'] = int(EMBED_LYRICS)
new_config['General']['download_dir'] = DOWNLOAD_DIR
new_config['General']['blackhole'] = int(BLACKHOLE)
new_config['General']['blackhole_dir'] = BLACKHOLE_DIR
new_config['General']['usenet_retention'] = USENET_RETENTION
new_config['General']['include_extras'] = int(INCLUDE_EXTRAS)
new_config['General']['autowant_upcoming'] = int(AUTOWANT_UPCOMING)
new_config['General']['autowant_all'] = int(AUTOWANT_ALL)
new_config['General']['numberofseeders'] = NUMBEROFSEEDERS
new_config['General']['torrentblackhole_dir'] = TORRENTBLACKHOLE_DIR
new_config['General']['isohunt'] = int(ISOHUNT)
new_config['General']['kat'] = int(KAT)
new_config['General']['mininova'] = int(MININOVA)
new_config['General']['download_torrent_dir'] = DOWNLOAD_TORRENT_DIR
new_config['Waffles'] = {}
new_config['Waffles']['waffles'] = int(WAFFLES)
new_config['Waffles']['waffles_uid'] = WAFFLES_UID
new_config['Waffles']['waffles_passkey'] = WAFFLES_PASSKEY
new_config['General']['search_interval'] = SEARCH_INTERVAL
new_config['General']['libraryscan_interval'] = LIBRARYSCAN_INTERVAL
new_config['General']['download_scan_interval'] = DOWNLOAD_SCAN_INTERVAL
new_config['SABnzbd'] = {}
new_config['SABnzbd']['sab_host'] = SAB_HOST
new_config['SABnzbd']['sab_username'] = SAB_USERNAME
new_config['SABnzbd']['sab_password'] = SAB_PASSWORD
new_config['SABnzbd']['sab_apikey'] = SAB_APIKEY
new_config['SABnzbd']['sab_category'] = SAB_CATEGORY
new_config['NZBMatrix'] = {}
new_config['NZBMatrix']['nzbmatrix'] = int(NZBMATRIX)
new_config['NZBMatrix']['nzbmatrix_username'] = NZBMATRIX_USERNAME
new_config['NZBMatrix']['nzbmatrix_apikey'] = NZBMATRIX_APIKEY
new_config['Newznab'] = {}
new_config['Newznab']['newznab'] = int(NEWZNAB)
new_config['Newznab']['newznab_host'] = NEWZNAB_HOST
new_config['Newznab']['newznab_apikey'] = NEWZNAB_APIKEY
new_config['NZBsorg'] = {}
new_config['NZBsorg']['nzbsorg'] = int(NZBSORG)
new_config['NZBsorg']['nzbsorg_uid'] = NZBSORG_UID
new_config['NZBsorg']['nzbsorg_hash'] = NZBSORG_HASH
new_config['Newzbin'] = {}
new_config['Newzbin']['newzbin'] = int(NEWZBIN)
new_config['Newzbin']['newzbin_uid'] = NEWZBIN_UID
new_config['Newzbin']['newzbin_password'] = NEWZBIN_PASSWORD
new_config['Prowl'] = {}
new_config['Prowl']['prowl_enabled'] = int(PROWL_ENABLED)
new_config['Prowl']['prowl_keys'] = PROWL_KEYS
new_config['Prowl']['prowl_onsnatch'] = int(PROWL_ONSNATCH)
new_config['Prowl']['prowl_priority'] = int(PROWL_PRIORITY)
new_config['XBMC'] = {}
new_config['XBMC']['xbmc_enabled'] = int(XBMC_ENABLED)
new_config['XBMC']['xbmc_host'] = XBMC_HOST
new_config['XBMC']['xbmc_username'] = XBMC_USERNAME
new_config['XBMC']['xbmc_password'] = XBMC_PASSWORD
new_config['XBMC']['xbmc_update'] = int(XBMC_UPDATE)
new_config['XBMC']['xbmc_notify'] = int(XBMC_NOTIFY)
new_config['NMA'] = {}
new_config['NMA']['nma_enabled'] = int(NMA_ENABLED)
new_config['NMA']['nma_apikey'] = NMA_APIKEY
new_config['NMA']['nma_priority'] = NMA_PRIORITY
new_config['Synoindex'] = {}
new_config['Synoindex']['synoindex_enabled'] = int(SYNOINDEX_ENABLED)
new_config['General']['lastfm_username'] = LASTFM_USERNAME
new_config['General']['interface'] = INTERFACE
new_config['General']['folder_permissions'] = FOLDER_PERMISSIONS
new_config['General']['music_encoder'] = int(MUSIC_ENCODER)
new_config['General']['encoder'] = ENCODER
new_config['General']['bitrate'] = int(BITRATE)
new_config['General']['samplingfrequency'] = int(SAMPLINGFREQUENCY)
new_config['General']['encoderfolder'] = ENCODERFOLDER
new_config['General']['advancedencoder'] = ADVANCEDENCODER
new_config['General']['encoderoutputformat'] = ENCODEROUTPUTFORMAT
new_config['General']['encoderquality'] = ENCODERQUALITY
new_config['General']['encodervbrcbr'] = ENCODERVBRCBR
new_config['General']['encoderlossless'] = ENCODERLOSSLESS
new_config['General']['mirror'] = MIRROR
new_config['General']['customhost'] = CUSTOMHOST
new_config['General']['customport'] = CUSTOMPORT
new_config['General']['customsleep'] = CUSTOMSLEEP
new_config['General']['hpuser'] = HPUSER
new_config['General']['hppass'] = HPPASS
new_config.write()
def start():
global __INITIALIZED__, started
if __INITIALIZED__:
# Start our scheduled background tasks
from headphones import updater, searcher, librarysync, postprocessor
SCHED.add_interval_job(updater.dbUpdate, hours=48)
SCHED.add_interval_job(searcher.searchforalbum, minutes=SEARCH_INTERVAL)
SCHED.add_interval_job(librarysync.libraryScan, minutes=LIBRARYSCAN_INTERVAL)
if CHECK_GITHUB:
SCHED.add_interval_job(versioncheck.checkGithub, minutes=CHECK_GITHUB_INTERVAL)
SCHED.add_interval_job(postprocessor.checkFolder, minutes=DOWNLOAD_SCAN_INTERVAL)
SCHED.start()
started = True
def dbcheck():
conn=sqlite3.connect(DB_FILE)
c=conn.cursor()
c.execute('CREATE TABLE IF NOT EXISTS artists (ArtistID TEXT UNIQUE, ArtistName TEXT, ArtistSortName TEXT, DateAdded TEXT, Status TEXT, IncludeExtras INTEGER, LatestAlbum TEXT, ReleaseDate TEXT, AlbumID TEXT, HaveTracks INTEGER, TotalTracks INTEGER, LastUpdated TEXT, ArtworkURL TEXT, ThumbURL TEXT)')
c.execute('CREATE TABLE IF NOT EXISTS albums (ArtistID TEXT, ArtistName TEXT, AlbumTitle TEXT, AlbumASIN TEXT, ReleaseDate TEXT, DateAdded TEXT, AlbumID TEXT UNIQUE, Status TEXT, Type TEXT, ArtworkURL TEXT, ThumbURL TEXT)')
c.execute('CREATE TABLE IF NOT EXISTS tracks (ArtistID TEXT, ArtistName TEXT, AlbumTitle TEXT, AlbumASIN TEXT, AlbumID TEXT, TrackTitle TEXT, TrackDuration, TrackID TEXT, TrackNumber INTEGER, Location TEXT, BitRate INTEGER, CleanName TEXT, Format TEXT)')
c.execute('CREATE TABLE IF NOT EXISTS snatched (AlbumID TEXT, Title TEXT, Size INTEGER, URL TEXT, DateAdded TEXT, Status TEXT, FolderName TEXT)')
c.execute('CREATE TABLE IF NOT EXISTS have (ArtistName TEXT, AlbumTitle TEXT, TrackNumber TEXT, TrackTitle TEXT, TrackLength TEXT, BitRate TEXT, Genre TEXT, Date TEXT, TrackID TEXT, Location TEXT, CleanName TEXT, Format TEXT)')
c.execute('CREATE TABLE IF NOT EXISTS lastfmcloud (ArtistName TEXT, ArtistID TEXT, Count INTEGER)')
c.execute('CREATE TABLE IF NOT EXISTS descriptions (ArtistID TEXT, ReleaseGroupID TEXT, ReleaseID TEXT, Summary TEXT, Content TEXT, LastUpdated TEXT)')
c.execute('CREATE TABLE IF NOT EXISTS blacklist (ArtistID TEXT UNIQUE)')
c.execute('CREATE TABLE IF NOT EXISTS releases (ReleaseID TEXT, ReleaseGroupID TEXT, UNIQUE(ReleaseID, ReleaseGroupID))')
c.execute('CREATE INDEX IF NOT EXISTS tracks_albumid ON tracks(AlbumID ASC)')
c.execute('CREATE INDEX IF NOT EXISTS album_artistid_reldate ON albums(ArtistID ASC, ReleaseDate DESC)')
try:
c.execute('SELECT IncludeExtras from artists')
except sqlite3.OperationalError:
c.execute('ALTER TABLE artists ADD COLUMN IncludeExtras INTEGER DEFAULT 0')
try:
c.execute('SELECT LatestAlbum from artists')
except sqlite3.OperationalError:
c.execute('ALTER TABLE artists ADD COLUMN LatestAlbum TEXT')
try:
c.execute('SELECT ReleaseDate from artists')
except sqlite3.OperationalError:
c.execute('ALTER TABLE artists ADD COLUMN ReleaseDate TEXT')
try:
c.execute('SELECT AlbumID from artists')
except sqlite3.OperationalError:
c.execute('ALTER TABLE artists ADD COLUMN AlbumID TEXT')
try:
c.execute('SELECT HaveTracks from artists')
except sqlite3.OperationalError:
c.execute('ALTER TABLE artists ADD COLUMN HaveTracks INTEGER DEFAULT 0')
try:
c.execute('SELECT TotalTracks from artists')
except sqlite3.OperationalError:
c.execute('ALTER TABLE artists ADD COLUMN TotalTracks INTEGER DEFAULT 0')
try:
c.execute('SELECT Type from albums')
except sqlite3.OperationalError:
c.execute('ALTER TABLE albums ADD COLUMN Type TEXT DEFAULT "Album"')
try:
c.execute('SELECT TrackNumber from tracks')
except sqlite3.OperationalError:
c.execute('ALTER TABLE tracks ADD COLUMN TrackNumber INTEGER')
try:
c.execute('SELECT FolderName from snatched')
except sqlite3.OperationalError:
c.execute('ALTER TABLE snatched ADD COLUMN FolderName TEXT')
try:
c.execute('SELECT Location from tracks')
except sqlite3.OperationalError:
c.execute('ALTER TABLE tracks ADD COLUMN Location TEXT')
try:
c.execute('SELECT Location from have')
except sqlite3.OperationalError:
c.execute('ALTER TABLE have ADD COLUMN Location TEXT')
try:
c.execute('SELECT BitRate from tracks')
except sqlite3.OperationalError:
c.execute('ALTER TABLE tracks ADD COLUMN BitRate INTEGER')
try:
c.execute('SELECT CleanName from tracks')
except sqlite3.OperationalError:
c.execute('ALTER TABLE tracks ADD COLUMN CleanName TEXT')
try:
c.execute('SELECT CleanName from have')
except sqlite3.OperationalError:
c.execute('ALTER TABLE have ADD COLUMN CleanName TEXT')
# Add the Format column
try:
c.execute('SELECT Format from have')
except sqlite3.OperationalError:
c.execute('ALTER TABLE have ADD COLUMN Format TEXT DEFAULT NULL')
try:
c.execute('SELECT Format from tracks')
except sqlite3.OperationalError:
c.execute('ALTER TABLE tracks ADD COLUMN Format TEXT DEFAULT NULL')
try:
c.execute('SELECT LastUpdated from artists')
except sqlite3.OperationalError:
c.execute('ALTER TABLE artists ADD COLUMN LastUpdated TEXT DEFAULT NULL')
try:
c.execute('SELECT ArtworkURL from artists')
except sqlite3.OperationalError:
c.execute('ALTER TABLE artists ADD COLUMN ArtworkURL TEXT DEFAULT NULL')
try:
c.execute('SELECT ArtworkURL from albums')
except sqlite3.OperationalError:
c.execute('ALTER TABLE albums ADD COLUMN ArtworkURL TEXT DEFAULT NULL')
try:
c.execute('SELECT ThumbURL from artists')
except sqlite3.OperationalError:
c.execute('ALTER TABLE artists ADD COLUMN ThumbURL TEXT DEFAULT NULL')
try:
c.execute('SELECT ThumbURL from albums')
except sqlite3.OperationalError:
c.execute('ALTER TABLE albums ADD COLUMN ThumbURL TEXT DEFAULT NULL')
try:
c.execute('SELECT ArtistID from descriptions')
except sqlite3.OperationalError:
c.execute('ALTER TABLE descriptions ADD COLUMN ArtistID TEXT DEFAULT NULL')
try:
c.execute('SELECT LastUpdated from descriptions')
except sqlite3.OperationalError:
c.execute('ALTER TABLE descriptions ADD COLUMN LastUpdated TEXT DEFAULT NULL')
conn.commit()
c.close()
def shutdown(restart=False, update=False):
cherrypy.engine.exit()
SCHED.shutdown(wait=False)
config_write()
if not restart and not update:
logger.info('Headphones is shutting down...')
if update:
logger.info('Headphones is updating...')
try:
versioncheck.update()
except Exception, e:
logger.warn('Headphones failed to update: %s. Restarting.' % e)
if PIDFILE :
logger.info ('Removing pidfile %s' % PIDFILE)
os.remove(PIDFILE)
if restart:
logger.info('Headphones is restarting...')
popen_list = [sys.executable, FULL_PATH]
popen_list += ARGS
if '--nolaunch' not in popen_list:
popen_list += ['--nolaunch']
logger.info('Restarting Headphones with ' + str(popen_list))
subprocess.Popen(popen_list, cwd=os.getcwd())
os._exit(0)