예제 #1
0
        public Tuple<Series, Episode> Match(Recording record, out float best)
        {
            best = -1;
            Series series = null;
            Episode episode = null;
            var search = SearchData.GetSeriesSearch(record.Title);
            if (search == null)
                return new Tuple<Series, Episode>(null, null);

            var seriesList = SeriesData.GetSeriesBySearchId(search.Id);
            EpisodeData.LoadEpisodes(seriesList);
            episode = Match(record, seriesList, out best);
            if (episode != null)
            {
                SearchData.SetSearchMatch(search, episode.SeriesId);
                series = episode.Series;
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(search.TargetId))
                    series = SeriesData.GetSeries(search.TargetId);
            }
            
            return new Tuple<Series, Episode>(series, episode);
        }
예제 #2
0
        public void Sync(Recording record)
        {
            var phrase = record.Title;
            var date = record.AirDate;

            var search = SearchData.GetSeriesSearch(phrase);
            SearchResultData.LoadSearchResults(search);
            if (search == null || DateTime.Now - search.UpdatedDate >= TimeSpan.FromMinutes(Config.SyncInterval))
            {
                var token = DownloadResults(phrase);
                var results = ParseResults(token).Where(a => IsMatch(record, a)).ToList();

                foreach (var result in results)
                {
                    var series = SeriesData.GetSeries(result.Id);                    
                    //EpisodeData.LoadEpisodes(series);
                    if (series == null || DateTime.Now - series.UpdatedDate > TimeSpan.FromMinutes(Config.SyncInterval))
                    {
                        token = DownloadSeries(result.Id);
                        series = ParseSeries(token);
                        series.AliasNames = result.AliasNames;
                        series.Episodes = ParseEpisodes(token);
                        SeriesData.SaveSeries(series);
                        EpisodeData.SaveEpisodes(series.Episodes);
                    }
                }

                search = search ?? new Search(MediaType.SeriesType, phrase, null);
                SearchData.SaveSearch(search);
                search.Results = results.Select(a => new SearchResult(search.Id, a.Id, search)).ToList();
                SearchResultData.SaveSearchResults(search.Results);
            }
        }
예제 #3
0
        public void Sync(Recording record)
        {
            var phrase = record.Title;
            var date = record.AirDate;

            var search = SearchData.GetMovieSearch(phrase, date);
            SearchResultData.LoadSearchResults(search);
            if (search == null || DateTime.Now - search.UpdatedDate >= TimeSpan.FromMinutes(Config.SyncInterval))
            {
                var token = DownloadResults(phrase, date);
                var results = ParseResults(token).Where(a => IsMatch(record, a)).ToList();
                var movieList = ParseMovies(token);

                foreach (var movie in movieList)
                {
                    if (results.Any(a => a.Id == movie.Id))
                    {
                        MovieData.SaveMovie(movie);
                    }
                }

                search = search ?? new Search(MediaType.MovieType, phrase, date);
                SearchData.SaveSearch(search);
                search.Results = results.Select(a => new SearchResult(search.Id, a.Id, search)).ToList();
                SearchResultData.SaveSearchResults(search.Results);
            }
        }
예제 #4
0
 public void UpdateFilename(Recording record, string file)
 {
     record.Filename = file;
     using (var db = DatabaseFactory.GetNpvrDbConnection())
     {
         db.Execute("update scheduled_recording set filename=? where oid=?", record.Filename, record.Oid);
     }
 }
예제 #5
0
 public bool IsMatch(Recording record, MovieSearchResult result)
 {
     float title = 0f;
     if (!string.IsNullOrWhiteSpace(record.Title) && !string.IsNullOrWhiteSpace(result.Title))
     {
         title = FuzzyUtil.Score(result.Title, record.Title);
     }
     return title >= .8f;
 }
예제 #6
0
 public void HandleSeries(Recording record, Series series)
 {
     //Create NFO
     xbmc.DeleteSeriesNfoFile(new FileInfo(record.Filename).DirectoryName);
     if (series == null)
     {
         xbmc.CreateSeriesNfoFile(record.Name, true);
     }
     else if (!string.Equals(record.Name, series.SeriesName, StringComparison.OrdinalIgnoreCase))
     {
         xbmc.CreateSeriesNfoFile(record.Name, series.Id, true);
     }
 }
