using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using AutoMapper; using FluentValidation; using Nancy; using NzbDrone.Api.Extensions; using NzbDrone.Common; using NzbDrone.Core.Tv; using NzbDrone.Core.Model; namespace NzbDrone.Api.Series { public class SeriesModule : NzbDroneApiModule//: RestModule { private readonly ISeriesService _seriesService; public SeriesModule(ISeriesService seriesService) : base("/Series") { _seriesService = seriesService; Get["/"] = x => AllSeries(); Get["/{id}"] = x => GetSeries((int)x.id); Post["/"] = x => AddSeries(); Put["/"] = x => UpdateSeries(); Delete["/{id}"] = x => DeleteSeries((int)x.id); } private Response AllSeries() { var series = _seriesService.GetAllSeries().ToList(); var seriesStats = _seriesService.SeriesStatistics(); var seriesModels = Mapper.Map, List>(series); foreach (var s in seriesModels) { var stats = seriesStats.SingleOrDefault(ss => ss.SeriesId == s.Id); if (stats == null) continue; s.EpisodeCount = stats.EpisodeCount; s.EpisodeFileCount = stats.EpisodeFileCount; s.NumberOfSeasons = stats.NumberOfSeasons; s.NextAiring = stats.NextAiring; } return seriesModels.AsResponse(); } private Response GetSeries(int id) { var series = _seriesService.GetSeries(id); var seriesModels = Mapper.Map(series); return seriesModels.AsResponse(); } private Response AddSeries() { var newSeries = Request.Body.FromJson(); //Todo: Alert the user if this series already exists //Todo: We need to create the folder if the user is adding a new series //(we can just create the folder and it won't blow up if it already exists) //We also need to remove any special characters from the filename before attempting to create it _seriesService.AddSeries(newSeries); return new Response { StatusCode = HttpStatusCode.Created }; } private Response UpdateSeries() { var request = Request.Body.FromJson(); var series = _seriesService.GetSeries(request.Id); series.Monitored = request.Monitored; series.SeasonFolder = request.SeasonFolder; series.QualityProfileId = request.QualityProfileId; //Todo: Do we want to force a scan when this path changes? Can we use events instead? series.RootFolderId = request.RootFolderId; series.FolderName = request.FolderName; series.BacklogSetting = (BacklogSettingType)request.BacklogSetting; if (!String.IsNullOrWhiteSpace(request.CustomStartDate)) series.CustomStartDate = DateTime.Parse(request.CustomStartDate, null, DateTimeStyles.RoundtripKind); else series.CustomStartDate = null; _seriesService.UpdateSeries(series); return request.AsResponse(); } private Response DeleteSeries(int id) { var deleteFiles = Convert.ToBoolean(Request.Headers["deleteFiles"].FirstOrDefault()); _seriesService.DeleteSeries(id, deleteFiles); return new Response { StatusCode = HttpStatusCode.OK }; } } public class SeriesValidator : AbstractValidator { private readonly DiskProvider _diskProvider; public SeriesValidator(DiskProvider diskProvider) { _diskProvider = diskProvider; } public SeriesValidator() { RuleSet("POST", () => { RuleFor(s => s.Id).GreaterThan(0); RuleFor(s => s.Path).NotEmpty().Must(_diskProvider.FolderExists); RuleFor(s => s.QualityProfileId).GreaterThan(0); }); } } }