updated add series

This commit is contained in:
Keivan Beigi 2013-01-28 10:06:54 -08:00 committed by kay.one
parent f3e601d4ed
commit 0531029ce7
16 changed files with 243 additions and 29 deletions

View File

@ -2,6 +2,7 @@
using System.Linq;
using NLog;
using Nancy;
using NzbDrone.Api.Extentions;
namespace NzbDrone.Api.ErrorManagment
{
@ -17,15 +18,21 @@ namespace NzbDrone.Api.ErrorManagment
public Response HandleException(NancyContext context, Exception exception)
{
var apiException = exception as ApiException;
if (apiException != null)
{
_logger.WarnException("API Error", apiException);
return apiException.ToErrorResponse();
}
_logger.ErrorException("Unexpected error", exception);
return null;
return new ErrorModel()
{
Message = exception.Message,
Description = exception.ToString()
}.AsResponse(HttpStatusCode.InternalServerError);
}
}
}

View File

@ -59,6 +59,9 @@
<Reference Include="AutoMapper">
<HintPath>..\packages\AutoMapper.2.2.0\lib\net40\AutoMapper.dll</HintPath>
</Reference>
<Reference Include="FluentValidation">
<HintPath>..\packages\FluentValidation.3.4.6.0\lib\Net40\FluentValidation.dll</HintPath>
</Reference>
<Reference Include="Nancy">
<HintPath>..\packages\Nancy.0.15.3\lib\net40\Nancy.dll</HintPath>
</Reference>
@ -93,6 +96,7 @@
<Compile Include="Extentions\Serializer.cs" />
<Compile Include="QualityProfiles\RootFolderModule.cs" />
<Compile Include="Series\SeriesModule.cs" />
<Compile Include="Series\SeriesLookupModule.cs" />
<Compile Include="ErrorManagment\ApiException.cs" />
<Compile Include="Bootstrapper.cs" />
<Compile Include="ErrorManagment\ErrorHandler.cs" />

View File

@ -0,0 +1,27 @@
using System.Linq;
using Nancy;
using NzbDrone.Api.Extentions;
using NzbDrone.Api.QualityType;
using NzbDrone.Core.Providers;
namespace NzbDrone.Api.Series
{
public class SeriesLookupModule : NzbDroneApiModule
{
private readonly TvDbProvider _tvDbProvider;
public SeriesLookupModule(TvDbProvider tvDbProvider)
: base("/Series/lookup")
{
_tvDbProvider = tvDbProvider;
Get["/"] = x => GetQualityType();
}
private Response GetQualityType()
{
var tvDbResults = _tvDbProvider.SearchSeries((string)Request.Query.term);
return tvDbResults.AsResponse();
}
}
}

View File

@ -1,27 +1,58 @@
using System.Linq;
using FluentValidation;
using Nancy;
using NzbDrone.Api.Extentions;
using NzbDrone.Api.QualityType;
using NzbDrone.Common;
using NzbDrone.Core.Jobs;
using NzbDrone.Core.Providers;
namespace NzbDrone.Api.Series
{
public class SeriesModule : NzbDroneApiModule
{
private readonly TvDbProvider _tvDbProvider;
private readonly SeriesProvider _seriesProvider;
private readonly JobProvider _jobProvider;
public SeriesModule(TvDbProvider tvDbProvider)
public SeriesModule(SeriesProvider seriesProvider, JobProvider jobProvider)
: base("/Series")
{
_tvDbProvider = tvDbProvider;
Get["/lookup"] = x => GetQualityType();
_seriesProvider = seriesProvider;
_jobProvider = jobProvider;
Post["/"] = x => AddSeries();
}
private Response GetQualityType()
private Response AddSeries()
{
var tvDbResults = _tvDbProvider.SearchSeries((string)Request.Query.term);
return tvDbResults.AsResponse();
var request = Request.Body.FromJson<Core.Repository.Series>();
_seriesProvider.AddSeries("", request.Path, request.SeriesId, request.QualityProfileId, null);
_jobProvider.QueueJob(typeof(ImportNewSeriesJob));
return new Response { StatusCode = HttpStatusCode.Created };
}
}
public class SeriesValidator : AbstractValidator<Core.Repository.Series>
{
private readonly DiskProvider _diskProvider;
public SeriesValidator(DiskProvider diskProvider)
{
_diskProvider = diskProvider;
}
public SeriesValidator()
{
RuleSet("POST", () =>
{
RuleFor(s => s.SeriesId).GreaterThan(0);
RuleFor(s => s.Path).NotEmpty().Must(_diskProvider.FolderExists);
RuleFor(s => s.QualityProfileId).GreaterThan(0);
});
}
}
}

