public static bool PlayEpisode(FileLocal episode) { if (player == null) { player = new VideoHandler(); } return(player.ResumeOrPlay(episode)); }
/// <summary> /// Shows the Rate Episode Dialog after playback has ended /// </summary> /// <param name="episode">The episode being rated</param> private void ShowRateDialog(FileLocal episode) { new Thread((o) => { FileLocal epToRate = o as FileLocal; if (epToRate == null) { return; } string seriesid = null; int seasonidx = 0; int episodeidx = 0; if (epToRate.AnimeEpisodes == null || epToRate.AnimeEpisodes.Count == 0 || !GetTVDBEpisodeInfo(epToRate.AnimeEpisodes[0], out seriesid, out seasonidx, out episodeidx)) { TraktLogger.Warning("Unable to rate episode, no AniDb/TVDb reference in database yet."); return; } if (!TraktSettings.ShowRateDialogOnWatched) { return; // not enabled } if (epToRate.AnimeEpisodes[0].UserRating > 0) { return; // already rated } TraktLogger.Debug("Showing rate dialog for '{0}'", epToRate.AnimeEpisodes[0].EpisodeName); TraktRateEpisode rateObject = new TraktRateEpisode { Title = epToRate.AniDB_File.AnimeSeries.SeriesName, Year = GetStartYear(epToRate.AniDB_File.AnimeSeries), Season = seasonidx.ToString(), Episode = episodeidx.ToString(), SeriesID = seriesid, UserName = TraktSettings.Username, Password = TraktSettings.Password }; // get the rating submitted to trakt int rating = int.Parse(GUIUtils.ShowRateDialog <TraktRateEpisode>(rateObject)); if (rating > 0) { TraktLogger.Debug("Rating {0} as {1}/10", epToRate.AnimeEpisodes[0].EpisodeName, rating.ToString()); // note: can't set rating locally as its read only } }) { Name = "Rate", IsBackground = true }.Start(episode); }
/// <summary> /// Playback an episode using My Anime internal Video Handler /// </summary> /// <param name="seriesid">series id of episode</param> /// <param name="seasonid">season index</param> /// <param name="episodeid">episode index</param> public static bool PlayEpisode(int seriesid, int seasonid, int episodeid) { var episodes = FileLocal.GetAll(); var episode = episodes.FirstOrDefault(e => e.AnimeEpisodes.Where(ae => ae.Series.TvDB_Episodes.Where(te => te.SeriesID == seriesid && te.SeasonNumber == seasonid && te.EpisodeNumber == episodeid).Count() == 1).Count() == 1); if (episode == null || string.IsNullOrEmpty(episode.FileNameFull)) { return(false); } return(PlayEpisode(episode)); }
/// <summary> /// Playback the first unwatched episode for a series using TVSeries internal Video Handler /// If no Unwatched episodes exists, play the Most Recently Aired /// </summary> /// <param name="seriesid">series id of episode</param> public static bool PlayFirstUnwatchedEpisode(int seriesid) { var episodes = FileLocal.GetAll(); if (episodes == null || episodes.Count == 0) { return(false); } // filter out anything we can't play episodes.RemoveAll(e => string.IsNullOrEmpty(e.FileNameFull)); if (episodes.Count == 0) { return(false); } // filter by tvdb series id episodes.RemoveAll(e => e.AniDB_File == null || e.AniDB_File.AnimeSeries.TvDB_ID != seriesid); TraktLogger.Info("Found {0} local episodes for TVDb {1}", episodes.Count, seriesid.ToString()); if (episodes.Count == 0) { return(false); } // sort by air date episodes.Sort(new Comparison <FileLocal>((x, y) => { return(x.AnimeEpisodes.First().AniDB_Episode.AirDate.CompareTo(y.AnimeEpisodes.First().AniDB_Episode.AirDate)); })); // filter out watched var episode = episodes.Where(e => e.AnimeEpisodes.First().IsWatched == 0).FirstOrDefault(); if (episode == null) { TraktLogger.Info("No Unwatched episodes found, Playing most recent episode"); episode = episodes.LastOrDefault(); } if (episode == null) { return(false); } return(PlayEpisode(episode)); }
private TraktEpisodeScrobble CreateScrobbleData(FileLocal episode) { string seriesid = null; int seasonidx = 0; int episodeidx = 0; if (episode.AnimeEpisodes == null || episode.AnimeEpisodes.Count == 0 || !GetTVDBEpisodeInfo(episode.AnimeEpisodes[0], out seriesid, out seasonidx, out episodeidx)) { TraktLogger.Warning("Unable to scrobble episodes, no AniDb/TVDb reference in database yet. Episode will be manually marked as seen on sync when available."); return(null); } // create scrobble data try { TraktEpisodeScrobble scrobbleData = new TraktEpisodeScrobble { Title = episode.AniDB_File.AnimeSeries.SeriesName, Year = GetStartYear(episode.AniDB_File.AnimeSeries), Season = seasonidx.ToString(), Episode = episodeidx.ToString(), SeriesID = seriesid, PluginVersion = TraktSettings.Version, MediaCenter = "Mediaportal", MediaCenterVersion = Assembly.GetEntryAssembly().GetName().Version.ToString(), MediaCenterBuildDate = String.Empty, UserName = TraktSettings.Username, Password = TraktSettings.Password }; return(scrobbleData); } catch { TraktLogger.Error("Failed to create scrobble data for '{0}'", episode.ToString()); return(null); } }
/// <summary> /// Confirm that my anime episode exists in our trakt collection /// </summary> /// <param name="traktEpisodes">trakt episode collection</param> /// <param name="episode">tvseries episode object</param> /// <returns>true if episode exists</returns> private bool TraktEpisodeExists(IEnumerable <TraktLibraryShow> traktEpisodes, FileLocal episode) { string seriesid = null; int seasonidx = 0; int episodeidx = 0; if (GetTVDBEpisodeInfo(episode.AnimeEpisodes[0], out seriesid, out seasonidx, out episodeidx)) { var items = traktEpisodes.Where(s => s.SeriesId == seriesid && s.Seasons.Where(e => e.Season == seasonidx && e.Episodes.Contains(episodeidx)).Count() == 1); return(items.Count() == 1); } return(false); }
public void SyncLibrary() { TraktLogger.Info("My Anime Starting Sync"); #region Get online data // get all episodes on trakt that are marked as in 'collection' IEnumerable <TraktLibraryShow> traktCollectionEpisodes = TraktAPI.TraktAPI.GetLibraryEpisodesForUser(TraktSettings.Username); if (traktCollectionEpisodes == null) { TraktLogger.Error("Error getting show collection from trakt server, cancelling sync."); return; } TraktLogger.Info("{0} tvshows in trakt collection", traktCollectionEpisodes.Count().ToString()); // get all episodes on trakt that are marked as 'seen' or 'watched' IEnumerable <TraktLibraryShow> traktWatchedEpisodes = TraktAPI.TraktAPI.GetWatchedEpisodesForUser(TraktSettings.Username); if (traktWatchedEpisodes == null) { TraktLogger.Error("Error getting shows watched from trakt server, cancelling sync."); return; } TraktLogger.Info("{0} tvshows with watched episodes in trakt library", traktWatchedEpisodes.Count().ToString()); // get all episodes on trakt that are marked as 'unseen' IEnumerable <TraktLibraryShow> traktUnSeenEpisodes = TraktAPI.TraktAPI.GetUnSeenEpisodesForUser(TraktSettings.Username); if (traktUnSeenEpisodes == null) { TraktLogger.Error("Error getting shows unseen from trakt server, cancelling sync."); return; } TraktLogger.Info("{0} tvshows with unseen episodes in trakt library", traktUnSeenEpisodes.Count().ToString()); #endregion #region Get local data List <FileLocal> localCollectionEpisodes = new List <FileLocal>(); List <FileLocal> localWatchedEpisodes = new List <FileLocal>(); // Get all local episodes in database localCollectionEpisodes = FileLocal.GetAll().Where(f => !string.IsNullOrEmpty(f.FileNameFull) && f.AnimeEpisodes.Count > 0).ToList(); TraktLogger.Info("{0} episodes with local files in my anime database", localCollectionEpisodes.Count.ToString()); // Get only Valid Episodes types localCollectionEpisodes.RemoveAll(lc => lc.AnimeEpisodes.Where(e => (e.EpisodeTypeEnum != enEpisodeType.Normal && e.EpisodeTypeEnum != enEpisodeType.Special)).Count() > 0); TraktLogger.Info("{0} episodes with valid episode types in my anime database", localCollectionEpisodes.Count.ToString()); // Get watched episodes localWatchedEpisodes = localCollectionEpisodes.Where(f => (f.AniDB_File != null && f.AniDB_File.IsWatched > 0) || (f.AnimeEpisodes != null && f.AnimeEpisodes[0].IsWatched > 0)).ToList(); TraktLogger.Info("{0} episodes watched in my anime database", localWatchedEpisodes.Count.ToString()); #endregion #region Sync collection/library to trakt // get list of episodes that we have not already trakt'd List <FileLocal> localEpisodesToSync = new List <FileLocal>(localCollectionEpisodes); foreach (FileLocal ep in localCollectionEpisodes) { if (TraktEpisodeExists(traktCollectionEpisodes, ep)) { // no interest in syncing, remove localEpisodesToSync.Remove(ep); } } // sync unseen episodes TraktLogger.Info("{0} episodes need to be added to Library", localEpisodesToSync.Count.ToString()); SyncLibrary(localEpisodesToSync, TraktSyncModes.library); #endregion #region Sync seen to trakt // get list of episodes that we have not already trakt'd // filter out any marked as UnSeen List <FileLocal> localWatchedEpisodesToSync = new List <FileLocal>(localWatchedEpisodes); foreach (FileLocal ep in localWatchedEpisodes) { if (TraktEpisodeExists(traktWatchedEpisodes, ep) || TraktEpisodeExists(traktUnSeenEpisodes, ep)) { // no interest in syncing, remove localWatchedEpisodesToSync.Remove(ep); } } // sync seen episodes TraktLogger.Info("{0} episodes need to be added to SeenList", localWatchedEpisodesToSync.Count.ToString()); SyncLibrary(localWatchedEpisodesToSync, TraktSyncModes.seen); #endregion #region Sync watched flags from trakt locally // Sync watched flags from trakt to local database // do not mark as watched locally if UnSeen on trakt foreach (FileLocal ep in localCollectionEpisodes.Where(e => e.AnimeEpisodes[0].IsWatched == 0)) { if (TraktEpisodeExists(traktWatchedEpisodes, ep) && !TraktEpisodeExists(traktUnSeenEpisodes, ep)) { // mark episode as watched TraktLogger.Info("Marking episode '{0}' as watched", ep.ToString()); ep.AnimeEpisodes[0].ToggleWatchedStatus(true, false); } } #endregion #region Sync unseen flags from trakt locally foreach (FileLocal ep in localCollectionEpisodes.Where(e => e.AnimeEpisodes[0].IsWatched > 1)) { if (TraktEpisodeExists(traktUnSeenEpisodes, ep)) { // mark episode as unwatched TraktLogger.Info("Marking episode '{0}' as unwatched", ep.ToString()); ep.AnimeEpisodes[0].ToggleWatchedStatus(false, false); } } #endregion #region Clean Library if (TraktSettings.KeepTraktLibraryClean && TraktSettings.TvShowPluginCount == 1) { TraktLogger.Info("Removing shows From Trakt Collection no longer in database"); // if we no longer have a file reference in database remove from library foreach (var series in traktCollectionEpisodes) { TraktEpisodeSync syncData = GetEpisodesForTraktRemoval(series, localCollectionEpisodes.Where(e => e.AniDB_File.AnimeSeries.TvDB_ID.ToString() == series.SeriesId).ToList()); if (syncData == null) { continue; } TraktResponse response = TraktAPI.TraktAPI.SyncEpisodeLibrary(syncData, TraktSyncModes.unlibrary); TraktAPI.TraktAPI.LogTraktResponse(response); Thread.Sleep(500); } } #endregion TraktLogger.Info("My Anime Sync Completed"); }
public bool Scrobble(string filename) { StopScrobble(); // stop check if not valid player type for plugin handler if (g_Player.IsTV || g_Player.IsTVRecording) { return(false); } // lookup episode by filename List <FileLocal> files = FileLocal.GetAll(); FileLocal file = files.FirstOrDefault(f => f.FileNameFull == filename); if (file == null) { return(false); } CurrentEpisode = file; TraktLogger.Info("Detected episode playing in My Anime: '{0}'", CurrentEpisode.ToString()); // create 15 minute timer to send watching status #region scrobble timer TraktTimer = new Timer(new TimerCallback((stateInfo) => { Thread.CurrentThread.Name = "Scrobble"; FileLocal episode = stateInfo as FileLocal; if (episode == null) { return; } // duration in minutes double duration = g_Player.Duration / 60; double progress = 0.0; // get current progress of player (in seconds) to work out percent complete if (g_Player.Duration > 0.0) { progress = (g_Player.CurrentPosition / g_Player.Duration) * 100.0; } TraktEpisodeScrobble scrobbleData = CreateScrobbleData(CurrentEpisode); if (scrobbleData == null) { return; } // set duration/progress in scrobble data scrobbleData.Duration = Convert.ToInt32(duration).ToString(); scrobbleData.Progress = Convert.ToInt32(progress).ToString(); // set watching status on trakt TraktResponse response = TraktAPI.TraktAPI.ScrobbleEpisodeState(scrobbleData, TraktScrobbleStates.watching); TraktAPI.TraktAPI.LogTraktResponse(response); }), CurrentEpisode, 3000, 900000); #endregion return(true); }
public void StopScrobble() { if (TraktTimer != null) { TraktTimer.Dispose(); } if (CurrentEpisode == null) { return; } #region Scrobble Thread scrobbleEpisode = new Thread(delegate(object o) { FileLocal episode = o as FileLocal; if (episode == null) { return; } TraktLogger.Info("My Anime episode considered watched '{0}'", episode.ToString()); // get scrobble data to send to api TraktEpisodeScrobble scrobbleData = CreateScrobbleData(episode); if (scrobbleData == null) { return; } // set duration/progress in scrobble data scrobbleData.Duration = Convert.ToInt32(g_Player.Duration / 60).ToString(); scrobbleData.Progress = "100"; TraktResponse response = TraktAPI.TraktAPI.ScrobbleEpisodeState(scrobbleData, TraktScrobbleStates.scrobble); TraktAPI.TraktAPI.LogTraktResponse(response); }) { IsBackground = true, Name = "Scrobble" }; #endregion // if episode is atleast 90% complete, consider watched if ((g_Player.CurrentPosition / g_Player.Duration) >= 0.9) { ShowRateDialog(CurrentEpisode); scrobbleEpisode.Start(CurrentEpisode); } else { #region Cancel Watching TraktLogger.Info("Stopped My Anime episode playback '{0}'", CurrentEpisode.ToString()); // stop scrobbling Thread cancelWatching = new Thread(delegate() { TraktEpisodeScrobble scrobbleData = new TraktEpisodeScrobble { UserName = TraktSettings.Username, Password = TraktSettings.Password }; TraktResponse response = TraktAPI.TraktAPI.ScrobbleEpisodeState(scrobbleData, TraktScrobbleStates.cancelwatching); TraktAPI.TraktAPI.LogTraktResponse(response); }) { IsBackground = true, Name = "CancelWatching" }; #endregion cancelWatching.Start(); } CurrentEpisode = null; }
/// <summary> /// Shows the Rate Episode Dialog after playback has ended /// </summary> /// <param name="episode">The episode being rated</param> private void ShowRateDialog(FileLocal episode) { new Thread((o) => { FileLocal epToRate = o as FileLocal; if (epToRate == null) return; string seriesid = null; int seasonidx = 0; int episodeidx = 0; if (epToRate.AnimeEpisodes == null || epToRate.AnimeEpisodes.Count == 0 || !GetTVDBEpisodeInfo(epToRate.AnimeEpisodes[0], out seriesid, out seasonidx, out episodeidx)) { TraktLogger.Warning("Unable to rate episode, no AniDb/TVDb reference in database yet."); return; } if (!TraktSettings.ShowRateDialogOnWatched) return; // not enabled if (epToRate.AnimeEpisodes[0].UserRating > 0) return; // already rated TraktLogger.Debug("Showing rate dialog for '{0}'", epToRate.AnimeEpisodes[0].EpisodeName); TraktRateEpisode rateObject = new TraktRateEpisode { Title = epToRate.AniDB_File.AnimeSeries.SeriesName, Year = GetStartYear(epToRate.AniDB_File.AnimeSeries), Season = seasonidx.ToString(), Episode = episodeidx.ToString(), SeriesID = seriesid, UserName = TraktSettings.Username, Password = TraktSettings.Password }; // get the rating submitted to trakt int rating = int.Parse(GUIUtils.ShowRateDialog<TraktRateEpisode>(rateObject)); if (rating > 0) { TraktLogger.Debug("Rating {0} as {1}/10", epToRate.AnimeEpisodes[0].EpisodeName, rating.ToString()); // note: can't set rating locally as its read only } }) { Name = "Rate", IsBackground = true }.Start(episode); }
/// <summary> /// Confirm that my anime episode exists in our trakt collection /// </summary> /// <param name="traktEpisodes">trakt episode collection</param> /// <param name="episode">tvseries episode object</param> /// <returns>true if episode exists</returns> private bool TraktEpisodeExists(IEnumerable<TraktLibraryShow> traktEpisodes, FileLocal episode) { string seriesid = null; int seasonidx = 0; int episodeidx = 0; if (GetTVDBEpisodeInfo(episode.AnimeEpisodes[0], out seriesid, out seasonidx, out episodeidx)) { var items = traktEpisodes.Where(s => s.SeriesId == seriesid && s.Seasons.Where(e => e.Season == seasonidx && e.Episodes.Contains(episodeidx)).Count() == 1); return items.Count() == 1; } return false; }
private TraktEpisodeScrobble CreateScrobbleData(FileLocal episode) { string seriesid = null; int seasonidx = 0; int episodeidx = 0; if (episode.AnimeEpisodes == null || episode.AnimeEpisodes.Count == 0 || !GetTVDBEpisodeInfo(episode.AnimeEpisodes[0], out seriesid, out seasonidx, out episodeidx)) { TraktLogger.Warning("Unable to scrobble episodes, no AniDb/TVDb reference in database yet. Episode will be manually marked as seen on sync when available."); return null; } // create scrobble data try { TraktEpisodeScrobble scrobbleData = new TraktEpisodeScrobble { Title = episode.AniDB_File.AnimeSeries.SeriesName, Year = GetStartYear(episode.AniDB_File.AnimeSeries), Season = seasonidx.ToString(), Episode = episodeidx.ToString(), SeriesID = seriesid, PluginVersion = TraktSettings.Version, MediaCenter = "Mediaportal", MediaCenterVersion = Assembly.GetEntryAssembly().GetName().Version.ToString(), MediaCenterBuildDate = String.Empty, UserName = TraktSettings.Username, Password = TraktSettings.Password }; return scrobbleData; } catch { TraktLogger.Error("Failed to create scrobble data for '{0}'", episode.ToString()); return null; } }
public void StopScrobble() { if (TraktTimer != null) TraktTimer.Dispose(); if (CurrentEpisode == null) return; #region Scrobble Thread scrobbleEpisode = new Thread(delegate(object o) { FileLocal episode = o as FileLocal; if (episode == null) return; TraktLogger.Info("My Anime episode considered watched '{0}'", episode.ToString()); // get scrobble data to send to api TraktEpisodeScrobble scrobbleData = CreateScrobbleData(episode); if (scrobbleData == null) return; // set duration/progress in scrobble data scrobbleData.Duration = Convert.ToInt32(g_Player.Duration / 60).ToString(); scrobbleData.Progress = "100"; TraktResponse response = TraktAPI.TraktAPI.ScrobbleEpisodeState(scrobbleData, TraktScrobbleStates.scrobble); TraktAPI.TraktAPI.LogTraktResponse(response); }) { IsBackground = true, Name = "Scrobble" }; #endregion // if episode is atleast 90% complete, consider watched if ((g_Player.CurrentPosition / g_Player.Duration) >= 0.9) { ShowRateDialog(CurrentEpisode); scrobbleEpisode.Start(CurrentEpisode); } else { #region Cancel Watching TraktLogger.Info("Stopped My Anime episode playback '{0}'", CurrentEpisode.ToString()); // stop scrobbling Thread cancelWatching = new Thread(delegate() { TraktEpisodeScrobble scrobbleData = new TraktEpisodeScrobble { UserName = TraktSettings.Username, Password = TraktSettings.Password }; TraktResponse response = TraktAPI.TraktAPI.ScrobbleEpisodeState(scrobbleData, TraktScrobbleStates.cancelwatching); TraktAPI.TraktAPI.LogTraktResponse(response); }) { IsBackground = true, Name = "CancelWatching" }; #endregion cancelWatching.Start(); } CurrentEpisode = null; }
public bool Scrobble(string filename) { StopScrobble(); // stop check if not valid player type for plugin handler if (g_Player.IsTV || g_Player.IsTVRecording) return false; // lookup episode by filename List<FileLocal> files = FileLocal.GetAll(); FileLocal file = files.FirstOrDefault(f => f.FileNameFull == filename); if (file == null) return false; CurrentEpisode = file; TraktLogger.Info("Detected episode playing in My Anime: '{0}'", CurrentEpisode.ToString()); // create 15 minute timer to send watching status #region scrobble timer TraktTimer = new Timer(new TimerCallback((stateInfo) => { Thread.CurrentThread.Name = "Scrobble"; FileLocal episode = stateInfo as FileLocal; if (episode == null) return; // duration in minutes double duration = g_Player.Duration / 60; double progress = 0.0; // get current progress of player (in seconds) to work out percent complete if (g_Player.Duration > 0.0) progress = (g_Player.CurrentPosition / g_Player.Duration) * 100.0; TraktEpisodeScrobble scrobbleData = CreateScrobbleData(CurrentEpisode); if (scrobbleData == null) return; // set duration/progress in scrobble data scrobbleData.Duration = Convert.ToInt32(duration).ToString(); scrobbleData.Progress = Convert.ToInt32(progress).ToString(); // set watching status on trakt TraktResponse response = TraktAPI.TraktAPI.ScrobbleEpisodeState(scrobbleData, TraktScrobbleStates.watching); TraktAPI.TraktAPI.LogTraktResponse(response); }), CurrentEpisode, 3000, 900000); #endregion return true; }
public static bool PlayEpisode(FileLocal episode) { if (player == null) player = new VideoHandler(); return player.ResumeOrPlay(episode); }
private TraktEpisodeScrobble CreateScrobbleData(FileLocal episode) { string seriesid = null; int seasonidx = 0; int episodeidx = 0; if (!GetTVDBEpisodeInfo(episode.AnimeEpisodes[0], out seriesid, out seasonidx, out episodeidx)) return null; // create scrobble data try { TraktEpisodeScrobble scrobbleData = new TraktEpisodeScrobble { Title = episode.AniDB_File.AnimeSeries.SeriesName, Year = GetStartYear(episode.AniDB_File.AnimeSeries), Season = seasonidx.ToString(), Episode = episodeidx.ToString(), SeriesID = seriesid, PluginVersion = TraktSettings.Version, MediaCenter = "Mediaportal", MediaCenterVersion = Assembly.GetEntryAssembly().GetName().Version.ToString(), MediaCenterBuildDate = String.Empty, UserName = TraktSettings.Username, Password = TraktSettings.Password }; return scrobbleData; } catch { TraktLogger.Error("Failed to create scrobble data for '{0}'", episode.ToString()); return null; } }