예제 #7
0
        public void Rename(Recording record, Movie movie)
        {
            //FileUtil.CreateDirectoryPath(xbmc.GetSeriesDirectory(record.Name));
            
            //Cleanup orphaned files
            if (!File.Exists(record.Filename))
            {
                xbmc.DeleteVideoNfoFile(record.Filename);
                return;
            }

            HandleMovie(record, movie);
        }
예제 #8
0
        public void HandleMovie(Recording record, Movie movie)
        {
            bool same;
            var oldFile = new FileInfo(record.Filename);
            var newFile = new FileInfo(GetMovieFilename(record, movie, out same));
            
            //Create NFO
            xbmc.DeleteVideoNfoFile(oldFile.FullName);
            if (movie == null)
            {
                xbmc.CreateMovieNfoFile(newFile.FullName, record);
            }

            if (same)
            {
                /*LogUtil.Log("No Change (Movie): " + record.Title + ":");
                LogUtil.Log("\tOld Filename: " + oldFile.Name);
                LogUtil.Log("\tNew Filename: " + newFile.Name);
                LogUtil.Log("");*/
                return; //nothing to do
            }

            //Move File
            File.Move(oldFile.FullName, newFile.FullName);
            new RecordingData().UpdateFilename(record, newFile.FullName);

            //Logging
            var update = oldFile.FullName.StartsWith(Config.XbmcMoviePath, StringComparison.OrdinalIgnoreCase);
            
            if (movie == null)
            {
                LogUtil.Log("Match Failure (Movie): " + record.Title + ":");
                LogUtil.Log("\tOld Filename: " + oldFile.Name);
                LogUtil.Log("\tNew Filename: " + newFile.Name);
                LogUtil.Log("");
            }
            else if (!update)
            {
                LogUtil.Log("Match Success (Movie): " + record.Title + ":");
                LogUtil.Log("\tOld Filename: " + oldFile.Name);
                LogUtil.Log("\tNew Filename: " + newFile.Name);
                LogUtil.Log("");
            }
            else
            {
                LogUtil.Log("Match Updated (Movie): " + record.Title + ":");
                LogUtil.Log("\tOld Filename: " + oldFile.Name);
                LogUtil.Log("\tNew Filename: " + newFile.Name);
                LogUtil.Log("");
            }
        }
예제 #9
0
        public void Rename(Recording record, Series series, Episode episode)
        {
            FileUtil.CreateDirectoryPath(xbmc.GetSeriesDirectory(record.Name));
            
            //Cleanup orphaned files
            if (!File.Exists(record.Filename))
            {
                xbmc.DeleteVideoNfoFile(record.Filename);
                return;
            }

            HandleSeries(record, series);
            HandleEpisode(record, episode);
        }
예제 #10
0
        public Movie Match(Recording record, out float best)
        {
            best = -1;
            var search = SearchData.GetMovieSearch(record.Title, record.AirDate);
            if (search == null)
                return null;

            var movieList = MovieData.GetMoviesBySearchId(search.Id);
            var movie = Match(record, movieList, out best);
            if (movie != null)
            {
                SearchData.SetSearchMatch(search, movie.Id);
            }
            return movie;
        }
예제 #11
0
 public string GetMovieFilename(Recording record, Movie movie, out bool same)
 {
     string oldFile = record.Filename;
     string newFile;
     int i = 1;
     do
     {
         var suffix = i == 1 ? "" : i.ToString();
         if (movie != null)
             newFile = xbmc.GetMovieFilename(movie.Title, movie.ReleaseDate.Value, suffix, "ts");
         else
             newFile = xbmc.GetAltMovieFilename(record.Name, record.StartTime.Value, suffix, "ts");
         same = string.Equals(oldFile, newFile, StringComparison.OrdinalIgnoreCase);
         i++;
     }
     while (File.Exists(newFile) && !same);
     return newFile;
 }
