1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2024-12-14 11:23:42 +02:00

Added more magic to fancy. it now automatically figures our response for PUT and POST based on request ID.

file name sample uses HTTP GET instead of post
This commit is contained in:
kay.one 2013-08-25 22:14:55 -07:00
parent 438e3199de
commit 4188946395
20 changed files with 135 additions and 198 deletions

View File

@ -1,5 +1,6 @@
using System;
using System.Linq;
using Nancy;
using NzbDrone.Api.Extensions;
using NzbDrone.Common.Composition;
using NzbDrone.Common.Messaging;
@ -16,10 +17,11 @@ public CommandModule(IMessageAggregator messageAggregator, IContainer container)
_messageAggregator = messageAggregator;
_container = container;
CreateResource = RunCommand;
Post["/"] = x => RunCommand(ReadResourceFromRequest());
}
private CommandResource RunCommand(CommandResource resource)
private Response RunCommand(CommandResource resource)
{
var commandType =
_container.GetImplementations(typeof(ICommand))
@ -29,7 +31,7 @@ private CommandResource RunCommand(CommandResource resource)
dynamic command = Request.Body.FromJson(commandType);
_messageAggregator.PublishCommand(command);
return resource;
return resource.AsResponse();
}
}
}

View File

@ -1,33 +1,93 @@
using FluentValidation;
using System.Collections.Generic;
using FluentValidation;
using Nancy.Responses;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Organizer;
using NzbDrone.Core.Qualities;
using NzbDrone.Core.Tv;
using Nancy.ModelBinding;
using NzbDrone.Api.Mapping;
using NzbDrone.Api.Extensions;
namespace NzbDrone.Api.Config
{
public class NamingModule : NzbDroneRestModule<NamingConfigResource>
{
private readonly INamingConfigService _namingConfigService;
private readonly IBuildFileNames _buildFileNames;
public NamingModule(INamingConfigService namingConfigService)
public NamingModule(INamingConfigService namingConfigService, IBuildFileNames buildFileNames)
: base("config/naming")
{
_namingConfigService = namingConfigService;
_buildFileNames = buildFileNames;
GetResourceSingle = GetNamingConfig;
UpdateResource = UpdateNamingConfig;
Get["/samples"] = x => GetExamples(this.Bind<NamingConfigResource>());
SharedValidator.RuleFor(c => c.MultiEpisodeStyle).InclusiveBetween(0, 3);
SharedValidator.RuleFor(c => c.NumberStyle).InclusiveBetween(0, 3);
SharedValidator.RuleFor(c => c.Separator).Matches(@"\s|\s\-\s|\.");
}
private NamingConfigResource UpdateNamingConfig(NamingConfigResource resource)
private void UpdateNamingConfig(NamingConfigResource resource)
{
return ToResource<NamingConfig>(_namingConfigService.Save, resource);
GetNewId<NamingConfig>(_namingConfigService.Save, resource);
}
private NamingConfigResource GetNamingConfig()
{
return ToResource(_namingConfigService.GetConfig);
return _namingConfigService.GetConfig().InjectTo<NamingConfigResource>();
}
private JsonResponse<NamingSampleResource> GetExamples(NamingConfigResource config)
{
var nameSpec = config.InjectTo<NamingConfig>();
var series = new Core.Tv.Series
{
SeriesType = SeriesTypes.Standard,
Title = "Series Title"
};
var episode1 = new Episode
{
SeasonNumber = 1,
EpisodeNumber = 1,
Title = "Episode Title (1)"
};
var episode2 = new Episode
{
SeasonNumber = 1,
EpisodeNumber = 2,
Title = "Episode Title (2)"
};
var episodeFile = new EpisodeFile
{
Quality = new QualityModel(Quality.HDTV720p),
Path = @"C:\Test\Series.Title.S01E01.720p.HDTV.x264-EVOLVE.mkv"
};
var sampleResource = new NamingSampleResource();
sampleResource.SingleEpisodeExample = _buildFileNames.BuildFilename(new List<Episode> { episode1 },
series,
episodeFile,
nameSpec);
episodeFile.Path = @"C:\Test\Series.Title.S01E01-E02.720p.HDTV.x264-EVOLVE.mkv";
sampleResource.MultiEpisodeExample = _buildFileNames.BuildFilename(new List<Episode> { episode1, episode2 },
series,
episodeFile,
nameSpec);
return sampleResource.AsResponse();
}
}
}

