mirror of https://github.com/Radarr/Radarr
Various anime improvements
Series type is persisted in the client New: Warning in UI if anime episode doesn't have an absolute episode number New: If series type is changed the series will be rescanned New: Update scene mappings when series is refreshed
This commit is contained in:
parent
86936303dd
commit
25abeb8c9c
|
@ -8,6 +8,7 @@ using NzbDrone.Core.Messaging.Commands;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Core.Tv.Events;
|
||||||
|
|
||||||
namespace NzbDrone.Core.DataAugmentation.Scene
|
namespace NzbDrone.Core.DataAugmentation.Scene
|
||||||
{
|
{
|
||||||
|
@ -21,6 +22,7 @@ namespace NzbDrone.Core.DataAugmentation.Scene
|
||||||
|
|
||||||
public class SceneMappingService : ISceneMappingService,
|
public class SceneMappingService : ISceneMappingService,
|
||||||
IHandleAsync<ApplicationStartedEvent>,
|
IHandleAsync<ApplicationStartedEvent>,
|
||||||
|
IHandle<SeriesRefreshStartingEvent>,
|
||||||
IExecute<UpdateSceneMappingCommand>
|
IExecute<UpdateSceneMappingCommand>
|
||||||
{
|
{
|
||||||
private readonly ISceneMappingRepository _repository;
|
private readonly ISceneMappingRepository _repository;
|
||||||
|
@ -80,9 +82,6 @@ namespace NzbDrone.Core.DataAugmentation.Scene
|
||||||
|
|
||||||
public Nullable<Int32> GetSeasonNumber(string title)
|
public Nullable<Int32> GetSeasonNumber(string title)
|
||||||
{
|
{
|
||||||
//TODO: we should be able to override xem aliases with ones from services
|
|
||||||
//Example Fairy Tail - Alias is assigned to season 2 (anidb), but we're still using tvdb for everything
|
|
||||||
|
|
||||||
var mapping = _gettvdbIdCache.Find(title.CleanSeriesTitle());
|
var mapping = _gettvdbIdCache.Find(title.CleanSeriesTitle());
|
||||||
|
|
||||||
if (mapping == null)
|
if (mapping == null)
|
||||||
|
@ -155,6 +154,11 @@ namespace NzbDrone.Core.DataAugmentation.Scene
|
||||||
UpdateMappings();
|
UpdateMappings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Handle(SeriesRefreshStartingEvent message)
|
||||||
|
{
|
||||||
|
UpdateMappings();
|
||||||
|
}
|
||||||
|
|
||||||
public void Execute(UpdateSceneMappingCommand message)
|
public void Execute(UpdateSceneMappingCommand message)
|
||||||
{
|
{
|
||||||
UpdateMappings();
|
UpdateMappings();
|
||||||
|
|
|
@ -595,6 +595,7 @@
|
||||||
<Compile Include="Tv\Commands\RefreshSeriesCommand.cs" />
|
<Compile Include="Tv\Commands\RefreshSeriesCommand.cs" />
|
||||||
<Compile Include="Tv\Ratings.cs" />
|
<Compile Include="Tv\Ratings.cs" />
|
||||||
<Compile Include="Tv\RefreshEpisodeService.cs" />
|
<Compile Include="Tv\RefreshEpisodeService.cs" />
|
||||||
|
<Compile Include="Tv\SeriesEditedService.cs" />
|
||||||
<Compile Include="Tv\SeriesRepository.cs" />
|
<Compile Include="Tv\SeriesRepository.cs" />
|
||||||
<Compile Include="Qualities\QualityModel.cs" />
|
<Compile Include="Qualities\QualityModel.cs" />
|
||||||
<Compile Include="Download\Clients\Sabnzbd\SabnzbdHistoryItem.cs" />
|
<Compile Include="Download\Clients\Sabnzbd\SabnzbdHistoryItem.cs" />
|
||||||
|
|
|
@ -5,10 +5,12 @@ namespace NzbDrone.Core.Tv.Events
|
||||||
public class SeriesEditedEvent : IEvent
|
public class SeriesEditedEvent : IEvent
|
||||||
{
|
{
|
||||||
public Series Series { get; private set; }
|
public Series Series { get; private set; }
|
||||||
|
public Series OldSeries { get; private set; }
|
||||||
|
|
||||||
public SeriesEditedEvent(Series series)
|
public SeriesEditedEvent(Series series, Series oldSeries)
|
||||||
{
|
{
|
||||||
Series = series;
|
Series = series;
|
||||||
|
OldSeries = oldSeries;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,7 +6,6 @@ using NLog;
|
||||||
using NzbDrone.Core.DataAugmentation.DailySeries;
|
using NzbDrone.Core.DataAugmentation.DailySeries;
|
||||||
using NzbDrone.Core.Instrumentation.Extensions;
|
using NzbDrone.Core.Instrumentation.Extensions;
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
using NzbDrone.Core.MediaFiles.Commands;
|
|
||||||
using NzbDrone.Core.Messaging.Commands;
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
using NzbDrone.Core.MetadataSource;
|
using NzbDrone.Core.MetadataSource;
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
using NzbDrone.Core.Messaging.Commands;
|
||||||
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
using NzbDrone.Core.Tv.Commands;
|
||||||
|
using NzbDrone.Core.Tv.Events;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Tv
|
||||||
|
{
|
||||||
|
public class SeriesEditedService : IHandle<SeriesEditedEvent>
|
||||||
|
{
|
||||||
|
private readonly CommandExecutor _commandExecutor;
|
||||||
|
|
||||||
|
public SeriesEditedService(CommandExecutor commandExecutor)
|
||||||
|
{
|
||||||
|
_commandExecutor = commandExecutor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Handle(SeriesEditedEvent message)
|
||||||
|
{
|
||||||
|
//TODO: Refresh if path has changed (also move files)
|
||||||
|
|
||||||
|
if (message.Series.SeriesType != message.OldSeries.SeriesType)
|
||||||
|
{
|
||||||
|
_commandExecutor.PublishCommandAsync(new RefreshSeriesCommand(message.Series.Id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -191,7 +191,7 @@ namespace NzbDrone.Core.Tv
|
||||||
}
|
}
|
||||||
|
|
||||||
var updatedSeries = _seriesRepository.Update(series);
|
var updatedSeries = _seriesRepository.Update(series);
|
||||||
_eventAggregator.PublishEvent(new SeriesEditedEvent(updatedSeries));
|
_eventAggregator.PublishEvent(new SeriesEditedEvent(updatedSeries, storedSeries));
|
||||||
|
|
||||||
return updatedSeries;
|
return updatedSeries;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,10 +42,11 @@ define(
|
||||||
},
|
},
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
'click .x-add' : '_addSeries',
|
'click .x-add' : '_addSeries',
|
||||||
'change .x-quality-profile': '_qualityProfileChanged',
|
'change .x-quality-profile' : '_qualityProfileChanged',
|
||||||
'change .x-root-folder' : '_rootFolderChanged',
|
'change .x-root-folder' : '_rootFolderChanged',
|
||||||
'change .x-season-folder' : '_seasonFolderChanged'
|
'change .x-season-folder' : '_seasonFolderChanged',
|
||||||
|
'change .x-series-type' : '_seriesTypeChanged'
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize: function () {
|
initialize: function () {
|
||||||
|
@ -67,6 +68,7 @@ define(
|
||||||
var defaultQuality = Config.getValue(Config.Keys.DefaultQualityProfileId);
|
var defaultQuality = Config.getValue(Config.Keys.DefaultQualityProfileId);
|
||||||
var defaultRoot = Config.getValue(Config.Keys.DefaultRootFolderId);
|
var defaultRoot = Config.getValue(Config.Keys.DefaultRootFolderId);
|
||||||
var useSeasonFolder = Config.getValueBoolean(Config.Keys.UseSeasonFolder, true);
|
var useSeasonFolder = Config.getValueBoolean(Config.Keys.UseSeasonFolder, true);
|
||||||
|
var defaultSeriesType = Config.getValueBoolean(Config.Keys.DefaultSeriesType, true);
|
||||||
|
|
||||||
if (QualityProfiles.get(defaultQuality)) {
|
if (QualityProfiles.get(defaultQuality)) {
|
||||||
this.ui.qualityProfile.val(defaultQuality);
|
this.ui.qualityProfile.val(defaultQuality);
|
||||||
|
@ -77,6 +79,7 @@ define(
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ui.seasonFolder.prop('checked', useSeasonFolder);
|
this.ui.seasonFolder.prop('checked', useSeasonFolder);
|
||||||
|
this.ui.rootFolder.val(defaultSeriesType);
|
||||||
|
|
||||||
var minSeasonNotZero = _.min(_.reject(this.model.get('seasons'), { seasonNumber: 0 }), 'seasonNumber');
|
var minSeasonNotZero = _.min(_.reject(this.model.get('seasons'), { seasonNumber: 0 }), 'seasonNumber');
|
||||||
|
|
||||||
|
@ -117,6 +120,10 @@ define(
|
||||||
else if (options.key === Config.Keys.UseSeasonFolder) {
|
else if (options.key === Config.Keys.UseSeasonFolder) {
|
||||||
this.ui.seasonFolder.prop('checked', options.value);
|
this.ui.seasonFolder.prop('checked', options.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (options.key === Config.Keys.DefaultSeriesType) {
|
||||||
|
this.ui.seriesType.val(options.value);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_qualityProfileChanged: function () {
|
_qualityProfileChanged: function () {
|
||||||
|
@ -139,6 +146,10 @@ define(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_seriesTypeChanged: function () {
|
||||||
|
Config.setValue(Config.Keys.DefaultSeriesType, this.ui.seriesType.val());
|
||||||
|
},
|
||||||
|
|
||||||
_setRootFolder: function (options) {
|
_setRootFolder: function (options) {
|
||||||
vent.trigger(vent.Commands.CloseModalCommand);
|
vent.trigger(vent.Commands.CloseModalCommand);
|
||||||
this.ui.rootFolder.val(options.model.id);
|
this.ui.rootFolder.val(options.model.id);
|
||||||
|
|
|
@ -172,3 +172,12 @@ td.delete-episode-file-cell {
|
||||||
.backup-type-cell {
|
.backup-type-cell {
|
||||||
width : 20px;
|
width : 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.table>tbody>tr>td, .table>thead>tr>th {
|
||||||
|
|
||||||
|
&.episode-warning-cell {
|
||||||
|
width : 1px;
|
||||||
|
padding-left : 0px;
|
||||||
|
padding-right : 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -8,10 +8,11 @@ define(
|
||||||
ConfigUpdatedEvent: 'ConfigUpdatedEvent'
|
ConfigUpdatedEvent: 'ConfigUpdatedEvent'
|
||||||
},
|
},
|
||||||
Keys : {
|
Keys : {
|
||||||
DefaultQualityProfileId: 'DefaultQualityProfileId',
|
DefaultQualityProfileId : 'DefaultQualityProfileId',
|
||||||
DefaultRootFolderId : 'DefaultRootFolderId',
|
DefaultRootFolderId : 'DefaultRootFolderId',
|
||||||
UseSeasonFolder : 'UseSeasonFolder',
|
UseSeasonFolder : 'UseSeasonFolder',
|
||||||
AdvancedSettings : 'advancedSettings'
|
DefaultSeriesType : 'DefaultSeriesType',
|
||||||
|
AdvancedSettings : 'advancedSettings'
|
||||||
},
|
},
|
||||||
|
|
||||||
getValueBoolean: function (key, defaultValue) {
|
getValueBoolean: function (key, defaultValue) {
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
define(
|
||||||
|
[
|
||||||
|
'Cells/NzbDroneCell',
|
||||||
|
'Series/SeriesCollection'
|
||||||
|
], function (NzbDroneCell, SeriesCollection) {
|
||||||
|
return NzbDroneCell.extend({
|
||||||
|
|
||||||
|
className: 'episode-warning-cell',
|
||||||
|
|
||||||
|
render: function () {
|
||||||
|
|
||||||
|
this.$el.empty();
|
||||||
|
|
||||||
|
if (SeriesCollection.get(this.model.get('seriesId')).get('seriesType') === 'anime') {
|
||||||
|
|
||||||
|
if (this.model.get('seasonNumber') > 0 && this.model.get('absoluteEpisodeNumber') === 0) {
|
||||||
|
this.$el.html('<i class="icon-nd-form-warning" title="Episode does not have an absolute episode number"></i>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.delegateEvents();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -10,6 +10,7 @@ define(
|
||||||
'Cells/EpisodeStatusCell',
|
'Cells/EpisodeStatusCell',
|
||||||
'Cells/EpisodeActionsCell',
|
'Cells/EpisodeActionsCell',
|
||||||
'Series/Details/EpisodeNumberCell',
|
'Series/Details/EpisodeNumberCell',
|
||||||
|
'Series/Details/EpisodeWarningCell',
|
||||||
'Commands/CommandController',
|
'Commands/CommandController',
|
||||||
'moment',
|
'moment',
|
||||||
'underscore',
|
'underscore',
|
||||||
|
@ -23,6 +24,7 @@ define(
|
||||||
EpisodeStatusCell,
|
EpisodeStatusCell,
|
||||||
EpisodeActionsCell,
|
EpisodeActionsCell,
|
||||||
EpisodeNumberCell,
|
EpisodeNumberCell,
|
||||||
|
EpisodeWarningCell,
|
||||||
CommandController,
|
CommandController,
|
||||||
Moment,
|
Moment,
|
||||||
_,
|
_,
|
||||||
|
@ -64,6 +66,13 @@ define(
|
||||||
label: '#',
|
label: '#',
|
||||||
cell : EpisodeNumberCell
|
cell : EpisodeNumberCell
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name : 'this',
|
||||||
|
label : '',
|
||||||
|
cell : EpisodeWarningCell,
|
||||||
|
sortable : false,
|
||||||
|
className : 'episode-warning-cell'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name : 'this',
|
name : 'this',
|
||||||
label : 'Title',
|
label : 'Title',
|
||||||
|
|
|
@ -35,6 +35,10 @@ define(
|
||||||
//Do we need this?
|
//Do we need this?
|
||||||
this.$el.addClass(column.get('name'));
|
this.$el.addClass(column.get('name'));
|
||||||
|
|
||||||
|
if (column.has('className')) {
|
||||||
|
this.$el.addClass(column.get('className'));
|
||||||
|
}
|
||||||
|
|
||||||
this.delegateEvents();
|
this.delegateEvents();
|
||||||
this.direction(column.get('direction'));
|
this.direction(column.get('direction'));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue