コード例 #1
0
        public ActionResult <SearchResource> GrabReleases(List <SearchResource> releases)
        {
            var source = UserAgentParser.ParseSource(Request.Headers["User-Agent"]);
            var host   = Request.GetHostName();

            var groupedReleases = releases.GroupBy(r => r.IndexerId);

            foreach (var indexerReleases in groupedReleases)
            {
                var indexerDef = _indexerFactory.Get(indexerReleases.Key);

                foreach (var release in indexerReleases)
                {
                    ValidateResource(release);

                    var releaseInfo = _remoteReleaseCache.Find(GetCacheKey(release));

                    try
                    {
                        _downloadService.SendReportToClient(releaseInfo, source, host, indexerDef.Redirect);
                    }
                    catch (ReleaseDownloadException ex)
                    {
                        _logger.Error(ex, "Getting release from indexer failed");
                    }
                }
            }

            return(Ok(releases));
        }
コード例 #2
0
        public async Task <object> GetDownload(int id, string link, string file)
        {
            var indexerDef = _indexerFactory.Get(id);
            var indexer    = _indexerFactory.GetInstance(indexerDef);

            if (_indexerLimitService.AtDownloadLimit(indexerDef))
            {
                throw new BadRequestException("Grab limit reached");
            }

            if (link.IsNullOrWhiteSpace() || file.IsNullOrWhiteSpace())
            {
                throw new BadRequestException("Invalid Prowlarr link");
            }

            file = WebUtility.UrlDecode(file);

            if (indexerDef == null)
            {
                throw new NotFoundException("Indexer Not Found");
            }

            var source = UserAgentParser.ParseSource(Request.Headers["User-Agent"]);
            var host   = Request.GetHostName();

            var unprotectedlLink = _downloadMappingService.ConvertToNormalLink(link);

            // If Indexer is set to download via Redirect then just redirect to the link
            if (indexer.SupportsRedirect && indexerDef.Redirect)
            {
                _downloadService.RecordRedirect(unprotectedlLink, id, source, host, file);
                return(RedirectPermanent(unprotectedlLink));
            }

            var downloadBytes = Array.Empty <byte>();

            downloadBytes = await _downloadService.DownloadReport(unprotectedlLink, id, source, host, file);

            // handle magnet URLs
            if (downloadBytes.Length >= 7 &&
                downloadBytes[0] == 0x6d &&
                downloadBytes[1] == 0x61 &&
                downloadBytes[2] == 0x67 &&
                downloadBytes[3] == 0x6e &&
                downloadBytes[4] == 0x65 &&
                downloadBytes[5] == 0x74 &&
                downloadBytes[6] == 0x3a)
            {
                var magnetUrl = Encoding.UTF8.GetString(downloadBytes);
                return(RedirectPermanent(magnetUrl));
            }

            var contentType = indexer.Protocol == DownloadProtocol.Torrent ? "application/x-bittorrent" : "application/x-nzb";
            var extension   = indexer.Protocol == DownloadProtocol.Torrent ? "torrent" : "nzb";
            var filename    = $"{file}.{extension}";

            return(File(downloadBytes, contentType, filename));
        }
コード例 #3
0
        public ActionResult <SearchResource> GrabRelease(SearchResource release)
        {
            ValidateResource(release);

            var releaseInfo = _remoteReleaseCache.Find(GetCacheKey(release));

            var indexerDef = _indexerFactory.Get(release.IndexerId);
            var source     = UserAgentParser.ParseSource(Request.Headers["User-Agent"]);
            var host       = Request.GetHostName();

            try
            {
                _downloadService.SendReportToClient(releaseInfo, source, host, indexerDef.Redirect);
            }
            catch (ReleaseDownloadException ex)
            {
                _logger.Error(ex, "Getting release from indexer failed");
                throw new NzbDroneClientException(HttpStatusCode.Conflict, "Getting release from indexer failed");
            }

            return(Ok(release));
        }
コード例 #4
0
 public void should_parse_user_agent(string userAgent, string parsedAgent)
 {
     UserAgentParser.ParseSource(userAgent).Should().Be(parsedAgent);
 }
