Exemple #1
0
def ReturnSearchTypeStructure(api_key, book, searchType):

    params = None

    if searchType == "book":
        params = {
            "t": "book",
            "apikey": api_key,
            "title": common.removeDisallowedFilenameChars(book['bookName']),
            "author": common.removeDisallowedFilenameChars(book['authorName']),
            "cat": 7020,  #7020=ebook
        }
    elif searchType == "mag":
        params = {
            "t": "search",
            "apikey": api_key,
            "cat": "7000,7010,7020",  #7000=Other,7010=Misc,7020 Ebook
            "q": common.removeDisallowedFilenameChars(book['searchterm']),
            "extended": 1,
        }
    else:
        params = {
            "t": "search",
            "apikey": api_key,
            #"cat": 7020,
            "q": book['searchterm'],
            "extended": 1,
        }

    logger.debug('NewzNabPlus] - Search parameters set to ' + str(params))

    return params
def ReturnSearchTypeStructure(api_key, book, searchType):
  
    params = None
    
    if searchType == "book":
        params = {
            "t": "book",
            "apikey": api_key,
            "title": common.removeDisallowedFilenameChars(book['bookName']),
            "author": common.removeDisallowedFilenameChars(book['authorName']),
            "cat": 7020,                #7020=ebook
        }
    elif searchType == "mag":
        params = {
            "t": "search",
            "apikey": api_key,
            "cat": "7000,7010,7020",    #7000=Other,7010=Misc,7020 Ebook
            "q": common.removeDisallowedFilenameChars(book['searchterm']),
            "extended": 1,
        }
    else:
                params = {
            "t": "search",
            "apikey": api_key,
            #"cat": 7020,
            "q": book['searchterm'],
            "extended": 1,
        }        
        
    logger.debug('NewzNabPlus] - Search parameters set to '+str(params))

    return params
Exemple #3
0
def ReturnSearchTypeStructure(api_key, book, searchType, searchMode):

    params = None
    if searchMode == "nzb":
        if searchType == "book":
            params = {
                "t": "book",
                "apikey": api_key,
                "title": common.removeDisallowedFilenameChars(book['bookName']),
                "author": common.removeDisallowedFilenameChars(book['authorName']),
                "cat": 7020,  # 7020=ebook
            }
        elif searchType == "mag":
            params = {
                "t": "search",
                "apikey": api_key,
                "cat": "7000,7010,7020",  # 7000=Other,7010=Misc,7020 Ebook
                "q": book['searchterm'],
                "extended": 1,
            }
        else:
            params = {
                "t": "search",
                "apikey": api_key,
                # this is a general search
                "q": book['searchterm'],
                "extended": 1,
            }
    if searchMode == "torznab":
        if searchType == "book":
            params = {
                "t": "search",
                "apikey": api_key,
                "cat": "8000,8010",  # 8000=book, 8010=ebook
                "q": book['searchterm'],
                "extended": 1,
            }
        elif searchType == "mag":
            params = {
                "t": "search",
                "apikey": api_key,
                "cat": "8030",  # 8030=magazines
                "q": book['searchterm'],
                "extended": 1,
            }
        else:
            params = {
                "t": "search",
                "apikey": api_key,
                # this is a general search
                "q": book['searchterm'],
                "extended": 1,
            }
    logger.debug('[NewzNabPlus] - Search parameters set to ' + str(params))

    return params
Exemple #4
0
    def _notify(self, message=None, event=None, pushover_apitoken=None, pushover_keys=None, 
                notificationType=None, method=None, force=False):
        """
        Sends a pushover notification based on the provided info or LL config

        title: The title of the notification to send
        message: The message string to send
        username: The username to send the notification to (optional, defaults to the username in the config)
        force: If True then the notification will be sent even if pushover is disabled in the config
        """
        try:
            message = common.removeDisallowedFilenameChars(message)
        except Exception, e:
            logger.warn("Pushover: could not convert  message: %s" % e)
Exemple #5
0
def ReturnSearchTypeStructure(api_key, book, searchType, searchMode):

    params = None
    if searchMode == "nzb":
        if searchType == "book":
            authorname = book['authorName']
            while authorname[1] in '. ':  # strip any leading initials
                authorname = authorname[2:].strip()  # and leading whitespace
            # middle initials can't have a dot
            authorname = authorname.replace('. ', ' ')
            params = {
                "t": "book",
                "apikey": api_key,
                "title": common.removeDisallowedFilenameChars(book['bookName']),
                "author": common.removeDisallowedFilenameChars(authorname),
                "cat": 7020,  # 7020=ebook
            }
        elif searchType == "shortbook":
            authorname = book['authorName']
            while authorname[1] in '. ':  # strip any leading initials
                authorname = authorname[2:].strip()  # and leading whitespace
            # middle initials can't have a dot
            authorname = authorname.replace('. ', ' ')
            params = {
                "t": "book",
                "apikey": api_key,
                "title": common.removeDisallowedFilenameChars(book['bookName'].split('(')[0]).strip(),
                "author": common.removeDisallowedFilenameChars(authorname),
                "cat": 7020,  # 7020=ebook
            }
        elif searchType == "author":
            authorname = book['authorName']
            while authorname[1] in '. ':  # strip any leading initials
                authorname = authorname[2:].strip()  # and leading whitespace
            # middle initials can't have a dot
            authorname = authorname.replace('. ', ' ')
            params = {
                "t": "search",
                "apikey": api_key,
                "q": common.removeDisallowedFilenameChars(authorname),
                "extended": 1,
            }
        elif searchType == "mag":
            params = {
                "t": "search",
                "apikey": api_key,
                "cat": "7000,7010,7020",  # 7000=Other,7010=Misc,7020 Ebook
                "q": book['searchterm'],
                "extended": 1,
            }
        else:
            params = {
                "t": "search",
                "apikey": api_key,
                # this is a general search
                "q": book['searchterm'],
                "extended": 1,
            }
    if searchMode == "torznab":
        if searchType == "book":
            params = {
                "t": "search",
                "apikey": api_key,
                "cat": "8000,8010",  # 8000=book, 8010=ebook
                "q": book['searchterm'],
                "extended": 1,
            }
        elif searchType == "shortbook":
            params = {
                "t": "search",
                "apikey": api_key,
                "cat": "8000,8010",  # 8000=book, 8010=ebook
                "q": book['searchterm'].split('(')[0],
                "extended": 1,
            }
        elif searchType == "mag":
            params = {
                "t": "search",
                "apikey": api_key,
                "cat": "8030",  # 8030=magazines
                "q": book['searchterm'],
                "extended": 1,
            }
        else:
            params = {
                "t": "search",
                "apikey": api_key,
                # this is a general search
                "q": book['searchterm'],
                "extended": 1,
            }
    logger.debug('[NewzNabPlus] - %s Search parameters set to %s' % (searchMode, str(params)))

    return params
Exemple #6
0
def ReturnSearchTypeStructure(provider, api_key, book, searchType, searchMode):

    params = None
    if searchType == "book":
        authorname = book['authorName']
        while authorname[1] in '. ':  # strip any leading initials
            authorname = authorname[2:].strip()  # and leading whitespace
        # middle initials can't have a dot
        authorname = authorname.replace('. ', ' ')
        authorname = common.removeDisallowedFilenameChars(authorname)
        bookname = common.removeDisallowedFilenameChars(book['bookName'])
        if provider['BOOKSEARCH'] and provider['BOOKCAT']:  # if specific booksearch, use it
            params = {
                "t": provider['BOOKSEARCH'],
                "apikey": api_key,
                "title": bookname,
                "author": authorname,
                "cat": provider['BOOKCAT']
            }
        elif provider['GENERALSEARCH'] and provider['BOOKCAT']: # if not, try general search
            params = {
                "t": provider['GENERALSEARCH'],
                "apikey": api_key,
                "q": authorname + ' ' + bookname,
                "cat": provider['BOOKCAT']
            }    
    elif searchType == "shortbook":
        authorname = book['authorName']
        while authorname[1] in '. ':  # strip any leading initials
            authorname = authorname[2:].strip()  # and leading whitespace
        # middle initials can't have a dot
        authorname = authorname.replace('. ', ' ')
        authorname = common.removeDisallowedFilenameChars(authorname)
        bookname = common.removeDisallowedFilenameChars(book['bookName'].split('(')[0]).strip()
        if provider['BOOKSEARCH'] and provider['BOOKCAT']:  # if specific booksearch, use it
            params = {
                "t": provider['BOOKSEARCH'],
                "apikey": api_key,
                "title": bookname,
                "author": authorname,
                "cat": provider['BOOKCAT']
            }
        elif provider['GENERALSEARCH'] and provider['BOOKCAT']:
            params = {
                "t": provider['GENERALSEARCH'],
                "apikey": api_key,
                "q": authorname + ' ' + bookname,
                "cat": provider['BOOKCAT']
            }            
    elif searchType == "author":
        authorname = book['authorName']
        while authorname[1] in '. ':  # strip any leading initials
            authorname = authorname[2:].strip()  # and leading whitespace
        # middle initials can't have a dot
        authorname = authorname.replace('. ', ' ')
        authorname = common.removeDisallowedFilenameChars(authorname)
        if provider['GENERALSEARCH']:
            params = {
                "t": provider['GENERALSEARCH'],
                "apikey": api_key,
                "q": authorname,
                "extended": provider['EXTENDED'],
            }
    elif searchType == "mag":
        if provider['MAGSEARCH'] and provider['MAGCAT']:  # if specific magsearch, use it
            params = {
                "t": provider['MAGSEARCH'],
                "apikey": api_key,
                "cat": provider['MAGCAT'],
                "q": books['searchterm'],
                "extended": provider['EXTENDED'],
            }
        elif provider['GENERALSEARCH'] and provider['MAGCAT']:
            params = {
               "t": provider['GENERALSEARCH'],
               "apikey": api_key,
               "cat": provider['MAGCAT'],
               "q": books['searchterm'],
               "extended": provider['EXTENDED'],
           }
    else:
        if provider['GENERALSEARCH']:
            params = {
                "t": provider['GENERALSEARCH'],
                "apikey": api_key,
                # this is a general search
                "q": books['searchterm'],
                "extended": provider['EXTENDED'],
            }
    if params:
        logger.debug('[NewzNabPlus] - %s Search parameters set to %s' % (searchMode, str(params)))
    else:
        logger.debug('[NewzNabPlus] - %s No matching search parameters' % searchMode)
            
    return params