View File

@ -1,8 +1,6 @@
using NzbDrone.Api.Config;
namespace NzbDrone.Api.Naming
namespace NzbDrone.Api.Config
{
public class NamingResource : NamingConfigResource
public class NamingSampleResource
{
public string SingleEpisodeExample { get; set; }
public string MultiEpisodeExample { get; set; }

View File

@ -1,10 +1,7 @@
using System.Collections.Generic;
using NzbDrone.Api.REST;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Tv;
using NzbDrone.Api.Extensions;
using System.Linq;
using Omu.ValueInjecter;
using NzbDrone.Api.Mapping;
namespace NzbDrone.Api.EpisodeFiles
{
@ -23,7 +20,7 @@ public EpisodeModule(IMediaFileService mediaFileService)
private EpisodeFileResource GetEpisodeFile(int id)
{
return ToResource(() => _mediaFileService.Get(id));
return _mediaFileService.Get(id).InjectTo<EpisodeFileResource>();
}
private List<EpisodeFileResource> GetEpisodeFiles()
@ -38,15 +35,11 @@ private List<EpisodeFileResource> GetEpisodeFiles()
return ToListResource(() => _mediaFileService.GetFilesBySeries(seriesId.Value));
}
private EpisodeFileResource SetQuality(EpisodeFileResource episodeFileResource)
private void SetQuality(EpisodeFileResource episodeFileResource)
{
var episodeFile = _mediaFileService.Get(episodeFileResource.Id);
episodeFile.Quality = episodeFileResource.Quality;
_mediaFileService.Update(episodeFile);
episodeFileResource.InjectFrom(episodeFile);
return episodeFileResource;
}
}
}

View File

@ -1,9 +1,6 @@
using System.Collections.Generic;
using NzbDrone.Api.REST;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Tv;
using NzbDrone.Api.Extensions;
using System.Linq;
namespace NzbDrone.Api.Episodes
{
@ -32,11 +29,9 @@ private List<EpisodeResource> GetEpisodes()
return ToListResource(() => _episodeService.GetEpisodeBySeries(seriesId.Value));
}
private EpisodeResource SetMonitored(EpisodeResource episodeResource)
private void SetMonitored(EpisodeResource episodeResource)
{
_episodeService.SetEpisodeMonitored(episodeResource.Id, episodeResource.Monitored);
return episodeResource;
}
}
}

View File

@ -31,7 +31,7 @@ private Response Index()
path.StartsWith("/api", StringComparison.CurrentCultureIgnoreCase) ||
path.StartsWith("/signalr", StringComparison.CurrentCultureIgnoreCase))
{
return null;
return new NotFoundResponse();
}
var mapper = _requestMappers.SingleOrDefault(m => m.CanHandle(path));
@ -44,7 +44,7 @@ private Response Index()
_logger.Warn("Couldn't find handler for {0}", path);
return null;
return new NotFoundResponse();
}
}
}

View File

