diff --git a/Headphones.py b/Headphones.py
old mode 100755
new mode 100644
index f8053ff4..ccef9ec1
--- a/Headphones.py
+++ b/Headphones.py
@@ -8,98 +8,98 @@ import headphones
from headphones import webstart, logger
try:
- import argparse
+ import argparse
except ImportError:
- import lib.argparse as argparse
-
+ import lib.argparse as argparse
+
def main():
- # Fixed paths to Headphones
- if hasattr(sys, 'frozen'):
- headphones.FULL_PATH = os.path.abspath(sys.executable)
- else:
- headphones.FULL_PATH = os.path.abspath(__file__)
-
- headphones.PROG_DIR = os.path.dirname(headphones.FULL_PATH)
- headphones.ARGS = sys.argv[1:]
-
- # Set up and gather command line arguments
- parser = argparse.ArgumentParser(description='Music add-on for SABnzbd+')
+ # Fixed paths to Headphones
+ if hasattr(sys, 'frozen'):
+ headphones.FULL_PATH = os.path.abspath(sys.executable)
+ else:
+ headphones.FULL_PATH = os.path.abspath(__file__)
+
+ headphones.PROG_DIR = os.path.dirname(headphones.FULL_PATH)
+ headphones.ARGS = sys.argv[1:]
+
+ # Set up and gather command line arguments
+ parser = argparse.ArgumentParser(description='Music add-on for SABnzbd+')
- parser.add_argument('-q', '--quiet', action='store_true', help='Turn off console logging')
- parser.add_argument('-d', '--daemon', action='store_true', help='Run as a daemon')
- parser.add_argument('-p', '--port', type=int, help='Force Headphones to run on a specified port')
- parser.add_argument('--datadir', help='Specify a directory where to store your data files')
- parser.add_argument('--config', help='Specify a config file to use')
- parser.add_argument('--nolaunch', action='store_true', help='Prevent browser from launching on startup')
-
- args = parser.parse_args()
-
- if args.quiet:
- headphones.QUIET=True
-
- if args.daemon:
- headphones.DAEMON=True
- headphones.QUIET=True
-
- if args.datadir:
- headphones.DATA_DIR = args.datadir
- else:
- headphones.DATA_DIR = headphones.PROG_DIR
-
- if args.config:
- headphones.CONFIG_FILE = args.config
- else:
- headphones.CONFIG_FILE = os.path.join(headphones.DATA_DIR, 'config.ini')
-
- # Try to create the DATA_DIR if it doesn't exist
- if not os.path.exists(headphones.DATA_DIR):
- try:
- os.makedirs(headphones.DATA_DIR)
- except OSError:
- raise SystemExit('Could not create data directory: ' + headphones.DATA_DIR + '. Exiting....')
-
- # Make sure the DATA_DIR is writeable
- if not os.access(headphones.DATA_DIR, os.W_OK):
- raise SystemExit('Cannot write to the data directory: ' + headphones.DATA_DIR + '. Exiting...')
-
- # Put the database in the DATA_DIR
- headphones.DB_FILE = os.path.join(headphones.DATA_DIR, 'headphones.db')
-
- headphones.CFG = ConfigObj(headphones.CONFIG_FILE)
-
- # Read config & start logging
- headphones.initialize()
-
- if headphones.DAEMON:
- headphones.daemonize()
-
- # Force the http port if neccessary
- if args.port:
- http_port = args.port
- logger.info('Starting Headphones on foced port: %i' % http_port)
- else:
- http_port = int(headphones.HTTP_PORT)
-
- # Try to start the server.
- webstart.initialize({
- 'http_port': http_port,
- 'http_host': headphones.HTTP_HOST,
- 'http_root': headphones.HTTP_ROOT,
- 'http_username': headphones.HTTP_USERNAME,
- 'http_password': headphones.HTTP_PASSWORD,
- })
-
- logger.info('Starting Headphones on port: %i' % http_port)
-
- if headphones.LAUNCH_BROWSER and not args.nolaunch:
- headphones.launch_browser(headphones.HTTP_HOST, http_port, headphones.HTTP_ROOT)
-
- # Start the background threads
- headphones.start()
-
- return
+ parser.add_argument('-q', '--quiet', action='store_true', help='Turn off console logging')
+ parser.add_argument('-d', '--daemon', action='store_true', help='Run as a daemon')
+ parser.add_argument('-p', '--port', type=int, help='Force Headphones to run on a specified port')
+ parser.add_argument('--datadir', help='Specify a directory where to store your data files')
+ parser.add_argument('--config', help='Specify a config file to use')
+ parser.add_argument('--nolaunch', action='store_true', help='Prevent browser from launching on startup')
+
+ args = parser.parse_args()
+
+ if args.quiet:
+ headphones.QUIET=True
+
+ if args.daemon:
+ headphones.DAEMON=True
+ headphones.QUIET=True
+
+ if args.datadir:
+ headphones.DATA_DIR = args.datadir
+ else:
+ headphones.DATA_DIR = headphones.PROG_DIR
+
+ if args.config:
+ headphones.CONFIG_FILE = args.config
+ else:
+ headphones.CONFIG_FILE = os.path.join(headphones.DATA_DIR, 'config.ini')
+
+ # Try to create the DATA_DIR if it doesn't exist
+ if not os.path.exists(headphones.DATA_DIR):
+ try:
+ os.makedirs(headphones.DATA_DIR)
+ except OSError:
+ raise SystemExit('Could not create data directory: ' + headphones.DATA_DIR + '. Exiting....')
+
+ # Make sure the DATA_DIR is writeable
+ if not os.access(headphones.DATA_DIR, os.W_OK):
+ raise SystemExit('Cannot write to the data directory: ' + headphones.DATA_DIR + '. Exiting...')
+
+ # Put the database in the DATA_DIR
+ headphones.DB_FILE = os.path.join(headphones.DATA_DIR, 'headphones.db')
+
+ headphones.CFG = ConfigObj(headphones.CONFIG_FILE)
+
+ # Read config & start logging
+ headphones.initialize()
+
+ if headphones.DAEMON:
+ headphones.daemonize()
+
+ # Force the http port if neccessary
+ if args.port:
+ http_port = args.port
+ logger.info('Starting Headphones on foced port: %i' % http_port)
+ else:
+ http_port = int(headphones.HTTP_PORT)
+
+ # Try to start the server.
+ webstart.initialize({
+ 'http_port': http_port,
+ 'http_host': headphones.HTTP_HOST,
+ 'http_root': headphones.HTTP_ROOT,
+ 'http_username': headphones.HTTP_USERNAME,
+ 'http_password': headphones.HTTP_PASSWORD,
+ })
+
+ logger.info('Starting Headphones on port: %i' % http_port)
+
+ if headphones.LAUNCH_BROWSER and not args.nolaunch:
+ headphones.launch_browser(headphones.HTTP_HOST, http_port, headphones.HTTP_ROOT)
+
+ # Start the background threads
+ headphones.start()
+
+ return
if __name__ == "__main__":
- main()
+ main()
diff --git a/headphones/__init__.py b/headphones/__init__.py
index eb8a5dd0..84023254 100644
--- a/headphones/__init__.py
+++ b/headphones/__init__.py
@@ -11,7 +11,8 @@ from lib.configobj import ConfigObj
import cherrypy
-from headphones import updater, searcher, importer, versioncheck, logger, postprocessor
+from headphones import updater, searcher, importer, versioncheck, logger, postprocessor, version, sab
+from headphones.common import *
FULL_PATH = None
PROG_DIR = None
@@ -92,8 +93,13 @@ NZBSORG = False
NZBSORG_UID = None
NZBSORG_HASH = None
+NEWZBIN = False
+NEWZBIN_UID = None
+NEWZBIN_PASSWORD = None
+
LASTFM_USERNAME = None
+
def CheckSection(sec):
""" Check if INI section exists, if not create it """
try:
@@ -138,351 +144,361 @@ def check_setting_str(config, cfg_name, item_name, def_val, log=True):
else:
logger.debug(item_name + " -> ******")
return my_val
-
+
def initialize():
- with INIT_LOCK:
-
- global __INITIALIZED__, FULL_PATH, PROG_DIR, QUIET, DAEMON, DATA_DIR, CONFIG_FILE, CFG, LOG_DIR, CACHE_DIR, \
- HTTP_PORT, HTTP_HOST, HTTP_USERNAME, HTTP_PASSWORD, HTTP_ROOT, LAUNCH_BROWSER, GIT_PATH, \
- CURRENT_VERSION, LATEST_VERSION, MUSIC_DIR, DESTINATION_DIR, PREFERRED_QUALITY, PREFERRED_BITRATE, DETECT_BITRATE, \
- CORRECT_METADATA, MOVE_FILES, RENAME_FILES, FOLDER_FORMAT, FILE_FORMAT, CLEANUP_FILES, INCLUDE_EXTRAS, \
- ADD_ALBUM_ART, EMBED_ALBUM_ART, DOWNLOAD_DIR, BLACKHOLE, BLACKHOLE_DIR, USENET_RETENTION, NZB_SEARCH_INTERVAL, \
- LIBRARYSCAN_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, LASTFM_USERNAME
-
- if __INITIALIZED__:
- return False
-
- # Make sure all the config sections exist
- CheckSection('General')
- CheckSection('SABnzbd')
- CheckSection('NZBMatrix')
- CheckSection('Newznab')
- CheckSection('NZBsorg')
-
- # Set global variables based on config file or use defaults
- 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))
- GIT_PATH = check_setting_str(CFG, 'General', 'git_path', '')
- LOG_DIR = check_setting_str(CFG, 'General', 'log_dir', '')
-
- 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))
- CORRECT_METADATA = bool(check_setting_int(CFG, 'General', 'correct_metadata', 0))
- MOVE_FILES = bool(check_setting_int(CFG, 'General', 'move_files', 0))
- RENAME_FILES = bool(check_setting_int(CFG, 'General', 'rename_files', 0))
- FOLDER_FORMAT = check_setting_str(CFG, 'General', 'folder_format', 'artist/album [year]')
- FILE_FORMAT = check_setting_str(CFG, 'General', 'file_format', 'tracknumber artist - album [year]- title')
- 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))
- 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))
-
- NZB_SEARCH_INTERVAL = check_setting_int(CFG, 'General', 'nzb_search_interval', 360)
- LIBRARYSCAN_INTERVAL = check_setting_int(CFG, 'General', 'libraryscan_interval', 180)
-
- 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', '')
-
- LASTFM_USERNAME = check_setting_str(CFG, 'General', 'lastfm_username', '')
-
- 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 not QUIET:
- 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(quiet=QUIET)
-
- # Update some old config code:
- if FOLDER_FORMAT == '%artist/%album/%track':
- FOLDER_FORMAT = 'artist/album [year]'
- if FILE_FORMAT == '%tracknumber %artist - %album - %title':
- FILE_FORMAT = 'tracknumber artist - album - title'
-
- # Put the cache dir in the data dir for now
- CACHE_DIR = os.path.join(DATA_DIR, 'cache')
- if not os.path.exists(CACHE_DIR):
- 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
- LATEST_VERSION = versioncheck.checkGithub()
+ with INIT_LOCK:
+
+ global __INITIALIZED__, FULL_PATH, PROG_DIR, QUIET, DAEMON, DATA_DIR, CONFIG_FILE, CFG, LOG_DIR, CACHE_DIR, \
+ HTTP_PORT, HTTP_HOST, HTTP_USERNAME, HTTP_PASSWORD, HTTP_ROOT, LAUNCH_BROWSER, GIT_PATH, \
+ CURRENT_VERSION, LATEST_VERSION, MUSIC_DIR, DESTINATION_DIR, PREFERRED_QUALITY, PREFERRED_BITRATE, DETECT_BITRATE, \
+ CORRECT_METADATA, MOVE_FILES, RENAME_FILES, FOLDER_FORMAT, FILE_FORMAT, CLEANUP_FILES, INCLUDE_EXTRAS, \
+ ADD_ALBUM_ART, EMBED_ALBUM_ART, DOWNLOAD_DIR, BLACKHOLE, BLACKHOLE_DIR, USENET_RETENTION, NZB_SEARCH_INTERVAL, \
+ LIBRARYSCAN_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
+
+ if __INITIALIZED__:
+ return False
+
+ # Make sure all the config sections exist
+ CheckSection('General')
+ CheckSection('SABnzbd')
+ CheckSection('NZBMatrix')
+ CheckSection('Newznab')
+ CheckSection('NZBsorg')
+ CheckSection('Newzbin')
+
+ # Set global variables based on config file or use defaults
+ 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))
+ GIT_PATH = check_setting_str(CFG, 'General', 'git_path', '')
+ LOG_DIR = check_setting_str(CFG, 'General', 'log_dir', '')
+
+ 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))
+ CORRECT_METADATA = bool(check_setting_int(CFG, 'General', 'correct_metadata', 0))
+ MOVE_FILES = bool(check_setting_int(CFG, 'General', 'move_files', 0))
+ RENAME_FILES = bool(check_setting_int(CFG, 'General', 'rename_files', 0))
+ FOLDER_FORMAT = check_setting_str(CFG, 'General', 'folder_format', 'artist/album [year]')
+ FILE_FORMAT = check_setting_str(CFG, 'General', 'file_format', 'tracknumber artist - album [year]- title')
+ 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))
+ 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))
+
+ NZB_SEARCH_INTERVAL = check_setting_int(CFG, 'General', 'nzb_search_interval', 360)
+ LIBRARYSCAN_INTERVAL = check_setting_int(CFG, 'General', 'libraryscan_interval', 180)
+
+ 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', '')
- __INITIALIZED__ = True
- return True
-
+ 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', '')
+
+ 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 not QUIET:
+ 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(quiet=QUIET)
+
+ # Update some old config code:
+ if FOLDER_FORMAT == '%artist/%album/%track':
+ FOLDER_FORMAT = 'artist/album [year]'
+ if FILE_FORMAT == '%tracknumber %artist - %album - %title':
+ FILE_FORMAT = 'tracknumber artist - album - title'
+
+ # Put the cache dir in the data dir for now
+ CACHE_DIR = os.path.join(DATA_DIR, 'cache')
+ if not os.path.exists(CACHE_DIR):
+ 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
+ LATEST_VERSION = versioncheck.checkGithub()
+
+ __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()
+ 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))
+ # 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())
-
- logger.info('Daemonized to PID: %s' % os.getpid())
-
+ 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())
+
+ logger.info('Daemonized to PID: %s' % os.getpid())
+
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)
+ 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 = ConfigObj()
+ new_config.filename = CONFIG_FILE
- new_config['General'] = {}
- 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']['log_dir'] = LOG_DIR
- new_config['General']['git_path'] = GIT_PATH
+ new_config['General'] = {}
+ 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']['log_dir'] = LOG_DIR
+ new_config['General']['git_path'] = GIT_PATH
- 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']['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']['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']['nzb_search_interval'] = NZB_SEARCH_INTERVAL
- new_config['General']['libraryscan_interval'] = LIBRARYSCAN_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']['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']['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']['nzb_search_interval'] = NZB_SEARCH_INTERVAL
+ new_config['General']['libraryscan_interval'] = LIBRARYSCAN_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['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['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['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['General']['lastfm_username'] = LASTFM_USERNAME
-
- new_config.write()
+ 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['General']['lastfm_username'] = LASTFM_USERNAME
+
+ new_config.write()
-
+
def start():
-
- global __INITIALIZED__, started
-
- if __INITIALIZED__:
-
- # Start our scheduled background tasks
+
+ global __INITIALIZED__, started
+
+ if __INITIALIZED__:
+
+ # Start our scheduled background tasks
- SCHED.add_cron_job(updater.dbUpdate, hour=4, minute=0, second=0)
- SCHED.add_interval_job(searcher.searchNZB, minutes=NZB_SEARCH_INTERVAL)
- SCHED.add_interval_job(importer.scanMusic, minutes=LIBRARYSCAN_INTERVAL)
- SCHED.add_interval_job(versioncheck.checkGithub, minutes=300)
- SCHED.add_interval_job(postprocessor.checkFolder, minutes=5)
+ SCHED.add_cron_job(updater.dbUpdate, hour=4, minute=0, second=0)
+ SCHED.add_interval_job(searcher.searchNZB, minutes=NZB_SEARCH_INTERVAL)
+ SCHED.add_interval_job(importer.scanMusic, minutes=LIBRARYSCAN_INTERVAL)
+ SCHED.add_interval_job(versioncheck.checkGithub, minutes=300)
+ SCHED.add_interval_job(postprocessor.checkFolder, minutes=5)
- SCHED.start()
-
- started = True
-
+ 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)')
- c.execute('CREATE TABLE IF NOT EXISTS albums (ArtistID TEXT, ArtistName TEXT, AlbumTitle TEXT, AlbumASIN TEXT, ReleaseDate TEXT, DateAdded TEXT, AlbumID TEXT UNIQUE, Status TEXT, Type TEXT)')
- c.execute('CREATE TABLE IF NOT EXISTS tracks (ArtistID TEXT, ArtistName TEXT, AlbumTitle TEXT, AlbumASIN TEXT, AlbumID TEXT, TrackTitle TEXT, TrackDuration, TrackID TEXT, TrackNumber INTEGER)')
- c.execute('CREATE TABLE IF NOT EXISTS snatched (AlbumID TEXT, Title TEXT, Size INTEGER, URL TEXT, DateAdded TEXT, Status TEXT, FolderName TEXT)')
- c.execute('CREATE TABLE IF NOT EXISTS have (ArtistName TEXT, AlbumTitle TEXT, TrackNumber TEXT, TrackTitle TEXT, TrackLength TEXT, BitRate TEXT, Genre TEXT, Date TEXT, TrackID TEXT)')
- c.execute('CREATE TABLE IF NOT EXISTS lastfmcloud (ArtistName TEXT, ArtistID TEXT, Count INTEGER)')
-
- 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"')
+ 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)')
+ c.execute('CREATE TABLE IF NOT EXISTS albums (ArtistID TEXT, ArtistName TEXT, AlbumTitle TEXT, AlbumASIN TEXT, ReleaseDate TEXT, DateAdded TEXT, AlbumID TEXT UNIQUE, Status TEXT, Type TEXT)')
+ c.execute('CREATE TABLE IF NOT EXISTS tracks (ArtistID TEXT, ArtistName TEXT, AlbumTitle TEXT, AlbumASIN TEXT, AlbumID TEXT, TrackTitle TEXT, TrackDuration, TrackID TEXT, TrackNumber INTEGER)')
+ c.execute('CREATE TABLE IF NOT EXISTS snatched (AlbumID TEXT, Title TEXT, Size INTEGER, URL TEXT, DateAdded TEXT, Status TEXT, FolderName TEXT)')
+ c.execute('CREATE TABLE IF NOT EXISTS have (ArtistName TEXT, AlbumTitle TEXT, TrackNumber TEXT, TrackTitle TEXT, TrackLength TEXT, BitRate TEXT, Genre TEXT, Date TEXT, TrackID TEXT)')
+ c.execute('CREATE TABLE IF NOT EXISTS lastfmcloud (ArtistName TEXT, ArtistID TEXT, Count INTEGER)')
+
+ 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')
-
- conn.commit()
- c.close()
+ 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')
+
+ conn.commit()
+ c.close()
-
+
def shutdown(restart=False, update=False):
-
- cherrypy.engine.exit()
- SCHED.shutdown(wait=False)
-
- config_write()
-
- if update:
- try:
- versioncheck.update()
- except Exception, e:
- logger.warn('Headphones failed to update: %s. Restarting.' % e)
-
- if restart:
-
- 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)
\ No newline at end of file
+
+ cherrypy.engine.exit()
+ SCHED.shutdown(wait=False)
+
+ config_write()
+
+ if update:
+ try:
+ versioncheck.update()
+ except Exception, e:
+ logger.warn('Headphones failed to update: %s. Restarting.' % e)
+
+ if restart:
+
+ 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)
\ No newline at end of file
diff --git a/headphones/classes.py b/headphones/classes.py
new file mode 100644
index 00000000..5dc37eb6
--- /dev/null
+++ b/headphones/classes.py
@@ -0,0 +1,131 @@
+# Author: Nic Wolfe
Newzbin:
+
+ Newzbin UID:
+
+
+ Newzbin Password:
+
+