def TORDownloadMethod(bookid=None, tor_prov=None, tor_title=None, tor_url=None):
    myDB = database.DBConnection()
    download = False
    full_url = tor_url # keep the url as stored in "wanted" table
    if (lazylibrarian.USE_TOR) and (lazylibrarian.TOR_DOWNLOADER_DELUGE or lazylibrarian.TOR_DOWNLOADER_UTORRENT
                                    or lazylibrarian.TOR_DOWNLOADER_BLACKHOLE or lazylibrarian.TOR_DOWNLOADER_TRANSMISSION):

        if tor_url.startswith('magnet'):
            torrent = tor_url  # allow magnet link to write to blackhole and hash to utorrent
        else:
            if '&file=' in tor_url:  # torznab results need to be re-encoded
                url = tor_url.split('&file=')[0]
                value = tor_url.split('&file=')[1]
                if isinstance(value, str):
                    value = value.decode('utf-8')  # make unicode
                value = unicodedata.normalize('NFC', value)  # normalize to short form
                value = value.encode('unicode-escape')  # then escape the result
                value = value.replace(' ', '%20')  # and encode any spaces
                tor_url = url + '&file=' + value

            request = urllib2.Request(ur'%s' % tor_url)
            if lazylibrarian.PROXY_HOST:
                request.set_proxy(lazylibrarian.PROXY_HOST, lazylibrarian.PROXY_TYPE)
            request.add_header('Accept-encoding', 'gzip')
            request.add_header('User-Agent', common.USER_AGENT)

            if tor_prov == 'KAT':
                host = lazylibrarian.KAT_HOST
                if not str(host)[:4] == "http":
                    host = 'http://' + host
                request.add_header('Referer', host)

            try:
                response = urllib2.urlopen(request)
                if response.info().get('Content-Encoding') == 'gzip':
                    buf = StringIO(response.read())
                    f = gzip.GzipFile(fileobj=buf)
                    torrent = f.read()
                else:
                    torrent = response.read()

            except urllib2.URLError as e:
                logger.warn('Error fetching torrent from url: ' + tor_url + ' %s' % e.reason)
                return
                
        # strip url back to the .torrent for passing to downloaders
        # deluge needs it stripping, transmission doesn't mind
        # not sure about utorrent
        if '?' in tor_url: 
            tor_url = tor_url.split('?')[0]
            
        if (lazylibrarian.TOR_DOWNLOADER_BLACKHOLE):
            logger.debug('Torrent blackhole')
            tor_title = common.removeDisallowedFilenameChars(tor_title)
            tor_name = str.replace(str(tor_title), ' ', '_')
            if tor_url.startswith('magnet'):
                tor_name = tor_name + '.magnet'
            else:
                tor_name = tor_name + '.torrent'
            tor_path = os.path.join(lazylibrarian.TORRENT_DIR, tor_name)
            torrent_file = open(tor_path, 'wb')
            torrent_file.write(torrent)
            torrent_file.close()
            logger.debug('Torrent file saved: %s' % tor_title)
            download = True

        if (lazylibrarian.TOR_DOWNLOADER_UTORRENT):
            logger.debug('Utorrent')
            hash = CalcTorrentHash(torrent)
            download = utorrent.addTorrent(tor_url, hash)

        if (lazylibrarian.TOR_DOWNLOADER_TRANSMISSION):
            logger.debug('Transmission')
            download = transmission.addTorrent(tor_url)

        if (lazylibrarian.TOR_DOWNLOADER_DELUGE):
            client = DelugeRPCClient(lazylibrarian.DELUGE_HOST,
                                     int(lazylibrarian.DELUGE_PORT),
                                     lazylibrarian.DELUGE_USER,
                                     lazylibrarian.DELUGE_PASS)
            if lazylibrarian.DELUGE_USER and lazylibrarian.DELUGE_PASS:
                client.connect()
                download = client.call('core.add_torrent_url', tor_url, {"name": tor_title})
                logger.debug('Deluge return value: %s' % download)
            else:
                logger.warn('Need user & pass for deluge, check config.')
    else:
        logger.warn('No torrent download method is enabled, check config.')
        return False

    if download:
        logger.debug(u'Torrent file has been downloaded from %s' % tor_url)
        myDB.action('UPDATE books SET status = "Snatched" WHERE BookID="%s"' % bookid)
        myDB.action('UPDATE wanted SET status = "Snatched" WHERE NZBurl="%s"' % full_url)
    else:
        logger.error(u'Failed to download torrent @ <a href="%s">%s</a>' % (full_url, tor_url))
        myDB.action('UPDATE wanted SET status = "Failed" WHERE NZBurl="%s"' % full_url)