@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Api.ClientSchema;
using NzbDrone.Api.Mapping;
using NzbDrone.Api.REST;
using NzbDrone.Core.Indexers;
using Omu.ValueInjecter;
@ -47,18 +46,14 @@ private List<IndexerResource> GetAll()
return result;
}
private IndexerResource CreateIndexer(IndexerResource indexerResource)
private int CreateIndexer(IndexerResource indexerResource)
{
var indexer = GetIndexer(indexerResource);
indexer = _indexerService.Create(indexer);
var response = indexer.InjectTo<IndexerResource>();
response.Fields = SchemaBuilder.GenerateSchema(indexer.Settings);
return response;
return indexer.Id;
}
private IndexerResource UpdateIndexer(IndexerResource indexerResource)
private void UpdateIndexer(IndexerResource indexerResource)
{
var indexer = _indexerService.Get(indexerResource.Id);
indexer.InjectFrom(indexerResource);
@ -66,12 +61,7 @@ private IndexerResource UpdateIndexer(IndexerResource indexerResource)
ValidateIndexer(indexer);
indexer = _indexerService.Update(indexer);
var response = indexer.InjectTo<IndexerResource>();
response.Fields = SchemaBuilder.GenerateSchema(indexer.Settings);
return response;
_indexerService.Update(indexer);
}

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using Nancy;
using NzbDrone.Api.Mapping;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;
@ -8,6 +9,8 @@
using NzbDrone.Core.Parser.Model;
using Omu.ValueInjecter;
using System.Linq;
using Nancy.ModelBinding;
using NzbDrone.Api.Extensions;
namespace NzbDrone.Api.Indexers
{
@ -31,17 +34,17 @@ public ReleaseModule(IFetchAndParseRss rssFetcherAndParser,
_downloadService = downloadService;
_parsingService = parsingService;
GetResourceAll = GetReleases;
CreateResource = DownloadRelease;
Post["/"] = x=> DownloadRelease(this.Bind<ReleaseResource>());
}
private ReleaseResource DownloadRelease(ReleaseResource release)
private Response DownloadRelease(ReleaseResource release)
{
var remoteEpisode = _parsingService.Map(release.InjectTo<ParsedEpisodeInfo>(), 0);
remoteEpisode.Report = release.InjectTo<ReportInfo>();
_downloadService.DownloadReport(remoteEpisode);
return release;
return release.AsResponse();
}
private List<ReleaseResource> GetReleases()

View File

@ -1,71 +0,0 @@
using System;
using System.Collections.Generic;
using NzbDrone.Api.Commands;
using NzbDrone.Api.Extensions;
using NzbDrone.Common.Messaging;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Organizer;
using NzbDrone.Core.Qualities;
using NzbDrone.Core.Tv;
using Omu.ValueInjecter;
namespace NzbDrone.Api.Naming
{
public class NamingModule : NzbDroneRestModule<NamingResource>
{
private readonly IBuildFileNames _buildFileNames;
public NamingModule(IBuildFileNames buildFileNames)
:base("naming")
{
_buildFileNames = buildFileNames;
CreateResource = GetExamples;
}
private NamingResource GetExamples(NamingResource resource)
{
var nameSpec = new NamingConfig();
nameSpec.InjectFrom(resource);
var series = new Core.Tv.Series
{
SeriesType = SeriesTypes.Standard,
Title = "Series Title"
};
var episode1 = new Episode
{
SeasonNumber = 1,
EpisodeNumber = 1,
Title = "Episode Title (1)"
};
var episode2 = new Episode
{
SeasonNumber = 1,
EpisodeNumber = 2,
Title = "Episode Title (2)"
};
var episodeFile = new EpisodeFile
{
Quality = new QualityModel(Quality.HDTV720p),
Path = @"C:\Test\Series.Title.S01E01.720p.HDTV.x264-EVOLVE.mkv"
};
resource.SingleEpisodeExample = _buildFileNames.BuildFilename(new List<Episode> { episode1 },
series,
episodeFile,
nameSpec);
episodeFile.Path = @"C:\Test\Series.Title.S01E01-E02.720p.HDTV.x264-EVOLVE.mkv";
resource.MultiEpisodeExample = _buildFileNames.BuildFilename(new List<Episode> { episode1, episode2 },
series,
episodeFile,
nameSpec);
return resource;
}
}
}

View File

@ -42,29 +42,17 @@ private List<NotificationResource> GetAll()
return result;
}
private NotificationResource Create(NotificationResource notificationResource)
private int Create(NotificationResource notificationResource)
{
var notification = GetNotification(notificationResource);
notification = _notificationService.Create(notification);
notificationResource.Id = notification.Id;
var response = notification.InjectTo<NotificationResource>();
response.Fields = SchemaBuilder.GenerateSchema(notification.Settings);
return response;
return _notificationService.Create(notification).Id;
}
private NotificationResource Update(NotificationResource notificationResource)
private void Update(NotificationResource notificationResource)
{
var notification = GetNotification(notificationResource);
notification.Id = notificationResource.Id;
notification = _notificationService.Update(notification);
var response = notification.InjectTo<NotificationResource>();
response.Fields = SchemaBuilder.GenerateSchema(notification.Settings);
return response;
_notificationService.Update(notification);
}
private void DeleteNotification(int id)

View File

@ -122,8 +122,7 @@
<Compile Include="Mapping\ResourceMappingException.cs" />
<Compile Include="Mapping\ValueInjectorExtensions.cs" />
<Compile Include="Missing\MissingModule.cs" />
<Compile Include="Naming\NamingResource.cs" />
<Compile Include="Naming\NamingModule.cs" />
<Compile Include="Config\NamingSampleResource.cs" />
<Compile Include="Notifications\NotificationSchemaModule.cs" />
<Compile Include="Notifications\NotificationModule.cs" />
<Compile Include="Notifications\NotificationResource.cs" />

