Shoko.Server/API/v3/Controllers/FileController.cs
/// <summary>
/// Link one or more episodes from a series to the same file.
/// </summary>
/// <param name="fileID">The file id.</param>
/// <param name="body">The body.</param>
/// <returns></returns>
Link one or more episodes from a series to the same file.
Link one or more episodes from a series to the same file .
[HttpPost("{fileID}/LinkFromSeries")]
        public ActionResult LinkMultipleEpisodesToFile(int fileID, [FromBody] File.Input.LinkSeriesBody body)
        {
            var file = RepoFactory.VideoLocal.GetByID(fileID);
            if (file == null) return NotFound();
            var series = RepoFactory.AnimeSeries.GetByID(body.seriesID);
            if (series == null) return BadRequest("Unable to find series entry");
            var episodeType = EpisodeType.Episode;
            var (rangeStart, startType, startErrorMessage) = Helpers.ModelHelper.GetEpisodeNumberAndTypeFromInput(body.rangeStart);
            if (!string.IsNullOrEmpty(startErrorMessage)) {
                return BadRequest(string.Format(startErrorMessage, "rangeStart"));
            }
            var (rangeEnd, endType, endErrorMessage) = Helpers.ModelHelper.GetEpisodeNumberAndTypeFromInput(body.rangeEnd);
            if (!string.IsNullOrEmpty(endErrorMessage)) {
                return BadRequest(string.Format(endErrorMessage, "rangeEnd"));
            }
            if (startType != endType) {
                return BadRequest("Unable to use different episode types in the `rangeStart` and `rangeEnd`.");
            }
            if (startType.HasValue) episodeType = startType.Value;
            var totalEpisodes = Helpers.ModelHelper.GetTotalEpisodesForType(series.GetAnimeEpisodes(), episodeType);
            if (rangeStart < 1) {
                return BadRequest("`rangeStart` cannot be lower than 1");
            }
            if (rangeStart > totalEpisodes) {
                return BadRequest("`rangeStart` cannot be higher than the total number of episodes for the selected type.");
            }
            if (rangeEnd < rangeStart) {
                return BadRequest("`rangeEnd`cannot be lower than `rangeStart`.");
            }
            if (rangeEnd > totalEpisodes) {
                return BadRequest("`rangeEnd` cannot be higher than the total number of episodes for the selected type.");
            }
            if (RemoveXRefsForFile(file))
                return BadRequest($"Cannot remove associations created from AniDB data for file '{file.VideoLocalID}'");
            for (int episodeNumber = rangeStart; episodeNumber <= rangeEnd; episodeNumber++)
            {
                var anidbEpisode = RepoFactory.AniDB_Episode.GetByAnimeIDAndEpisodeTypeNumber(series.AniDB_ID, episodeType, episodeNumber)[0];
                if (anidbEpisode == null)
                    return InternalError("Could not find the AniDB entry for episode");
                var episode = RepoFactory.AnimeEpisode.GetByAniDBEpisodeID(anidbEpisode.EpisodeID);
                if (episode == null)
                    return InternalError("Could not find episode entry");
                var command = new CommandRequest_LinkFileManually(fileID, episode.AnimeEpisodeID);
                command.Save();
            }
            return Ok();
        }
[ HttpPost ( " " ) ] public ActionResult LinkMultipleEpisodesToFile ( int fileID , [ FromBody ] File . Input . LinkSeriesBody body ) { var file = RepoFactory . VideoLocal . GetByID ( fileID ) ; if ( file == null ) return NotFound ( ) ; var series = RepoFactory . AnimeSeries . GetByID ( body . seriesID ) ; if ( series == null ) return BadRequest ( " " ) ; var episodeType = EpisodeType . Episode ; var ( rangeStart , startType , startErrorMessage ) = Helpers . ModelHelper . GetEpisodeNumberAndTypeFromInput ( body . rangeStart ) ; if ( ! string . IsNullOrEmpty ( startErrorMessage ) ) { return BadRequest ( string . Format ( startErrorMessage , " " ) ) ; } var ( rangeEnd , endType , endErrorMessage ) = Helpers . ModelHelper . GetEpisodeNumberAndTypeFromInput ( body . rangeEnd ) ; if ( ! string . IsNullOrEmpty ( endErrorMessage ) ) { return BadRequest ( string . Format ( endErrorMessage , " " ) ) ; } if ( startType != endType ) { return BadRequest ( " " ) ; } if ( startType . HasValue ) episodeType = startType . Value ; var totalEpisodes = Helpers . ModelHelper . GetTotalEpisodesForType ( series . GetAnimeEpisodes ( ) , episodeType ) ; if ( rangeStart < 1 ) { return BadRequest ( " " ) ; } if ( rangeStart > totalEpisodes ) { return BadRequest ( " " ) ; } if ( rangeEnd < rangeStart ) { return BadRequest ( " " ) ; } if ( rangeEnd > totalEpisodes ) { return BadRequest ( " " ) ; } if ( RemoveXRefsForFile ( file ) ) return BadRequest ( $" Cannot remove associations created from AniDB data for file ' { file . VideoLocalID } ' " ) ; for ( int episodeNumber = rangeStart ; episodeNumber <= rangeEnd ; episodeNumber ++ ) { var anidbEpisode = RepoFactory . AniDB_Episode . GetByAnimeIDAndEpisodeTypeNumber ( series . AniDB_ID , episodeType , episodeNumber ) [ 0 ] ; if ( anidbEpisode == null ) return InternalError ( " " ) ; var episode = RepoFactory . AnimeEpisode . GetByAniDBEpisodeID ( anidbEpisode . EpisodeID ) ; if ( episode == null ) return InternalError ( " " ) ; var command = new CommandRequest_LinkFileManually ( fileID , episode . AnimeEpisodeID ) ; command . Save ( ) ; } return Ok ( ) ; }
Link one or more episodes from a series to the same file.
Link one or more episodes from a series to the same file .
// Set the episode type if it was included in the input. // Validate the range.
None
fileID
int
The file id.
The file id .
File.Input.LinkSeriesBody
[FromBody]
body
None