Exemple #8
0
def ReturnSearchTypeStructure(api_key, book, searchType, searchMode):

    params = None
    if searchMode == "nzb":
        if searchType == "book":
            authorname = book['authorName']
            while authorname[1] in '. ':  # strip any leading initials
                authorname = authorname[2:].strip()  # and leading whitespace
            # middle initials can't have a dot
            authorname = authorname.replace('. ', ' ')
            params = {
                "t": "book",
                "apikey": api_key,
                "title":
                common.removeDisallowedFilenameChars(book['bookName']),
                "author": common.removeDisallowedFilenameChars(authorname),
                "cat": "7020",  # 7020=ebook
            }
        elif searchType == "shortbook":
            authorname = book['authorName']
            while authorname[1] in '. ':  # strip any leading initials
                authorname = authorname[2:].strip()  # and leading whitespace
            # middle initials can't have a dot
            authorname = authorname.replace('. ', ' ')
            params = {
                "t":
                "book",
                "apikey":
                api_key,
                "title":
                common.removeDisallowedFilenameChars(
                    book['bookName'].split('(')[0]).strip(),
                "author":
                common.removeDisallowedFilenameChars(authorname),
                "cat":
                "7020",  # 7020=ebook
            }
        elif searchType == "author":
            authorname = book['authorName']
            while authorname[1] in '. ':  # strip any leading initials
                authorname = authorname[2:].strip()  # and leading whitespace
            # middle initials can't have a dot
            authorname = authorname.replace('. ', ' ')
            params = {
                "t": "search",
                "apikey": api_key,
                "q": common.removeDisallowedFilenameChars(authorname),
                "extended": 1,
            }
        elif searchType == "mag":
            params = {
                "t": "search",
                "apikey": api_key,
                "cat": "7000,7010,7020",  # 7000=Other,7010=Misc,7020 Ebook
                "q": book['searchterm'],
                "extended": 1,
            }
        else:
            params = {
                "t": "search",
                "apikey": api_key,
                # this is a general search
                "q": book['searchterm'],
                "extended": 1,
            }
    if searchMode == "nzedb":
        if searchType == "book":
            authorname = book['authorName']
            while authorname[1] in '. ':  # strip any leading initials
                authorname = authorname[2:].strip()  # and leading whitespace
            # middle initials can't have a dot
            authorname = authorname.replace('. ', ' ')
            params = {
                "t":
                "search",
                "apikey":
                api_key,
                "q":
                common.removeDisallowedFilenameChars(authorname) + ' ' +
                common.removeDisallowedFilenameChars(book['bookName']),
                "cat":
                "8000,8010",  # 8000=book, 8010=ebook
            }
        elif searchType == "shortbook":
            authorname = book['authorName']
            while authorname[1] in '. ':  # strip any leading initials
                authorname = authorname[2:].strip()  # and leading whitespace
            # middle initials can't have a dot
            authorname = authorname.replace('. ', ' ')
            params = {
                "t":
                "search",
                "apikey":
                api_key,
                "q":
                common.removeDisallowedFilenameChars(authorname) + ' ' +
                common.removeDisallowedFilenameChars(
                    book['bookName'].split('(')[0]).strip(),
                "cat":
                "8000,8010",  # 8000=book, 8010=ebook
            }
        elif searchType == "author":
            authorname = book['authorName']
            while authorname[1] in '. ':  # strip any leading initials
                authorname = authorname[2:].strip()  # and leading whitespace
            # middle initials can't have a dot
            authorname = authorname.replace('. ', ' ')
            params = {
                "t": "search",
                "apikey": api_key,
                "q": common.removeDisallowedFilenameChars(authorname),
                "extended": 1,
            }
        elif searchType == "mag":
            params = {
                "t": "search",
                "apikey": api_key,
                "cat": "8030",  # 8030=mag
                "q": book['searchterm'],
                "extended": 1,
            }
        else:
            params = {
                "t": "search",
                "apikey": api_key,
                # this is a general search
                "q": book['searchterm'],
                "extended": 1,
            }
    if searchMode == "torznab":
        if searchType == "book":
            params = {
                "t": "search",
                "apikey": api_key,
                "cat": "8000,8010",  # 8000=book, 8010=ebook
                "q": book['searchterm'],
                "extended": 1,
            }
        elif searchType == "shortbook":
            params = {
                "t": "search",
                "apikey": api_key,
                "cat": "8000,8010",  # 8000=book, 8010=ebook
                "q": book['searchterm'].split('(')[0],
                "extended": 1,
            }
        elif searchType == "mag":
            params = {
                "t": "search",
                "apikey": api_key,
                "cat": "8030",  # 8030=magazines
                "q": book['searchterm'],
                "extended": 1,
            }
        else:
            params = {
                "t": "search",
                "apikey": api_key,
                # this is a general search
                "q": book['searchterm'],
                "extended": 1,
            }
    logger.debug('[NewzNabPlus] - %s Search parameters set to %s' %
                 (searchMode, str(params)))

    return params