예제 #12
0
        public void ParseEventDetail(Recording record)
        {
            if (record == null)
                return;

            record.StartTime = record.StartTime != null ? (DateTime?)record.StartTime.Value.ToLocalTime() : null;
            record.EndTime = record.EndTime != null ? (DateTime?)record.EndTime.Value.ToLocalTime() : null;
            XDocument doc = XDocument.Parse(record.EventXml);
            DateTime? airDate = doc.Descendants("OriginalAirDate").FirstValue<DateTime?>();
            bool? firstRun = doc.Descendants("FirstRun").FirstValue<bool?>();
            string title = doc.Descendants("Title").FirstValue<string>();
            string subtitle = doc.Descendants("SubTitle").FirstValue<string>();
            string season = doc.Descendants("Season").FirstValue<string>();
            string episode = doc.Descendants("Episode").FirstValue<string>();
            string description = doc.Descendants("Description").FirstValue<string>();
            string uniqueId = doc.Descendants("UniqueID").FirstValue<string>();
            List<string> genres = doc.Descendants("Genre").Select(a => a.Value).ToList();

            if (airDate == null && firstRun != null && firstRun.Value)
            {
                airDate = record.StartTime;
            }

            record.AirDate = airDate;
            record.FirstRun = firstRun;
            record.Title = title;
            record.SubTitle = subtitle;
            record.Season = season;
            record.Episode = episode;            
            record.Description = description;
            record.UniqueId = uniqueId;
            record.UniqueSeriesId = ParseUniqueSeriesId(uniqueId);
            record.UniqueEpisodeId = ParseUniqueEpisodeId(uniqueId);
            record.Genres = genres;
            record.IsMovie = uniqueId != null && uniqueId.StartsWith("MV", StringComparison.OrdinalIgnoreCase);
            record.IsMovie = record.IsMovie || genres.Contains("Movie", StringComparer.OrdinalIgnoreCase) || genres.Contains("Movies", StringComparer.OrdinalIgnoreCase);
        }
예제 #13
0
        public Movie Match(Recording record, List<Movie> movieList, out float best)
        {
            best = -1;

            if (movieList.Count == 0)
                return null;

            Movie match = null;            
            bool success = false;
            
            foreach (var movie in movieList)
            {
                //TITLE
                float title = 0f;
                if (!string.IsNullOrWhiteSpace(record.Title) && !string.IsNullOrWhiteSpace(movie.Title))
                {
                    title = FuzzyUtil.Score(movie.Title, record.Title);
                }

                //PASS / FAIL?
                float result = title;
                bool pass = false;
                if (title >= .8f)
                    pass = true;

                //MATCH?
                if (pass && result > best)
                {
                    match = movie;
                    best = result;
                    success = success || pass;
                }
            }

            return success ? match : null;
        }
예제 #14
0
 public string GetEpisodeFilename(Recording record, Episode episode, out bool same)
 {
     string oldFile = record.Filename;
     string newFile;
     int i = 1;
     do
     {
         var suffix = i == 1 ? "" : i.ToString();
         if (episode != null)
             newFile = xbmc.GetEpisodeFilename(record.Name, episode.SeasonNumber, episode.EpisodeNumber, episode.EpisodeName, suffix, "ts");
         else
             newFile = xbmc.GetAltEpisodeFilename(record.Name, record.StartTime.Value, record.SubTitle, suffix, "ts");
         same = string.Equals(oldFile, newFile, StringComparison.OrdinalIgnoreCase);
         i++;
     }
     while (File.Exists(newFile) && !same);
     return newFile;
 }
예제 #15
0
        public void CreateEpisodeNfoFile(string file, Recording record)
        {
            file = DeriveNfoFile(file);

            XElement episode = new XElement("episodedetails");
            if (!string.IsNullOrWhiteSpace(record.SubTitle))
                episode.Add(new XElement("title", record.SubTitle));
            else
                episode.Add(new XElement("title", record.StartTime.Value.ToString("MM/dd/yyyy")));
            if (record.AirDate != null)
                episode.Add(new XElement("aired", record.AirDate));
            if (!string.IsNullOrWhiteSpace(record.Description))
                episode.Add(new XElement("plot", record.Description));
            if (!string.IsNullOrWhiteSpace(record.Season))
                episode.Add(new XElement("season", record.Season));
            if (!string.IsNullOrWhiteSpace(record.Episode))
                episode.Add(new XElement("episode", record.Episode));
            episode.Save(file);
            //Program.Log("Created Episode NFO file: " + new FileInfo(file).Name);
        }
