public AnimeEpisodeVM GetEpisodeForVideo(VideoDetailedVM vid, EpisodeList epList) { // get the episodes that this file applies to try { List <JMMServerBinary.Contract_AnimeEpisode> eps = JMMServerVM.Instance.clientBinaryHTTP.GetEpisodesForFile(vid.VideoLocalID, JMMServerVM.Instance.CurrentUser.JMMUserID.Value); foreach (JMMServerBinary.Contract_AnimeEpisode epcontract in eps) { foreach (object epObj in epList.lbEpisodes.ItemsSource) { AnimeEpisodeVM epItem = epObj as AnimeEpisodeVM; if (epItem.AnimeEpisodeID == vid.AnimeEpisodeID) { return(epItem); } } } } catch (Exception ex) { Utils.ShowErrorMessage(ex); } return(null); }
public SeasonSeasonModel(String season) { var seasonPath = Paths.SeasonPath(Paths.Json, season); Season = new Season(seasonPath); EpisodeList = Season.EpisodeList; if (!Config.IsAuthor && EpisodeList.Any()) { var publishedEpisodes = EpisodeList .Where(e => e.IsPublished()).ToList(); var nextSeason = ((char)(season[0] + 1)).ToString(); var nextSeasonExists = Paths.SeasonPathExists(Paths.Json, nextSeason); if (!nextSeasonExists) { var lastEpisode = publishedEpisodes.Last(); publishedEpisodes.Remove(lastEpisode); } EpisodeList = publishedEpisodes .Where(e => e.HasSummary()) .ToList(); } }
//public CommonCommand RefreshToDoListCommand //{ // get // { // return new CommonCommand((o) => // { // RefreshToDoList(); // }); // } //} public override void LoadInfo() { EpisodeList.Clear(); TargetObject.EpisodeList.ForEach(v => { EpisodeList.Add(new EpisodeViewModel() { TargetObject = v }); }); SceneList.Clear(); TargetObject.SceneList.ForEach(v => { SceneList.Add(new SceneViewModel() { TargetObject = v }); }); NoteList.Clear(); TargetObject.NoteList.ForEach(v => NoteList.Add(new NoteViewModel() { TargetObject = v })); //RefreshToDoList(); base.LoadInfo(); }
// Updates the data of a specific podcast private void btnUpdatePod_Click(object sender, EventArgs e) { try { string title = lvPods.SelectedItems[0].SubItems[1].Text; string url = tbUrl.Text; string category = cbCategory.Text; var stringFrequency = cbFrequency.SelectedItem; if (Validator.StringNotEmpty(title) && Validator.StringNotEmpty(category) && Validator.ParseFrequency(stringFrequency)) { int frequency = Int32.Parse(stringFrequency.ToString()); PodcastList.DeletePod(title); EpisodeList.DeleteEpisodes(title); DataLayerAccessor.AddPodcast(url, category, frequency); DataLayerAccessor.CreateFiles(); UpdatePodListView(); lvEpisodes.Items.Clear(); tbEpDescription.Clear(); MessageBox.Show("Podcasten uppdaterades!", "Wohoo!", MessageBoxButtons.OK, MessageBoxIcon.Information); } } catch { MessageBox.Show("Ingen podcast är vald.", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
// New RSS feed public static void RssFeed(string url, string cat, int freq) { // Reading the feed XmlReader reader = XmlReader.Create(url); SyndicationFeed feed = SyndicationFeed.Load(reader); reader.Close(); // Creating a Podcast object and adding it to PodcastList string podTitle = feed.Title.Text; int nrOfEp = feed.Items.Count(); Podcast podcast = new Podcast(url, nrOfEp, podTitle, cat, freq); PodcastList.AddPodcast(podcast); // Creating the Episodes objects and adding them to PodcastEpList foreach (SyndicationItem item in feed.Items) { string title = item.Title.Text; string description = item.Summary.Text; Episode episode = new Episode(podTitle, title, description); EpisodeList.AddEpisode(episode); } TheTimer.SetTimer(url, podTitle, cat, freq); }
public static void GetPodcastFromRss(string category, int updateFrequency, string url) { using (var reader = XmlReader.Create(url)) { try { var feed = SyndicationFeed.Load(reader); var podcastName = feed.Title.Text; int episodeCount = 0; foreach (SyndicationItem s in feed.Items) { var episodeName = s.Title.Text; var detail = s.Summary.Text; var episode = new Episode(episodeName, podcastName, detail); EpisodeList.Add(episode); episodeCount++; } PodcastList.AddPodcast(new Podcast(podcastName, category, updateFrequency, episodeCount, url)); PodcastUpdate.pUpdate(podcastName, category, updateFrequency, url); } catch (Exception) { System.Windows.Forms.MessageBox.Show("Cannot read RSS"); } } }
//Genomför en uppdatering av en podcast med en uppdaterad feed private PodCast PerformPodUpdate(PodCast p, SyndicationFeed updatedFeed) { p.Name = updatedFeed.Title.Text; p.LastUpdated = updatedFeed.LastUpdatedTime; p.Episodes = EpisodeList <Episode> .FromSyndicationItems(updatedFeed.Items); return(p); }
public ShowPage() { this.InitializeComponent(); DataContext = new ShowPageViewModel(); EpisodeList.RegisterPropertyChangedCallback(ItemsControl.ItemsSourceProperty, OnItemsSourceChanged); }
private void UpdaterTBoxEpisodeDetail(string episode) { var episodelist = EpisodeList.GetEpisodes().Where(p => p.EpisodeName.Equals(episode)).ToList(); foreach (var ep in episodelist) { rTBoxEpisodeDetail.Text = ep.overrideEpisodeDetail(); } }
public MainPage() { this.InitializeComponent(); this.NavigationCacheMode = NavigationCacheMode.Required; DataContext = new MainPageViewModel(); EpisodeList.RegisterPropertyChangedCallback(ItemsControl.ItemsSourceProperty, OnItemsSourceChanged); }
//Uppdaterar listan med podcastavsnitt private void UpdateEpisodeList(PodCast feed) { EpisodeList <Episode> epList = feed.Episodes; lvPodCastEpisodes.Items.Clear(); lvPodCastEpisodes.Items.AddRange(epList.ToListViewItems()); if (epList != null && epList.Count > 0) { UpdateEpisodeDetails(epList.Get(0)); } }
public void UpdatePodcasts(string podcast) { int updatefrequency = Convert.ToInt32(comboBoxUpdateFrequency.Text.Split(' ')[0]); PodcastList.RemovePodcast(podcast); EpisodeList.RemoveEpisode(podcast); Podcast.AddPodcast(comboBoxCategory.Text, updatefrequency, textBoxUrl.Text); UpdatelistViewPodcast(); listViewEpisodes.Items.Clear(); rTBoxEpisodeDetail.Clear(); }
public static void SaveEpisodes() { if (File.Exists("episode.txt")) { File.Delete("episode.txt"); } using (Stream stream = File.OpenWrite(Environment.CurrentDirectory + "\\episode.txt")) { new XmlSerializer(typeof(List <Episode>)).Serialize(stream, EpisodeList.GetEpisodes()); stream.Close(); } }
private void btnDelete_Click(object sender, EventArgs e) { try { string podcast = listViewPodcast.SelectedItems[0].Text; PodcastList.RemovePodcast(podcast); EpisodeList.RemoveEpisode(podcast); UpdatelistViewPodcast(); } catch (Exception) { MessageBox.Show("You must select the podcast you want to delete!"); } }
private void UpdatelistViewEpisodes(string podcast) { var episodelist = EpisodeList.GetEpisodes().Where(titel => titel.PodcastName == podcast).ToList(); listViewEpisodes.Items.Clear(); for (int i = 0; i < episodelist.Count; i++) { Episode episode = episodelist[i]; var list = new ListViewItem(new[] { episode.EpisodeName }); listViewEpisodes.Items.Add(list); } }
public static void CreateEpisodes() { if (File.Exists("episode.txt")) { XDocument.Load("episode.txt").Descendants("Episode").Select(p => new { episodeName = p.Element("EpisodeName").Value, podcastName = p.Element("PodcastName").Value, episodeDetail = p.Element("EpisodeDetail").Value, }).ToList().ForEach(p => { EpisodeList.Add(new Episode(p.episodeName, p.podcastName, p.episodeDetail)); }); } }
// Creates the episode file and puts data into it. public static void CreateEpisodeFile() { // Deleted the file if found to not leave old data in it and cause errors if (File.Exists(currentDirectory + "\\data\\Episodes.txt")) { File.Delete(currentDirectory + "\\data\\Episodes.txt"); } //Creating the file Stream stream = File.OpenWrite(currentDirectory + "\\data\\Episodes.txt"); // Writing to the file XmlSerializer serializer = new XmlSerializer(typeof(List <Episode>)); serializer.Serialize(stream, EpisodeList.GetEpList()); stream.Close(); }
private void SwitchButtonClick(object sender, RoutedEventArgs e) { var button = (Button)sender; var subject = (Model.SubjectLarge)DataContext; if (button.Content.ToString() == "SP") { EpisodeItemsControl.ItemsSource = subject.eps_special; } else { var item = (sender as FrameworkElement).DataContext; var index = SwitchButtonListView.Items.IndexOf(item); EpisodeItemsControl.ItemsSource = subject.eps_normal; EpisodeList.ScrollToVerticalOffset(index * 100 * 40); } }
// Updates the text box of the Description public void UpdateEpisodeDescription(string title) { string description = ""; List <Episode> list = EpisodeList.GetEpList(); foreach (Episode ep in list) { if (ep.Title == title) { description = ep.Description; break; } } tbEpDescription.Clear(); tbEpDescription.AppendText(description); }
// Updates the list view of the Episodes public void UpdateEpisodeListView(string title) { lvEpisodes.Items.Clear(); List <Episode> epList = EpisodeList.GetEpList(); foreach (var ep in epList) { if (ep.PodTitle == title) { var list = new ListViewItem(new[] { ep.Title }); lvEpisodes.Items.Add(list); } } }
public override void SaveInfo() { TargetObject.SceneList.Clear(); foreach (var s in SceneList) { TargetObject.SceneList.Add(s.TargetObject); } TargetObject.EpisodeList.Clear(); EpisodeList.ToList().ForEach(v => { TargetObject.EpisodeList.Add(v.TargetObject); }); TargetObject.NoteList.Clear(); NoteList.ToList().ForEach(v => TargetObject.NoteList.Add(v.TargetObject)); //TargetObject.KeyWordList.Clear(); //KeyWordList.ToList().ForEach(v => TargetObject.KeyWordList.Add(v)); base.SaveInfo(); }
// Loads the file data and puts it into the episode list class public static void GetEpisodeList() { if (File.Exists("data\\Episodes.txt")) { XDocument xdoc = XDocument.Load("data\\Episodes.txt"); xdoc.Descendants("Episode").Select(p => new { podTitle = p.Element("PodTitle").Value, title = p.Element("Title").Value, desc = p.Element("Description").Value, }).ToList().ForEach(p => { Episode ep = new Episode( p.podTitle, p.title, p.desc); EpisodeList.AddEpisode(ep); }); } }
private void insertInEpisodeList(String file) { var dir = new DirectoryInfo(file); if (dir.Parent?.Parent == null) { return; } var episodeName = dir.Name; var seasonName = dir.Parent.Name.Replace("_", ""); var path = dir.Parent.Parent.FullName; var episode = Episode.Get(path, seasonName, episodeName); if (episode != null && episode.IsPublished()) { EpisodeList.Add(episode); } }
// The timer, NOT DONE!!! private static async void TimerElapsed(object sender, System.Timers.ElapsedEventArgs e, string url, string title, string category, int frequency) { List <Podcast> list = PodcastList.GetPodList(); bool PodExists = false; int NumberOfEpisodes = 0; int OldNumberOfEpisodes = await RssReader.GetNumberOfEpisodes(url); foreach (Podcast pod in list) { if (pod.Title == title) { NumberOfEpisodes = pod.Episodes; PodExists = true; } } if (!PodExists) { timer.Enabled = false; } if (NumberOfEpisodes > OldNumberOfEpisodes) { PodcastList.DeletePod(title); EpisodeList.DeleteEpisodes(title); DataLayerAccessor.AddPodcast(url, category, frequency); CreateFile.CreatePodcastFile(); CreateFile.CreateEpisodeFile(); timer.Enabled = false; MessageBox.Show("Nytt avsnitt har hittats!", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { MessageBox.Show("Inga nya avsnitt hittades!", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Error); } PodExists = false; }
// Button to delete a podcast private void btnDeletePod_Click(object sender, EventArgs e) { try { string title = lvPods.SelectedItems[0].SubItems[1].Text; if (Validator.StringNotEmpty(title)) { PodcastList.DeletePod(title); EpisodeList.DeleteEpisodes(title); DataLayerAccessor.CreateFiles(); UpdatePodListView(); lvEpisodes.Items.Clear(); tbEpDescription.Clear(); } } catch { MessageBox.Show("Ingen podcast är vald.", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
internal void AddSeries(Uri fileUri, int fileSize, byte number) { EpisodeList.Add(new Episode($"Episode {number}", fileUri, fileSize, number)); }
public PodcastViewModel(IScreen hostScreen, IPlayerModel player, IEventAggregator eventAggregator, IDialogService dialogService, IFeedParser feedParser, IChannelStore channelStore, IPlaylistStore playlistStore) : base(eventAggregator) { HostScreen = hostScreen; Player = player; DialogService = dialogService; FeedParser = feedParser; this.channelStore = channelStore; this.playlistStore = playlistStore; GetChannelsCommand = ReactiveCommand.CreateFromTask(async _ => await GetChannels()); GetChannelsCommand.IsExecuting.ObserveOn(RxApp.MainThreadScheduler) .Subscribe(_ => OnChannelsBusy(GetChannelsCommand.GetHashCode(), _)); PlayItemCommand = ReactiveCommand.CreateFromTask <IPlayable>(async _ => await OnPlayEpisode(_ as Episode)); // open url OpenUrlDialogCommand = ReactiveCommand.CreateFromTask(async _ => await OpenUrlDialog()); OpenUrlDialogCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler) .Subscribe(_ => LogAndNotify(NotificationType.Error, Messages.ERR_CHANNEL_LOAD)); // channels busy indicator this.WhenAnyObservable(_ => _.ChannelsBusyList.CountChanged).DistinctUntilChanged() .Subscribe(_ => IsChannelsBusy = _ > 0); // episodes busy indicator this.WhenAnyObservable(_ => _.EpisodesBusyList.CountChanged).DistinctUntilChanged() .Subscribe(_ => IsEpisodesBusy = _ > 0); OpenUrlCommand = ReactiveCommand.CreateFromTask <string>(async _ => await OnOpenUrl(_)); OpenUrlCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler) .Subscribe(_ => LogAndNotify(NotificationType.Error, Messages.ERR_CHANNEL_LOAD)); // load channel LoadChannelFromUrlCommand = ReactiveCommand.CreateFromTask <string>(LoadChannelFromUrlAsync); OpenUrlCommand.IsExecuting.ObserveOn(RxApp.MainThreadScheduler).Subscribe(_ => { OnChannelsBusy(OpenUrlCommand.GetHashCode(), _); OnEpisodesBusy(OpenUrlCommand.GetHashCode(), _); }); LoadChannelFromUrlCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler) .Subscribe(_ => LogAndNotify(NotificationType.Error, Messages.ERR_CHANNEL_LOAD)); // delete channel ConfirmDeleteChannelCommand = ReactiveCommand.CreateFromTask <Channel>(async _ => await ConfirmDelete(_)); DeleteChannelCommand = ReactiveCommand.CreateFromTask <Channel>(async _ => await DeleteChannel(_)); DeleteChannelCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler) .Subscribe(_ => LogAndNotify(NotificationType.Error, Messages.ERR_CHANNEL_DELETE)); DeleteChannelCommand.IsExecuting.Subscribe(_ => { OnChannelsBusy(DeleteChannelCommand.GetHashCode(), _); OnEpisodesBusy(DeleteChannelCommand.GetHashCode(), _); }); var existsSelectedChannel = this.WhenAny(vm => vm.SelectedChannel, _ => SelectedChannel != null); this.WhenAnyValue(vm => vm.SelectedChannel).Select(_ => _ == null ? 0 : SelectedChannel.Id) .ToProperty(this, _ => _.SelectedChannelId, out selectedChannelId); RemoveFilterCommand = ReactiveCommand.Create <Unit>(_ => SelectedChannel = null, existsSelectedChannel); MarkAllPlayedCommand = ReactiveCommand.CreateFromTask <Channel>(async _ => await MarkChannelPlayed(_)); CopyUrlCommand = ReactiveCommand.Create <Channel>(_ => Clipboard.SetText(_.Link)); var episodeSet = this.WhenAnyValue(_ => _.SelectedEpisode); // detail this.WhenAnyValue(vm => vm.SelectedChannel).NotNull().Cast <IDetailEntity>() .Merge(episodeSet.Cast <IDetailEntity>()) .ToProperty(this, _ => _.CurrentDetailEntity, out currentDetailEntity); this.WhenAnyValue(vm => vm.Player.LocateCurrent).NotNull() .Subscribe(c => c.Subscribe(_ => LocatePageForCurrent())); // episode list is loading this.WhenAnyValue(_ => _.EpisodeList.IsLoading).SubscribeOn(RxApp.MainThreadScheduler) .Subscribe(_ => OnEpisodesBusy(EpisodeList.GetHashCode(), _)); ScrollIntoView = ReactiveCommand.Create <int, int>(_ => _); // playlist AddToPlaylist = ReactiveCommand.CreateFromTask <Playlist>(async _ => await AddEpisodeToPlaylist(_)); // sort order this.WhenAnyValue(_ => _.SelectedEpisodeSortOrder) .Subscribe(_ => EpisodeOrderBy.OnNext(GetEpisodeSortOrder(_))); ToggleSortDirectionCommand = ReactiveCommand.Create( () => EpisodeOrderBy.OnNext(GetEpisodeSortOrder(SelectedEpisodeSortOrder, false))); // on channels changed this.WhenAnyValue(_ => _.Channels).NotNull().Subscribe(_ => OnChannelsChanged()); // update channels var canUpdate = new BehaviorSubject <bool>(false); UpdateChannelsCommand = ReactiveCommand.CreateFromTask(async _ => await UpdateChannelsAsync(), canUpdate.DistinctUntilChanged()); UpdateChannelsCommand.IsExecuting.CombineLatest(this.WhenAnyValue(_ => _.Channels.IsEmpty), (exec, empty) => !exec && !empty && IsUpdateEnabled).DistinctUntilChanged() .Subscribe(_ => canUpdate.OnNext(_)); UpdateChannelsCommand.IsExecuting.ObserveOn(RxApp.MainThreadScheduler).Subscribe(_ => IsUpdating = _); UpdateChannelsCommand.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler) .Subscribe(_ => LogAndNotify(NotificationType.Error, Messages.ERR_CHANNEL_UPDATE)); // init episodes EpisodeList = InitEpisodeList(); EpisodeList.Changed.Subscribe(_ => InitActivePlaylist()); // detail ToggleShowDetailCommand = ReactiveCommand.Create <bool, bool>(_ => _); DeactivateCommand = ReactiveCommand.Create(() => { }); }
public void UpdateStats(bool watchedStats, bool missingEpsStats, bool updateAllGroupsAbove) { DateTime start = DateTime.Now; DateTime startOverall = DateTime.Now; logger.Info("Starting Updating STATS for SERIES {0} ({1} - {2} - {3})", this.ToString(), watchedStats, missingEpsStats, updateAllGroupsAbove); AnimeSeries_UserRepository repSeriesUser = new AnimeSeries_UserRepository(); AnimeEpisode_UserRepository repEpisodeUser = new AnimeEpisode_UserRepository(); VideoLocalRepository repVids = new VideoLocalRepository(); CrossRef_File_EpisodeRepository repXrefs = new CrossRef_File_EpisodeRepository(); JMMUserRepository repUsers = new JMMUserRepository(); List <JMMUser> allUsers = repUsers.GetAll(); DateTime startEps = DateTime.Now; List <AnimeEpisode> eps = GetAnimeEpisodes(); TimeSpan tsEps = DateTime.Now - startEps; logger.Trace("Got episodes for SERIES {0} in {1}ms", this.ToString(), tsEps.TotalMilliseconds); DateTime startVids = DateTime.Now; List <VideoLocal> vidsTemp = repVids.GetByAniDBAnimeID(this.AniDB_ID); List <CrossRef_File_Episode> crossRefs = repXrefs.GetByAnimeID(this.AniDB_ID); Dictionary <int, List <CrossRef_File_Episode> > dictCrossRefs = new Dictionary <int, List <CrossRef_File_Episode> >(); foreach (CrossRef_File_Episode xref in crossRefs) { if (!dictCrossRefs.ContainsKey(xref.EpisodeID)) { dictCrossRefs[xref.EpisodeID] = new List <CrossRef_File_Episode>(); } dictCrossRefs[xref.EpisodeID].Add(xref); } Dictionary <string, VideoLocal> dictVids = new Dictionary <string, VideoLocal>(); foreach (VideoLocal vid in vidsTemp) { dictVids[vid.Hash] = vid; } TimeSpan tsVids = DateTime.Now - startVids; logger.Trace("Got video locals for SERIES {0} in {1}ms", this.ToString(), tsVids.TotalMilliseconds); if (watchedStats) { foreach (JMMUser juser in allUsers) { //this.WatchedCount = 0; AnimeSeries_User userRecord = GetUserRecord(juser.JMMUserID); if (userRecord == null) { userRecord = new AnimeSeries_User(juser.JMMUserID, this.AnimeSeriesID); } // reset stats userRecord.UnwatchedEpisodeCount = 0; userRecord.WatchedEpisodeCount = 0; userRecord.WatchedCount = 0; userRecord.WatchedDate = null; DateTime startUser = DateTime.Now; List <AnimeEpisode_User> epUserRecords = repEpisodeUser.GetByUserID(juser.JMMUserID); Dictionary <int, AnimeEpisode_User> dictUserRecords = new Dictionary <int, AnimeEpisode_User>(); foreach (AnimeEpisode_User usrec in epUserRecords) { dictUserRecords[usrec.AnimeEpisodeID] = usrec; } TimeSpan tsUser = DateTime.Now - startUser; logger.Trace("Got user records for SERIES {0}/{1} in {2}ms", this.ToString(), juser.Username, tsUser.TotalMilliseconds); foreach (AnimeEpisode ep in eps) { // if the episode doesn't have any files then it won't count towards watched/unwatched counts List <VideoLocal> epVids = new List <VideoLocal>(); if (dictCrossRefs.ContainsKey(ep.AniDB_EpisodeID)) { foreach (CrossRef_File_Episode xref in dictCrossRefs[ep.AniDB_EpisodeID]) { if (xref.EpisodeID == ep.AniDB_EpisodeID) { if (dictVids.ContainsKey(xref.Hash)) { epVids.Add(dictVids[xref.Hash]); } } } } if (epVids.Count == 0) { continue; } if (ep.EpisodeTypeEnum == AniDBAPI.enEpisodeType.Episode || ep.EpisodeTypeEnum == AniDBAPI.enEpisodeType.Special) { AnimeEpisode_User epUserRecord = null; if (dictUserRecords.ContainsKey(ep.AnimeEpisodeID)) { epUserRecord = dictUserRecords[ep.AnimeEpisodeID]; } if (epUserRecord != null && epUserRecord.WatchedDate.HasValue) { userRecord.WatchedEpisodeCount++; } else { userRecord.UnwatchedEpisodeCount++; } if (epUserRecord != null) { if (userRecord.WatchedDate.HasValue) { if (epUserRecord.WatchedDate > userRecord.WatchedDate) { userRecord.WatchedDate = epUserRecord.WatchedDate; } } else { userRecord.WatchedDate = epUserRecord.WatchedDate; } userRecord.WatchedCount += epUserRecord.WatchedCount; } } } repSeriesUser.Save(userRecord); } } TimeSpan ts = DateTime.Now - start; logger.Trace("Updated WATCHED stats for SERIES {0} in {1}ms", this.ToString(), ts.TotalMilliseconds); start = DateTime.Now; if (missingEpsStats) { enAnimeType animeType = enAnimeType.TVSeries; AniDB_Anime aniDB_Anime = this.GetAnime(); if (aniDB_Anime != null) { animeType = aniDB_Anime.AnimeTypeEnum; } MissingEpisodeCount = 0; MissingEpisodeCountGroups = 0; // get all the group status records AniDB_GroupStatusRepository repGrpStat = new AniDB_GroupStatusRepository(); List <AniDB_GroupStatus> grpStatuses = repGrpStat.GetByAnimeID(this.AniDB_ID); // find all the episodes for which the user has a file // from this we can determine what their latest episode number is // find out which groups the user is collecting List <int> userReleaseGroups = new List <int>(); foreach (AnimeEpisode ep in eps) { List <VideoLocal> vids = new List <VideoLocal>(); if (dictCrossRefs.ContainsKey(ep.AniDB_EpisodeID)) { foreach (CrossRef_File_Episode xref in dictCrossRefs[ep.AniDB_EpisodeID]) { if (xref.EpisodeID == ep.AniDB_EpisodeID) { if (dictVids.ContainsKey(xref.Hash)) { vids.Add(dictVids[xref.Hash]); } } } } //List<VideoLocal> vids = ep.VideoLocals; foreach (VideoLocal vid in vids) { AniDB_File anifile = vid.GetAniDBFile(); if (anifile != null) { if (!userReleaseGroups.Contains(anifile.GroupID)) { userReleaseGroups.Add(anifile.GroupID); } } } } int latestLocalEpNumber = 0; EpisodeList epReleasedList = new EpisodeList(animeType); EpisodeList epGroupReleasedList = new EpisodeList(animeType); foreach (AnimeEpisode ep in eps) { //List<VideoLocal> vids = ep.VideoLocals; if (ep.EpisodeTypeEnum != AniDBAPI.enEpisodeType.Episode) { continue; } List <VideoLocal> vids = new List <VideoLocal>(); if (dictCrossRefs.ContainsKey(ep.AniDB_EpisodeID)) { foreach (CrossRef_File_Episode xref in dictCrossRefs[ep.AniDB_EpisodeID]) { if (xref.EpisodeID == ep.AniDB_EpisodeID) { if (dictVids.ContainsKey(xref.Hash)) { vids.Add(dictVids[xref.Hash]); } } } } AniDB_Episode aniEp = ep.AniDB_Episode; int thisEpNum = aniEp.EpisodeNumber; if (thisEpNum > latestLocalEpNumber && vids.Count > 0) { latestLocalEpNumber = thisEpNum; } // does this episode have a file released // does this episode have a file released by the group the user is collecting bool epReleased = false; bool epReleasedGroup = false; foreach (AniDB_GroupStatus gs in grpStatuses) { if (gs.LastEpisodeNumber >= thisEpNum) { epReleased = true; } if (userReleaseGroups.Contains(gs.GroupID) && gs.HasGroupReleasedEpisode(thisEpNum)) { epReleasedGroup = true; } } try { epReleasedList.Add(ep, (!epReleased || vids.Count != 0)); epGroupReleasedList.Add(ep, (!epReleasedGroup || vids.Count != 0)); } catch (Exception e) { logger.Trace("Error {0}", e.ToString()); throw; } } foreach (EpisodeList.StatEpisodes eplst in epReleasedList) { if (!eplst.Available) { MissingEpisodeCount++; } } foreach (EpisodeList.StatEpisodes eplst in epGroupReleasedList) { if (!eplst.Available) { MissingEpisodeCountGroups++; } } this.LatestLocalEpisodeNumber = latestLocalEpNumber; } ts = DateTime.Now - start; logger.Trace("Updated MISSING EPS stats for SERIES {0} in {1}ms", this.ToString(), ts.TotalMilliseconds); start = DateTime.Now; AnimeSeriesRepository rep = new AnimeSeriesRepository(); rep.Save(this); if (updateAllGroupsAbove) { foreach (AnimeGroup grp in AllGroupsAbove) { grp.UpdateStats(watchedStats, missingEpsStats); } } ts = DateTime.Now - start; logger.Trace("Updated GROUPS ABOVE stats for SERIES {0} in {1}ms", this.ToString(), ts.TotalMilliseconds); start = DateTime.Now; TimeSpan tsOverall = DateTime.Now - startOverall; logger.Info("Finished Updating STATS for SERIES {0} in {1}ms ({2} - {3} - {4})", this.ToString(), tsOverall.TotalMilliseconds, watchedStats, missingEpsStats, updateAllGroupsAbove); }