Exemple #9
0
def ReturnSearchTypeStructure(provider, api_key, book, searchType, searchMode):

    params = None
    if searchType == "book":
        authorname = book['authorName']
        while authorname[1] in '. ':  # strip any leading initials
            authorname = authorname[2:].strip()  # and leading whitespace
        # middle initials can't have a dot
        authorname = authorname.replace('. ', ' ')
        authorname = common.removeDisallowedFilenameChars(authorname)
        bookname = common.removeDisallowedFilenameChars(book['bookName'])
        if provider['BOOKSEARCH'] and provider[
                'BOOKCAT']:  # if specific booksearch, use it
            params = {
                "t": provider['BOOKSEARCH'],
                "apikey": api_key,
                "title": bookname,
                "author": authorname,
                "cat": provider['BOOKCAT']
            }
        elif provider['GENERALSEARCH'] and provider[
                'BOOKCAT']:  # if not, try general search
            params = {
                "t": provider['GENERALSEARCH'],
                "apikey": api_key,
                "q": authorname + ' ' + bookname,
                "cat": provider['BOOKCAT']
            }
    elif searchType == "shortbook":
        authorname = book['authorName']
        while authorname[1] in '. ':  # strip any leading initials
            authorname = authorname[2:].strip()  # and leading whitespace
        # middle initials can't have a dot
        authorname = authorname.replace('. ', ' ')
        authorname = common.removeDisallowedFilenameChars(authorname)
        bookname = common.removeDisallowedFilenameChars(
            book['bookName'].split('(')[0]).strip()
        if provider['BOOKSEARCH'] and provider[
                'BOOKCAT']:  # if specific booksearch, use it
            params = {
                "t": provider['BOOKSEARCH'],
                "apikey": api_key,
                "title": bookname,
                "author": authorname,
                "cat": provider['BOOKCAT']
            }
        elif provider['GENERALSEARCH'] and provider['BOOKCAT']:
            params = {
                "t": provider['GENERALSEARCH'],
                "apikey": api_key,
                "q": authorname + ' ' + bookname,
                "cat": provider['BOOKCAT']
            }
    elif searchType == "author":
        authorname = book['authorName']
        while authorname[1] in '. ':  # strip any leading initials
            authorname = authorname[2:].strip()  # and leading whitespace
        # middle initials can't have a dot
        authorname = authorname.replace('. ', ' ')
        authorname = common.removeDisallowedFilenameChars(authorname)
        if provider['GENERALSEARCH']:
            params = {
                "t": provider['GENERALSEARCH'],
                "apikey": api_key,
                "q": authorname,
                "extended": provider['EXTENDED'],
            }
    elif searchType == "mag":
        if provider['MAGSEARCH'] and provider[
                'MAGCAT']:  # if specific magsearch, use it
            params = {
                "t": provider['MAGSEARCH'],
                "apikey": api_key,
                "cat": provider['MAGCAT'],
                "q": book['searchterm'],
                "extended": provider['EXTENDED'],
            }
        elif provider['GENERALSEARCH'] and provider['MAGCAT']:
            params = {
                "t": provider['GENERALSEARCH'],
                "apikey": api_key,
                "cat": provider['MAGCAT'],
                "q": book['searchterm'],
                "extended": provider['EXTENDED'],
            }
    else:
        if provider['GENERALSEARCH']:
            params = {
                "t": provider['GENERALSEARCH'],
                "apikey": api_key,
                # this is a general search
                "q": book['searchterm'],
                "extended": provider['EXTENDED'],
            }
    if params:
        logger.debug('[NewzNabPlus] - %s Search parameters set to %s' %
                     (searchMode, str(params)))
    else:
        logger.debug('[NewzNabPlus] - %s No matching search parameters' %
                     searchMode)

    return params
def TORDownloadMethod(bookid=None, tor_prov=None, tor_title=None, tor_url=None):
    myDB = database.DBConnection()
    download = False
    full_url = tor_url  # keep the url as stored in "wanted" table
    if (lazylibrarian.TOR_DOWNLOADER_DELUGE or
        lazylibrarian.TOR_DOWNLOADER_UTORRENT or
        lazylibrarian.TOR_DOWNLOADER_QBITTORRENT or
        lazylibrarian.TOR_DOWNLOADER_BLACKHOLE or
        lazylibrarian.TOR_DOWNLOADER_TRANSMISSION):

        if tor_url.startswith('magnet'):
            torrent = tor_url  # allow magnet link to write to blackhole and hash to utorrent
        else:
            if '&file=' in tor_url:
                # torznab results need to be re-encoded
                # had a problem with torznab utf-8 encoded strings not matching
                # our utf-8 strings because of long/short form differences
                url = tor_url.split('&file=')[0]
                value = tor_url.split('&file=')[1]
                if isinstance(value, str):
                    value = value.decode('utf-8')  # make unicode
                value = unicodedata.normalize('NFC', value)  # normalize to short form
                value = value.encode('unicode-escape')  # then escape the result
                value = value.replace(' ', '%20')  # and encode any spaces
                tor_url = url + '&file=' + value

            # strip url back to the .torrent as some sites add parameters
            if '?' in tor_url:
                tor_url = tor_url.split('?')[0]

            request = urllib2.Request(ur'%s' % tor_url)
            if lazylibrarian.PROXY_HOST:
                request.set_proxy(lazylibrarian.PROXY_HOST, lazylibrarian.PROXY_TYPE)
            request.add_header('Accept-encoding', 'gzip')
            request.add_header('User-Agent', common.USER_AGENT)

            # PAB removed this, KAT serves us html instead of torrent if this header is sent
            # if tor_prov == 'KAT':
            #    host = lazylibrarian.KAT_HOST
            #    if not str(host)[:4] == "http":
            #        host = 'http://' + host
            #    request.add_header('Referer', host)

            try:
                response = urllib2.urlopen(request, timeout=90)
                if response.info().get('Content-Encoding') == 'gzip':
                    buf = StringIO(response.read())
                    f = gzip.GzipFile(fileobj=buf)
                    torrent = f.read()
                else:
                    torrent = response.read()

            except (urllib2.URLError, socket.timeout) as e:
                logger.warn('Error fetching torrent from url: %s, %s' % (tor_url, e))
                return False

        if lazylibrarian.TOR_DOWNLOADER_BLACKHOLE:
            tor_title = common.removeDisallowedFilenameChars(tor_title)
            logger.debug("Sending %s to blackhole" % tor_title)
            tor_name = str.replace(str(tor_title), ' ', '_')
            if tor_url.startswith('magnet'):
                tor_name = tor_name + '.magnet'
            else:
                tor_name = tor_name + '.torrent'
            tor_path = os.path.join(lazylibrarian.TORRENT_DIR, tor_name)
            with open(tor_path, 'wb') as torrent_file:
                torrent_file.write(torrent)
            logger.debug('Torrent file saved: %s' % tor_title)
            download = True

        if  (lazylibrarian.TOR_DOWNLOADER_UTORRENT and lazylibrarian.UTORRENT_HOST):
            logger.debug("Sending %s to Utorrent" % tor_title)
            hash = CalcTorrentHash(torrent)
            download = utorrent.addTorrent(tor_url, hash)

        if  (lazylibrarian.TOR_DOWNLOADER_QBITTORRENT and lazylibrarian.QBITTORRENT_HOST):
            logger.debug("Sending %s to qbittorrent" % tor_title)
            download = qbittorrent.addTorrent(tor_url)

        if  (lazylibrarian.TOR_DOWNLOADER_TRANSMISSION and lazylibrarian.TRANSMISSION_HOST):
            logger.debug("Sending %s to Transmission" % tor_title)
            download = transmission.addTorrent(tor_url)

        if  (lazylibrarian.TOR_DOWNLOADER_DELUGE and lazylibrarian.DELUGE_HOST):
            logger.debug("Sending %s to Deluge" % tor_title)
            if not lazylibrarian.DELUGE_USER:
                # no username, talk to the webui
                download = deluge.addTorrent(tor_url)
            else:
                # have username, talk to the daemon
                client = DelugeRPCClient(lazylibrarian.DELUGE_HOST,
                                     int(lazylibrarian.DELUGE_PORT),
                                     lazylibrarian.DELUGE_USER,
                                     lazylibrarian.DELUGE_PASS)
                client.connect()
                args = {"name": tor_title}
                download = client.call('core.add_torrent_url', tor_url, args)
                logger.debug('Deluge torrent_id: %s' % download)
                if download and lazylibrarian.DELUGE_LABEL:
                    labelled = client.call('label.set_torrent', download, lazylibrarian.DELUGE_LABEL)
                    logger.debug('Deluge label returned: %s' % labelled)
    else:
        logger.warn('No torrent download method is enabled, check config.')
        return False

    if download:
        logger.debug(u'Torrent id %s has been downloaded from %s' % (download, tor_url))
        myDB.action('UPDATE books SET status = "Snatched" WHERE BookID="%s"' % bookid)
        myDB.action('UPDATE wanted SET status = "Snatched" WHERE NZBurl="%s"' % full_url)
        return True
    else:
        logger.error(u'Failed to download torrent @ <a href="%s">%s</a>' % (full_url, tor_url))
        myDB.action('UPDATE wanted SET status = "Failed" WHERE NZBurl="%s"' % full_url)
        return False