예제 #16
0
        public void CreateMovieNfoFile(string file, Recording record)
        {
            file = DeriveNfoFile(file);

            XElement movie = new XElement("movie");
            if (!string.IsNullOrWhiteSpace(record.Title))
                movie.Add(new XElement("title", record.Title));
            if (record.AirDate != null)
                movie.Add(new XElement("year", record.AirDate.Value.Year.ToString()));
            if (!string.IsNullOrWhiteSpace(record.Description))
                movie.Add(new XElement("plot", record.Description));
            movie.Save(file);
            //Program.Log("Created Episode NFO file: " + new FileInfo(file).Name);
        }
예제 #17
0
        public Episode Match(Recording record, List<Series> seriesList, out float best)
        {
            best = -1;

            if (seriesList.Count == 0)
                return null;

            Episode match = null;
            float bestTitle = -1f, bestSubtitle = -1f, bestDate = -1f;
            bool success = false;
            var episodeSplit = SplitEpisodes(record.SubTitle);
            
            foreach (var series in seriesList)
            {
                //TITLE
                float title = 0f;
                if (!string.IsNullOrWhiteSpace(record.Title) && !string.IsNullOrWhiteSpace(series.SeriesName))
                {
                    var temp = FuzzyUtil.Score(series.SeriesName, record.Title);
                    var seriesSplit = SplitSeries(series.SeriesName).Union(SplitAliases(series.AliasNames));
                    title = seriesSplit.Max(a => FuzzyUtil.Score(a, record.Title));
                    title = title * .99f + temp * .01f;
                }

                foreach (var episode in series.Episodes)
                {
                    //SUBTITLE
                    float subtitle = 0f;
                    if (!string.IsNullOrWhiteSpace(record.SubTitle) && !string.IsNullOrWhiteSpace(episode.EpisodeName))
                    {
                        var temp = FuzzyUtil.Score(episode.EpisodeName, record.SubTitle);
                        subtitle = episodeSplit.Max(a => FuzzyUtil.Score(episode.EpisodeName, a));
                        subtitle = subtitle * .99f + temp * .01f;
                    }

                    //AIR DATE
                    float date = 0f;
                    if (record.AirDate != null && episode.FirstAired != null)
                    {
                        date = FuzzyUtil.Score(episode.FirstAired.Value.Date, record.AirDate.Value.Date);
                    }

                    //FIRST RUN
                    if (record.FirstRun == true && record.StartTime != null && episode.FirstAired != null)
                    {
                        date = Math.Max(date, FuzzyUtil.Score(episode.FirstAired.Value.Date, record.StartTime.Value.Date));
                    }

                    //PASS / FAIL?
                    bool pass = false;
                    if (title >= .8f && subtitle >= .8f && date >= .8f)
                    {
                        pass = true;
                    }
                    else if (title >= .8f && subtitle >= .8f)
                    {
                        pass = true;
                        date = 0;
                    }
                    else if (title >= .8f && date >= .8f)
                    {
                        pass = true;
                        subtitle = 0;
                    }
                    float result = .33f * title + .33f * subtitle + .33f * date;
                    
                    
                    //MATCH?
                    if (pass && result > best)
                    {
                        match = episode;
                        best = result;
                        bestTitle = title;
                        bestSubtitle = subtitle;
                        bestDate = date;
                        success = success || pass;
                    }
                }
            }

            /*if (!success)
            {
                Console.WriteLine(record.Title + " " + record.SubTitle);
                Console.WriteLine("\tTITLE: " + bestTitle);
                Console.WriteLine("\tSUBTITLE: " + bestSubtitle);
                Console.WriteLine("\tAIRED: " + bestAired);
            }*/

            return success ? match : null;
        }
예제 #18
0
 public bool IsMatch(Recording record, TvSearchResult result)
 {
     float title = 0f;
     if (!string.IsNullOrWhiteSpace(record.Title) && !string.IsNullOrWhiteSpace(result.SeriesName))
     {
         var seriesSplit = TvDbMatch.SplitSeries(result.SeriesName).Union(TvDbMatch.SplitAliases(result.AliasNames));
         title = seriesSplit.Max(a => FuzzyUtil.Score(a, record.Title));
     }
     return title >= .8f;
 }