예제 #1
0
        public void Finds_Name_With_Allowed_Punctuation()
        {
            var file = @"Z:\downloaded\[WhyNot] Steins;Gate [BD 720p AAC]\[WhyNot] Steins;Gate - 01 [BD 720p AAC][5CFFC1C7].mkv";
            var name = Path.GetFileName(file);

            var matcher = new TvMatcher();
            var match = matcher.Match(name);

            Assert.NotNull(match);
            Assert.Equal("Steins;Gate", match.Name);
        }
        void CheckUnmonitoredFile(string fileName)
        {
            Logger.Debug("File is not monitored: " + fileName);
            var mon = new MonitoredFile {
                FileName = fileName,
                Start = DateTime.Now
            };

            using(var info = new MediaInfo(fileName)) {
                mon.Length = info.Length;
            }

            var name = Path.GetFileName(fileName);
            var match = new TvMatcher().Match(name);
            if(match != null) {
                Logger.Debug("Found episode info: " + match.ToString());

                mon.TvMatch = match;

                // Try and look it up
                // TODO: movies
                Series series;
                using(var db = new EpisodeTrackerDBContext()) {
                    series = db.Series.SingleOrDefault(s => s.Name == match.Name || s.Aliases.Any(a => a.Name == match.Name));

                    int? tvdbid = null;
                    if(series == null) {
                        var results = new TVDBRequest().Search(match.Name);
                        var first = results.FirstOrDefault();
                        if(first != null) {
                            Logger.Debug("Found TVDB result: " + first.Name);
                            series = db.Series.SingleOrDefault(s => s.TVDBID == first.ID || s.Name == first.Name || s.Aliases.Any(a => a.Name == first.Name));
                            tvdbid = first.ID;
                        }
                    }else {
                        tvdbid = series.TVDBID;
                    }

                    if(tvdbid.HasValue) {
                        if(series == null || series.Updated <= DateTime.Now.AddDays(-7)) {
                            var syncer = new TVDBSeriesSyncer {
                                TVDBID = tvdbid.Value,
                                Name = match.Name,
                                DownloadBannersAsync = true
                            };
                            syncer.Sync();
                        }

                        // Pull out series again as it might have been updated
                        series = db.Series
                            .Include(s => s.Episodes)
                            .Single(s => s.TVDBID == tvdbid.Value);

                        mon.Series = series;

                        if(match.Season.HasValue) {
                            var eps = series.Episodes.Where(ep => ep.Season == match.Season.Value);
                            if(match.ToEpisode.HasValue) {
                                mon.Episodes = eps.Where(ep => ep.Number >= match.Episode && ep.Number <= match.ToEpisode.Value);
                            } else {
                                mon.Episodes = eps.Where(ep => ep.Number == match.Episode);
                            }
                        } else {
                            mon.Episodes = series.Episodes.Where(ep => ep.AbsoluteNumber == match.Episode);
                        }

                        if(mon.Episodes != null) {
                            Logger.Debug("Found TVDB episodes: " + String.Join(" + ", mon.Episodes.Select(e => e.Name)));
                        }
                    }
                }
            }

            monitored.Add(mon);
        }
        public List<EpisodeTorrentSearcherResult> Search(Episode episode, out List<EpisodeTorrentSearcherResult> misses)
        {
            var searchers = new ITorrentSearcher[] {
                new KickAssTorrentsSeacher()
                //,new ISOHuntSearcher()
            };

            Logger.Build().Episode(episode).Message("Beginning search").Debug();

            string text;
            var series = Regex.Replace(episode.Series.Name, @"['\-_()]", "");
            if(!UseAbsoluteEpisodeFormat) {
                text = String.Format("{0} S{1:00}E{2:00}", series, episode.Season, episode.Number);
            } else {
                text = String.Format("{0} {1}", series, episode.AbsoluteNumber);
            }

            Logger.Build().Episode(episode).Message("Search text: " + text).Debug();

            var matcher = new TvMatcher();

            var results = searchers
                .AsParallel()
                .SelectMany(s => {
                    try {
                        return s.Search(text);
                    } catch(Exception e) {
                        Logger.Build().Episode(episode).Message("Error searching " + s.GetType().Name + ": " + e).Error();
                        return new List<TorrentResult>();
                    }
                })
                .Select(r => new {
                    Match = matcher.Match(r.Title),
                    Torrent = r
                })
                .ToList()
                .OrderByDescending(r => r.Torrent.Leechs)
                .OrderByDescending(r => r.Torrent.Seeds);

            var minBytes = MinMB.HasValue ? MinMB * 1024 * 1024 : (default(int?));
            var maxBytes = MaxMB.HasValue ? MaxMB * 1024 * 1024 : (default(int?));
            var seriesMatch = new TvMatcher().Match(series);
            var cleanSeries = seriesMatch != null ? seriesMatch.Name : series;

            var matches = results
                .Where(r => {
                    var entry = Logger.Build().Episode(episode);
                    var msg = "Result " + r.Torrent + " {0}: {1}";

                    if(r.Match == null) {
                        entry.Message(msg, "does not match TV episode format", r.Torrent.Title).Debug();
                        return false;
                    }

                    if(r.Match.Name.IndexOf(cleanSeries, StringComparison.OrdinalIgnoreCase) == -1
                        && r.Match.Name.IndexOf(episode.Series.Name, StringComparison.OrdinalIgnoreCase) == -1) {
                            entry.Message(msg, "does not contain series name", r.Match).Debug();
                            return false;
                    }

                    if(!episode.Equals(r.Match, UseAbsoluteEpisodeFormat)) {
                        entry.Message(msg, "match does not match episode", r.Match).Debug();
                        return false;
                    }

                    if(r.Torrent.Seeds < MinSeeds.GetValueOrDefault(int.MinValue)) {
                        entry.Message(msg, "does not match min seeds", MinSeeds).Debug();
                        return false;
                    }

                    if(r.Torrent.Length < minBytes.GetValueOrDefault(int.MinValue)) {
                        entry.Message(msg, "does not match min bytes", minBytes).Debug();
                        return false;
                    }

                    if(r.Torrent.Length > maxBytes.GetValueOrDefault(int.MaxValue)) {
                        entry.Message(msg, "does not match max bytes", maxBytes).Debug();
                        return false;
                    }

                    if(HD.HasValue && (r.Torrent.Title.Contains("720p") || r.Torrent.Title.Contains("1080p")) != HD.Value) {
                        entry.Message(msg, "does not match HD value", HD).Debug();
                        return false;
                    }

                    return true;
                });

            misses = results
                .Except(matches)
                .Select(r => new EpisodeTorrentSearcherResult {
                    Title = r.Torrent.Title,
                    DownloadURL = r.Torrent.DownloadURL,
                    MB = r.Torrent.Length / 1024 / 1024,
                    Published = r.Torrent.Published,
                    Seeds = r.Torrent.Seeds,
                    Leechs = r.Torrent.Leechs,
                    Match = r.Match
                })
                .ToList();

            Logger.Build()
                .Episode(episode)
                .Message("Found download results: {0} matches, {1} misses", matches.Count(), misses.Count())
                .Debug();

            return matches.Select(r => new EpisodeTorrentSearcherResult {
                Title = r.Torrent.Title,
                DownloadURL = r.Torrent.DownloadURL,
                MB = r.Torrent.Length / 1024 / 1024,
                Published = r.Torrent.Published,
                Seeds = r.Torrent.Seeds,
                Leechs = r.Torrent.Leechs,
                Match = r.Match
            })
            .ToList();
        }