def DownloadMethod(bookid=None, tor_prov=None, tor_title=None, tor_url=None):

    myDB = database.DBConnection()
    download = False
    if (lazylibrarian.USE_TOR) and (
        lazylibrarian.TOR_DOWNLOADER_DELUGE
        or lazylibrarian.TOR_DOWNLOADER_UTORRENT
        or lazylibrarian.TOR_DOWNLOADER_BLACKHOLE
        or lazylibrarian.TOR_DOWNLOADER_TRANSMISSION
    ):
        request = urllib2.Request(tor_url)
        if lazylibrarian.PROXY_HOST:
            request.set_proxy(lazylibrarian.PROXY_HOST, lazylibrarian.PROXY_TYPE)
        request.add_header("Accept-encoding", "gzip")
        request.add_header("User-Agent", common.USER_AGENT)

        if tor_prov == "KAT":
            request.add_header("Referer", "http://kat.ph/")

        response = urllib2.urlopen(request)
        if response.info().get("Content-Encoding") == "gzip":
            buf = StringIO(response.read())
            f = gzip.GzipFile(fileobj=buf)
            torrent = f.read()
        else:
            torrent = response.read()

        if lazylibrarian.TOR_DOWNLOADER_BLACKHOLE:
            logger.info("Torrent blackhole")
            tor_title = common.removeDisallowedFilenameChars(tor_title)
            tor_name = str.replace(str(tor_title), " ", "_") + ".torrent"
            tor_path = os.path.join(lazylibrarian.TORRENT_DIR, tor_name)

            torrent_file = open(tor_path, "wb")
            torrent_file.write(torrent)
            torrent_file.close()
            logger.info("Torrent file saved: %s" % tor_title)
            download = True

        if lazylibrarian.TOR_DOWNLOADER_UTORRENT:
            logger.info("Utorrent")
            hash = CalcTorrentHash(torrent)
            download = utorrent.addTorrent(tor_url, hash)

        if lazylibrarian.TOR_DOWNLOADER_TRANSMISSION:
            logger.info("Transmission")
            download = transmission.addTorrent(tor_url)

        if lazylibrarian.TOR_DOWNLOADER_DELUGE:
            client = DelugeRPCClient(
                lazylibrarian.DELUGE_HOST,
                int(lazylibrarian.DELUGE_PORT),
                lazylibrarian.DELUGE_USER,
                lazylibrarian.DELUGE_PASS,
            )
            client.connect()
            download = client.call("add_torrent_url", tor_url, {"name": tor_title})
            logger.info("Deluge return value: %s" % download)

    else:
        logger.error("No torrent download method is enabled, check config.")
        return False

    if download:
        logger.debug("Torrent file has been downloaded from " + str(tor_url))
        myDB.action('UPDATE books SET status = "Snatched" WHERE BookID=?', [bookid])
        myDB.action('UPDATE wanted SET status = "Snatched" WHERE NZBurl=?', [tor_url])
    else:
        logger.error(u'Failed to download torrent @ <a href="%s">%s</a>' % (tor_url, tor_url))
        myDB.action('UPDATE wanted SET status = "Failed" WHERE NZBurl=?', [tor_url])
