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
pull/4/head
kay.one 11 years ago
parent 438e3199de
commit 4188946395

@ -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 @@ namespace NzbDrone.Api.Commands
_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 @@ namespace NzbDrone.Api.Commands
dynamic command = Request.Body.FromJson(commandType);
_messageAggregator.PublishCommand(command);
return resource;
return resource.AsResponse();
}
}
}

@ -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();
}
}
}

@ -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; }

@ -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 @@ namespace NzbDrone.Api.EpisodeFiles
private EpisodeFileResource GetEpisodeFile(int id)
{
return ToResource(() => _mediaFileService.Get(id));
return _mediaFileService.Get(id).InjectTo<EpisodeFileResource>();
}
private List<EpisodeFileResource> GetEpisodeFiles()
@ -38,15 +35,11 @@ namespace NzbDrone.Api.EpisodeFiles
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;
}
}
}

@ -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 @@ namespace NzbDrone.Api.Episodes
return ToListResource(() => _episodeService.GetEpisodeBySeries(seriesId.Value));
}
private EpisodeResource SetMonitored(EpisodeResource episodeResource)
private void SetMonitored(EpisodeResource episodeResource)
{
_episodeService.SetEpisodeMonitored(episodeResource.Id, episodeResource.Monitored);
return episodeResource;
}
}
}

@ -31,7 +31,7 @@ namespace NzbDrone.Api.Frontend
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 @@ namespace NzbDrone.Api.Frontend
_logger.Warn("Couldn't find handler for {0}", path);
return null;
return new NotFoundResponse();
}
}
}

@ -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 @@ namespace NzbDrone.Api.Indexers
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 @@ namespace NzbDrone.Api.Indexers
ValidateIndexer(indexer);
indexer = _indexerService.Update(indexer);
var response = indexer.InjectTo<IndexerResource>();
response.Fields = SchemaBuilder.GenerateSchema(indexer.Settings);
return response;
_indexerService.Update(indexer);
}

@ -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;
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 @@ namespace NzbDrone.Api.Indexers
_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()

@ -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;
}
}
}

@ -42,29 +42,17 @@ namespace NzbDrone.Api.Notifications
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)

@ -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" />

@ -22,11 +22,11 @@ namespace NzbDrone.Api
}
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 @@ namespace NzbDrone.Api
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()
{

@ -30,11 +30,11 @@ namespace NzbDrone.Api.Qualities
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 @@ namespace NzbDrone.Api.Qualities
_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)

@ -19,16 +19,15 @@ namespace NzbDrone.Api.Qualities
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()

@ -19,8 +19,8 @@ namespace NzbDrone.Api.REST
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 @@ namespace NzbDrone.Api.REST
}
}
protected Func<TResource, TResource> CreateResource
protected Func<TResource, int> CreateResource
{
private get { return _createResource; }
set
@ -140,36 +140,37 @@ namespace NzbDrone.Api.REST
_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>();

@ -16,9 +16,9 @@ namespace NzbDrone.Api.RootFolders
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()

@ -13,7 +13,7 @@ namespace NzbDrone.Api.Seasons
_seasonService = seasonService;
GetResourceAll = GetSeasons;
UpdateResource = SetMonitored;
UpdateResource = Update;
Post["/pass"] = x => SetSeasonPass();
}
@ -27,14 +27,12 @@ namespace NzbDrone.Api.Seasons
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()

@ -66,18 +66,14 @@ namespace NzbDrone.Api.Series
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)

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

@ -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 () {
var self = this;
_updateExamples: function () {
var data = this.model.toJSON();
data.id = 0;
var self = this;
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) {

Loading…
Cancel
Save