async void Download_Click(object sender, RoutedEventArgs e) { var selected = dataGrid.SelectedItems.Cast<EpisodeInfo>().Select(i => i.Episode.ID); IEnumerable<Episode> episodes; using(var db = new EpisodeTrackerDBContext()) { episodes = db.Episodes .Where(ep => selected.Contains(ep.ID)) .Include(ep => ep.Series) .ToList(); } var downloadingModel = new StatusModal(); grid.Children.Add(downloadingModel); downloadingModel.Text = "Searching..."; downloadingModel.SubText = "0/" + episodes.Count(); downloadingModel.ShowProgress = true; downloadingModel.ShowSubText = true; var complete = 0; var results = new List<Tuple<Episode, EpisodeTorrentSearcherResult>>(); await Task.Factory.StartNew(() => { episodes.AsParallel() .ForAll(ep => { var downloader = new EpisodeDownloader(ep); var result = downloader.Download(); if(result != null) { RunTorrentHelper.Run(result); lock(results) results.Add(Tuple.Create<Episode, EpisodeTorrentSearcherResult>(ep, result)); } Interlocked.Increment(ref complete); this.Dispatcher.BeginInvoke(new Action(() => { downloadingModel.UpdateProgress(complete, episodes.Count()); downloadingModel.SubText = String.Format("{0}/{1}", complete, episodes.Count()); if(result != null) { var win = App.Current.MainWindow as MainWindow; win.Taskbar.ShowCustomBalloon(new NotificationBalloon { HeaderText = "Episode Tracker", BodyText = "Found new download: " + result.Title }, PopupAnimation.Slide, 5000); } })); }); }); grid.Children.Remove(downloadingModel); MessageBox.Show(String.Format("Found {0} new download(s) out of {1}", results.Count(r => r.Item2 != null), results.Count())); }
async void FindFilesAsync() { var status = new StatusModal { Text = "Searching for episode files...", SubText = "Files found: 0", ShowSubText = true }; grid.Children.Add(status); var tasks = new List<Task<List<EpisodeFileSearchResult>>>(); var searcher = new EpisodeFileSearcher(); var totalFound = 0; searcher.FilesFound += (o, e) => { this.Dispatcher.BeginInvoke(new Action(() => { Interlocked.Add(ref totalFound, e.Results); status.SubText = "Files found: " + totalFound; })); }; foreach(var path in Core.Models.Settings.Default.Libraries) { tasks.Add(searcher.SearchAsync(path)); } try { await Task.WhenAll(tasks); } catch(ApplicationException e) { Logger.Error("Error searching for files: " + e); MessageBox.Show(e.Message); } var groups = tasks .Where(t => !t.IsFaulted) .SelectMany(t => t.Result) .GroupBy(r => r.Match.Name, StringComparer.OrdinalIgnoreCase) .Select(g => new SeriesFileInfo { SeriesName = g.Key, Results = g.ToList() }) .OrderBy(g => g.SeriesName); foundFiles = new ObservableCollection<SeriesFileInfo>(groups); dataGrid.ItemsSource = foundFiles; var total = groups.Count(); status.Text = "Downloading series info..."; status.SubText = String.Format("{0} / {1} series", 0, total); status.ShowProgress = true; var completed = 0; await Task.Factory.StartNew(() => { var para = foundFiles .AsParallel() .WithDegreeOfParallelism(5); para.ForAll(info => { try { FindSeries(info); } catch(Exception e) { throw new ApplicationException("Problem finding series: " + info.SeriesName, e); } Interlocked.Increment(ref completed); this.Dispatcher.BeginInvoke(new Action(() => { status.SubText = String.Format("{0} / {1} series", completed, total); status.UpdateProgress(completed, total); })); }); }); grid.Children.Remove(status); }
async void PerformWatch(Episode episode) { if(episode == null) { MessageBox.Show("Nothing to watch"); } if(episode.FileName == null || !File.Exists(episode.FileName)) { // Try and find var status = new StatusModal { Text = "Searching for episode file...", SubText = "Parsing files: 0", ShowSubText = true }; status.SetValue(Grid.RowProperty, 1); grid.Children.Add(status); var searcher = new EpisodeFileSearcher(); var totalFound = 0; searcher.FilesFound += (o, ea) => { this.Dispatcher.BeginInvoke(new Action(() => { Interlocked.Add(ref totalFound, ea.Results); status.SubText = "Parsing files: " + totalFound; })); }; var results = await Task.Factory.StartNew(() => { return Core.Models.Settings.Default.Libraries.AsParallel() .Select(path => { try { return searcher.Search(path); } catch(Exception e) { Logger.Error("Problem searching for episode file: " + episode + "-->" + e); return new List<EpisodeFileSearchResult>(); } }); }); var groups = results .SelectMany(r => r) .GroupBy(r => r.Match.Name, StringComparer.OrdinalIgnoreCase) .Select(g => new { SeriesName = g.Key, Results = g.ToList() }) .OrderBy(g => g.SeriesName); var total = groups.Count(); HashSet<string> aliases; Series series; using(var db = new EpisodeTrackerDBContext()) { series = db.Series.Single(s => s.ID == episode.SeriesID); aliases = new HashSet<string>(series.Aliases.Select(a => a.Name), StringComparer.OrdinalIgnoreCase); if(!aliases.Contains(series.Name)) aliases.Add(series.Name); } status.Text = "Checking results..."; status.SubText = String.Format("{0} / {1} series", 0, total); status.ShowProgress = true; var completed = 0; EpisodeFileSearchResult result = null; await Task.Factory.StartNew(() => { var para = groups .AsParallel() .WithDegreeOfParallelism(5); para.ForAll(info => { try { using(var db = new EpisodeTrackerDBContext()) { var seriesName = info.SeriesName; if(db.SeriesIgnore.Any(s => s.Name == seriesName)) { return; } if(!aliases.Contains(seriesName)) return; var ep = episode; var r = info.Results.FirstOrDefault(f => Episode.EqualsMatchExpression(f.Match).Compile()(ep)); if(r != null) result = r; } } finally { Interlocked.Increment(ref completed); this.Dispatcher.BeginInvoke(new Action(() => { status.SubText = String.Format("{0} / {1} series", completed, total); status.UpdateProgress(completed, total); })); } }); }); grid.Children.Remove(status); if(result != null) { using(var db = new EpisodeTrackerDBContext()) { var episodeDB = db.Episodes.Single(ep => ep.ID == episode.ID); episodeDB.FileName = result.FileName; episode.FileName = result.FileName; db.SaveChanges(); } } else { MessageBox.Show("Could not find file"); return; } } try { Process.Start(episode.FileName); } catch(Exception ex) { MessageBox.Show("Problem opening file: " + ex.Message); Logger.Error("Error opening filename: " + episode.FileName + " - " + ex); } }
private async void Sync_Click(object sender, RoutedEventArgs e) { var selected = dataGrid.SelectedItems .Cast<object>() .Where(o => o is SeriesFileInfo) .Cast<SeriesFileInfo>() .Where(s => s.TVDBID.HasValue) .ToList(); var total = selected.Count(); var status = new StatusModal { Text = "Processing " + foundFiles.Sum(g => g.Results.Count()) + " files...", SubText = String.Format("{0} / {1} series", 0, total), ShowSubText = true, ShowProgress = true, }; grid.Children.Add(status); var completed = 0; await Task.Factory.StartNew(() => { var para = selected .AsParallel() .WithDegreeOfParallelism(5); para.ForAll(info => { SyncFiles(info); Interlocked.Increment(ref completed); this.Dispatcher.BeginInvoke(new Action(() => { status.SubText = String.Format("{0} / {1} series", completed, total); status.UpdateProgress(completed, total); })); }); }); grid.Children.Remove(status); }