def TORDownloadMethod(bookid=None,
                      tor_prov=None,
                      tor_title=None,
                      tor_url=None):
    myDB = database.DBConnection()
    download = False
    full_url = tor_url  # keep the url as stored in "wanted" table
    if (lazylibrarian.TOR_DOWNLOADER_DELUGE
            or lazylibrarian.TOR_DOWNLOADER_UTORRENT
            or lazylibrarian.TOR_DOWNLOADER_QBITTORRENT
            or lazylibrarian.TOR_DOWNLOADER_BLACKHOLE
            or lazylibrarian.TOR_DOWNLOADER_TRANSMISSION):

        if tor_url.startswith('magnet'):
            torrent = tor_url  # allow magnet link to write to blackhole and hash to utorrent
        else:
            if '&file=' in tor_url:
                # torznab results need to be re-encoded
                # had a problem with torznab utf-8 encoded strings not matching
                # our utf-8 strings because of long/short form differences
                url = tor_url.split('&file=')[0]
                value = tor_url.split('&file=')[1]
                if isinstance(value, str):
                    value = value.decode('utf-8')  # make unicode
                value = unicodedata.normalize('NFC',
                                              value)  # normalize to short form
                value = value.encode(
                    'unicode-escape')  # then escape the result
                value = value.replace(' ', '%20')  # and encode any spaces
                tor_url = url + '&file=' + value

            # strip url back to the .torrent as some sites add parameters
            if '?' in tor_url:
                tor_url = tor_url.split('?')[0]

            request = urllib2.Request(ur'%s' % tor_url)
            if lazylibrarian.PROXY_HOST:
                request.set_proxy(lazylibrarian.PROXY_HOST,
                                  lazylibrarian.PROXY_TYPE)
            request.add_header('Accept-encoding', 'gzip')
            request.add_header('User-Agent', common.USER_AGENT)

            # PAB removed this, KAT serves us html instead of torrent if this header is sent
            # if tor_prov == 'KAT':
            #    host = lazylibrarian.KAT_HOST
            #    if not str(host)[:4] == "http":
            #        host = 'http://' + host
            #    request.add_header('Referer', host)

            try:
                response = urllib2.urlopen(request, timeout=90)
                if response.info().get('Content-Encoding') == 'gzip':
                    buf = StringIO(response.read())
                    f = gzip.GzipFile(fileobj=buf)
                    torrent = f.read()
                else:
                    torrent = response.read()

            except (urllib2.URLError, socket.timeout) as e:
                logger.warn('Error fetching torrent from url: %s, %s' %
                            (tor_url, e))
                return False

        if lazylibrarian.TOR_DOWNLOADER_BLACKHOLE:
            tor_title = common.removeDisallowedFilenameChars(tor_title)
            logger.debug("Sending %s to blackhole" % tor_title)
            tor_name = str.replace(str(tor_title), ' ', '_')
            if tor_url.startswith('magnet'):
                tor_name = tor_name + '.magnet'
            else:
                tor_name = tor_name + '.torrent'
            tor_path = os.path.join(lazylibrarian.TORRENT_DIR, tor_name)
            with open(tor_path, 'wb') as torrent_file:
                torrent_file.write(torrent)
            logger.debug('Torrent file saved: %s' % tor_title)
            download = True

        if lazylibrarian.TOR_DOWNLOADER_UTORRENT:
            logger.debug("Sending %s to Utorrent" % tor_title)
            hash = CalcTorrentHash(torrent)
            download = utorrent.addTorrent(tor_url, hash)

        if lazylibrarian.TOR_DOWNLOADER_QBITTORRENT:
            logger.debug("Sending %s to qbittorrent" % tor_title)
            download = qbittorrent.addTorrent(tor_url)

        if lazylibrarian.TOR_DOWNLOADER_TRANSMISSION:
            logger.debug("Sending %s to Transmission" % tor_title)
            download = transmission.addTorrent(tor_url)

        if lazylibrarian.TOR_DOWNLOADER_DELUGE:
            logger.debug("Sending %s to Deluge" % tor_title)
            client = DelugeRPCClient(lazylibrarian.DELUGE_HOST,
                                     int(lazylibrarian.DELUGE_PORT),
                                     lazylibrarian.DELUGE_USER,
                                     lazylibrarian.DELUGE_PASS)
            if lazylibrarian.DELUGE_USER and lazylibrarian.DELUGE_PASS:
                client.connect()
                download = client.call('core.add_torrent_url', tor_url,
                                       {"name": tor_title})
                logger.debug('Deluge return value: %s' % download)
            else:
                logger.warn('Need user & pass for deluge, check config.')
    else:
        logger.warn('No torrent download method is enabled, check config.')
        return False

    if download:
        logger.debug(u'Torrent file has been downloaded from %s' % tor_url)
        myDB.action('UPDATE books SET status = "Snatched" WHERE BookID="%s"' %
                    bookid)
        myDB.action('UPDATE wanted SET status = "Snatched" WHERE NZBurl="%s"' %
                    full_url)
        return True
    else:
        logger.error(u'Failed to download torrent @ <a href="%s">%s</a>' %
                     (full_url, tor_url))
        myDB.action('UPDATE wanted SET status = "Failed" WHERE NZBurl="%s"' %
                    full_url)
        return False