View File

@ -22,11 +22,11 @@ protected NzbDroneRestModule(string resource)
}
protected TResource ToResource<TModel>(Func<TModel, TModel> function, TResource resource) where TModel : ModelBase, new()
protected int GetNewId<TModel>(Func<TModel, TModel> function, TResource resource) where TModel : ModelBase, new()
{
var model = resource.InjectTo<TModel>();
function(model);
return model.InjectTo<TResource>();
return model.Id;
}
protected List<TResource> ToListResource<TModel>(Func<IEnumerable<TModel>> function) where TModel : ModelBase, new()
@ -35,17 +35,6 @@ protected NzbDroneRestModule(string resource)
return modelList.InjectTo<List<TResource>>();
}
protected TResource ToResource<TModel>(Func<TModel> function) where TModel : ModelBase, new()
{
var modelList = function();
return modelList.InjectTo<TResource>();
}
protected TResource ToResource<TModel>(Func<int, TModel> action, int id) where TModel : ModelBase, new()
{
var model = action(id);
return model.InjectTo<TResource>();
}
protected PagingResource<TResource> ApplyToPage<TModel>(Func<PagingSpec<TModel>, PagingSpec<TModel>> function, PagingSpec<TModel> pagingSpec) where TModel : ModelBase, new()
{

View File

@ -30,11 +30,11 @@ public QualityProfileModule(QualityProfileService qualityProfileService)
DeleteResource = DeleteProfile;
}
private QualityProfileResource Create(QualityProfileResource resource)
private int Create(QualityProfileResource resource)
{
var model = resource.InjectTo<QualityProfile>();
model = _qualityProfileService.Add(model);
return GetById(model.Id);
return model.Id;
}
private void DeleteProfile(int id)
@ -42,11 +42,10 @@ private void DeleteProfile(int id)
_qualityProfileService.Delete(id);
}
private QualityProfileResource Update(QualityProfileResource resource)
private void Update(QualityProfileResource resource)
{
var model = resource.InjectTo<QualityProfile>();
_qualityProfileService.Update(model);
return GetById(resource.Id);
}
private QualityProfileResource GetById(int id)

View File

@ -19,16 +19,15 @@ public QualitySizeModule(QualitySizeService qualityTypeProvider)
UpdateResource = Update;
}
private QualitySizeResource Update(QualitySizeResource resource)
private void Update(QualitySizeResource resource)
{
var model = resource.InjectTo<QualitySize>();
_qualityTypeProvider.Update(model);
return GetById(resource.Id);
}
private QualitySizeResource GetById(int id)
{
return ToResource(() => _qualityTypeProvider.Get(id));
return _qualityTypeProvider.Get(id).InjectTo<QualitySizeResource>();
}
private List<QualitySizeResource> GetAll()

View File

