Esempio n. 1
0
def internalapi_addnzb(args):
    logger.debug("Add NZB request with args %s" % args)
    searchResultIds = json.loads(args["searchresultids"])
    try:
        downloader = getDownloaderInstanceByName(args["downloader"])
    except DownloaderNotFoundException as e:
        logger.error(e.message)
        return jsonify({"success": False})
    added = 0
    for searchResultId in searchResultIds:
        try:
            searchResult = SearchResult.get(SearchResult.id == searchResultId)
        except SearchResult.DoesNotExist:
            logger.error("Unable to find search result with ID %d in database" % searchResultId)
            continue
        link = get_nzb_link_and_guid(searchResultId, True, downloader=downloader.setting.name)

        if downloader.setting.nzbAddingType == config.NzbAddingTypeSelection.link:  # We send a link to the downloader. The link is either to us (where it gets answered or redirected, thet later getnzb will be called) or directly to the indexer
            add_success = downloader.add_link(link, searchResult.title, args["category"])
        else:  # We download an NZB send it to the downloader
            nzbdownloadresult = download_nzb_and_log(searchResultId)
            if nzbdownloadresult is not None:
                add_success = downloader.add_nzb(nzbdownloadresult.content, SearchResult.get(SearchResult.id == searchResultId).title, args["category"])
            else:
                add_success = False
        if add_success:
            added += 1

    if added:
        return jsonify({"success": True, "added": added, "of": len(searchResultIds)})
    else:
        return jsonify({"success": False})
Esempio n. 2
0
def api(args):
    logger.debug(request.url)
    logger.debug("API request: %s" % args)
    # Map newznab api parameters to internal
    args["category"] = args["cat"]
    args["episode"] = args["ep"]

    if args["q"] is not None and args["q"] != "":
        args["query"] = args["q"]  # Because internally we work with "query" instead of "q"
    if config.settings.main.apikey and ("apikey" not in args or args["apikey"] != config.settings.main.apikey):
        logger.error("Tried API access with invalid or missing API key")
        raise Unauthorized("API key not provided or invalid")
    elif args["t"] in ("search", "tvsearch", "movie", "book"):
        return api_search(args)
    elif args["t"] == "get":
        searchResultId = int(args["id"][len("nzbhydrasearchresult"):])
        searchResult = SearchResult.get(SearchResult.id == searchResultId)
        if config.settings.main.logging.logIpAddresses:
            logger.info("API request from %s to download %s from %s" % (getIp(), searchResult.title, searchResult.indexer.name))
        else:
            logger.info("API request to download %s from %s" % (searchResult.title, searchResult.indexer.name))
        return extract_nzb_infos_and_return_response(searchResultId)
    elif args["t"] == "caps":
        xml = render_template("caps.html")
        return Response(xml, mimetype="text/xml")
    elif args["t"] == "details":
        searchResultId = int(args["id"][len("nzbhydrasearchresult"):])
        searchResult = SearchResult.get(SearchResult.id == searchResultId)
        logger.info("API request from to get detils for %s from %s" % (searchResult.title, searchResult.indexer.name))
        item = get_entry_by_id(searchResult.indexer.name, searchResult.guid, searchResult.title)
        if item is None:
            logger.error("Unable to find or parse details for %s" % searchResult.title)
            return "Unable to get details", 500
        item.link = get_nzb_link_and_guid(searchResultId, False)[0]  # We need to make sure the link in the details refers to us
        return render_search_results_for_api([item], None, None, output=args["o"])
    elif args["t"] == "getnfo":
        searchResultId = int(args["id"][len("nzbhydrasearchresult"):])
        result = get_nfo(searchResultId)
        if result["has_nfo"]:
            if args["raw"] == 1:
                return result["nfo"]
            else:
                # TODO Return as json if requested
                return render_template("nfo.html", nfo=result["nfo"])
        else:
            return Response('<error code="300" description="No such item"/>', mimetype="text/xml")

    else:
        logger.error("Unknown API request. Supported functions: search, tvsearch, movie, get, caps, details, getnfo")
        return "Unknown API request. Supported functions: search, tvsearch, movie, get, caps, details, getnfo", 500
Esempio n. 3
0
def download_nzb_and_log(searchResultId):
    link, papiaccess, _ = get_indexer_nzb_link(searchResultId, "serve", True)
    indexerName = None
    try:
        indexerName = SearchResult.get(SearchResult.id == searchResultId).indexer.name
        indexer = indexers.getIndexerByName(indexerName)
        r = indexer.get(link, timeout=10)
        r.raise_for_status()

        papiaccess.response_successful = True
        papiaccess.response_time = r.elapsed.microseconds / 1000

        return IndexerNzbDownloadResult(content=r.content, headers=r.headers)
    except IndexerNotFoundException:
        if indexerName:
            logger.error("Unable to find indexer with name %s" % indexerName)
        else:
            logger.error("Unable to find indexer for search result id %s" % searchResultId)
        return None
    except SearchResult.DoesNotExist:
        logger.error("Unable to find search result with ID %s" % searchResultId)
        return None
    except RequestException as e:
        logger.error("Error while connecting to URL %s: %s" % (link, str(e)))
        papiaccess.error = str(e)
        return None
    finally:
        papiaccess.save()