def TORDownloadMethod(bookid=None, tor_prov=None, tor_title=None, tor_url=None):
    myDB = database.DBConnection()
    download = False
    full_url = tor_url  # keep the url as stored in "wanted" table
    if (
        lazylibrarian.TOR_DOWNLOADER_DELUGE
        or lazylibrarian.TOR_DOWNLOADER_UTORRENT
        or lazylibrarian.TOR_DOWNLOADER_QBITTORRENT
        or lazylibrarian.TOR_DOWNLOADER_BLACKHOLE
        or lazylibrarian.TOR_DOWNLOADER_TRANSMISSION
    ):

        if tor_url.startswith("magnet"):
            torrent = tor_url  # allow magnet link to write to blackhole and hash to utorrent
        else:
            if "&file=" in tor_url:
                # torznab results need to be re-encoded
                # had a problem with torznab utf-8 encoded strings not matching
                # our utf-8 strings because of long/short form differences
                url = tor_url.split("&file=")[0]
                value = tor_url.split("&file=")[1]
                if isinstance(value, str):
                    value = value.decode("utf-8")  # make unicode
                value = unicodedata.normalize("NFC", value)  # normalize to short form
                value = value.encode("unicode-escape")  # then escape the result
                value = value.replace(" ", "%20")  # and encode any spaces
                tor_url = url + "&file=" + value

            # strip url back to the .torrent as some sites add parameters
            if "?" in tor_url:
                tor_url = tor_url.split("?")[0]

            request = urllib2.Request(ur"%s" % tor_url)
            if lazylibrarian.PROXY_HOST:
                request.set_proxy(lazylibrarian.PROXY_HOST, lazylibrarian.PROXY_TYPE)
            request.add_header("Accept-encoding", "gzip")
            request.add_header("User-Agent", common.USER_AGENT)

            # PAB removed this, KAT serves us html instead of torrent if this header is sent
            # if tor_prov == 'KAT':
            #    host = lazylibrarian.KAT_HOST
            #    if not str(host)[:4] == "http":
            #        host = 'http://' + host
            #    request.add_header('Referer', host)

            try:
                response = urllib2.urlopen(request, timeout=90)
                if response.info().get("Content-Encoding") == "gzip":
                    buf = StringIO(response.read())
                    f = gzip.GzipFile(fileobj=buf)
                    torrent = f.read()
                else:
                    torrent = response.read()

            except urllib2.URLError as e:
                logger.warn("Error fetching torrent from url: " + tor_url + " %s" % e.reason)
                return False

        if lazylibrarian.TOR_DOWNLOADER_BLACKHOLE:
            tor_title = common.removeDisallowedFilenameChars(tor_title)
            logger.debug("Sending %s to blackhole" % tor_title)
            tor_name = str.replace(str(tor_title), " ", "_")
            if tor_url.startswith("magnet"):
                tor_name = tor_name + ".magnet"
            else:
                tor_name = tor_name + ".torrent"
            tor_path = os.path.join(lazylibrarian.TORRENT_DIR, tor_name)
            with open(tor_path, "wb") as torrent_file:
                torrent_file.write(torrent)
            logger.debug("Torrent file saved: %s" % tor_title)
            download = True

        if lazylibrarian.TOR_DOWNLOADER_UTORRENT:
            logger.debug("Sending %s to Utorrent" % tor_title)
            hash = CalcTorrentHash(torrent)
            download = utorrent.addTorrent(tor_url, hash)

        if lazylibrarian.TOR_DOWNLOADER_QBITTORRENT:
            logger.debug("Sending %s to qbittorrent" % tor_title)
            download = qbittorrent.addTorrent(tor_url)

        if lazylibrarian.TOR_DOWNLOADER_TRANSMISSION:
            logger.debug("Sending %s to Transmission" % tor_title)
            download = transmission.addTorrent(tor_url)

        if lazylibrarian.TOR_DOWNLOADER_DELUGE:
            logger.debug("Sending %s to Deluge" % tor_title)
            client = DelugeRPCClient(
                lazylibrarian.DELUGE_HOST,
                int(lazylibrarian.DELUGE_PORT),
                lazylibrarian.DELUGE_USER,
                lazylibrarian.DELUGE_PASS,
            )
            if lazylibrarian.DELUGE_USER and lazylibrarian.DELUGE_PASS:
                client.connect()
                download = client.call("core.add_torrent_url", tor_url, {"name": tor_title})
                logger.debug("Deluge return value: %s" % download)
            else:
                logger.warn("Need user & pass for deluge, check config.")
    else:
        logger.warn("No torrent download method is enabled, check config.")
        return False

    if download:
        logger.debug(u"Torrent file has been downloaded from %s" % tor_url)
        myDB.action('UPDATE books SET status = "Snatched" WHERE BookID="%s"' % bookid)
        myDB.action('UPDATE wanted SET status = "Snatched" WHERE NZBurl="%s"' % full_url)
        return True
    else:
        logger.error(u'Failed to download torrent @ <a href="%s">%s</a>' % (full_url, tor_url))
        myDB.action('UPDATE wanted SET status = "Failed" WHERE NZBurl="%s"' % full_url)
        return False