@ -19,8 +19,8 @@ public abstract class RestModule<TResource> : NancyModule
private Func<List<TResource>> _getResourceAll;
private Func<PagingResource<TResource>, PagingResource<TResource>> _getResourcePaged;
private Func<TResource> _getResourceSingle;
private Func<TResource, TResource> _createResource;
private Func<TResource, TResource> _updateResource;
private Func<TResource, int> _createResource;
private Action<TResource> _updateResource;
protected ResourceValidator<TResource> PostValidator { get; private set; }
protected ResourceValidator<TResource> PutValidator { get; private set; }
@ -132,7 +132,7 @@ protected Func<TResource> GetResourceSingle
}
}
protected Func<TResource, TResource> CreateResource
protected Func<TResource, int> CreateResource
{
private get { return _createResource; }
set
@ -140,36 +140,37 @@ protected Func<TResource, TResource> CreateResource
_createResource = value;
Post[ROOT_ROUTE] = options =>
{
var resource = CreateResource(ReadFromRequest());
return resource.AsResponse(HttpStatusCode.Created);
var id = CreateResource(ReadResourceFromRequest());
return GetResourceById(id).AsResponse(HttpStatusCode.Created);
};
}
}
protected Func<TResource, TResource> UpdateResource
protected Action<TResource> UpdateResource
{
private get { return _updateResource; }
set
{
_updateResource = value;
Put[ROOT_ROUTE] = options =>
{
var resource = UpdateResource(ReadFromRequest());
return resource.AsResponse(HttpStatusCode.Accepted);
};
{
var resource = ReadResourceFromRequest();
UpdateResource(resource);
return GetResourceById(resource.Id).AsResponse(HttpStatusCode.Accepted);
};
Put[ID_ROUTE] = options =>
{
var model = ReadFromRequest();
model.Id = options.Id;
var resource = UpdateResource(model);
return resource.AsResponse(HttpStatusCode.Accepted);
var resource = ReadResourceFromRequest();
resource.Id = options.Id;
UpdateResource(resource);
return GetResourceById(resource.Id).AsResponse(HttpStatusCode.Accepted);
};
}
}
private TResource ReadFromRequest()
protected TResource ReadResourceFromRequest()
{
//TODO: handle when request is null
var resource = Request.Body.FromJson<TResource>();

View File

@ -16,9 +16,9 @@ public RootFolderModule(IRootFolderService rootFolderService)
DeleteResource = DeleteFolder;
}
private RootFolderResource CreateRootFolder(RootFolderResource rootFolderResource)
private int CreateRootFolder(RootFolderResource rootFolderResource)
{
return ToResource<RootFolder>(_rootFolderService.Add, rootFolderResource);
return GetNewId<RootFolder>(_rootFolderService.Add, rootFolderResource);
}
private List<RootFolderResource> GetRootFolders()

View File

@ -13,7 +13,7 @@ public SeasonModule(ISeasonService seasonService)
_seasonService = seasonService;
GetResourceAll = GetSeasons;
UpdateResource = SetMonitored;
UpdateResource = Update;
Post["/pass"] = x => SetSeasonPass();
}
@ -27,14 +27,12 @@ private List<SeasonResource> GetSeasons()
return ToListResource<Season>(() => _seasonService.GetSeasonsBySeries(seriesId));
}
return ToListResource<Season>(() => _seasonService.GetAllSeasons());
return ToListResource(() => _seasonService.GetAllSeasons());
}
private SeasonResource SetMonitored(SeasonResource seasonResource)
private void Update(SeasonResource seasonResource)
{
_seasonService.SetMonitored(seasonResource.SeriesId, seasonResource.SeasonNumber, seasonResource.Monitored);
return seasonResource;
}
private List<SeasonResource> SetSeasonPass()

View File

@ -66,18 +66,14 @@ private List<SeriesResource> AllSeries()
return seriesResources;
}
private SeriesResource AddSeries(SeriesResource seriesResource)
private int AddSeries(SeriesResource seriesResource)
{
return ToResource<Core.Tv.Series>(_seriesService.AddSeries, seriesResource);
return GetNewId<Core.Tv.Series>(_seriesService.AddSeries, seriesResource);
}
private SeriesResource UpdateSeries(SeriesResource seriesResource)
private void UpdateSeries(SeriesResource seriesResource)
{
var resource = ToResource<Core.Tv.Series>(_seriesService.UpdateSeries, seriesResource);
MapCoversToLocal(resource);
FetchAndLinkSeriesStatistics(resource);
return resource;
GetNewId<Core.Tv.Series>(_seriesService.UpdateSeries, seriesResource);
}
private void DeleteSeries(int id)

View File

@ -1,4 +1,4 @@
'use strict';
'use strict';
define(
[
'Settings/SettingsModelBase'

View File

@ -19,13 +19,13 @@ define(
'change .x-rename-episodes': '_setNamingOptionsVisibility'
},
onRender: function(){
if(!this.model.get('renameEpisodes')){
onRender: function () {
if (!this.model.get('renameEpisodes')) {
this.ui.namingOptions.hide();
}
this.listenTo(this.model, 'change', this._buildExamples);
this._buildExamples();
this.listenTo(this.model, 'change', this._updateExamples);
this._updateExamples();
},
_setNamingOptionsVisibility: function () {
@ -39,16 +39,14 @@ define(
}
},
_buildExamples: function () {
_updateExamples: function () {
var self = this;
var data = this.model.toJSON();
data.id = 0;
var promise = $.ajax({
type: 'POST',
url : window.ApiRoot + '/naming',
data: JSON.stringify(data)
type: 'GET',
url : window.ApiRoot + '/config/naming/samples',
data: this.model.toJSON()
});
promise.done(function (result) {