View File

@ -2,6 +2,7 @@
<packages>
<package id="Autofac" version="2.6.3.862" targetFramework="net40" />
<package id="AutoMapper" version="2.2.0" targetFramework="net40" />
<package id="FluentValidation" version="3.4.6.0" targetFramework="net40" />
<package id="Nancy" version="0.15.3" targetFramework="net40" />
<package id="Nancy.Bootstrappers.Autofac" version="0.15.3" targetFramework="net40" />
<package id="Nancy.Hosting.Aspnet" version="0.15.3" targetFramework="net40" />

View File

@ -390,6 +390,7 @@
<Content Include="_backboneApp\JsLibraries\backbone.js" />
<Content Include="_backboneApp\JsLibraries\backbone.marionette.js" />
<Content Include="_backboneApp\AddSeries\addSeriesLayoutTemplate.html" />
<Content Include="_backboneApp\Series\SeriesModel.js" />
<Content Include="_backboneApp\Shared\ErrorModel.js" />
<Content Include="_backboneApp\Shared\ErrorTemplate.html" />
<Content Include="_backboneApp\Shared\ErrorView.js" />

View File

@ -66,8 +66,8 @@ NzbDrone.AddSeries.AddNewSeriesView = Backbone.Marionette.Layout.extend({
resultUpdated: function (options, context) {
_.each(options.models, function (model) {
model.set('rootFolders', context.rootFoldersCollection.models);
model.set('qualityProfiles', context.qualityProfilesCollection.models);
model.set('rootFolders', context.rootFoldersCollection);
model.set('qualityProfiles', context.qualityProfilesCollection);
});
context.searchResult.show(context.resultView);

View File

@ -4,17 +4,17 @@
</div>
<div id="{{id}}" class="accordion-body collapse">
<div class="accordion-inner">
<select class="root-dir-input span7">
{{#each rootFolders}}
<select class="span7 x-root-folder">
{{#each rootFolders.models}}
<option value="{{id}}">{{attributes.path}}</option>
{{/each}}
</select>
<select class="quality-profile-input span2">
{{#each qualityProfiles}}
<select class="span2 x-quality-profile">
{{#each qualityProfiles.models}}
<option value="{{id}}">{{attributes.name}}</option>
{{/each}}
</select>
<div class="btn btn-success pull-right icon-plus">
<div class="btn btn-success pull-right icon-plus x-add">
</div>
</div>
<div name="overview"></div>

View File

@ -1,17 +1,47 @@
/// <reference path="../../app.js" />
/// <reference path="../SearchResultModel.js" />
/// <reference path="../../Series/SeriesModel.js" />
/// <reference path="../SearchResultCollection.js" />
NzbDrone.AddSeries.SearchItemView = Backbone.Marionette.ItemView.extend({
template: "AddSeries/AddNewSeries/SearchResultTemplate",
className: 'search-item accordion-group',
ui: {
qualityProfile: '.x-quality-profile',
rootFolder: '.x-root-folder'
},
events: {
'click .x-add': 'add'
},
onRender: function () {
this.listenTo(this.model, 'change', this.render);
//this.listenTo(this.model.get('rootFolders'), 'reset', this.render);
//this.listenTo(this.model.get('qualityProfiles'), 'reset', this.render);
},
add: function () {
var seriesId = this.model.get('id');
var title = this.model.get('seriesName');
var quality = this.ui.qualityProfile.val();
var rootFolderId = this.ui.rootFolder.val();
var rootPath = this.model.get('rootFolders').get(rootFolderId).get('path');
var path = rootPath + "\\" + title;
var model = new NzbDrone.Series.SeriesModel({
seriesId: seriesId,
title: title,
qualityProfileId: quality,
path: path
});
model.save();
}
});
NzbDrone.AddSeries.SearchResultView = Backbone.Marionette.CollectionView.extend({
@ -23,5 +53,7 @@ NzbDrone.AddSeries.SearchResultView = Backbone.Marionette.CollectionView.extend(
initialize: function () {
this.listenTo(this.collection, 'reset', this.render);
},
});

View File

@ -1,8 +1,10 @@
/// <reference path="../app.js" />
/// <reference path="SearchResultModel.js" />
"use strict";
NzbDrone.AddSeries.SearchResultCollection = Backbone.Collection.extend({
url: NzbDrone.Constants.ApiRoot + '/series/lookup',
model: NzbDrone.AddSeries.SearchResultModel,
model: NzbDrone.AddSeries.SearchResultModel
});

View File

@ -9,7 +9,7 @@ _.extend(Marionette.TemplateCache.prototype, {
console.log("Loading template '" + templateId + "'");
jQuery.ajax({
$.ajax({
url: '_backboneApp//' + templateId + '.html',
cache:false,
async: false

View File

@ -0,0 +1,10 @@
NzbDrone.Series.SeriesModel = Backbone.Model.extend({
url: NzbDrone.Constants.ApiRoot + '/series'
});
NzbDrone.Series.SeriesCollection = Backbone.Collection.extend({
model: NzbDrone.Series.SeriesModel,
url: NzbDrone.Constants.ApiRoot + '/series',
});

View File

@ -9,6 +9,13 @@ NzbDrone.Shared.ErrorCollection = Backbone.Collection.extend({
NzbDrone.Shared.ErrorModel = Backbone.Model.extend({
mutators: {
pre: function () {
return this.get('message').lines().lenght > 1;
}
},
defaults: {
"title": "NO_TITLE",
"message": "NO_MESSAGE",

View File

@ -1,4 +1,9 @@
<div class="alert alert-error">
<button type="button" class="close" data-dismiss="alert">×</button>
<i class="icon-warning-sign" /><strong>{{title}}</strong> {{message}}
<i class="icon-warning-sign" /><strong>{{title}}</strong>
{{#if preFormatted}}
<pre> {{message}}</pre>
{{else}}
{{message}}
{{/if}}
</div>

View File

@ -18,6 +18,7 @@ if (typeof console == "undefined") {
}
NzbDrone = new Backbone.Marionette.Application();
NzbDrone.Series = NzbDrone.module("Series");
NzbDrone.AddSeries = NzbDrone.module("AddSeries");
NzbDrone.Quality = NzbDrone.module("Quality");
NzbDrone.Shared = NzbDrone.module("Shared");
@ -36,14 +37,14 @@ NzbDrone.Constants = {
};
NzbDrone.Events = {
DisplayInMainRegion: "DisplayInMainRegion",
DisplayInMainRegion: "DisplayInMainRegion"
};
NzbDrone.Routes = {
Series: {
Add: 'series/add',
},
Add: 'series/add'
}
};
NzbDrone.Controller = Backbone.Marionette.Controller.extend({
@ -55,7 +56,7 @@ NzbDrone.Controller = Backbone.Marionette.Controller.extend({
notFound: function () {
alert('route not found');
},
}
});
@ -78,7 +79,7 @@ NzbDrone.addInitializer(function (options) {
NzbDrone.addRegions({
mainRegion: "#main-region",
errorRegion: "#error-region",
errorRegion: "#error-region"
});
NzbDrone.Router = new NzbDrone.Router();

View File

@ -1,3 +1,89 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/Environment/Editor/MatchingBraceHighlighting/Position/@EntryValue">BOTH_SIDES</s:String>
<s:String x:Key="/Default/Environment/Editor/MatchingBraceHighlighting/Style/@EntryValue">OUTLINE</s:String></wpf:ResourceDictionary>
<s:String x:Key="/Default/Environment/Editor/MatchingBraceHighlighting/Style/@EntryValue">OUTLINE</s:String>
<s:Boolean x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=5C7F3FB135E52A44B9447C48B2EEEE92/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=5C7F3FB135E52A44B9447C48B2EEEE92/AbsolutePath/@EntryValue">C:\Dropbox\Git\NzbDrone\NzbDrone.sln.DotSettings</s:String>
<s:Boolean x:Key="/Default/Environment/InjectedLayers/InjectedLayerCustomization/=File5C7F3FB135E52A44B9447C48B2EEEE92/@KeyIndexDefined">True</s:Boolean>
<s:Double x:Key="/Default/Environment/InjectedLayers/InjectedLayerCustomization/=File5C7F3FB135E52A44B9447C48B2EEEE92/RelativePriority/@EntryValue">1</s:Double>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/QuickList/=26E712D4B91E2E49A0E92C0AFE6FF57E/Entry/=38860059D7978D4DAF1997C7CBC46A78/EntryName/@EntryValue">Backbone model</s:String>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/QuickList/=26E712D4B91E2E49A0E92C0AFE6FF57E/Entry/=38860059D7978D4DAF1997C7CBC46A78/Position/@EntryValue">5</s:Int64>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=4F6A0CA32FE60746A73308F7E39A63C1/@KeyIndexDefined">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=4F6A0CA32FE60746A73308F7E39A63C1/Applicability/=File/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=4F6A0CA32FE60746A73308F7E39A63C1/CustomProperties/=Extension/@EntryIndexedValue">js</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=4F6A0CA32FE60746A73308F7E39A63C1/CustomProperties/=FileName/@EntryIndexedValue">Model</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=4F6A0CA32FE60746A73308F7E39A63C1/CustomProperties/=ValidateFileName/@EntryIndexedValue">True</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=4F6A0CA32FE60746A73308F7E39A63C1/Description/@EntryValue">Backbone Model</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=4F6A0CA32FE60746A73308F7E39A63C1/Field/=ModelName/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=4F6A0CA32FE60746A73308F7E39A63C1/Field/=ModelName/Expression/@EntryValue">getFileNameWithoutExtension()</s:String>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=4F6A0CA32FE60746A73308F7E39A63C1/Field/=ModelName/Order/@EntryValue">0</s:Int64>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=4F6A0CA32FE60746A73308F7E39A63C1/Field/=resource/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=4F6A0CA32FE60746A73308F7E39A63C1/Field/=resource/Expression/@EntryValue">getFileNameWithoutExtension()</s:String>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=4F6A0CA32FE60746A73308F7E39A63C1/Field/=resource/InitialRange/@EntryValue">-1</s:Int64>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=4F6A0CA32FE60746A73308F7E39A63C1/Field/=resource/Order/@EntryValue">1</s:Int64>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=4F6A0CA32FE60746A73308F7E39A63C1/Reformat/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=4F6A0CA32FE60746A73308F7E39A63C1/Scope/=0A12C11AC0ACCA4E921B6B2CEE180C57/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=4F6A0CA32FE60746A73308F7E39A63C1/Scope/=0A12C11AC0ACCA4E921B6B2CEE180C57/Type/@EntryValue">InAnyWebProject</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=4F6A0CA32FE60746A73308F7E39A63C1/ShortenQualifiedReferences/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=4F6A0CA32FE60746A73308F7E39A63C1/Text/@EntryValue">NzbDrone.$ModelName$Model = Backbone.Model.extend({&#xD;
&#xD;
});&#xD;
&#xD;
&#xD;
$ModelName$Collection = Backbone.Collection.extend({&#xD;
&#xD;
model: NzbDrone.$ModelName$Model,&#xD;
url: NzbDrone.Constants.ApiRoot + '/$resource$',&#xD;
&#xD;
});&#xD;
</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=686B0D0C738CD1449F9389FEB5A34944/@KeyIndexDefined">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=686B0D0C738CD1449F9389FEB5A34944/Applicability/=Live/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=686B0D0C738CD1449F9389FEB5A34944/Description/@EntryValue">Backbone Model</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=686B0D0C738CD1449F9389FEB5A34944/Field/=ModelName/@KeyIndexDefined">True</s:Boolean>
<s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=686B0D0C738CD1449F9389FEB5A34944/Field/=ModelName/Order/@EntryValue">0</s:Int64>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=686B0D0C738CD1449F9389FEB5A34944/Reformat/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=686B0D0C738CD1449F9389FEB5A34944/Scope/=FFA15E6CFCBE90499C572A859225B012/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=686B0D0C738CD1449F9389FEB5A34944/Scope/=FFA15E6CFCBE90499C572A859225B012/Type/@EntryValue">InJavaScriptFile</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=686B0D0C738CD1449F9389FEB5A34944/Shortcut/@EntryValue">model</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=686B0D0C738CD1449F9389FEB5A34944/ShortenQualifiedReferences/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=686B0D0C738CD1449F9389FEB5A34944/Text/@EntryValue">$ModelName$ = Backbone.M</s:String>
</wpf:ResourceDictionary>