using System.Linq; using System.Collections.Generic; using NLog; using NzbDrone.Common.Instrumentation.Extensions; using NzbDrone.Common.Extensions; using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; using NzbDrone.Core.Download.Pending; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Indexers; using System.ServiceModel.Syndication; using System.Xml; using NzbDrone.Common.Http; using NzbDrone.Core.Tv; using System; using System.IO; using NzbDrone.Core.Parser; using NzbDrone.Core.IndexerSearch; using NzbDrone.Core.IndexerSearch.Definitions; namespace NzbDrone.Core.MetadataSource.PreDB { public interface IPreDBService { bool HasReleases(Movie movie); } public class PreDBService : IPreDBService, IExecute { private readonly IFetchAndParseRss _rssFetcherAndParser; private readonly IMakeDownloadDecision _downloadDecisionMaker; private readonly IProcessDownloadDecisions _processDownloadDecisions; private readonly IPendingReleaseService _pendingReleaseService; private readonly IEventAggregator _eventAggregator; private readonly IMovieService _movieService; private readonly IHttpClient _httpClient; private readonly IParsingService _parsingService; private readonly Logger _logger; public PreDBService( IFetchAndParseRss rssFetcherAndParser, IMakeDownloadDecision downloadDecisionMaker, IProcessDownloadDecisions processDownloadDecisions, IPendingReleaseService pendingReleaseService, IEventAggregator eventAggregator, IMovieService movieService, IHttpClient httpClient, IParsingService parsingService, Logger logger) { _rssFetcherAndParser = rssFetcherAndParser; _downloadDecisionMaker = downloadDecisionMaker; _processDownloadDecisions = processDownloadDecisions; _pendingReleaseService = pendingReleaseService; _eventAggregator = eventAggregator; _movieService = movieService; _httpClient = httpClient; _parsingService = parsingService; _logger = logger; } private List GetResults(string category = "", string search = "") { return new List(); var builder = new HttpRequestBuilder("http://predb.me").AddQueryParam("rss", "1"); if (category.IsNotNullOrWhiteSpace()) { builder.AddQueryParam("cats", category); } if (search.IsNotNullOrWhiteSpace()) { builder.AddQueryParam("search", search); } var request = builder.Build(); request.AllowAutoRedirect = true; request.SuppressHttpError = true; var response = _httpClient.Get(request); if (response.StatusCode != System.Net.HttpStatusCode.OK) { _logger.Warn("Non 200 StatusCode {0} encountered while searching PreDB.", response.StatusCode); return new List(); } try { var reader = XmlReader.Create(new StringReader(response.Content)); var items = SyndicationFeed.Load(reader); var results = new List(); foreach (SyndicationItem item in items.Items) { var result = new PreDBResult(); result.Title = item.Title.Text; result.Link = item.Links[0].Uri.ToString(); results.Add(result); } return results; } catch (Exception ex) { _logger.Error(ex, "Error while searching PreDB."); } return new List(); } private List FindMatchesToResults(List results) { var matches = new List(); foreach (PreDBResult result in results) { var parsedInfo = Parser.Parser.ParseMovieTitle(result.Title, true); if (parsedInfo != null) { var movie = _movieService.FindByTitle(parsedInfo.MovieTitle, parsedInfo.Year); if (movie != null) { matches.Add(movie); } } } return matches; } private List Sync() { _logger.ProgressInfo("Starting PreDB Sync"); var results = GetResults("movies"); var matches = FindMatchesToResults(results); return matches; } public void Execute(PreDBSyncCommand message) { var haveNewReleases = Sync(); foreach (Movie movie in haveNewReleases) { if (!movie.HasPreDBEntry) { movie.HasPreDBEntry = true; _movieService.UpdateMovie(movie); } if (movie.Monitored) { //Maybe auto search each movie once? } } _eventAggregator.PublishEvent(new PreDBSyncCompleteEvent(haveNewReleases)); } public bool HasReleases(Movie movie) { try { var results = GetResults("movies", movie.Title); foreach (PreDBResult result in results) { var parsed = Parser.Parser.ParseMovieTitle(result.Title, true); if (parsed == null) { parsed = new Parser.Model.ParsedMovieInfo { MovieTitle = result.Title, Year = 0 }; } var match = _parsingService.Map(parsed, "", new MovieSearchCriteria { Movie = movie }); if (match != null && match.RemoteMovie.Movie != null && match.RemoteMovie.Movie.Id == movie.Id) { return true; } } return false; } catch (Exception ex) { _logger.Warn(ex, "Error while looking on predb.me."); return false; } } } }