Esempio n. 4
0
def download_nzb_and_log(searchResultId):
    link, papiaccess, _ = get_indexer_nzb_link(searchResultId, "serve", True)
    indexerName = None
    try:
        indexerName = SearchResult.get(
            SearchResult.id == searchResultId).indexer.name
        indexer = indexers.getIndexerByName(indexerName)
        r = indexer.get(link, timeout=10)
        r.raise_for_status()

        papiaccess.response_successful = True
        papiaccess.response_time = r.elapsed.microseconds / 1000

        return IndexerNzbDownloadResult(content=r.content, headers=r.headers)
    except IndexerNotFoundException:
        if indexerName:
            logger.error("Unable to find indexer with name %s" % indexerName)
        else:
            logger.error("Unable to find indexer for search result id %s" %
                         searchResultId)
        return None
    except SearchResult.DoesNotExist:
        logger.error("Unable to find search result with ID %s" %
                     searchResultId)
        return None
    except RequestException as e:
        logger.error("Error while connecting to URL %s: %s" % (link, str(e)))
        papiaccess.error = str(e)
        return None
    finally:
        papiaccess.save()
Esempio n. 5
0
def get_indexer_nzb_link(searchResultId, mode, log_api_access, internal=False):
    """
    Build a link that leads to the actual NZB of the indexer using the given informations. We log this as indexer API access and NZB download because this is only called
    when the NZB will be actually downloaded later (by us or a downloader) 
    :return: str
    """
    searchResult = SearchResult.get(SearchResult.id == searchResultId)
    indexerName = searchResult.indexer.name
    indexer = indexers.getIndexerByName(indexerName)
    link = searchResult.link

    # Log to database
    papiaccess = IndexerApiAccess(
        indexer=indexer.indexer,
        type="nzb",
        url=link,
        response_successful=None) if log_api_access else None
    try:
        papiaccess.username = request.authorization.username if request.authorization is not None else None
    except RuntimeError:
        pass
    papiaccess.save()
    pnzbdl = IndexerNzbDownload(searchResult=searchResult,
                                apiAccess=papiaccess,
                                mode=mode,
                                title=searchResult.title,
                                internal=internal)
    pnzbdl.save()

    return link, papiaccess, pnzbdl
Esempio n. 6
0
def get_details(guid):
    searchResultId = int(guid[len("nzbhydrasearchresult"):])
    searchResult = SearchResult.get(SearchResult.id == searchResultId)
    details_link = get_details_link(searchResult.indexer.name, searchResult.guid)
    if details_link:
        return redirect(details_link)
    return "Unable to find details", 500
Esempio n. 7
0
def get_nzb_response(searchResultId):
    try:
        searchResult = SearchResult.get(SearchResult.id == searchResultId)
    except SearchResult.DoesNotExist:
        logger.error("Unable to find search result with ID %s" %
                     searchResultId)
        return "Unable to find search result with ID %s" % searchResultId, 500
    nzbdownloadresult = download_nzb_and_log(searchResultId)
    if nzbdownloadresult is not None:
        bio = BytesIO(nzbdownloadresult.content)
        filename = searchResult.title + ".nzb" if searchResult.title is not None else "nzbhydra.nzb"
        response = send_file(bio,
                             mimetype='application/x-nzb;',
                             as_attachment=True,
                             attachment_filename=filename,
                             add_etags=False)
        response.headers["content-length"] = len(nzbdownloadresult.content)

        for header in nzbdownloadresult.headers.keys():
            if header.lower().startswith("x-dnzb") or header.lower() in (
                    "content-disposition", "content-type"):
                response.headers[header] = nzbdownloadresult.headers[header]
        logger.info("Returning downloaded NZB %s from %s" %
                    (searchResult.title, searchResult.indexer.name))
        return response
    else:
        logger.error("Error while trying to download NZB %s from %s" %
                     (searchResult.title, searchResult.indexer.name))
        return "Unable to download NZB", 500
Esempio n. 8
0
def getnzb(args):
    logger.debug("Get NZB request with args %s" % args)
    searchResult = SearchResult.get(SearchResult.id == args["searchresultid"])
    if config.settings.main.logging.logIpAddresses:
        logger.info("API request from %s to download %s from %s" % (getIp(), searchResult.title, searchResult.indexer.name))
    else:
        logger.info("API request to download %s from %s" % (searchResult.title, searchResult.indexer.name))
    return extract_nzb_infos_and_return_response(args["searchresultid"], args["downloader"])
