/// <summary> /// Scrobbles a episode from a videoInfo object /// </summary> /// <returns>returns true if successfully scrobbled</returns> public static bool ScrobbleEpisode(VideoInfo videoInfo, TraktScrobbleStates state) { // get scrobble data to send to api TraktEpisodeScrobble scrobbleData = CreateEpisodeScrobbleData(videoInfo); if (scrobbleData == null) { return(false); } // get duration/position in minutes double duration = videoInfo.Runtime > 0.0 ? videoInfo.Runtime : g_Player.Duration / 60; double position = g_Player.CurrentPosition / 60; double progress = 0.0; if (duration > 0.0) { progress = (position / duration) * 100.0; } // sometimes with recordings/timeshifting we can get invalid player properties // adjust if duration is less than a typical episode scrobbleData.Duration = (duration < 10.0) ? "30" : Convert.ToInt32(duration).ToString(); scrobbleData.Progress = (state == TraktScrobbleStates.scrobble) ? "100" : Convert.ToInt32(progress).ToString(); TraktResponse response = TraktAPI.TraktAPI.ScrobbleEpisodeState(scrobbleData, state); return(TraktLogger.LogTraktResponse(response)); }
/// <summary> /// Scrobbles a movie from a videoInfo object /// </summary> /// <returns>returns true if successfully scrobbled</returns> public static bool ScrobbleMovie(VideoInfo videoInfo, TraktScrobbleStates state) { TraktMovieScrobble scrobbleData = CreateMovieScrobbleData(videoInfo); if (scrobbleData == null) return false; // get duration/position in minutes double duration = videoInfo.Runtime > 0.0 ? videoInfo.Runtime : g_Player.Duration / 60; double position = g_Player.CurrentPosition / 60; double progress = 0.0; if (duration > 0.0) progress = (position / duration) * 100.0; // sometimes with recordings/timeshifting we can get inaccurate player properties // adjust if duration is less than a typical movie scrobbleData.Duration = (duration < 15.0) ? "60" : Convert.ToInt32(duration).ToString(); scrobbleData.Progress = (state == TraktScrobbleStates.scrobble) ? "100" : Convert.ToInt32(progress).ToString(); TraktResponse response = TraktAPI.TraktAPI.ScrobbleMovieState(scrobbleData, state); return TraktAPI.TraktAPI.LogTraktResponse(response); }
/// <summary> /// Creates Scrobble data based on a DBMovieInfo object /// </summary> /// <param name="psc"></param> /// <param name="pc">PlayerContext</param> /// <param name="starting"></param> /// <param name="scrobbleData"></param> /// <param name="state"></param> /// <returns>The Trakt scrobble data to send</returns> private bool TryCreateScrobbleData(IPlayerSlotController psc, IPlayerContext pc, bool starting, out AbstractScrobble scrobbleData, out TraktScrobbleStates state) { scrobbleData = null; state = starting ? TraktScrobbleStates.watching : TraktScrobbleStates.scrobble; if (_settings.Settings.Authentication == null) return false; string username = _settings.Settings.Authentication.Username; string password = _settings.Settings.Authentication.Password; if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password)) return false; // For canceling the watching, it is to have no TraktMovieScrobble. if (pc.CurrentMediaItem == null) { if (starting) return false; state = TraktScrobbleStates.cancelwatching; return true; } bool isMovie = pc.CurrentMediaItem.Aspects.ContainsKey(MovieAspect.ASPECT_ID); bool isSeries = pc.CurrentMediaItem.Aspects.ContainsKey(SeriesAspect.ASPECT_ID); if (!isMovie && !isSeries) return false; string title = pc.CurrentPlayer != null ? pc.CurrentPlayer.MediaItemTitle : null; IMediaPlaybackControl pmc = pc.CurrentPlayer as IMediaPlaybackControl; TimeSpan currentPosition; if (pmc != null) { _progressUpdateWorks[psc].Duration = pmc.Duration; currentPosition = pmc.CurrentTime; } else { // Player is already removed on stopping, so take the resume position if available currentPosition = _progressUpdateWorks[psc].ResumePosition; } int progress = currentPosition == TimeSpan.Zero ? (starting ? 0 : 100) : Math.Min((int)(currentPosition.TotalSeconds * 100 / _progressUpdateWorks[psc].Duration.TotalSeconds), 100); string value; int iValue; DateTime dtValue; long lValue; if (isMovie) { TraktMovieScrobble movie = new TraktMovieScrobble(); if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, MovieAspect.ATTR_IMDB_ID, out value) && !string.IsNullOrWhiteSpace(value)) movie.IMDBID = value; if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, MovieAspect.ATTR_TMDB_ID, out iValue) && iValue > 0) movie.TMDBID = iValue.ToString(); if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, MediaAspect.ATTR_RECORDINGTIME, out dtValue)) movie.Year = dtValue.Year.ToString(); if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, MovieAspect.ATTR_RUNTIME_M, out iValue) && iValue > 0) movie.Duration = iValue.ToString(); scrobbleData = movie; } if (isSeries) { TraktEpisodeScrobble series = new TraktEpisodeScrobble(); if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, SeriesAspect.ATTR_IMDB_ID, out value) && !string.IsNullOrWhiteSpace(value)) series.IMDBID = value; if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, SeriesAspect.ATTR_TVDB_ID, out iValue)) series.SeriesID = iValue.ToString(); if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, SeriesAspect.ATTR_SERIESNAME, out value) && !string.IsNullOrWhiteSpace(value)) series.Title = value; if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, SeriesAspect.ATTR_FIRSTAIRED, out dtValue)) series.Year = dtValue.Year.ToString(); if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, SeriesAspect.ATTR_SEASON, out iValue)) series.Season = iValue.ToString(); List<int> intList; if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, SeriesAspect.ATTR_EPISODE, out intList) && intList.Any()) series.Episode = intList.First().ToString(); // TODO: multi episode files?! scrobbleData = series; } // Fallback duration info if (string.IsNullOrWhiteSpace(scrobbleData.Duration) && MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, VideoAspect.ATTR_DURATION, out lValue) && lValue > 0) scrobbleData.Duration = (lValue / 60).ToString(); if (string.IsNullOrWhiteSpace(scrobbleData.Title)) scrobbleData.Title = title; scrobbleData.Progress = progress.ToString(); if (!starting && progress < WATCHED_PERCENT) state = TraktScrobbleStates.cancelwatching; scrobbleData.PluginVersion = TraktSettings.Version; scrobbleData.MediaCenter = "MediaPortal 2"; scrobbleData.MediaCenterVersion = Assembly.GetEntryAssembly().GetName().Version.ToString(); scrobbleData.MediaCenterBuildDate = String.Empty; scrobbleData.Username = username; scrobbleData.Password = password; return true; }
/// <summary> /// Scrobbles a given movie /// </summary> /// <param name="movie">Movie to Scrobble</param> /// <param name="state">Scrobbling mode to use</param> private void ScrobbleHandler(DBMovieInfo movie, TraktScrobbleStates state) { TraktLogger.Debug("Scrobbling Movie {0}", movie.Title); // MovingPictures stores duration in milliseconds, g_Player reports in seconds Double currentPosition = g_Player.CurrentPosition; Double duration = movie.ActualRuntime == 0 ? g_Player.Duration : movie.ActualRuntime / 1000.0; // extra checks for runtime in case both movpics and g_player reports incorrect // runtime for online field (if available) is in minutes if (duration == 0.0) duration = movie.Runtime * 60.0; Double percentageCompleted = duration != 0.0 ? (currentPosition / duration * 100.0) : 0.0; TraktLogger.Debug(string.Format("Percentage of {0} is {1}%", movie.Title, percentageCompleted.ToString("N2"))); //Create Scrobbling Data TraktMovieScrobble scrobbleData = CreateScrobbleData(movie); if (scrobbleData != null) { // duration is reported in minutes scrobbleData.Duration = Convert.ToInt32(duration / 60).ToString(); scrobbleData.Progress = Convert.ToInt32(percentageCompleted).ToString(); BackgroundWorker scrobbler = new BackgroundWorker(); scrobbler.DoWork += new DoWorkEventHandler(scrobbler_DoWork); scrobbler.RunWorkerCompleted += new RunWorkerCompletedEventHandler(scrobbler_RunWorkerCompleted); scrobbler.RunWorkerAsync(new MovieScrobbleAndMode { MovieScrobble = scrobbleData, ScrobbleState = state }); } }
/// <summary> /// Creates Scrobble data based on a DBMovieInfo object /// </summary> /// <param name="psc"></param> /// <param name="pc">PlayerContext</param> /// <param name="starting"></param> /// <param name="scrobbleData"></param> /// <param name="state"></param> /// <returns>The Trakt scrobble data to send</returns> private bool TryCreateScrobbleData(IPlayerSlotController psc, IPlayerContext pc, bool starting, out AbstractScrobble scrobbleData, out TraktScrobbleStates state) { scrobbleData = null; state = starting ? TraktScrobbleStates.watching : TraktScrobbleStates.scrobble; if (_settings.Settings.Authentication == null) { return(false); } string username = _settings.Settings.Authentication.Username; string password = _settings.Settings.Authentication.Password; if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password)) { return(false); } // For canceling the watching, it is to have no TraktMovieScrobble. if (pc.CurrentMediaItem == null) { if (starting) { return(false); } state = TraktScrobbleStates.cancelwatching; return(true); } bool isMovie = pc.CurrentMediaItem.Aspects.ContainsKey(MovieAspect.ASPECT_ID); bool isSeries = pc.CurrentMediaItem.Aspects.ContainsKey(SeriesAspect.ASPECT_ID); if (!isMovie && !isSeries) { return(false); } string title = pc.CurrentPlayer != null ? pc.CurrentPlayer.MediaItemTitle : null; IMediaPlaybackControl pmc = pc.CurrentPlayer as IMediaPlaybackControl; TimeSpan currentPosition; if (pmc != null) { _progressUpdateWorks[psc].Duration = pmc.Duration; currentPosition = pmc.CurrentTime; } else { // Player is already removed on stopping, so take the resume position if available currentPosition = _progressUpdateWorks[psc].ResumePosition; } int progress = currentPosition == TimeSpan.Zero ? (starting ? 0 : 100) : Math.Min((int)(currentPosition.TotalSeconds * 100 / _progressUpdateWorks[psc].Duration.TotalSeconds), 100); string value; int iValue; DateTime dtValue; long lValue; if (isMovie) { TraktMovieScrobble movie = new TraktMovieScrobble(); if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, MovieAspect.ATTR_IMDB_ID, out value) && !string.IsNullOrWhiteSpace(value)) { movie.IMDBID = value; } if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, MovieAspect.ATTR_TMDB_ID, out iValue) && iValue > 0) { movie.TMDBID = iValue.ToString(); } if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, MediaAspect.ATTR_RECORDINGTIME, out dtValue)) { movie.Year = dtValue.Year.ToString(); } if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, MovieAspect.ATTR_RUNTIME_M, out iValue) && iValue > 0) { movie.Duration = iValue.ToString(); } scrobbleData = movie; } if (isSeries) { TraktEpisodeScrobble series = new TraktEpisodeScrobble(); if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, SeriesAspect.ATTR_IMDB_ID, out value) && !string.IsNullOrWhiteSpace(value)) { series.IMDBID = value; } if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, SeriesAspect.ATTR_TVDB_ID, out iValue)) { series.TVDBID = iValue.ToString(); } if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, SeriesAspect.ATTR_SERIESNAME, out value) && !string.IsNullOrWhiteSpace(value)) { series.Title = value; } if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, SeriesAspect.ATTR_FIRSTAIRED, out dtValue)) { series.Year = dtValue.Year.ToString(); } if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, SeriesAspect.ATTR_SEASON, out iValue)) { series.Season = iValue.ToString(); } List <int> intList; if (MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, SeriesAspect.ATTR_EPISODE, out intList) && intList.Any()) { series.Episode = intList.First().ToString(); // TODO: multi episode files?! } scrobbleData = series; } // Fallback duration info if (string.IsNullOrWhiteSpace(scrobbleData.Duration) && MediaItemAspect.TryGetAttribute(pc.CurrentMediaItem.Aspects, VideoAspect.ATTR_DURATION, out lValue) && lValue > 0) { scrobbleData.Duration = (lValue / 60).ToString(); } if (string.IsNullOrWhiteSpace(scrobbleData.Title)) { scrobbleData.Title = title; } scrobbleData.Progress = progress.ToString(); if (!starting && progress < WATCHED_PERCENT) { state = TraktScrobbleStates.cancelwatching; } scrobbleData.PluginVersion = TraktSettings.Version; scrobbleData.MediaCenter = "MediaPortal 2"; scrobbleData.MediaCenterVersion = Assembly.GetEntryAssembly().GetName().Version.ToString(); scrobbleData.MediaCenterBuildDate = String.Empty; scrobbleData.Username = username; scrobbleData.Password = password; return(true); }
/// <summary> /// Sends Scrobble data to Trakt /// </summary> /// <param name="scrobbleData">The Data to send</param> /// <param name="status">The mode to send it as</param> /// <returns>The response from Trakt</returns> public static TraktResponse ScrobbleEpisodeState(TraktEpisodeScrobble scrobbleData, TraktScrobbleStates status) { // check that we have everything we need // server can accept title if movie id is not supplied if (status != TraktScrobbleStates.cancelwatching) { if (scrobbleData == null) { TraktResponse error = new TraktResponse { Error = "Not enough information to send to server", Status = "failure" }; return error; } } // serialize Scrobble object to JSON and send to server string response = Transmit(string.Format(TraktURIs.ScrobbleShow, status), scrobbleData.ToJSON()); // return success or failure return response.FromJSON<TraktResponse>(); }