def goodreads_oauth2(): global request_token, consumer, token, client try: if request_token and 'oauth_token' in request_token and 'oauth_token_secret' in request_token: token = oauth.Token(request_token['oauth_token'], request_token['oauth_token_secret']) else: return "Unable to run oAuth2 - Have you run oAuth1?" except Exception as e: logger.error("Exception in oAuth2: %s %s" % (type(e).__name__, traceback.format_exc())) return "Unable to run oAuth2 - Have you run oAuth1?" access_token_url = '%s/oauth/access_token' % 'https://www.goodreads.com' client = oauth.Client(consumer, token) try: response, content = client.request(access_token_url, 'POST') except Exception as e: logger.error("Exception in oauth2 client.request: %s %s" % (type(e).__name__, traceback.format_exc())) return "Error in oauth2 client request: see error log" if not response['status'].startswith('2'): return 'Invalid response [%s] from %s' % (response['status'], access_token_url) access_token = dict(parse_qsl(content)) if not PY2: access_token = {key.decode("utf-8"): access_token[key].decode("utf-8") for key in access_token} # print access_token lazylibrarian.CONFIG['GR_OAUTH_TOKEN'] = access_token['oauth_token'] lazylibrarian.CONFIG['GR_OAUTH_SECRET'] = access_token['oauth_token_secret'] lazylibrarian.config_write('API') return "Authorisation complete"
def goodreads_oauth2(): global request_token, consumer, token, client # noinspection PyBroadException try: token = oauth.Token(request_token['oauth_token'], request_token['oauth_token_secret']) except Exception: return "Unable to run oAuth2. Have you run oAuth1?" access_token_url = '%s/oauth/access_token' % 'https://www.goodreads.com' client = oauth.Client(consumer, token) try: response, content = client.request(access_token_url, 'POST') except Exception as e: return "Exception in client.request: %s %s" % (type(e).__name__, str(e)) if response['status'] != '200': return 'Invalid response: %s' % response['status'] access_token = dict(parse_qsl(content)) # print access_token lazylibrarian.CONFIG['GR_OAUTH_TOKEN'] = access_token['oauth_token'] lazylibrarian.CONFIG['GR_OAUTH_SECRET'] = access_token[ 'oauth_token_secret'] lazylibrarian.config_write('API') return {"Authorisation complete"}
def shutdown(self): lazylibrarian.config_write() lazylibrarian.SIGNAL = 'shutdown' message = 'closing ...' return serve_template(templatename="shutdown.html", title="Close library", message=message, timer=15) return page
def configUpdate(self, http_host='0.0.0.0', http_user=None, http_port=5299, http_pass=None, http_look=None, launch_browser=0, logdir=None, imp_onlyisbn=0, imp_preflang=None, imp_autoadd=None, sab_host=None, sab_port=None, sab_subdir=None, sab_api=None, sab_user=None, sab_pass=None, destination_copy=0, destination_dir=None, download_dir=None, sab_cat=None, usenet_retention=None, blackhole=0, blackholedir=None, newznab=0, newznab_host=None, newznab_api=None, newznab2=0, newznab_host2=None, newznab_api2=None,newzbin=0, newzbin_uid=None, newzbin_pass=None, ebook_type=None, gr_api=None, usenetcrawler = 0, usenetcrawler_host=None, usenetcrawler_api = None): lazylibrarian.HTTP_HOST = http_host lazylibrarian.HTTP_PORT = http_port lazylibrarian.HTTP_USER = http_user lazylibrarian.HTTP_PASS = http_pass lazylibrarian.HTTP_LOOK = http_look lazylibrarian.LAUNCH_BROWSER = launch_browser lazylibrarian.LOGDIR = logdir lazylibrarian.IMP_ONLYISBN = imp_onlyisbn lazylibrarian.IMP_PREFLANG = imp_preflang lazylibrarian.IMP_AUTOADD = imp_autoadd lazylibrarian.SAB_HOST = sab_host lazylibrarian.SAB_PORT = sab_port lazylibrarian.SAB_SUBDIR = sab_subdir lazylibrarian.SAB_API = sab_api lazylibrarian.SAB_USER = sab_user lazylibrarian.SAB_PASS = sab_pass lazylibrarian.SAB_CAT = sab_cat lazylibrarian.DESTINATION_COPY = destination_copy lazylibrarian.DESTINATION_DIR = destination_dir lazylibrarian.DOWNLOAD_DIR = download_dir lazylibrarian.USENET_RETENTION = usenet_retention lazylibrarian.BLACKHOLE = blackhole lazylibrarian.BLACKHOLEDIR = blackholedir lazylibrarian.NEWZNAB = newznab lazylibrarian.NEWZNAB_HOST = newznab_host lazylibrarian.NEWZNAB_API = newznab_api lazylibrarian.NEWZNAB2 = newznab2 lazylibrarian.NEWZNAB_HOST2 = newznab_host2 lazylibrarian.NEWZNAB_API2 = newznab_api2 lazylibrarian.NEWZBIN = newzbin lazylibrarian.NEWZBIN_UID = newzbin_uid lazylibrarian.NEWZBIN_PASS = newzbin_pass lazylibrarian.USENETCRAWLER = usenetcrawler lazylibrarian.USENETCRAWLER_HOST = usenetcrawler_host lazylibrarian.USENETCRAWLER_API = usenetcrawler_api lazylibrarian.EBOOK_TYPE = ebook_type lazylibrarian.GR_API = gr_api lazylibrarian.config_write() logger.debug('Config file has been updated') raise cherrypy.HTTPRedirect("config")
def cancelSearchType(searchType, errorMsg, provider): """ See if errorMsg contains a known error response for an unsupported search function depending on which searchType. If it does, disable that searchtype for the relevant provider return True if cancelled """ errorlist = [ 'no such function', 'unknown parameter', 'unknown function', 'bad_gateway', 'bad request', 'bad_request', 'incorrect parameter', 'does not support' ] errormsg = errorMsg.lower() if (provider['BOOKSEARCH'] and searchType in ["book", "shortbook"]) or \ (provider['AUDIOSEARCH'] and searchType in ["audio", "shortaudio"]): match = False for item in errorlist: if item in errormsg: match = True break if match: if searchType in ["book", "shortbook"]: msg = 'BOOKSEARCH' elif searchType in ["audio", "shortaudio"]: msg = 'AUDIOSEARCH' else: msg = '' if msg: for providerlist in [ lazylibrarian.NEWZNAB_PROV, lazylibrarian.TORZNAB_PROV ]: count = 0 while count < len(providerlist): if providerlist[count]['HOST'] == provider['HOST']: if str(provider['MANUAL']) == 'False': logger.error( "Disabled %s=%s for %s" % (msg, provider[msg], provider['DISPNAME'])) providerlist[count][msg] = "" lazylibrarian.config_write(provider['NAME']) return True count += 1 logger.error('Unable to disable searchtype [%s] for %s' % (searchType, provider['DISPNAME'])) return False
def configUpdate(self, http_host='0.0.0.0', http_user=None, http_port=5299, http_pass=None, http_look=None, launch_browser=0, logdir=None, imp_onlyisbn=0, imp_preflang=None, sab_host=None, sab_port=None, sab_api=None, sab_user=None, sab_pass=None, destination_copy=0, destination_dir=None, download_dir=None, sab_cat=None, usenet_retention=None, blackhole=0, blackholedir=None, nzbmatrix=0, nzbmatrix_user=None, nzbmatrix_api=None, newznab=0, newznab_host=None, newznab_api=None, newzbin=0, newzbin_uid=None, newzbin_pass=None, ebook_type=None, gr_api=None): lazylibrarian.HTTP_HOST = http_host lazylibrarian.HTTP_PORT = http_port lazylibrarian.HTTP_USER = http_user lazylibrarian.HTTP_PASS = http_pass lazylibrarian.HTTP_LOOK = http_look lazylibrarian.LAUNCH_BROWSER = launch_browser lazylibrarian.LOGDIR = logdir lazylibrarian.IMP_ONLYISBN = imp_onlyisbn lazylibrarian.IMP_PREFLANG = imp_preflang lazylibrarian.SAB_HOST = sab_host lazylibrarian.SAB_PORT = sab_port lazylibrarian.SAB_API = sab_api lazylibrarian.SAB_USER = sab_user lazylibrarian.SAB_PASS = sab_pass lazylibrarian.SAB_CAT = sab_cat lazylibrarian.DESTINATION_COPY = destination_copy lazylibrarian.DESTINATION_DIR = destination_dir lazylibrarian.DOWNLOAD_DIR = download_dir lazylibrarian.USENET_RETENTION = usenet_retention lazylibrarian.BLACKHOLE = blackhole lazylibrarian.BLACKHOLEDIR = blackholedir lazylibrarian.NZBMATRIX = nzbmatrix lazylibrarian.NZBMATRIX_USER = nzbmatrix_user lazylibrarian.NZBMATRIX_API = nzbmatrix_api lazylibrarian.NEWZNAB = newznab lazylibrarian.NEWZNAB_HOST = newznab_host lazylibrarian.NEWZNAB_API = newznab_api lazylibrarian.NEWZBIN = newzbin lazylibrarian.NEWZBIN_UID = newzbin_uid lazylibrarian.NEWZBIN_PASS = newzbin_pass lazylibrarian.EBOOK_TYPE = ebook_type lazylibrarian.GR_API = gr_api lazylibrarian.config_write() raise cherrypy.HTTPRedirect("config")
def configUpdate(self, http_host='0.0.0.0', http_user=None, http_port=5299, http_pass=None, http_look=None, launch_browser=0, logdir=None, imp_onlyisbn=0, imp_preflang=None, sab_host=None, sab_port=None, sab_api=None, sab_user=None, sab_pass=None, sab_dir=None, sab_cat=None, usenet_retention=None, blackhole=0, blackholedir=None, nzbmatrix=0, nzbmatrix_user=None, nzbmatrix_api=None, newznab=0, newznab_host=None, newznab_api=None, nzbsorg=0, nzbsorg_uid=None, nzbsorg_hash=None, newzbin=0, newzbin_uid=None, newzbin_pass=None): lazylibrarian.HTTP_HOST = http_host lazylibrarian.HTTP_PORT = http_port lazylibrarian.HTTP_USER = http_user lazylibrarian.HTTP_PASS = http_pass lazylibrarian.HTTP_LOOK = http_look lazylibrarian.LAUNCH_BROWSER = launch_browser lazylibrarian.LOGDIR = logdir lazylibrarian.IMP_ONLYISBN = imp_onlyisbn lazylibrarian.IMP_PREFLANG = imp_preflang lazylibrarian.SAB_HOST = sab_host lazylibrarian.SAB_PORT = sab_port lazylibrarian.SAB_API = sab_api lazylibrarian.SAB_USER = sab_user lazylibrarian.SAB_PASS = sab_pass lazylibrarian.SAB_DIR = sab_dir lazylibrarian.SAB_CAT = sab_cat lazylibrarian.USENET_RETENTION = usenet_retention lazylibrarian.BLACKHOLE = blackhole lazylibrarian.BLACKHOLEDIR = blackholedir lazylibrarian.NZBMATRIX = nzbmatrix lazylibrarian.NZBMATRIX_USER = nzbmatrix_user lazylibrarian.NZBMATRIX_API = nzbmatrix_api lazylibrarian.NEWZNAB = newznab lazylibrarian.NEWZNAB_HOST = newznab_host lazylibrarian.NEWZNAB_API = newznab_api lazylibrarian.NZBSORG = nzbsorg lazylibrarian.NZBSORG_UID = nzbsorg_uid lazylibrarian.NZBSORG_HASH = nzbsorg_hash lazylibrarian.NEWZBIN = newzbin lazylibrarian.NEWZBIN_UID = newzbin_uid lazylibrarian.NEWZBIN_PASS = newzbin_pass lazylibrarian.config_write() raise cherrypy.HTTPRedirect("config")
def cancelSearchType(searchType, errorMsg, provider): """ See if errorMsg contains a known error response for an unsupported search function depending on which searchType. If it does, disable that searchtype for the relevant provider return True if cancelled """ errorlist = ['no such function', 'unknown parameter', 'unknown function', 'bad_gateway', 'bad request', 'bad_request', 'incorrect parameter', 'does not support'] errormsg = errorMsg.lower() if (provider['BOOKSEARCH'] and searchType in ["book", "shortbook"]) or \ (provider['AUDIOSEARCH'] and searchType in ["audio", "shortaudio"]): match = False for item in errorlist: if item in errormsg: match = True break if match: if searchType in ["book", "shortbook"]: msg = 'BOOKSEARCH' elif searchType in ["audio", "shortaudio"]: msg = 'AUDIOSEARCH' else: msg = '' if msg: for providerlist in [lazylibrarian.NEWZNAB_PROV, lazylibrarian.TORZNAB_PROV]: count = 0 while count < len(providerlist): if providerlist[count]['HOST'] == provider['HOST']: if str(provider['MANUAL']) == 'False': logger.error("Disabled %s=%s for %s" % (msg, provider[msg], provider['DISPNAME'])) providerlist[count][msg] = "" lazylibrarian.config_write(provider['NAME']) return True count += 1 logger.error('Unable to disable searchtype [%s] for %s' % (searchType, provider['DISPNAME'])) return False
def NewzNabPlus(book=None, provider=None, searchType=None, searchMode=None): host = provider['HOST'] api_key = provider['API'] logger.debug('[NewzNabPlus] searchType [%s] with Host [%s] mode [%s] using api [%s] for item [%s]' % ( searchType, host, searchMode, api_key, str(book))) results = [] data = None params = ReturnSearchTypeStructure(provider, api_key, book, searchType, searchMode) if not str(host)[:4] == "http": host = 'http://' + host if params: URL = host + '/api?' + urllib.urlencode(params) try: request = urllib2.Request(URL) if lazylibrarian.PROXY_HOST: request.set_proxy(lazylibrarian.PROXY_HOST, lazylibrarian.PROXY_TYPE) request.add_header('User-Agent', USER_AGENT) resp = urllib2.urlopen(request, timeout=90) try: data = ElementTree.parse(resp) except (urllib2.URLError, socket.timeout, IOError, EOFError) as e: logger.error('Error fetching data from %s: %s' % (host, e)) data = None except Exception as e: logger.error("Error opening url %s, %s" % (URL, e)) data = None if data: # to debug because of api logger.debug(u'Parsing results from <a href="%s">%s</a>' % (URL, host)) rootxml = data.getroot() if rootxml.tag == 'error': errormsg = rootxml.get('description', default='unknown error') logger.error(u"%s - %s" % (host, errormsg)) if provider['BOOKSEARCH']: # maybe the host doesn't support it errorlist = ['no such function', 'unknown parameter', 'unknown function', 'incorrect parameter'] match = False for item in errorlist: if item in errormsg.lower() and provider['BOOKSEARCH'].lower() in errormsg.lower(): match = True if match: count = 0 while count < len(lazylibrarian.NEWZNAB_PROV): if lazylibrarian.NEWZNAB_PROV[count]['HOST'] == provider['HOST']: if str(provider['MANUAL']) == 'False': logger.error("Disabled booksearch=%s for %s" % (provider['BOOKSEARCH'],provider['HOST'])) lazylibrarian.NEWZNAB_PROV[count]['BOOKSEARCH'] = "" lazylibrarian.config_write() else: logger.error("Unable to disable booksearch for %s [MANUAL=%s]" % (provider['HOST'], provider['MANUAL'])) count += 1 else: resultxml = rootxml.getiterator('item') nzbcount = 0 for nzb in resultxml: try: nzbcount = nzbcount + 1 results.append(ReturnResultsFieldsBySearchType(book, nzb, searchType, host, searchMode)) except IndexError: logger.debug('No results from %s for %s' % (host, book['searchterm'])) logger.debug(u'Found %s nzb at %s for: %s' % (nzbcount, host, book['searchterm'])) else: logger.debug('No data returned from %s for %s' % (host, book['searchterm'])) return results
def NewzNabPlus(book=None, provider=None, searchType=None, searchMode=None): """ Generic NewzNabplus query function takes in host+key+type and returns the result set regardless of who based on site running NewzNab+ ref http://usenetreviewz.com/nzb-sites/ """ host = provider['HOST'] api_key = provider['API'] logger.debug( '[NewzNabPlus] searchType [%s] with Host [%s] mode [%s] using api [%s] for item [%s]' % (searchType, host, searchMode, api_key, str(book))) results = [] params = ReturnSearchTypeStructure(provider, api_key, book, searchType, searchMode) if params: if not str(host)[:4] == "http": host = 'http://' + host URL = host + '/api?' + urllib.urlencode(params) rootxml = None logger.debug("[NewzNabPlus] URL = %s" % URL) result, success = fetchURL(URL) if success: try: rootxml = ElementTree.fromstring(result) except Exception as e: logger.error('Error parsing data from %s: %s' % (host, str(e))) rootxml = None else: if not result or result == "''": result = "Got an empty response" logger.error('Error reading data from %s: %s' % (host, result)) if rootxml is not None: # to debug because of api logger.debug(u'Parsing results from <a href="%s">%s</a>' % (URL, host)) if rootxml.tag == 'error': errormsg = rootxml.get('description', default='unknown error') logger.error(u"%s - %s" % (host, errormsg)) if provider[ 'BOOKSEARCH'] and searchType == "book": # maybe the host doesn't support it errorlist = [ 'no such function', 'unknown parameter', 'unknown function', 'incorrect parameter' ] match = False for item in errorlist: if item in errormsg.lower(): match = True if match: count = 0 while count < len(lazylibrarian.NEWZNAB_PROV): if lazylibrarian.NEWZNAB_PROV[count][ 'HOST'] == provider['HOST']: if str(provider['MANUAL']) == 'False': logger.error( "Disabled booksearch=%s for %s" % (provider['BOOKSEARCH'], provider['HOST'])) lazylibrarian.NEWZNAB_PROV[count][ 'BOOKSEARCH'] = "" lazylibrarian.config_write() else: logger.error( "Unable to disable booksearch for %s [MANUAL=%s]" % (provider['HOST'], provider['MANUAL'])) count += 1 else: resultxml = rootxml.getiterator('item') nzbcount = 0 for nzb in resultxml: try: nzbcount += 1 results.append( ReturnResultsFieldsBySearchType( book, nzb, host, searchMode)) except IndexError: logger.debug('No results from %s for %s' % (host, book['searchterm'])) logger.debug(u'Found %s nzb at %s for: %s' % (nzbcount, host, book['searchterm'])) else: logger.debug('No data returned from %s for %s' % (host, book['searchterm'])) return results
def main(): # rename this thread threading.currentThread().name = "MAIN" # Set paths if hasattr(sys, 'frozen'): lazylibrarian.FULL_PATH = os.path.abspath(sys.executable) else: lazylibrarian.FULL_PATH = os.path.abspath(__file__) lazylibrarian.PROG_DIR = os.path.dirname(lazylibrarian.FULL_PATH) lazylibrarian.ARGS = sys.argv[1:] lazylibrarian.SYS_ENCODING = None try: locale.setlocale(locale.LC_ALL, "") lazylibrarian.SYS_ENCODING = locale.getpreferredencoding() except (locale.Error, IOError): pass # for OSes that are poorly configured I'll just force UTF-8 # windows cp1252 can't handle some accented author names, # eg "Marie Kondō" U+014D: LATIN SMALL LETTER O WITH MACRON, but utf-8 does if not lazylibrarian.SYS_ENCODING or lazylibrarian.SYS_ENCODING in ( 'ANSI_X3.4-1968', 'US-ASCII', 'ASCII') or '1252' in lazylibrarian.SYS_ENCODING: lazylibrarian.SYS_ENCODING = 'UTF-8' # Set arguments from optparse import OptionParser p = OptionParser() p.add_option('-d', '--daemon', action="store_true", dest='daemon', help="Run the server as a daemon") p.add_option('-q', '--quiet', action="store_true", dest='quiet', help="Don't log to console") p.add_option('--debug', action="store_true", dest='debug', help="Show debuglog messages") p.add_option('--nolaunch', action="store_true", dest='nolaunch', help="Don't start browser") p.add_option('--update', action="store_true", dest='update', help="Update to latest version (only git or source installs)") p.add_option('--port', dest='port', default=None, help="Force webinterface to listen on this port") p.add_option('--datadir', dest='datadir', default=None, help="Path to the data directory") p.add_option('--config', dest='config', default=None, help="Path to config.ini file") p.add_option('-p', '--pidfile', dest='pidfile', default=None, help="Store the process id in the given file") p.add_option('--loglevel', dest='loglevel', default=None, help="Debug loglevel") options, args = p.parse_args() lazylibrarian.LOGLEVEL = 1 if options.debug: lazylibrarian.LOGLEVEL = 2 if options.quiet: lazylibrarian.LOGLEVEL = 0 if options.daemon: if 'windows' not in platform.system().lower(): lazylibrarian.DAEMON = True # lazylibrarian.daemonize() else: print("Daemonize not supported under Windows, starting normally") if options.nolaunch: lazylibrarian.CONFIG['LAUNCH_BROWSER'] = False if options.update: lazylibrarian.SIGNAL = 'update' # This is the "emergency recovery" update in case lazylibrarian won't start. # Set up some dummy values for the update as we have not read the config file yet lazylibrarian.CONFIG['GIT_PROGRAM'] = '' lazylibrarian.CONFIG['GIT_USER'] = '******' lazylibrarian.CONFIG['GIT_REPO'] = 'lazylibrarian' lazylibrarian.CONFIG['LOGLIMIT'] = 2000 versioncheck.getInstallType() if lazylibrarian.CONFIG['INSTALL_TYPE'] not in ['git', 'source']: lazylibrarian.SIGNAL = None print('Cannot update, not a git or source installation') else: lazylibrarian.shutdown(restart=True, update=True) if options.loglevel: try: lazylibrarian.LOGLEVEL = int(options.loglevel) except: pass if options.datadir: lazylibrarian.DATADIR = str(options.datadir) else: lazylibrarian.DATADIR = lazylibrarian.PROG_DIR if options.config: lazylibrarian.CONFIGFILE = str(options.config) else: lazylibrarian.CONFIGFILE = os.path.join(lazylibrarian.DATADIR, "config.ini") if options.pidfile: if lazylibrarian.DAEMON: lazylibrarian.PIDFILE = str(options.pidfile) # create and check (optional) paths if not os.path.isdir(lazylibrarian.DATADIR): try: os.makedirs(lazylibrarian.DATADIR) except OSError: raise SystemExit('Could not create data directory: ' + lazylibrarian.DATADIR + '. Exit ...') if not os.access(lazylibrarian.DATADIR, os.W_OK): raise SystemExit('Cannot write to the data directory: ' + lazylibrarian.DATADIR + '. Exit ...') print("Lazylibrarian is starting up...") time.sleep(4) # allow a bit of time for old task to exit if restarting. Needs to free logfile and server port. # create database and config lazylibrarian.DBFILE = os.path.join(lazylibrarian.DATADIR, 'lazylibrarian.db') lazylibrarian.CFG = configparser.RawConfigParser() lazylibrarian.CFG.read(lazylibrarian.CONFIGFILE) # REMINDER ############ NO LOGGING BEFORE HERE ############### # There is no point putting in any logging above this line, as its not set till after initialize. lazylibrarian.initialize() if lazylibrarian.CONFIG['VERSIONCHECK_INTERVAL'] == 0: logger.debug('Automatic update checks are disabled') # pretend we're up to date so we don't keep warning the user # version check button will still override this if you want to lazylibrarian.CONFIG['LATEST_VERSION'] = lazylibrarian.CONFIG['CURRENT_VERSION'] lazylibrarian.CONFIG['COMMITS_BEHIND'] = 0 else: # Set the install type (win,git,source) & # check the version when the application starts versioncheck.checkForUpdates() logger.debug('Current Version [%s] - Latest remote version [%s] - Install type [%s]' % ( lazylibrarian.CONFIG['CURRENT_VERSION'], lazylibrarian.CONFIG['LATEST_VERSION'], lazylibrarian.CONFIG['INSTALL_TYPE'])) if check_int(lazylibrarian.CONFIG['GIT_UPDATED'], 0) == 0: if lazylibrarian.CONFIG['CURRENT_VERSION'] == lazylibrarian.CONFIG['LATEST_VERSION']: if lazylibrarian.CONFIG['INSTALL_TYPE'] == 'git' and lazylibrarian.CONFIG['COMMITS_BEHIND'] == 0: lazylibrarian.CONFIG['GIT_UPDATED'] = str(int(time.time())) logger.debug('Setting update timestamp to now') # flatpak insists on PROG_DIR being read-only so we have to move version.txt into CACHEDIR old_file = os.path.join(lazylibrarian.PROG_DIR, 'version.txt') version_file = os.path.join(lazylibrarian.CACHEDIR, 'version.txt') if os.path.isfile(old_file): if not os.path.isfile(version_file): try: with open(old_file, 'r') as s: with open(version_file, 'w') as d: d.write(s.read()) except OSError: logger.warn("Unable to copy version.txt") try: os.remove(old_file) except OSError: pass # for dockers that haven't updated correctly from github to gitlab, force source install if lazylibrarian.CONFIG['CURRENT_VERSION'] != lazylibrarian.CONFIG['LATEST_VERSION']: if lazylibrarian.CONFIG['INSTALL_TYPE'] == 'git' and lazylibrarian.CONFIG['COMMITS_BEHIND'] == 0: if os.path.exists('/app/lazylibrarian/.git'): os.remove(version_file) shutil.rmtree('/app/lazylibrarian/.git') lazylibrarian.CONFIG['INSTALL_TYPE'] = 'source' lazylibrarian.CONFIG['GIT_USER'] = '******' lazylibrarian.CONFIG['GIT_HOST'] = 'gitlab.com' lazylibrarian.CONFIG['GITLAB_TOKEN'] = 'gitlab+deploy-token-26212:[email protected]' lazylibrarian.config_write('Git') if not os.path.isfile(version_file) and lazylibrarian.CONFIG['INSTALL_TYPE'] == 'source': # User may be running an old source zip, so try to force update lazylibrarian.CONFIG['COMMITS_BEHIND'] = 1 lazylibrarian.SIGNAL = 'update' # but only once in case the update fails, don't loop with open(version_file, 'w') as f: f.write("UNKNOWN SOURCE") if lazylibrarian.CONFIG['COMMITS_BEHIND'] <= 0 and lazylibrarian.SIGNAL == 'update': lazylibrarian.SIGNAL = None if lazylibrarian.CONFIG['COMMITS_BEHIND'] == 0: logger.debug('Not updating, LazyLibrarian is already up to date') else: logger.debug('Not updating, LazyLibrarian has local changes') if lazylibrarian.DAEMON: lazylibrarian.daemonize() # Try to start the server. if options.port: lazylibrarian.CONFIG['HTTP_PORT'] = int(options.port) logger.info('Starting LazyLibrarian on forced port: %s, webroot "%s"' % (lazylibrarian.CONFIG['HTTP_PORT'], lazylibrarian.CONFIG['HTTP_ROOT'])) else: lazylibrarian.CONFIG['HTTP_PORT'] = int(lazylibrarian.CONFIG['HTTP_PORT']) logger.info('Starting LazyLibrarian on port: %s, webroot "%s"' % (lazylibrarian.CONFIG['HTTP_PORT'], lazylibrarian.CONFIG['HTTP_ROOT'])) webStart.initialize({ 'http_port': lazylibrarian.CONFIG['HTTP_PORT'], 'http_host': lazylibrarian.CONFIG['HTTP_HOST'], 'http_root': lazylibrarian.CONFIG['HTTP_ROOT'], 'http_user': lazylibrarian.CONFIG['HTTP_USER'], 'http_pass': lazylibrarian.CONFIG['HTTP_PASS'], 'http_proxy': lazylibrarian.CONFIG['HTTP_PROXY'], 'https_enabled': lazylibrarian.CONFIG['HTTPS_ENABLED'], 'https_cert': lazylibrarian.CONFIG['HTTPS_CERT'], 'https_key': lazylibrarian.CONFIG['HTTPS_KEY'], 'opds_enabled': lazylibrarian.CONFIG['OPDS_ENABLED'], 'opds_authentication': lazylibrarian.CONFIG['OPDS_AUTHENTICATION'], 'opds_username': lazylibrarian.CONFIG['OPDS_USERNAME'], 'opds_password': lazylibrarian.CONFIG['OPDS_PASSWORD'], }) if lazylibrarian.CONFIG['LAUNCH_BROWSER'] and not options.nolaunch: lazylibrarian.launch_browser(lazylibrarian.CONFIG['HTTP_HOST'], lazylibrarian.CONFIG['HTTP_PORT'], lazylibrarian.CONFIG['HTTP_ROOT']) curr_ver = dbupgrade.upgrade_needed() if curr_ver: lazylibrarian.UPDATE_MSG = 'Updating database to version %s' % curr_ver threading.Thread(target=dbupgrade.dbupgrade, name="DB_UPGRADE", args=[curr_ver]).start() lazylibrarian.start() while True: if not lazylibrarian.SIGNAL: try: time.sleep(1) except KeyboardInterrupt: lazylibrarian.shutdown() else: if lazylibrarian.SIGNAL == 'shutdown': lazylibrarian.shutdown() elif lazylibrarian.SIGNAL == 'restart': lazylibrarian.shutdown(restart=True) elif lazylibrarian.SIGNAL == 'update': lazylibrarian.shutdown(restart=True, update=True) lazylibrarian.SIGNAL = None
def configUpdate(self, http_host='0.0.0.0', http_user=None, http_port=5299, http_pass=None, http_look=None, launch_browser=0, logdir=None, imp_onlyisbn=0, imp_preflang=None, imp_autoadd=None, sab_host=None, sab_port=None, sab_subdir=None, sab_api=None, sab_user=None, sab_pass=None, destination_copy=0, destination_dir=None, download_dir=None, sab_cat=None, usenet_retention=None, blackhole=0, blackholedir=None, newznab=0, newznab_host=None, newznab_api=None, newznab2=0, newznab_host2=None, newznab_api2=None,newzbin=0, newzbin_uid=None, newzbin_pass=None, ebook_type=None, book_api=None, gr_api=None, gb_api=None, usenetcrawler = 0, usenetcrawler_host=None, usenetcrawler_api = None, versioncheck_interval=None, search_interval=None, scan_interval=None, ebook_dest_folder=None, ebook_dest_file=None, mag_dest_folder=None, mag_dest_file=None, use_twitter=0, twitter_notify_onsnatch=0, twitter_notify_ondownload=0): lazylibrarian.HTTP_HOST = http_host lazylibrarian.HTTP_PORT = http_port lazylibrarian.HTTP_USER = http_user lazylibrarian.HTTP_PASS = http_pass lazylibrarian.HTTP_LOOK = http_look lazylibrarian.LAUNCH_BROWSER = launch_browser lazylibrarian.LOGDIR = logdir lazylibrarian.IMP_ONLYISBN = imp_onlyisbn lazylibrarian.IMP_PREFLANG = imp_preflang lazylibrarian.IMP_AUTOADD = imp_autoadd lazylibrarian.SAB_HOST = sab_host lazylibrarian.SAB_PORT = sab_port lazylibrarian.SAB_SUBDIR = sab_subdir lazylibrarian.SAB_API = sab_api lazylibrarian.SAB_USER = sab_user lazylibrarian.SAB_PASS = sab_pass lazylibrarian.SAB_CAT = sab_cat lazylibrarian.DESTINATION_COPY = destination_copy lazylibrarian.DESTINATION_DIR = destination_dir lazylibrarian.DOWNLOAD_DIR = download_dir lazylibrarian.USENET_RETENTION = usenet_retention lazylibrarian.BLACKHOLE = blackhole lazylibrarian.BLACKHOLEDIR = blackholedir lazylibrarian.NEWZNAB = newznab lazylibrarian.NEWZNAB_HOST = newznab_host lazylibrarian.NEWZNAB_API = newznab_api lazylibrarian.NEWZNAB2 = newznab2 lazylibrarian.NEWZNAB_HOST2 = newznab_host2 lazylibrarian.NEWZNAB_API2 = newznab_api2 lazylibrarian.NEWZBIN = newzbin lazylibrarian.NEWZBIN_UID = newzbin_uid lazylibrarian.NEWZBIN_PASS = newzbin_pass lazylibrarian.USENETCRAWLER = usenetcrawler lazylibrarian.USENETCRAWLER_HOST = usenetcrawler_host lazylibrarian.USENETCRAWLER_API = usenetcrawler_api lazylibrarian.EBOOK_TYPE = ebook_type lazylibrarian.BOOK_API = book_api lazylibrarian.GR_API = gr_api lazylibrarian.GB_API = gb_api lazylibrarian.SEARCH_INTERVAL = search_interval lazylibrarian.SCAN_INTERVAL = scan_interval lazylibrarian.VERSIONCHECK_INTERVAL = versioncheck_interval lazylibrarian.EBOOK_DEST_FOLDER = ebook_dest_folder lazylibrarian.EBOOK_DEST_FILE = ebook_dest_file lazylibrarian.MAG_DEST_FOLDER = mag_dest_folder lazylibrarian.MAG_DEST_FILE = mag_dest_file lazylibrarian.USE_TWITTER = use_twitter lazylibrarian.TWITTER_NOTIFY_ONSNATCH = twitter_notify_onsnatch lazylibrarian.TWITTER_NOTIFY_ONDOWNLOAD = twitter_notify_ondownload lazylibrarian.config_write() logger.debug('Config file has been updated') raise cherrypy.HTTPRedirect("config")
def NewzNabPlus(book=None, provider=None, searchType=None, searchMode=None): """ Generic NewzNabplus query function takes in host+key+type and returns the result set regardless of who based on site running NewzNab+ ref http://usenetreviewz.com/nzb-sites/ """ host = provider['HOST'] api_key = provider['API'] logger.debug( '[NewzNabPlus] searchType [%s] with Host [%s] mode [%s] using api [%s] for item [%s]' % (searchType, host, searchMode, api_key, str(book))) results = [] params = ReturnSearchTypeStructure(provider, api_key, book, searchType, searchMode) if params: if not str(host)[:4] == "http": host = 'http://' + host if host[-1:] == '/': host = host[:-1] URL = host + '/api?' + urllib.urlencode(params) sterm = book['searchterm'] if isinstance(sterm, str) and hasattr(sterm, "decode"): sterm = sterm.decode('utf-8') rootxml = None logger.debug("[NewzNabPlus] URL = %s" % URL) result, success = fetchURL(URL) if success: try: rootxml = ElementTree.fromstring(result) except Exception as e: logger.error('Error parsing data from %s: %s %s' % (host, type(e).__name__, str(e))) rootxml = None else: if not result or result == "''": result = "Got an empty response" logger.error('Error reading data from %s: %s' % (host, result)) BlockProvider(host, result) if rootxml is not None: # to debug because of api logger.debug('Parsing results from <a href="%s">%s</a>' % (URL, host)) if rootxml.tag == 'error': errormsg = rootxml.get('description', default='unknown error') logger.error("%s - %s" % (host, errormsg)) # maybe the host doesn't support the search type match = False if (provider['BOOKSEARCH'] and searchType in ["book", "shortbook"]) or \ (provider['AUDIOSEARCH'] and searchType in ["audio", "shortaudio"]): errorlist = [ 'no such function', 'unknown parameter', 'unknown function', 'bad request', 'incorrect parameter', 'does not support' ] for item in errorlist: if item in errormsg.lower(): match = True if match: count = 0 if searchType in ["book", "shortbook"]: msg = 'BOOKSEARCH' elif searchType in ["audio", "shortaudio"]: msg = 'AUDIOSEARCH' else: msg = '' if not msg: logger.error( 'Error trying to disable searchtype [%s] for %s' % (searchType, host)) else: while count < len(lazylibrarian.NEWZNAB_PROV): if lazylibrarian.NEWZNAB_PROV[count][ 'HOST'] == provider['HOST']: if str(provider['MANUAL']) == 'False': logger.error("Disabled %s=%s for %s" % (msg, provider[msg], provider['HOST'])) lazylibrarian.NEWZNAB_PROV[count][ msg] = "" threadname = threading.currentThread( ).name lazylibrarian.config_write() threading.currentThread( ).name = threadname else: logger.error( "Unable to disable %s for %s [MANUAL=%s]" % (msg, provider['HOST'], provider['MANUAL'])) count += 1 if not match: BlockProvider(provider['HOST'], errormsg) else: resultxml = rootxml.getiterator('item') nzbcount = 0 maxage = check_int(lazylibrarian.CONFIG['USENET_RETENTION'], 0) for nzb in resultxml: try: thisnzb = ReturnResultsFieldsBySearchType( book, nzb, host, searchMode, provider['DLPRIORITY']) if not maxage: nzbcount += 1 results.append(thisnzb) else: # example nzbdate format: Mon, 27 May 2013 02:12:09 +0200 nzbdate = thisnzb['nzbdate'] try: parts = nzbdate.split(' ') nzbdate = ' '.join( parts[:5]) # strip the +0200 dt = datetime.datetime.strptime( nzbdate, "%a, %d %b %Y %H:%M:%S").timetuple() nzbage = age( '%04d-%02d-%02d' % (dt.tm_year, dt.tm_mon, dt.tm_mday)) except Exception as e: logger.debug( 'Unable to get age from [%s] %s %s' % (thisnzb['nzbdate'], type(e).__name__, str(e))) nzbage = 0 if nzbage <= maxage: nzbcount += 1 results.append(thisnzb) else: logger.debug('%s is too old (%s day%s)' % (thisnzb['nzbtitle'], nzbage, plural(nzbage))) except IndexError: logger.debug('No results from %s for %s' % (host, sterm)) logger.debug('Found %s nzb at %s for: %s' % (nzbcount, host, sterm)) else: logger.debug('No data returned from %s for %s' % (host, sterm)) return results
def NewzNabPlus(book=None, provider=None, searchType=None, searchMode=None): """ Generic NewzNabplus query function takes in host+key+type and returns the result set regardless of who based on site running NewzNab+ ref http://usenetreviewz.com/nzb-sites/ """ host = provider['HOST'] api_key = provider['API'] logger.debug('[NewzNabPlus] searchType [%s] with Host [%s] mode [%s] using api [%s] for item [%s]' % ( searchType, host, searchMode, api_key, str(book))) results = [] data = None params = ReturnSearchTypeStructure(provider, api_key, book, searchType, searchMode) if params: if not str(host)[:4] == "http": host = 'http://' + host URL = host + '/api?' + urllib.urlencode(params) rootxml = None result, success = fetchURL(URL) if success: try: rootxml = ElementTree.fromstring(result) except Exception as e: logger.error('Error parsing data from %s: %s' % (host, str(e))) rootxml = None else: logger.error('Error reading data from %s: %s' % (host, result)) if rootxml is not None: # to debug because of api logger.debug(u'Parsing results from <a href="%s">%s</a>' % (URL, host)) if rootxml.tag == 'error': errormsg = rootxml.get('description', default='unknown error') logger.error(u"%s - %s" % (host, errormsg)) if provider['BOOKSEARCH']: # maybe the host doesn't support it errorlist = ['no such function', 'unknown parameter', 'unknown function', 'incorrect parameter'] match = False for item in errorlist: if item in errormsg.lower() and provider['BOOKSEARCH'].lower() in errormsg.lower(): match = True if match: count = 0 while count < len(lazylibrarian.NEWZNAB_PROV): if lazylibrarian.NEWZNAB_PROV[count]['HOST'] == provider['HOST']: if str(provider['MANUAL']) == 'False': logger.error( "Disabled booksearch=%s for %s" % (provider['BOOKSEARCH'], provider['HOST'])) lazylibrarian.NEWZNAB_PROV[count]['BOOKSEARCH'] = "" lazylibrarian.config_write() else: logger.error( "Unable to disable booksearch for %s [MANUAL=%s]" % (provider['HOST'], provider['MANUAL'])) count += 1 else: resultxml = rootxml.getiterator('item') nzbcount = 0 for nzb in resultxml: try: nzbcount = nzbcount + 1 results.append(ReturnResultsFieldsBySearchType(book, nzb, searchType, host, searchMode)) except IndexError: logger.debug('No results from %s for %s' % (host, book['searchterm'])) logger.debug(u'Found %s nzb at %s for: %s' % (nzbcount, host, book['searchterm'])) else: logger.debug('No data returned from %s for %s' % (host, book['searchterm'])) return results
def get_capabilities(provider, force=False): """ query provider for caps if none loaded yet, or if config entry is too old and not set manually. """ if not force and len(provider['UPDATED']) == 10: # any stored values? match = True if (age(provider['UPDATED']) > lazylibrarian.CONFIG['CACHE_AGE']) and not provider['MANUAL']: logger.debug('Stored capabilities for %s are too old' % provider['HOST']) match = False else: match = False if match: logger.debug('Using stored capabilities for %s' % provider['HOST']) else: host = provider['HOST'] if not str(host)[:4] == "http": host = 'http://' + host if host[-1:] == '/': host = host[:-1] URL = host + '/api?t=caps' # most providers will give you caps without an api key logger.debug('Requesting capabilities for %s' % URL) source_xml, success = fetchURL(URL, raw=True) data = None if not success: logger.debug("Error getting xml from %s, %s" % (URL, source_xml)) else: try: data = ElementTree.fromstring(source_xml) if data.tag == 'error': logger.debug("Unable to get capabilities: %s" % data.attrib) success = False except (ElementTree.ParseError, UnicodeEncodeError): logger.debug("Error parsing xml from %s, %s" % (URL, source_xml)) success = False if not success: # If it failed, retry with api key if provider['API']: URL = URL + '&apikey=' + provider['API'] logger.debug('Retrying capabilities with apikey for %s' % URL) source_xml, success = fetchURL(URL, raw=True) if not success: logger.debug("Error getting xml from %s, %s" % (URL, source_xml)) else: try: data = ElementTree.fromstring(source_xml) if data.tag == 'error': logger.debug("Unable to get capabilities: %s" % data.attrib) success = False except (ElementTree.ParseError, UnicodeEncodeError): logger.debug("Error parsing xml from %s, %s" % (URL, source_xml)) success = False else: logger.debug('Unable to retry capabilities, no apikey for %s' % URL) if not success: logger.warn("Unable to get capabilities for %s: No data returned" % URL) # might be a temporary error if provider['BOOKCAT'] or provider['MAGCAT'] or provider['AUDIOCAT']: logger.debug('Using old stored capabilities for %s' % provider['HOST']) else: # or might be provider doesn't do caps logger.debug('Using default capabilities for %s' % provider['HOST']) provider['GENERALSEARCH'] = 'search' provider['EXTENDED'] = '1' provider['BOOKCAT'] = '' provider['MAGCAT'] = '' provider['AUDIOCAT'] = '' provider['BOOKSEARCH'] = '' provider['MAGSEARCH'] = '' provider['AUDIOSEARCH'] = '' provider['UPDATED'] = today() lazylibrarian.config_write(provider['NAME']) elif data is not None: logger.debug("Parsing xml for capabilities of %s" % URL) # # book search isn't mentioned in the caps xml returned by # nzbplanet,jackett,oznzb,usenet-crawler, so we can't use it as a test # but the newznab+ ones usually support t=book and categories in 7000 range # whereas nZEDb ones don't support t=book and use categories in 8000 range # also some providers give searchtype but no supportedparams, so we still # can't tell what queries will be accepted # also category names can be lowercase or Mixed, magazine subcat name isn't # consistent, and subcat can be just subcat or category/subcat subcat > lang # eg "Magazines" "Mags" or "Books/Magazines" "Mags > French" # Load all languages for now as we don't know which the user might want # # # set some defaults # provider['GENERALSEARCH'] = 'search' provider['EXTENDED'] = '1' provider['BOOKCAT'] = '' provider['MAGCAT'] = '' provider['AUDIOCAT'] = '' provider['BOOKSEARCH'] = '' provider['MAGSEARCH'] = '' provider['AUDIOSEARCH'] = '' # search = data.find('searching/search') if search is not None: # noinspection PyUnresolvedReferences if 'available' in search.attrib: # noinspection PyUnresolvedReferences if search.attrib['available'] == 'yes': provider['GENERALSEARCH'] = 'search' categories = data.getiterator('category') for cat in categories: if 'name' in cat.attrib: if cat.attrib['name'].lower() == 'audio': provider['AUDIOCAT'] = cat.attrib['id'] subcats = cat.getiterator('subcat') for subcat in subcats: if 'audiobook' in subcat.attrib['name'].lower(): provider['AUDIOCAT'] = subcat.attrib['id'] elif cat.attrib['name'].lower() == 'books': provider['BOOKCAT'] = cat.attrib['id'] # if no specific magazine subcategory, use books provider['MAGCAT'] = cat.attrib['id'] # set default booksearch if provider['BOOKCAT'] == '7000': # looks like newznab+, should support book-search provider['BOOKSEARCH'] = 'book' else: # looks like nZEDb, probably no book-search provider['BOOKSEARCH'] = '' # but check in case we got some settings back search = data.find('searching/book-search') if search: # noinspection PyUnresolvedReferences if 'available' in search.attrib: # noinspection PyUnresolvedReferences if search.attrib['available'] == 'yes': provider['BOOKSEARCH'] = 'book' else: provider['BOOKSEARCH'] = '' # subcategories override main category (not in addition to) # but allow multile subcategories (mags->english, mags->french) subcats = cat.getiterator('subcat') ebooksubs = '' magsubs = '' for subcat in subcats: if 'ebook' in subcat.attrib['name'].lower(): if ebooksubs: ebooksubs = ebooksubs + ',' ebooksubs = ebooksubs + subcat.attrib['id'] if 'magazines' in subcat.attrib['name'].lower() or 'mags' in subcat.attrib['name'].lower(): if magsubs: magsubs = magsubs + ',' magsubs = magsubs + subcat.attrib['id'] if ebooksubs: provider['BOOKCAT'] = ebooksubs if magsubs: provider['MAGCAT'] = magsubs logger.info("Categories: Books %s : Mags %s : Audio %s : BookSearch '%s'" % (provider['BOOKCAT'], provider['MAGCAT'], provider['AUDIOCAT'], provider['BOOKSEARCH'])) provider['UPDATED'] = today() lazylibrarian.config_write(provider['NAME']) return provider
def configUpdate(self, http_host='0.0.0.0', http_root=None, http_user=None, http_port=5299, http_pass=None, http_look=None, launch_browser=0, logdir=None, imp_onlyisbn=0, imp_preflang=None, imp_autoadd=None, match_ratio=80, nzb_downloader_sabnzbd=0, nzb_downloader_blackhole=0, use_nzb=0, use_tor=0, proxy_host=None, proxy_type=None, sab_host=None, sab_port=None, sab_subdir=None, sab_api=None, sab_user=None, sab_pass=None, destination_copy=0, destination_dir=None, download_dir=None, sab_cat=None, usenet_retention=None, nzb_blackholedir=None, torrent_dir=None, numberofseeders=0, tor_downloader_blackhole=0, tor_downloader_utorrent=0, newznab=0, newznab_host=None, newznab_api=None, newznab2=0, newznab_host2=None, newznab_api2=None,newzbin=0, newzbin_uid=None, newzbin_pass=None, kat=0, ebook_type=None, book_api=None, gr_api=None, gb_api=None, usenetcrawler = 0, usenetcrawler_host=None, usenetcrawler_api = None, versioncheck_interval=None, search_interval=None, scan_interval=None, ebook_dest_folder=None, ebook_dest_file=None, mag_dest_folder=None, mag_dest_file=None, use_twitter=0, twitter_notify_onsnatch=0, twitter_notify_ondownload=0, utorrent_host=None, utorrent_user=None, utorrent_pass=None, notfound_status='Wanted', full_scan=0, add_author=1, utorrent_label=None, use_boxcar=0, boxcar_notify_onsnatch=0, boxcar_notify_ondownload=0, boxcar_token=None, use_pushbullet=0, pushbullet_notify_onsnatch=0, pushbullet_notify_ondownload=0, pushbullet_token=None, pushbullet_deviceid=None, nma_enabled=False, nma_apikey=None, nma_priority=0, nma_onsnatch=0): lazylibrarian.HTTP_HOST = http_host lazylibrarian.HTTP_ROOT = http_root lazylibrarian.HTTP_PORT = http_port lazylibrarian.HTTP_USER = http_user lazylibrarian.HTTP_PASS = http_pass lazylibrarian.HTTP_LOOK = http_look lazylibrarian.LAUNCH_BROWSER = launch_browser lazylibrarian.PROXY_HOST = proxy_host lazylibrarian.PROXY_TYPE = proxy_type lazylibrarian.LOGDIR = logdir lazylibrarian.MATCH_RATIO = match_ratio lazylibrarian.IMP_ONLYISBN = imp_onlyisbn lazylibrarian.IMP_PREFLANG = imp_preflang lazylibrarian.IMP_AUTOADD = imp_autoadd lazylibrarian.SAB_HOST = sab_host lazylibrarian.SAB_PORT = sab_port lazylibrarian.SAB_SUBDIR = sab_subdir lazylibrarian.SAB_API = sab_api lazylibrarian.SAB_USER = sab_user lazylibrarian.SAB_PASS = sab_pass lazylibrarian.SAB_CAT = sab_cat lazylibrarian.DESTINATION_COPY = destination_copy lazylibrarian.DESTINATION_DIR = destination_dir lazylibrarian.DOWNLOAD_DIR = download_dir lazylibrarian.USENET_RETENTION = usenet_retention lazylibrarian.NZB_BLACKHOLEDIR = nzb_blackholedir lazylibrarian.NZB_DOWNLOADER_SABNZBD = nzb_downloader_sabnzbd lazylibrarian.NZB_DOWNLOADER_BLACKHOLE = nzb_downloader_blackhole lazylibrarian.TORRENT_DIR = torrent_dir lazylibrarian.NUMBEROFSEEDERS = numberofseeders lazylibrarian.TOR_DOWNLOADER_BLACKHOLE = tor_downloader_blackhole lazylibrarian.TOR_DOWNLOADER_UTORRENT = tor_downloader_utorrent lazylibrarian.NEWZNAB = newznab lazylibrarian.NEWZNAB_HOST = newznab_host lazylibrarian.NEWZNAB_API = newznab_api lazylibrarian.NEWZNAB2 = newznab2 lazylibrarian.NEWZNAB_HOST2 = newznab_host2 lazylibrarian.NEWZNAB_API2 = newznab_api2 lazylibrarian.NEWZBIN = newzbin lazylibrarian.NEWZBIN_UID = newzbin_uid lazylibrarian.NEWZBIN_PASS = newzbin_pass lazylibrarian.UTORRENT_HOST = utorrent_host lazylibrarian.UTORRENT_USER = utorrent_user lazylibrarian.UTORRENT_PASS = utorrent_pass lazylibrarian.UTORRENT_LABEL = utorrent_label lazylibrarian.KAT = kat lazylibrarian.USE_NZB = use_nzb lazylibrarian.USE_TOR = use_tor lazylibrarian.USENETCRAWLER = usenetcrawler lazylibrarian.USENETCRAWLER_HOST = usenetcrawler_host lazylibrarian.USENETCRAWLER_API = usenetcrawler_api lazylibrarian.EBOOK_TYPE = ebook_type lazylibrarian.BOOK_API = book_api lazylibrarian.GR_API = gr_api lazylibrarian.GB_API = gb_api lazylibrarian.SEARCH_INTERVAL = search_interval lazylibrarian.SCAN_INTERVAL = scan_interval lazylibrarian.VERSIONCHECK_INTERVAL = versioncheck_interval lazylibrarian.FULL_SCAN = full_scan lazylibrarian.NOTFOUND_STATUS = notfound_status lazylibrarian.ADD_AUTHOR = add_author lazylibrarian.EBOOK_DEST_FOLDER = ebook_dest_folder lazylibrarian.EBOOK_DEST_FILE = ebook_dest_file lazylibrarian.MAG_DEST_FOLDER = mag_dest_folder lazylibrarian.MAG_DEST_FILE = mag_dest_file lazylibrarian.USE_TWITTER = use_twitter lazylibrarian.TWITTER_NOTIFY_ONSNATCH = twitter_notify_onsnatch lazylibrarian.TWITTER_NOTIFY_ONDOWNLOAD = twitter_notify_ondownload lazylibrarian.USE_BOXCAR = use_boxcar lazylibrarian.BOXCAR_NOTIFY_ONSNATCH = boxcar_notify_onsnatch lazylibrarian.BOXCAR_NOTIFY_ONDOWNLOAD = boxcar_notify_ondownload lazylibrarian.BOXCAR_TOKEN = boxcar_token lazylibrarian.USE_PUSHBULLET = use_pushbullet lazylibrarian.PUSHBULLET_NOTIFY_ONSNATCH = pushbullet_notify_onsnatch lazylibrarian.PUSHBULLET_NOTIFY_ONDOWNLOAD = pushbullet_notify_ondownload lazylibrarian.PUSHBULLET_TOKEN = pushbullet_token lazylibrarian.PUSHBULLET_DEVICEID = pushbullet_deviceid lazylibrarian.NMA_ENABLED = nma_enabled lazylibrarian.NMA_APIKEY = nma_apikey lazylibrarian.NMA_PRIORITY = nma_priority lazylibrarian.NMA_ONSNATCH = nma_onsnatch lazylibrarian.config_write() logger.debug('Config file has been updated') raise cherrypy.HTTPRedirect("config")
def NewzNabPlus(book=None, provider=None, searchType=None, searchMode=None): host = provider['HOST'] api_key = provider['API'] logger.debug( '[NewzNabPlus] searchType [%s] with Host [%s] mode [%s] using api [%s] for item [%s]' % (searchType, host, searchMode, api_key, str(book))) results = [] data = None params = ReturnSearchTypeStructure(provider, api_key, book, searchType, searchMode) if not str(host)[:4] == "http": host = 'http://' + host if params: URL = host + '/api?' + urllib.urlencode(params) try: request = urllib2.Request(URL) if lazylibrarian.PROXY_HOST: request.set_proxy(lazylibrarian.PROXY_HOST, lazylibrarian.PROXY_TYPE) request.add_header('User-Agent', USER_AGENT) resp = urllib2.urlopen(request, timeout=90) try: data = ElementTree.parse(resp) except (urllib2.URLError, socket.timeout, IOError, EOFError) as e: logger.error('Error fetching data from %s: %s' % (host, e)) data = None except Exception as e: logger.error("Error opening url %s, %s" % (URL, e)) data = None if data: # to debug because of api logger.debug(u'Parsing results from <a href="%s">%s</a>' % (URL, host)) rootxml = data.getroot() if rootxml.tag == 'error': errormsg = rootxml.get('description', default='unknown error') logger.error(u"%s - %s" % (host, errormsg)) if provider['BOOKSEARCH']: # maybe the host doesn't support it errorlist = [ 'no such function', 'unknown parameter', 'unknown function', 'incorrect parameter' ] match = False for item in errorlist: if item in errormsg.lower() and provider[ 'BOOKSEARCH'].lower() in errormsg.lower(): match = True if match: count = 0 while count < len(lazylibrarian.NEWZNAB_PROV): if lazylibrarian.NEWZNAB_PROV[count][ 'HOST'] == provider['HOST']: if str(provider['MANUAL']) == 'False': logger.error( "Disabled booksearch=%s for %s" % (provider['BOOKSEARCH'], provider['HOST'])) lazylibrarian.NEWZNAB_PROV[count][ 'BOOKSEARCH'] = "" lazylibrarian.config_write() else: logger.error( "Unable to disable booksearch for %s [MANUAL=%s]" % (provider['HOST'], provider['MANUAL'])) count += 1 else: resultxml = rootxml.getiterator('item') nzbcount = 0 for nzb in resultxml: try: nzbcount = nzbcount + 1 results.append( ReturnResultsFieldsBySearchType( book, nzb, searchType, host, searchMode)) except IndexError: logger.debug('No results from %s for %s' % (host, book['searchterm'])) logger.debug(u'Found %s nzb at %s for: %s' % (nzbcount, host, book['searchterm'])) else: logger.debug('No data returned from %s for %s' % (host, book['searchterm'])) return results
def configUpdate(self, http_host='0.0.0.0', http_root=None, http_user=None, http_port=5299, http_pass=None, http_look=None, launch_browser=0, logdir=None, imp_onlyisbn=0, imp_preflang=None, imp_autoadd=None, match_ratio=80, nzb_downloader_sabnzbd=0, nzb_downloader_nzbget=0, nzb_downloader_blackhole=0, use_nzb=0, use_tor=0, proxy_host=None, proxy_type=None, sab_host=None, sab_port=None, sab_subdir=None, sab_api=None, sab_user=None, sab_pass=None, destination_copy=0, destination_dir=None, download_dir=None, sab_cat=None, usenet_retention=None, nzb_blackholedir=None, torrent_dir=None, numberofseeders=0, tor_downloader_blackhole=0, tor_downloader_utorrent=0, nzbget_host=None, nzbget_user=None, nzbget_pass=None, nzbget_cat=None, nzbget_priority=0, newznab=0, newznab_host=None, newznab_api=None, newznab2=0, newznab_host2=None, newznab_api2=None, newzbin=0, newzbin_uid=None, newzbin_pass=None, kat=0, ebook_type=None, book_api=None, gr_api=None, gb_api=None, usenetcrawler=0, usenetcrawler_host=None, usenetcrawler_api=None, versioncheck_interval=None, search_interval=None, scan_interval=None, ebook_dest_folder=None, ebook_dest_file=None, mag_dest_folder=None, mag_dest_file=None, use_twitter=0, twitter_notify_onsnatch=0, twitter_notify_ondownload=0, utorrent_host=None, utorrent_user=None, utorrent_pass=None, notfound_status='Wanted', full_scan=0, add_author=1, tor_downloader_transmission=0, transmission_host=None, transmission_user=None, transmission_pass=None, tor_downloader_deluge=0, deluge_host=None, deluge_user=None, deluge_pass=None, deluge_port=None, utorrent_label=None, use_boxcar=0, boxcar_notify_onsnatch=0, boxcar_notify_ondownload=0, boxcar_token=None, use_pushbullet=0, pushbullet_notify_onsnatch=0, pushbullet_notify_ondownload=0, pushbullet_token=None, pushbullet_deviceid=None, use_pushover=0, pushover_onsnatch=0, pushover_priority=0, pushover_keys=None, pushover_apitoken=None, pushover_ondownload=0, nma_enabled=False, nma_apikey=None, nma_priority=0, nma_onsnatch=0): lazylibrarian.HTTP_HOST = http_host lazylibrarian.HTTP_ROOT = http_root lazylibrarian.HTTP_PORT = http_port lazylibrarian.HTTP_USER = http_user lazylibrarian.HTTP_PASS = http_pass lazylibrarian.HTTP_LOOK = http_look lazylibrarian.LAUNCH_BROWSER = launch_browser lazylibrarian.PROXY_HOST = proxy_host lazylibrarian.PROXY_TYPE = proxy_type lazylibrarian.LOGDIR = logdir lazylibrarian.MATCH_RATIO = match_ratio lazylibrarian.IMP_ONLYISBN = imp_onlyisbn lazylibrarian.IMP_PREFLANG = imp_preflang lazylibrarian.IMP_AUTOADD = imp_autoadd lazylibrarian.SAB_HOST = sab_host lazylibrarian.SAB_PORT = sab_port lazylibrarian.SAB_SUBDIR = sab_subdir lazylibrarian.SAB_API = sab_api lazylibrarian.SAB_USER = sab_user lazylibrarian.SAB_PASS = sab_pass lazylibrarian.SAB_CAT = sab_cat lazylibrarian.NZBGET_HOST = nzbget_host lazylibrarian.NZBGET_USER = nzbget_user lazylibrarian.NZBGET_PASS = nzbget_pass lazylibrarian.NZBGET_CATEGORY = nzbget_cat lazylibrarian.NZBGET_PRIORITY = nzbget_priority lazylibrarian.DESTINATION_COPY = destination_copy lazylibrarian.DESTINATION_DIR = destination_dir lazylibrarian.DOWNLOAD_DIR = download_dir lazylibrarian.USENET_RETENTION = usenet_retention lazylibrarian.NZB_BLACKHOLEDIR = nzb_blackholedir lazylibrarian.NZB_DOWNLOADER_SABNZBD = nzb_downloader_sabnzbd lazylibrarian.NZB_DOWNLOADER_NZBGET = nzb_downloader_nzbget lazylibrarian.NZB_DOWNLOADER_BLACKHOLE = nzb_downloader_blackhole lazylibrarian.TORRENT_DIR = torrent_dir lazylibrarian.NUMBEROFSEEDERS = numberofseeders lazylibrarian.TOR_DOWNLOADER_BLACKHOLE = tor_downloader_blackhole lazylibrarian.TOR_DOWNLOADER_UTORRENT = tor_downloader_utorrent lazylibrarian.TOR_DOWNLOADER_TRANSMISSION = tor_downloader_transmission lazylibrarian.TOR_DOWNLOADER_DELUGE = tor_downloader_deluge lazylibrarian.NEWZNAB = newznab lazylibrarian.NEWZNAB_HOST = newznab_host lazylibrarian.NEWZNAB_API = newznab_api lazylibrarian.NEWZNAB2 = newznab2 lazylibrarian.NEWZNAB_HOST2 = newznab_host2 lazylibrarian.NEWZNAB_API2 = newznab_api2 lazylibrarian.NEWZBIN = newzbin lazylibrarian.NEWZBIN_UID = newzbin_uid lazylibrarian.NEWZBIN_PASS = newzbin_pass lazylibrarian.UTORRENT_HOST = utorrent_host lazylibrarian.UTORRENT_USER = utorrent_user lazylibrarian.UTORRENT_PASS = utorrent_pass lazylibrarian.UTORRENT_LABEL = utorrent_label lazylibrarian.TRANSMISSION_HOST = transmission_host lazylibrarian.TRANSMISSION_USER = transmission_user lazylibrarian.TRANSMISSION_PASS = transmission_pass lazylibrarian.DELUGE_HOST = deluge_host lazylibrarian.DELUGE_PORT = deluge_port lazylibrarian.DELUGE_USER = deluge_user lazylibrarian.DELUGE_PASS = deluge_pass lazylibrarian.KAT = kat lazylibrarian.USE_NZB = use_nzb lazylibrarian.USE_TOR = use_tor lazylibrarian.USENETCRAWLER = usenetcrawler lazylibrarian.USENETCRAWLER_HOST = usenetcrawler_host lazylibrarian.USENETCRAWLER_API = usenetcrawler_api lazylibrarian.EBOOK_TYPE = ebook_type lazylibrarian.BOOK_API = book_api lazylibrarian.GR_API = gr_api lazylibrarian.GB_API = gb_api lazylibrarian.SEARCH_INTERVAL = search_interval lazylibrarian.SCAN_INTERVAL = scan_interval lazylibrarian.VERSIONCHECK_INTERVAL = versioncheck_interval lazylibrarian.FULL_SCAN = full_scan lazylibrarian.NOTFOUND_STATUS = notfound_status lazylibrarian.ADD_AUTHOR = add_author lazylibrarian.EBOOK_DEST_FOLDER = ebook_dest_folder lazylibrarian.EBOOK_DEST_FILE = ebook_dest_file lazylibrarian.MAG_DEST_FOLDER = mag_dest_folder lazylibrarian.MAG_DEST_FILE = mag_dest_file lazylibrarian.USE_TWITTER = use_twitter lazylibrarian.TWITTER_NOTIFY_ONSNATCH = twitter_notify_onsnatch lazylibrarian.TWITTER_NOTIFY_ONDOWNLOAD = twitter_notify_ondownload lazylibrarian.USE_BOXCAR = use_boxcar lazylibrarian.BOXCAR_NOTIFY_ONSNATCH = boxcar_notify_onsnatch lazylibrarian.BOXCAR_NOTIFY_ONDOWNLOAD = boxcar_notify_ondownload lazylibrarian.BOXCAR_TOKEN = boxcar_token lazylibrarian.USE_PUSHBULLET = use_pushbullet lazylibrarian.PUSHBULLET_NOTIFY_ONSNATCH = pushbullet_notify_onsnatch lazylibrarian.PUSHBULLET_NOTIFY_ONDOWNLOAD = pushbullet_notify_ondownload lazylibrarian.PUSHBULLET_TOKEN = pushbullet_token lazylibrarian.PUSHBULLET_DEVICEID = pushbullet_deviceid lazylibrarian.USE_PUSHOVER = use_pushover lazylibrarian.PUSHOVER_ONSNATCH = pushover_onsnatch lazylibrarian.PUSHOVER_ONDOWNLOAD = pushover_ondownload lazylibrarian.PUSHOVER_KEYS = pushover_keys lazylibrarian.PUSHOVER_APITOKEN = pushover_apitoken lazylibrarian.PUSHOVER_PRIORITY = pushover_priority lazylibrarian.NMA_ENABLED = nma_enabled lazylibrarian.NMA_APIKEY = nma_apikey lazylibrarian.NMA_PRIORITY = nma_priority lazylibrarian.NMA_ONSNATCH = nma_onsnatch lazylibrarian.config_write() logger.debug('Config file has been updated') raise cherrypy.HTTPRedirect("config")
def get_capabilities(provider): """ query provider for caps if none loaded yet, or if config entry is too old and not set manually. """ match = False if len(provider['UPDATED']) == 10: # any stored values? match = True if (age(provider['UPDATED']) > lazylibrarian.CACHE_AGE) and not provider['MANUAL']: logger.debug('Stored capabilities for %s are too old' % provider['HOST']) match = False if match: logger.debug('Using stored capabilities for %s' % provider['HOST']) else: host = provider['HOST'] if not str(host)[:4] == "http": host = 'http://' + host URL = host + '/api?t=caps&apikey=' + provider['API'] logger.debug('Requesting capabilities for %s' % URL) source_xml, success = fetchURL(URL) if success: data = ElementTree.fromstring(source_xml) else: logger.debug(u"Error getting xml from %s, %s" % (URL, source_xml)) data = '' if len(data): logger.debug(u"Parsing xml for capabilities of %s" % URL) # # book search isn't mentioned in the caps xml returned by # nzbplanet,jackett,oznzb,usenet-crawler, so we can't use it as a test # but the newznab+ ones usually support t=book and categories in 7000 range # whereas nZEDb ones don't support t=book and use categories in 8000 range # also some providers give searchtype but no supportedparams, so we still # can't tell what queries will be accepted # also category names can be lowercase or Mixed, magazine subcat name isn't # consistent, and subcat can be just subcat or category/subcat subcat > lang # eg "Magazines" "Mags" or "Books/Magazines" "Mags > French" # Load all languages for now as we don't know which the user might want # # # set some defaults # provider['GENERALSEARCH'] = 'search' provider['EXTENDED'] = '1' provider['BOOKCAT'] = '' provider['MAGCAT'] = '' provider['BOOKSEARCH'] = '' provider['MAGSEARCH'] = '' # search = data.find('searching/search') if search is not None: if 'available' in search.attrib: if search.attrib['available'] == 'yes': provider['GENERALSEARCH'] = 'search' categories = data.getiterator('category') for cat in categories: if 'name' in cat.attrib: if cat.attrib['name'].lower() == 'books': bookcat = cat.attrib['id'] # keep main bookcat for later provider['BOOKCAT'] = bookcat provider['MAGCAT'] = '' if provider['BOOKCAT'] == '7000': # looks like newznab+, should support book-search provider['BOOKSEARCH'] = 'book' # but check in case search = data.find('searching/book-search') if search is not None: if 'available' in search.attrib: if search.attrib['available'] == 'yes': provider['BOOKSEARCH'] = 'book' else: provider['BOOKSEARCH'] = '' else: # looks like nZEDb, probably no book-search provider['BOOKSEARCH'] = '' # but check in case search = data.find('searching/book-search') if search is not None: if 'available' in search.attrib: if search.attrib['available'] == 'yes': provider['BOOKSEARCH'] = 'book' else: provider['BOOKSEARCH'] = '' subcats = cat.getiterator('subcat') for subcat in subcats: if 'ebook' in subcat.attrib['name'].lower(): provider['BOOKCAT'] = "%s,%s" % (provider['BOOKCAT'], subcat.attrib['id']) if 'magazines' in subcat.attrib['name'].lower() or 'mags' in subcat.attrib['name'].lower(): if provider['MAGCAT']: provider['MAGCAT'] = "%s,%s" % (provider['MAGCAT'], subcat.attrib['id']) else: provider['MAGCAT'] = subcat.attrib['id'] # if no specific magazine subcategory, use books if not provider['MAGCAT']: provider['MAGCAT'] = bookcat logger.debug("Categories: Books %s : Mags %s" % (provider['BOOKCAT'], provider['MAGCAT'])) provider['UPDATED'] = today() lazylibrarian.config_write() else: logger.warn(u"Unable to get capabilities for %s: No data returned" % URL) return provider
def configUpdate(self, http_host='0.0.0.0', http_user=None, http_port=5299, http_pass=None, http_look=None, launch_browser=0, logdir=None, imp_onlyisbn=0, imp_preflang=None, sab_host=None, sab_port=None, sab_api=None, sab_user=None, sab_pass=None, destination_copy=0, destination_dir=None, download_dir=None, sab_cat=None, usenet_retention=None, blackhole=0, blackholedir=None, nzbmatrix=0, nzbmatrix_user=None, nzbmatrix_api=None, newznab=0, newznab_host=None, newznab_api=None, newzbin=0, newzbin_uid=None, newzbin_pass=None, search_interval=None, scan_interval=None, ebook_dest_folder=None, ebook_dest_file=None, mag_dest_folder=None, mag_dest_file=None, use_twitter=0, twitter_notify_onsnatch=0, twitter_notify_ondownload=0): if twitter_notify_onsnatch == "on": twitter_notify_onsnatch = 1 else: twitter_notify_onsnatch = 0 if twitter_notify_ondownload == "on": twitter_notify_ondownload = 1 else: twitter_notify_ondownload = 0 if use_twitter == "on": use_twitter = 1 else: use_twitter = 0 lazylibrarian.HTTP_HOST = http_host lazylibrarian.HTTP_PORT = http_port lazylibrarian.HTTP_USER = http_user lazylibrarian.HTTP_PASS = http_pass lazylibrarian.HTTP_LOOK = http_look lazylibrarian.LAUNCH_BROWSER = launch_browser lazylibrarian.LOGDIR = logdir lazylibrarian.IMP_ONLYISBN = imp_onlyisbn lazylibrarian.IMP_PREFLANG = imp_preflang lazylibrarian.SAB_HOST = sab_host lazylibrarian.SAB_PORT = sab_port lazylibrarian.SAB_API = sab_api lazylibrarian.SAB_USER = sab_user lazylibrarian.SAB_PASS = sab_pass lazylibrarian.SAB_CAT = sab_cat lazylibrarian.DESTINATION_COPY = destination_copy lazylibrarian.DESTINATION_DIR = destination_dir lazylibrarian.DOWNLOAD_DIR = download_dir lazylibrarian.USENET_RETENTION = usenet_retention lazylibrarian.BLACKHOLE = blackhole lazylibrarian.BLACKHOLEDIR = blackholedir lazylibrarian.NZBMATRIX = nzbmatrix lazylibrarian.NZBMATRIX_USER = nzbmatrix_user lazylibrarian.NZBMATRIX_API = nzbmatrix_api lazylibrarian.NEWZNAB = newznab lazylibrarian.NEWZNAB_HOST = newznab_host lazylibrarian.NEWZNAB_API = newznab_api lazylibrarian.NEWZBIN = newzbin lazylibrarian.NEWZBIN_UID = newzbin_uid lazylibrarian.NEWZBIN_PASS = newzbin_pass lazylibrarian.SEARCH_INTERVAL = search_interval lazylibrarian.SCAN_INTERVAL = scan_interval lazylibrarian.EBOOK_DEST_FOLDER = ebook_dest_folder lazylibrarian.EBOOK_DEST_FILE = ebook_dest_file lazylibrarian.MAG_DEST_FOLDER = mag_dest_folder lazylibrarian.MAG_DEST_FILE = mag_dest_file lazylibrarian.USE_TWITTER = use_twitter lazylibrarian.TWITTER_NOTIFY_ONSNATCH = twitter_notify_onsnatch lazylibrarian.TWITTER_NOTIFY_ONDOWNLOAD = twitter_notify_ondownload lazylibrarian.config_write() raise cherrypy.HTTPRedirect("config")
def get_capabilities(provider, force=False): """ query provider for caps if none loaded yet, or if config entry is too old and not set manually. """ if not force and len(provider['UPDATED']) == 10: # any stored values? match = True if (age(provider['UPDATED']) > lazylibrarian.CONFIG['CACHE_AGE']) and not provider['MANUAL']: logger.debug('Stored capabilities for %s are too old' % provider['HOST']) match = False else: match = False if match: logger.debug('Using stored capabilities for %s' % provider['HOST']) else: host = provider['HOST'] if not str(host)[:4] == "http": host = 'http://' + host if host[-1:] == '/': host = host[:-1] URL = host + '/api?t=caps' # most providers will give you caps without an api key logger.debug('Requesting capabilities for %s' % URL) source_xml, success = fetchURL(URL) # If it failed, retry with api key if not success: if provider['API']: URL = URL + '&apikey=' + provider['API'] logger.debug('Requesting capabilities for %s' % URL) source_xml, success = fetchURL(URL) if success: try: data = ElementTree.fromstring(source_xml) except ElementTree.ParseError: data = '' logger.debug("Error parsing xml from %s, %s" % (URL, source_xml)) else: logger.debug("Error getting xml from %s, %s" % (URL, source_xml)) data = '' if len(data): logger.debug("Parsing xml for capabilities of %s" % URL) # # book search isn't mentioned in the caps xml returned by # nzbplanet,jackett,oznzb,usenet-crawler, so we can't use it as a test # but the newznab+ ones usually support t=book and categories in 7000 range # whereas nZEDb ones don't support t=book and use categories in 8000 range # also some providers give searchtype but no supportedparams, so we still # can't tell what queries will be accepted # also category names can be lowercase or Mixed, magazine subcat name isn't # consistent, and subcat can be just subcat or category/subcat subcat > lang # eg "Magazines" "Mags" or "Books/Magazines" "Mags > French" # Load all languages for now as we don't know which the user might want # # # set some defaults # provider['GENERALSEARCH'] = 'search' provider['EXTENDED'] = '1' provider['BOOKCAT'] = '' provider['MAGCAT'] = '' provider['AUDIOCAT'] = '' provider['BOOKSEARCH'] = '' provider['MAGSEARCH'] = '' provider['AUDIOSEARCH'] = '' # search = data.find('searching/search') if search is not None: # noinspection PyUnresolvedReferences if 'available' in search.attrib: # noinspection PyUnresolvedReferences if search.attrib['available'] == 'yes': provider['GENERALSEARCH'] = 'search' categories = data.getiterator('category') for cat in categories: if 'name' in cat.attrib: if cat.attrib['name'].lower() == 'audio': provider['AUDIOCAT'] = cat.attrib['id'] subcats = cat.getiterator('subcat') for subcat in subcats: if 'audiobook' in subcat.attrib['name'].lower(): provider['AUDIOCAT'] = "%s,%s" % ( provider['AUDIOCAT'], subcat.attrib['id']) elif cat.attrib['name'].lower() == 'books': bookcat = cat.attrib[ 'id'] # keep main bookcat for starting magazines later provider['BOOKCAT'] = bookcat provider['MAGCAT'] = '' # set default booksearch if provider['BOOKCAT'] == '7000': # looks like newznab+, should support book-search provider['BOOKSEARCH'] = 'book' else: # looks like nZEDb, probably no book-search provider['BOOKSEARCH'] = '' # but check in case we got some settings back search = data.find('searching/book-search') if search: # noinspection PyUnresolvedReferences if 'available' in search.attrib: # noinspection PyUnresolvedReferences if search.attrib['available'] == 'yes': provider['BOOKSEARCH'] = 'book' else: provider['BOOKSEARCH'] = '' subcats = cat.getiterator('subcat') for subcat in subcats: if 'ebook' in subcat.attrib['name'].lower(): provider['BOOKCAT'] = "%s,%s" % ( provider['BOOKCAT'], subcat.attrib['id']) if 'magazines' in subcat.attrib['name'].lower( ) or 'mags' in subcat.attrib['name'].lower(): if provider['MAGCAT']: provider['MAGCAT'] = "%s,%s" % ( provider['MAGCAT'], subcat.attrib['id']) else: provider['MAGCAT'] = subcat.attrib['id'] # if no specific magazine subcategory, use books if not provider['MAGCAT']: provider['MAGCAT'] = bookcat logger.debug("Categories: Books %s : Mags %s : Audio %s" % (provider['BOOKCAT'], provider['MAGCAT'], provider['AUDIOCAT'])) provider['UPDATED'] = today() threadname = threading.currentThread().name lazylibrarian.config_write() threading.currentThread().name = threadname else: logger.warn("Unable to get capabilities for %s: No data returned" % URL) return provider
def configUpdate(self, http_host='0.0.0.0', http_user=None, http_port=5299, http_pass=None, http_look=None, launch_browser=0, logdir=None, imp_onlyisbn=0, imp_preflang=None, sab_host=None, sab_port=None, sab_api=None, sab_user=None, sab_pass=None, destination_copy=0, destination_dir=None, download_dir=None, sab_cat=None, usenet_retention=None, blackhole=0, blackholedir=None, nzbmatrix=0, nzbmatrix_user=None, nzbmatrix_api=None, newznab=0, newznab_host=None, newznab_api=None, newzbin=0, newzbin_uid=None, newzbin_pass=None, ebook_type=None): lazylibrarian.HTTP_HOST = http_host lazylibrarian.HTTP_PORT = http_port lazylibrarian.HTTP_USER = http_user lazylibrarian.HTTP_PASS = http_pass lazylibrarian.HTTP_LOOK = http_look lazylibrarian.LAUNCH_BROWSER = launch_browser lazylibrarian.LOGDIR = logdir lazylibrarian.IMP_ONLYISBN = imp_onlyisbn lazylibrarian.IMP_PREFLANG = imp_preflang lazylibrarian.SAB_HOST = sab_host lazylibrarian.SAB_PORT = sab_port lazylibrarian.SAB_API = sab_api lazylibrarian.SAB_USER = sab_user lazylibrarian.SAB_PASS = sab_pass lazylibrarian.SAB_CAT = sab_cat lazylibrarian.DESTINATION_COPY = destination_copy lazylibrarian.DESTINATION_DIR = destination_dir lazylibrarian.DOWNLOAD_DIR = download_dir lazylibrarian.USENET_RETENTION = usenet_retention lazylibrarian.BLACKHOLE = blackhole lazylibrarian.BLACKHOLEDIR = blackholedir lazylibrarian.NZBMATRIX = nzbmatrix lazylibrarian.NZBMATRIX_USER = nzbmatrix_user lazylibrarian.NZBMATRIX_API = nzbmatrix_api lazylibrarian.NEWZNAB = newznab lazylibrarian.NEWZNAB_HOST = newznab_host lazylibrarian.NEWZNAB_API = newznab_api lazylibrarian.NEWZBIN = newzbin lazylibrarian.NEWZBIN_UID = newzbin_uid lazylibrarian.NEWZBIN_PASS = newzbin_pass lazylibrarian.EBOOK_TYPE = ebook_type lazylibrarian.config_write() raise cherrypy.HTTPRedirect("config")