Esempio n. 9
0
def get_nfo(searchresultid):
    try:
        searchResult = SearchResult.get(SearchResult.id == searchresultid)
        indexer = indexers.getIndexerByName(searchResult.indexer.name)
        has_nfo, nfo, message = indexer.get_nfo(searchResult.guid)
        return {"has_nfo": has_nfo, "nfo": nfo, "message": message}
    except IndexerNotFoundException as e:
        logger.error(e.message)
        return {"has_nfo": False, "error": "Unable to find indexer"}
Esempio n. 10
0
def get_nfo(searchresultid):
    try:
        searchResult = SearchResult.get(SearchResult.id == searchresultid)
        indexer = indexers.getIndexerByName(searchResult.indexer.name)
        has_nfo, nfo, message = indexer.get_nfo(searchResult.guid)
        return {"has_nfo": has_nfo, "nfo": nfo, "message": message}
    except IndexerNotFoundException as e:
        logger.error(e.message)
        return {"has_nfo": False, "error": "Unable to find indexer"}
Esempio n. 11
0
File: api.py Progetto: gspu/nzbhydra
def getNzbById(searchResultId):
    # type: (int) -> (IndexerNzbDownloadResult, SearchResult)
    """
    :rtype: (IndexerNzbDownloadResult, SearchResult)
    """
    try:
        searchResult = SearchResult.get(SearchResult.id == searchResultId)
    except SearchResult.DoesNotExist:
        logger.error("Unable to find search result with ID %s" % searchResultId)
        raise NzbDownloadException("Unable to find search result with ID %s" % searchResultId)
    nzbdownloadresult = download_nzb_and_log(searchResultId)
    if nzbdownloadresult is None:
        logger.error("Error while trying to download NZB %s from %s" % (searchResult.title, searchResult.indexer.name))
        raise NzbDownloadException("Unable to download NZB")
    return nzbdownloadresult, searchResult
Esempio n. 12
0
def get_nzb_response(searchResultId):
    searchResult = SearchResult.get(SearchResult.id == searchResultId)
    nzbdownloadresult = download_nzb_and_log(searchResultId)
    if nzbdownloadresult is not None:
        bio = BytesIO(nzbdownloadresult.content)
        filename = searchResult.title + ".nzb" if searchResult.title is not None else "nzbhydra.nzb"
        response = send_file(bio, mimetype='application/x-nzb;', as_attachment=True, attachment_filename=filename, add_etags=False)
        response.headers["content-length"] = len(nzbdownloadresult.content)

        for header in nzbdownloadresult.headers.keys():
            if header.lower().startswith("x-dnzb") or header.lower() in ("content-disposition", "content-type"):
                response.headers[header] = nzbdownloadresult.headers[header]
        logger.info("Returning downloaded NZB %s from %s" % (searchResult.title, searchResult.indexer.name))
        return response
    else:
        logger.error("Error while trying to download NZB %s from %s" % (searchResult.title, searchResult.indexer.name))
        return "Unable to download NZB", 500
Esempio n. 13
0
def getNzbById(searchResultId):
    # type: (int) -> (IndexerNzbDownloadResult, SearchResult)
    """
    :rtype: (IndexerNzbDownloadResult, SearchResult)
    """
    try:
        searchResult = SearchResult.get(SearchResult.id == searchResultId)
    except SearchResult.DoesNotExist:
        logger.error("Unable to find search result with ID %s" %
                     searchResultId)
        raise NzbDownloadException("Unable to find search result with ID %s" %
                                   searchResultId)
    nzbdownloadresult = download_nzb_and_log(searchResultId)
    if nzbdownloadresult is None:
        logger.error("Error while trying to download NZB %s from %s" %
                     (searchResult.title, searchResult.indexer.name))
        raise NzbDownloadException("Unable to download NZB")
    return nzbdownloadresult, searchResult
Esempio n. 14
0
def get_indexer_nzb_link(searchResultId, mode, log_api_access, internal=False):
    """
    Build a link that leads to the actual NZB of the indexer using the given informations. We log this as indexer API access and NZB download because this is only called
    when the NZB will be actually downloaded later (by us or a downloader) 
    :return: str
    """
    searchResult = SearchResult.get(SearchResult.id == searchResultId)
    indexerName = searchResult.indexer.name
    indexer = indexers.getIndexerByName(indexerName)
    link = searchResult.link

    # Log to database
    papiaccess = IndexerApiAccess(indexer=indexer.indexer, type="nzb", url=link, response_successful=None) if log_api_access else None
    try:
        papiaccess.username = request.authorization.username if request.authorization is not None else None
    except RuntimeError:
        pass
    papiaccess.save()
    pnzbdl = IndexerNzbDownload(searchResult=searchResult, apiAccess=papiaccess, mode=mode, title=searchResult.title, internal=internal)
    pnzbdl.save()

    return link, papiaccess, pnzbdl