コード例 #5
0
        public async Task <IActionResult> GetNewznabResponse(int id, [FromQuery] NewznabRequest request)
        {
            var requestType = request.t;

            request.source = UserAgentParser.ParseSource(Request.Headers["User-Agent"]);
            request.server = Request.GetServerUrl();
            request.host   = Request.GetHostName();

            if (requestType.IsNullOrWhiteSpace())
            {
                return(Content(CreateErrorXML(200, "Missing parameter (t)"), "application/rss+xml"));
            }

            request.imdbid = request.imdbid?.TrimStart('t') ?? null;

            if (request.imdbid.IsNotNullOrWhiteSpace())
            {
                if (!int.TryParse(request.imdbid, out var imdb) || imdb == 0)
                {
                    return(Content(CreateErrorXML(201, "Incorrect parameter (imdbid)"), "application/rss+xml"));
                }
            }

            if (id == 0)
            {
                switch (requestType)
                {
                case "caps":
                    var caps = new IndexerCapabilities
                    {
                        TvSearchParams = new List <TvSearchParam>
                        {
                            TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep
                        },
                        MovieSearchParams = new List <MovieSearchParam>
                        {
                            MovieSearchParam.Q
                        },
                        MusicSearchParams = new List <MusicSearchParam>
                        {
                            MusicSearchParam.Q
                        },
                        BookSearchParams = new List <BookSearchParam>
                        {
                            BookSearchParam.Q
                        }
                    };

                    foreach (var cat in NewznabStandardCategory.AllCats)
                    {
                        caps.Categories.AddCategoryMapping(1, cat);
                    }

                    return(Content(caps.ToXml(), "application/rss+xml"));

                case "search":
                case "tvsearch":
                case "music":
                case "book":
                case "movie":
                    var results = new NewznabResults();
                    results.Releases = new List <ReleaseInfo>
                    {
                        new ReleaseInfo
                        {
                            Title       = "Test Release",
                            Guid        = "https://prowlarr.com",
                            DownloadUrl = "https://prowlarr.com",
                            PublishDate = DateTime.Now
                        }
                    };

                    return(Content(results.ToXml(DownloadProtocol.Usenet), "application/rss+xml"));
                }
            }

            var indexerDef = _indexerFactory.Get(id);

            if (indexerDef == null)
            {
                throw new NotFoundException("Indexer Not Found");
            }

            var indexer = _indexerFactory.GetInstance(indexerDef);

            //TODO Optimize this so it's not called here and in NzbSearchService (for manual search)
            if (_indexerLimitService.AtQueryLimit(indexerDef))
            {
                return(Content(CreateErrorXML(500, $"Request limit reached ({((IIndexerSettings)indexer.Definition.Settings).BaseSettings.QueryLimit})"), "application/rss+xml"));
            }

            switch (requestType)
            {
            case "caps":
                var caps = indexer.GetCapabilities();
                return(Content(caps.ToXml(), "application/rss+xml"));

            case "search":
            case "tvsearch":
            case "music":
            case "book":
            case "movie":
                var results = await _nzbSearchService.Search(request, new List <int> {
                    indexerDef.Id
                }, false);

                foreach (var result in results.Releases)
                {
                    result.DownloadUrl = result.DownloadUrl.IsNotNullOrWhiteSpace() ? _downloadMappingService.ConvertToProxyLink(new Uri(result.DownloadUrl), request.server, indexerDef.Id, result.Title).AbsoluteUri : null;

                    if (result.DownloadProtocol == DownloadProtocol.Torrent)
                    {
                        ((TorrentInfo)result).MagnetUrl = ((TorrentInfo)result).MagnetUrl.IsNotNullOrWhiteSpace() ? _downloadMappingService.ConvertToProxyLink(new Uri(((TorrentInfo)result).MagnetUrl), request.server, indexerDef.Id, result.Title).AbsoluteUri : null;
                    }
                }

                return(Content(results.ToXml(indexer.Protocol), "application/rss+xml"));

            default:
                return(Content(CreateErrorXML(202, $"No such function ({requestType})"), "application/rss+xml"));
            }
        }