Shoko.Server/API/v3/Controllers/FileController.cs
/// <summary>
/// Update either watch status, resume position, or both.
/// </summary>
/// <param name="fileID">VideoLocal ID. Watch status and resume position is kept per file, regardless of how many duplicates the file has.</param>
/// <param name="eventName">The name of the event that triggered the scrobble.</param>
/// <param name="episodeID">The episode id to scrobble to trakt.</param>
/// <param name="watched">True if file should be marked as watched, false if file should be unmarked, or null if it shall not be updated.</param>
/// <param name="resumePosition">Number of ticks into the video to resume from, or null if it shall not be updated.</param>
/// <returns></returns>
Update either watch status, resume position, or both.
Update either watch status resume position or both .
[HttpPatch("{fileID}/Scrobble")]
        public ActionResult ScrobbleFileAndEpisode([FromRoute] int fileID, [FromQuery(Name = "event")] string eventName = null, [FromQuery] int? episodeID = null, [FromQuery] bool? watched = null, [FromQuery] long? resumePosition = null)
        {
            if (string.IsNullOrEmpty(eventName)) {
                return ScrobbleStatusOnFile(fileID, watched, resumePosition);
            }
            var file = RepoFactory.VideoLocal.GetByID(fileID);
            if (file == null) return BadRequest("Could not get VideoLocal with ID: " + fileID);
            var episode = episodeID.HasValue ? RepoFactory.AnimeEpisode.GetByID(episodeID.Value) : file.GetAnimeEpisodes()?.FirstOrDefault();
            if (episode == null) return BadRequest("Could not get AnimeEpisode with ID: " + episodeID);
            var playbackPositionTicks = resumePosition ?? 0;
            var watchedTillCompletion = watched ?? false;
            if (playbackPositionTicks >= file.Duration) {
                watchedTillCompletion = true;
                playbackPositionTicks = 0;
            }
            switch (eventName) {
                case "play":
                case "resume":
                    ScrobbleToTrakt(file, episode, playbackPositionTicks, ScrobblePlayingStatus.Start);
                    break;
                case "pause":
                    ScrobbleToTrakt(file, episode, playbackPositionTicks, ScrobblePlayingStatus.Pause);
                    break;
                case "stop":
                    ScrobbleToTrakt(file, episode, playbackPositionTicks, ScrobblePlayingStatus.Stop);
                    break;
                case "scrobble":
                    break;
                case "user-interaction":
                    break;
            }
            file.ToggleWatchedStatus(watchedTillCompletion, User.JMMUserID);
            file.SetResumePosition(playbackPositionTicks, User.JMMUserID);
            return NoContent();
        }
[ HttpPatch ( " " ) ] public ActionResult ScrobbleFileAndEpisode ( [ FromRoute ] int fileID , [ FromQuery ( Name = " " ) ] string eventName = null , [ FromQuery ] int ? episodeID = null , [ FromQuery ] bool ? watched = null , [ FromQuery ] long ? resumePosition = null ) { if ( string . IsNullOrEmpty ( eventName ) ) { return ScrobbleStatusOnFile ( fileID , watched , resumePosition ) ; } var file = RepoFactory . VideoLocal . GetByID ( fileID ) ; if ( file == null ) return BadRequest ( " " + fileID ) ; var episode = episodeID . HasValue ? RepoFactory . AnimeEpisode . GetByID ( episodeID . Value ) : file . GetAnimeEpisodes ( ) ? . FirstOrDefault ( ) ; if ( episode == null ) return BadRequest ( " " + episodeID ) ; var playbackPositionTicks = resumePosition ?? 0 ; var watchedTillCompletion = watched ?? false ; if ( playbackPositionTicks >= file . Duration ) { watchedTillCompletion = true ; playbackPositionTicks = 0 ; } switch ( eventName ) { case " " : case " " : ScrobbleToTrakt ( file , episode , playbackPositionTicks , ScrobblePlayingStatus . Start ) ; break ; case " " : ScrobbleToTrakt ( file , episode , playbackPositionTicks , ScrobblePlayingStatus . Pause ) ; break ; case " " : ScrobbleToTrakt ( file , episode , playbackPositionTicks , ScrobblePlayingStatus . Stop ) ; break ; case " " : break ; case " " : break ; } file . ToggleWatchedStatus ( watchedTillCompletion , User . JMMUserID ) ; file . SetResumePosition ( playbackPositionTicks , User . JMMUserID ) ; return NoContent ( ) ; }
Update either watch status, resume position, or both.
Update either watch status resume position or both .
// Handle legacy scrobble events. // The playback was started. // The playback was resumed after a pause. // The playback was paused. // The playback was ended. // The playback is still active, but the playback position changed. // A user interaction caused the watch state to change.
None
int
[FromRoute]
string
[FromQuery(Name = "event")]
int?
[FromQuery]
bool?
[FromQuery]
long?
[FromQuery]
fileID
VideoLocal ID. Watch status and resume position is kept per file, regardless of how many duplicates the file has.
VideoLocal ID . Watch status and resume position is kept per file regardless of how many duplicates the file has .
eventName
The name of the event that triggered the scrobble.
The name of the event that triggered the scrobble .
episodeID
The episode id to scrobble to trakt.
The episode id to scrobble to trakt .
watched
True if file should be marked as watched, false if file should be unmarked, or null if it shall not be updated.
True if file should be marked as watched false if file should be unmarked or null if it shall not be updated .
resumePosition
Number of ticks into the video to resume from, or null if it shall not be updated.
Number of ticks into the video to resume from or null if it shall not be updated .