mirror of
https://github.com/Radarr/Radarr.git
synced 2026-04-18 21:35:51 -04:00
Compare commits
19 Commits
v0.2.0.182
...
v0.2.0.196
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d67f6237e | ||
|
|
a691ffa7b7 | ||
|
|
aa9537c201 | ||
|
|
a3d9fb1c20 | ||
|
|
62a1e70c86 | ||
|
|
93d0d21846 | ||
|
|
b1c5a3ac14 | ||
|
|
55a525ba2f | ||
|
|
a53768463b | ||
|
|
24cbd6bcef | ||
|
|
3ab3e66853 | ||
|
|
40ca469339 | ||
|
|
2cbd2f719f | ||
|
|
53cbfa803b | ||
|
|
c0b0310bbd | ||
|
|
30e50062a8 | ||
|
|
85fd8f2c65 | ||
|
|
f72b042d5d | ||
|
|
2d3a3a0677 |
2
.github/ISSUE_TEMPLATE.md
vendored
2
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,6 +1,8 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Please use the search bar and make sure you are not submitting an already submitted issue.
|
||||||
|
|
||||||
Provide a description of the feature request or bug, the more details the better.
|
Provide a description of the feature request or bug, the more details the better.
|
||||||
When possible include a log!
|
When possible include a log!
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using NzbDrone.Api.Movie;
|
||||||
using NzbDrone.Api.REST;
|
using NzbDrone.Api.REST;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
using NzbDrone.Api.Series;
|
using NzbDrone.Api.Series;
|
||||||
@@ -11,13 +12,14 @@ namespace NzbDrone.Api.Blacklist
|
|||||||
{
|
{
|
||||||
public int SeriesId { get; set; }
|
public int SeriesId { get; set; }
|
||||||
public List<int> EpisodeIds { get; set; }
|
public List<int> EpisodeIds { get; set; }
|
||||||
|
public int MovieId { get; set; }
|
||||||
public string SourceTitle { get; set; }
|
public string SourceTitle { get; set; }
|
||||||
public QualityModel Quality { get; set; }
|
public QualityModel Quality { get; set; }
|
||||||
public DateTime Date { get; set; }
|
public DateTime Date { get; set; }
|
||||||
public DownloadProtocol Protocol { get; set; }
|
public DownloadProtocol Protocol { get; set; }
|
||||||
public string Indexer { get; set; }
|
public string Indexer { get; set; }
|
||||||
public string Message { get; set; }
|
public string Message { get; set; }
|
||||||
|
public MovieResource Movie { get; set; }
|
||||||
public SeriesResource Series { get; set; }
|
public SeriesResource Series { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,7 +32,7 @@ namespace NzbDrone.Api.Blacklist
|
|||||||
return new BlacklistResource
|
return new BlacklistResource
|
||||||
{
|
{
|
||||||
Id = model.Id,
|
Id = model.Id,
|
||||||
|
MovieId = model.MovieId,
|
||||||
SeriesId = model.SeriesId,
|
SeriesId = model.SeriesId,
|
||||||
EpisodeIds = model.EpisodeIds,
|
EpisodeIds = model.EpisodeIds,
|
||||||
SourceTitle = model.SourceTitle,
|
SourceTitle = model.SourceTitle,
|
||||||
@@ -39,7 +41,7 @@ namespace NzbDrone.Api.Blacklist
|
|||||||
Protocol = model.Protocol,
|
Protocol = model.Protocol,
|
||||||
Indexer = model.Indexer,
|
Indexer = model.Indexer,
|
||||||
Message = model.Message,
|
Message = model.Message,
|
||||||
|
Movie = model.Movie.ToResource(),
|
||||||
Series = model.Series.ToResource()
|
Series = model.Series.ToResource()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -201,6 +201,8 @@ namespace NzbDrone.Api.Movie
|
|||||||
//var mappings = null;//_sceneMappingService.FindByTvdbId(resource.TvdbId);
|
//var mappings = null;//_sceneMappingService.FindByTvdbId(resource.TvdbId);
|
||||||
|
|
||||||
//if (mappings == null) return;
|
//if (mappings == null) return;
|
||||||
|
|
||||||
|
//Not necessary anymore
|
||||||
|
|
||||||
//resource.AlternateTitles = mappings.Select(v => new AlternateTitleResource { Title = v.Title, SeasonNumber = v.SeasonNumber, SceneSeasonNumber = v.SceneSeasonNumber }).ToList();
|
//resource.AlternateTitles = mappings.Select(v => new AlternateTitleResource { Title = v.Title, SeasonNumber = v.SeasonNumber, SceneSeasonNumber = v.SceneSeasonNumber }).ToList();
|
||||||
}
|
}
|
||||||
@@ -239,7 +241,7 @@ namespace NzbDrone.Api.Movie
|
|||||||
|
|
||||||
public void Handle(MediaCoversUpdatedEvent message)
|
public void Handle(MediaCoversUpdatedEvent message)
|
||||||
{
|
{
|
||||||
//BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
|
BroadcastResourceChange(ModelAction.Updated, message.Movie.Id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -236,7 +236,7 @@ namespace NzbDrone.Api.Series
|
|||||||
|
|
||||||
public void Handle(MediaCoversUpdatedEvent message)
|
public void Handle(MediaCoversUpdatedEvent message)
|
||||||
{
|
{
|
||||||
BroadcastResourceChange(ModelAction.Updated, message.Series.Id);
|
//BroadcastResourceChange(ModelAction.Updated, message.Series.Id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,5 +47,17 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||||||
{
|
{
|
||||||
QualityParser.ParseQuality(title).Revision.Version.Should().Be(version);
|
QualityParser.ParseQuality(title).Revision.Version.Should().Be(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestCase("Deadpool 2016 2160p 4K UltraHD BluRay DTS-HD MA 7 1 x264-Whatevs", 19)]
|
||||||
|
[TestCase("Deadpool 2016 2160p 4K UltraHD DTS-HD MA 7 1 x264-Whatevs", 16)]
|
||||||
|
[TestCase("Deadpool 2016 4K 2160p UltraHD BluRay AAC2 0 HEVC x265", 19)]
|
||||||
|
[TestCase("The Revenant 2015 2160p UHD BluRay DTS x264-Whatevs", 19)]
|
||||||
|
[TestCase("The Revenant 2015 2160p UHD BluRay FLAC 7 1 x264-Whatevs", 19)]
|
||||||
|
[TestCase("The Martian 2015 2160p Ultra HD BluRay DTS-HD MA 7 1 x264-Whatevs", 19)]
|
||||||
|
[TestCase("Into the Inferno 2016 2160p Netflix WEBRip DD5 1 x264-Whatevs", 18)]
|
||||||
|
public void should_parse_ultrahd_from_title(string title, int version)
|
||||||
|
{
|
||||||
|
QualityParser.ParseQuality(title).Quality.Id.Should().Be(version);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ namespace NzbDrone.Core.Blacklisting
|
|||||||
{
|
{
|
||||||
public int SeriesId { get; set; }
|
public int SeriesId { get; set; }
|
||||||
public Series Series { get; set; }
|
public Series Series { get; set; }
|
||||||
|
public int MovieId { get; set; }
|
||||||
|
public Movie Movie { get; set; }
|
||||||
public List<int> EpisodeIds { get; set; }
|
public List<int> EpisodeIds { get; set; }
|
||||||
public string SourceTitle { get; set; }
|
public string SourceTitle { get; set; }
|
||||||
public QualityModel Quality { get; set; }
|
public QualityModel Quality { get; set; }
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace NzbDrone.Core.Blacklisting
|
|||||||
{
|
{
|
||||||
List<Blacklist> BlacklistedByTitle(int seriesId, string sourceTitle);
|
List<Blacklist> BlacklistedByTitle(int seriesId, string sourceTitle);
|
||||||
List<Blacklist> BlacklistedByTorrentInfoHash(int seriesId, string torrentInfoHash);
|
List<Blacklist> BlacklistedByTorrentInfoHash(int seriesId, string torrentInfoHash);
|
||||||
List<Blacklist> BlacklistedBySeries(int seriesId);
|
List<Blacklist> BlacklistedByMovie(int seriesId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BlacklistRepository : BasicRepository<Blacklist>, IBlacklistRepository
|
public class BlacklistRepository : BasicRepository<Blacklist>, IBlacklistRepository
|
||||||
@@ -20,15 +20,15 @@ namespace NzbDrone.Core.Blacklisting
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Blacklist> BlacklistedByTitle(int seriesId, string sourceTitle)
|
public List<Blacklist> BlacklistedByTitle(int movieId, string sourceTitle)
|
||||||
{
|
{
|
||||||
return Query.Where(e => e.SeriesId == seriesId)
|
return Query.Where(e => e.MovieId == movieId)
|
||||||
.AndWhere(e => e.SourceTitle.Contains(sourceTitle));
|
.AndWhere(e => e.SourceTitle.Contains(sourceTitle));
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Blacklist> BlacklistedByTorrentInfoHash(int seriesId, string torrentInfoHash)
|
public List<Blacklist> BlacklistedByTorrentInfoHash(int movieId, string torrentInfoHash)
|
||||||
{
|
{
|
||||||
return Query.Where(e => e.SeriesId == seriesId)
|
return Query.Where(e => e.MovieId == movieId)
|
||||||
.AndWhere(e => e.TorrentInfoHash.Contains(torrentInfoHash));
|
.AndWhere(e => e.TorrentInfoHash.Contains(torrentInfoHash));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,9 +37,14 @@ namespace NzbDrone.Core.Blacklisting
|
|||||||
return Query.Where(b => b.SeriesId == seriesId);
|
return Query.Where(b => b.SeriesId == seriesId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Blacklist> BlacklistedByMovie(int movieId)
|
||||||
|
{
|
||||||
|
return Query.Where(b => b.MovieId == movieId);
|
||||||
|
}
|
||||||
|
|
||||||
protected override SortBuilder<Blacklist> GetPagedQuery(QueryBuilder<Blacklist> query, PagingSpec<Blacklist> pagingSpec)
|
protected override SortBuilder<Blacklist> GetPagedQuery(QueryBuilder<Blacklist> query, PagingSpec<Blacklist> pagingSpec)
|
||||||
{
|
{
|
||||||
var baseQuery = query.Join<Blacklist, Series>(JoinType.Inner, h => h.Series, (h, s) => h.SeriesId == s.Id);
|
var baseQuery = query.Join<Blacklist, Movie>(JoinType.Inner, h => h.Movie, (h, s) => h.MovieId == s.Id);
|
||||||
|
|
||||||
return base.GetPagedQuery(baseQuery, pagingSpec);
|
return base.GetPagedQuery(baseQuery, pagingSpec);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace NzbDrone.Core.Blacklisting
|
|||||||
|
|
||||||
IExecute<ClearBlacklistCommand>,
|
IExecute<ClearBlacklistCommand>,
|
||||||
IHandle<DownloadFailedEvent>,
|
IHandle<DownloadFailedEvent>,
|
||||||
IHandleAsync<SeriesDeletedEvent>
|
IHandleAsync<MovieDeletedEvent>
|
||||||
{
|
{
|
||||||
private readonly IBlacklistRepository _blacklistRepository;
|
private readonly IBlacklistRepository _blacklistRepository;
|
||||||
|
|
||||||
@@ -128,8 +128,9 @@ namespace NzbDrone.Core.Blacklisting
|
|||||||
{
|
{
|
||||||
var blacklist = new Blacklist
|
var blacklist = new Blacklist
|
||||||
{
|
{
|
||||||
SeriesId = message.SeriesId,
|
SeriesId = 0,
|
||||||
EpisodeIds = message.EpisodeIds,
|
EpisodeIds = message.EpisodeIds,
|
||||||
|
MovieId = message.MovieId,
|
||||||
SourceTitle = message.SourceTitle,
|
SourceTitle = message.SourceTitle,
|
||||||
Quality = message.Quality,
|
Quality = message.Quality,
|
||||||
Date = DateTime.UtcNow,
|
Date = DateTime.UtcNow,
|
||||||
@@ -144,9 +145,9 @@ namespace NzbDrone.Core.Blacklisting
|
|||||||
_blacklistRepository.Insert(blacklist);
|
_blacklistRepository.Insert(blacklist);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleAsync(SeriesDeletedEvent message)
|
public void HandleAsync(MovieDeletedEvent message)
|
||||||
{
|
{
|
||||||
var blacklisted = _blacklistRepository.BlacklistedBySeries(message.Series.Id);
|
var blacklisted = _blacklistRepository.BlacklistedByMovie(message.Movie.Id);
|
||||||
|
|
||||||
_blacklistRepository.DeleteMany(blacklisted);
|
_blacklistRepository.DeleteMany(blacklisted);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
using System.Data;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(122)]
|
||||||
|
public class add_movieid_to_blacklist : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Alter.Table("Blacklist").AddColumn("MovieId").AsInt32().Nullable().WithDefaultValue(0);
|
||||||
|
Alter.Table("Blacklist").AlterColumn("SeriesId").AsInt32().Nullable();
|
||||||
|
Alter.Table("Blacklist").AlterColumn("EpisodeIds").AsString().Nullable();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,7 +33,11 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
|||||||
public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
|
public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
|
||||||
{
|
{
|
||||||
|
|
||||||
throw new NotImplementedException();
|
if (_blacklistService.Blacklisted(subject.Movie.Id, subject.Release))
|
||||||
|
{
|
||||||
|
_logger.Debug("{0} is blacklisted, rejecting.", subject.Release.Title);
|
||||||
|
return Decision.Reject("Release is blacklisted");
|
||||||
|
}
|
||||||
|
|
||||||
return Decision.Accept();
|
return Decision.Accept();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ namespace NzbDrone.Core.Download.Clients.Nzbget
|
|||||||
[FieldDefinition(7, Label = "Use SSL", Type = FieldType.Checkbox)]
|
[FieldDefinition(7, Label = "Use SSL", Type = FieldType.Checkbox)]
|
||||||
public bool UseSsl { get; set; }
|
public bool UseSsl { get; set; }
|
||||||
|
|
||||||
[FieldDefinition(8, Label = "Add Paused", Type = FieldType.Checkbox)]
|
[FieldDefinition(8, Label = "Add Paused", Type = FieldType.Checkbox, HelpText = "This option requires at least NzbGet version 16.0")]
|
||||||
public bool AddPaused { get; set; }
|
public bool AddPaused { get; set; }
|
||||||
|
|
||||||
public NzbDroneValidationResult Validate()
|
public NzbDroneValidationResult Validate()
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ namespace NzbDrone.Core.MediaCover
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EnsureCovers(Movie movie)
|
private void EnsureCovers(Movie movie, int retried = 0)
|
||||||
{
|
{
|
||||||
foreach (var cover in movie.Images)
|
foreach (var cover in movie.Images)
|
||||||
{
|
{
|
||||||
@@ -130,7 +130,25 @@ namespace NzbDrone.Core.MediaCover
|
|||||||
}
|
}
|
||||||
catch (WebException e)
|
catch (WebException e)
|
||||||
{
|
{
|
||||||
_logger.Warn(string.Format("Couldn't download media cover for {0}. {1}", movie, e.Message));
|
if (e.Status == WebExceptionStatus.ProtocolError)
|
||||||
|
{
|
||||||
|
_logger.Warn(e, "Server returned different code than 200. The poster is probably not available yet.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Warn(e, string.Format("Couldn't download media cover for {0}. {1}", movie, e.Message));
|
||||||
|
if (retried < 3)
|
||||||
|
{
|
||||||
|
retried = +1;
|
||||||
|
_logger.Warn("Retrying for the {0}. time in ten seconds.", retried);
|
||||||
|
System.Threading.Thread.Sleep(10*1000);
|
||||||
|
EnsureCovers(movie, retried);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.Warn(e, "Couldn't download media cover even after retrying five times :(.");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -68,22 +68,22 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
|||||||
{
|
{
|
||||||
//check if already imported
|
//check if already imported
|
||||||
if (importResults.Select(r => r.ImportDecision.LocalMovie.Movie)
|
if (importResults.Select(r => r.ImportDecision.LocalMovie.Movie)
|
||||||
.Select(e => e.Id).Contains(localMovie.Movie.Id))
|
.Select(m => m.Id).Contains(localMovie.Movie.Id))
|
||||||
{
|
{
|
||||||
importResults.Add(new ImportResult(importDecision, "Movie has already been imported"));
|
importResults.Add(new ImportResult(importDecision, "Movie has already been imported"));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var episodeFile = new MovieFile();
|
var movieFile = new MovieFile();
|
||||||
episodeFile.DateAdded = DateTime.UtcNow;
|
movieFile.DateAdded = DateTime.UtcNow;
|
||||||
episodeFile.MovieId = localMovie.Movie.Id;
|
movieFile.MovieId = localMovie.Movie.Id;
|
||||||
episodeFile.Path = localMovie.Path.CleanFilePath();
|
movieFile.Path = localMovie.Path.CleanFilePath();
|
||||||
episodeFile.Size = _diskProvider.GetFileSize(localMovie.Path);
|
movieFile.Size = _diskProvider.GetFileSize(localMovie.Path);
|
||||||
episodeFile.Quality = localMovie.Quality;
|
movieFile.Quality = localMovie.Quality;
|
||||||
episodeFile.MediaInfo = localMovie.MediaInfo;
|
movieFile.MediaInfo = localMovie.MediaInfo;
|
||||||
episodeFile.Movie = localMovie.Movie;
|
movieFile.Movie = localMovie.Movie;
|
||||||
episodeFile.ReleaseGroup = localMovie.ParsedMovieInfo.ReleaseGroup;
|
movieFile.ReleaseGroup = localMovie.ParsedMovieInfo.ReleaseGroup;
|
||||||
episodeFile.Edition = localMovie.ParsedMovieInfo.Edition;
|
movieFile.Edition = localMovie.ParsedMovieInfo.Edition;
|
||||||
|
|
||||||
bool copyOnly;
|
bool copyOnly;
|
||||||
switch (importMode)
|
switch (importMode)
|
||||||
@@ -102,17 +102,17 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
|||||||
|
|
||||||
if (newDownload)
|
if (newDownload)
|
||||||
{
|
{
|
||||||
episodeFile.SceneName = GetSceneName(downloadClientItem, localMovie);
|
movieFile.SceneName = GetSceneName(downloadClientItem, localMovie);
|
||||||
|
|
||||||
var moveResult = _episodeFileUpgrader.UpgradeMovieFile(episodeFile, localMovie, copyOnly);
|
var moveResult = _episodeFileUpgrader.UpgradeMovieFile(movieFile, localMovie, copyOnly); //TODO: Check if this works
|
||||||
oldFiles = moveResult.OldFiles;
|
oldFiles = moveResult.OldFiles;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
episodeFile.RelativePath = localMovie.Movie.Path.GetRelativePath(episodeFile.Path);
|
movieFile.RelativePath = localMovie.Movie.Path.GetRelativePath(movieFile.Path);
|
||||||
}
|
}
|
||||||
|
|
||||||
_mediaFileService.Add(episodeFile);
|
_mediaFileService.Add(movieFile);
|
||||||
importResults.Add(new ImportResult(importDecision));
|
importResults.Add(new ImportResult(importDecision));
|
||||||
|
|
||||||
if (newDownload)
|
if (newDownload)
|
||||||
@@ -122,22 +122,22 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
|||||||
|
|
||||||
if (downloadClientItem != null)
|
if (downloadClientItem != null)
|
||||||
{
|
{
|
||||||
_eventAggregator.PublishEvent(new MovieImportedEvent(localMovie, episodeFile, newDownload, downloadClientItem.DownloadClient, downloadClientItem.DownloadId, downloadClientItem.IsReadOnly));
|
_eventAggregator.PublishEvent(new MovieImportedEvent(localMovie, movieFile, newDownload, downloadClientItem.DownloadClient, downloadClientItem.DownloadId, downloadClientItem.IsReadOnly));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_eventAggregator.PublishEvent(new MovieImportedEvent(localMovie, episodeFile, newDownload));
|
_eventAggregator.PublishEvent(new MovieImportedEvent(localMovie, movieFile, newDownload));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newDownload)
|
if (newDownload)
|
||||||
{
|
{
|
||||||
_eventAggregator.PublishEvent(new MovieDownloadedEvent(localMovie, episodeFile, oldFiles));
|
_eventAggregator.PublishEvent(new MovieDownloadedEvent(localMovie, movieFile, oldFiles));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_logger.Warn(e, "Couldn't import episode " + localMovie);
|
_logger.Warn(e, "Couldn't import movie " + localMovie);
|
||||||
importResults.Add(new ImportResult(importDecision, "Failed to import episode"));
|
importResults.Add(new ImportResult(importDecision, "Failed to import movie"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -111,11 +111,11 @@ namespace NzbDrone.Core.MediaFiles
|
|||||||
|
|
||||||
public List<string> FilterExistingFiles(List<string> files, Movie movie)
|
public List<string> FilterExistingFiles(List<string> files, Movie movie)
|
||||||
{
|
{
|
||||||
var seriesFiles = GetFilesBySeries(movie.Id).Select(f => Path.Combine(movie.Path, f.RelativePath)).ToList();
|
var movieFiles = GetFilesByMovie(movie.Id).Select(f => Path.Combine(movie.Path, f.RelativePath)).ToList();
|
||||||
|
|
||||||
if (!seriesFiles.Any()) return files;
|
if (!movieFiles.Any()) return files;
|
||||||
|
|
||||||
return files.Except(seriesFiles, PathEqualityComparer.Instance).ToList();
|
return files.Except(movieFiles, PathEqualityComparer.Instance).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public EpisodeFile Get(int id)
|
public EpisodeFile Get(int id)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using NLog;
|
using NLog;
|
||||||
@@ -18,14 +18,17 @@ namespace NzbDrone.Core.MediaFiles
|
|||||||
public class MediaFileTableCleanupService : IMediaFileTableCleanupService
|
public class MediaFileTableCleanupService : IMediaFileTableCleanupService
|
||||||
{
|
{
|
||||||
private readonly IMediaFileService _mediaFileService;
|
private readonly IMediaFileService _mediaFileService;
|
||||||
|
private readonly IMovieService _movieService;
|
||||||
private readonly IEpisodeService _episodeService;
|
private readonly IEpisodeService _episodeService;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public MediaFileTableCleanupService(IMediaFileService mediaFileService,
|
public MediaFileTableCleanupService(IMediaFileService mediaFileService,
|
||||||
|
IMovieService movieService,
|
||||||
IEpisodeService episodeService,
|
IEpisodeService episodeService,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
{
|
{
|
||||||
_mediaFileService = mediaFileService;
|
_mediaFileService = mediaFileService;
|
||||||
|
_movieService = movieService;
|
||||||
_episodeService = episodeService;
|
_episodeService = episodeService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
@@ -89,61 +92,39 @@ namespace NzbDrone.Core.MediaFiles
|
|||||||
|
|
||||||
public void Clean(Movie movie, List<string> filesOnDisk)
|
public void Clean(Movie movie, List<string> filesOnDisk)
|
||||||
{
|
{
|
||||||
|
var movieFiles = _mediaFileService.GetFilesByMovie(movie.Id);
|
||||||
//TODO: Update implementation for movies.
|
|
||||||
var seriesFiles = _mediaFileService.GetFilesBySeries(movie.Id);
|
|
||||||
var episodes = _episodeService.GetEpisodeBySeries(movie.Id);
|
|
||||||
|
|
||||||
var filesOnDiskKeys = new HashSet<string>(filesOnDisk, PathEqualityComparer.Instance);
|
var filesOnDiskKeys = new HashSet<string>(filesOnDisk, PathEqualityComparer.Instance);
|
||||||
|
|
||||||
foreach (var seriesFile in seriesFiles)
|
foreach(var movieFile in movieFiles)
|
||||||
{
|
{
|
||||||
var episodeFile = seriesFile;
|
var movieFilePath = Path.Combine(movie.Path, movieFile.RelativePath);
|
||||||
var episodeFilePath = Path.Combine(movie.Path, episodeFile.RelativePath);
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!filesOnDiskKeys.Contains(episodeFilePath))
|
if (!filesOnDiskKeys.Contains(movieFilePath))
|
||||||
{
|
{
|
||||||
_logger.Debug("File [{0}] no longer exists on disk, removing from db", episodeFilePath);
|
_logger.Debug("File [{0}] no longer exists on disk, removing from db", movieFilePath);
|
||||||
_mediaFileService.Delete(seriesFile, DeleteMediaFileReason.MissingFromDisk);
|
_mediaFileService.Delete(movieFile, DeleteMediaFileReason.MissingFromDisk);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (episodes.None(e => e.EpisodeFileId == episodeFile.Id))
|
//var localMovie = _parsingService.GetLocalMovie(movieFile.Path, movie);
|
||||||
{
|
|
||||||
_logger.Debug("File [{0}] is not assigned to any episodes, removing from db", episodeFilePath);
|
|
||||||
_mediaFileService.Delete(episodeFile, DeleteMediaFileReason.NoLinkedEpisodes);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// var localEpsiode = _parsingService.GetLocalEpisode(episodeFile.Path, series);
|
//if (localMovie == null)
|
||||||
//
|
//{
|
||||||
// if (localEpsiode == null || episodes.Count != localEpsiode.Episodes.Count)
|
// _logger.Debug("File [{0}] parsed episodes has changed, removing from db", localMovie.Path);
|
||||||
// {
|
// _mediaFileService.Delete(localMovie);
|
||||||
// _logger.Debug("File [{0}] parsed episodes has changed, removing from db", episodeFile.Path);
|
// continue;
|
||||||
// _mediaFileService.Delete(episodeFile);
|
//}
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
var errorMessage = string.Format("Unable to cleanup EpisodeFile in DB: {0}", episodeFile.Id);
|
var errorMessage = string.Format("Unable to cleanup MovieFile in DB: {0}", movieFile.Id);
|
||||||
_logger.Error(ex, errorMessage);
|
_logger.Error(ex, errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var e in episodes)
|
|
||||||
{
|
|
||||||
var episode = e;
|
|
||||||
|
|
||||||
if (episode.EpisodeFileId > 0 && seriesFiles.None(f => f.Id == episode.EpisodeFileId))
|
|
||||||
{
|
|
||||||
episode.EpisodeFileId = 0;
|
|
||||||
_episodeService.UpdateEpisode(episode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -107,7 +107,7 @@ namespace NzbDrone.Core.MediaFiles
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* var movies = _movieService.MoviesWithFiles(message.Series.Id);
|
var movies = _movieService.MoviesWithFiles(message.Movie.Id);
|
||||||
|
|
||||||
var movieFiles = new List<MovieFile>();
|
var movieFiles = new List<MovieFile>();
|
||||||
var updated = new List<MovieFile>();
|
var updated = new List<MovieFile>();
|
||||||
@@ -119,7 +119,7 @@ namespace NzbDrone.Core.MediaFiles
|
|||||||
|
|
||||||
movieFiles.Add(movieFile);
|
movieFiles.Add(movieFile);
|
||||||
|
|
||||||
if (ChangeFileDate(movieFile, message.Series, moviesInFile))
|
if (ChangeFileDate(movieFile, message.Movie))
|
||||||
{
|
{
|
||||||
updated.Add(movieFile);
|
updated.Add(movieFile);
|
||||||
}
|
}
|
||||||
@@ -127,13 +127,13 @@ namespace NzbDrone.Core.MediaFiles
|
|||||||
|
|
||||||
if (updated.Any())
|
if (updated.Any())
|
||||||
{
|
{
|
||||||
_logger.ProgressDebug("Changed file date for {0} files of {1} in {2}", updated.Count, movieFiles.Count, message.Series.Title);
|
_logger.ProgressDebug("Changed file date for {0} files of {1} in {2}", updated.Count, movieFiles.Count, message.Movie.Title);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.ProgressDebug("No file dates changed for {0}", message.Series.Title);
|
_logger.ProgressDebug("No file dates changed for {0}", message.Movie.Title);
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ChangeFileDateToLocalAirDate(string filePath, string fileDate, string fileTime)
|
private bool ChangeFileDateToLocalAirDate(string filePath, string fileDate, string fileTime)
|
||||||
|
|||||||
@@ -38,10 +38,13 @@ namespace NzbDrone.Core.MediaFiles
|
|||||||
|
|
||||||
public MovieFileMoveResult UpgradeMovieFile(MovieFile episodeFile, LocalMovie localEpisode, bool copyOnly = false)
|
public MovieFileMoveResult UpgradeMovieFile(MovieFile episodeFile, LocalMovie localEpisode, bool copyOnly = false)
|
||||||
{
|
{
|
||||||
|
_logger.Trace("Upgrading existing episode file.");
|
||||||
var moveFileResult = new MovieFileMoveResult();
|
var moveFileResult = new MovieFileMoveResult();
|
||||||
|
localEpisode.Movie.MovieFile.LazyLoad();
|
||||||
var existingFile = localEpisode.Movie.MovieFile;
|
var existingFile = localEpisode.Movie.MovieFile;
|
||||||
|
existingFile.LazyLoad();
|
||||||
|
|
||||||
if (existingFile.IsLoaded)
|
if (existingFile.IsLoaded && existingFile.Value != null)
|
||||||
{
|
{
|
||||||
var file = existingFile.Value;
|
var file = existingFile.Value;
|
||||||
var episodeFilePath = Path.Combine(localEpisode.Movie.Path, file.RelativePath);
|
var episodeFilePath = Path.Combine(localEpisode.Movie.Path, file.RelativePath);
|
||||||
@@ -55,6 +58,10 @@ namespace NzbDrone.Core.MediaFiles
|
|||||||
moveFileResult.OldFiles.Add(file);
|
moveFileResult.OldFiles.Add(file);
|
||||||
_mediaFileService.Delete(file, DeleteMediaFileReason.Upgrade);
|
_mediaFileService.Delete(file, DeleteMediaFileReason.Upgrade);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.Warn("The existing movie file was not lazy loaded.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -183,6 +183,7 @@
|
|||||||
<Compile Include="Datastore\Migration\002_remove_tvrage_imdb_unique_constraint.cs" />
|
<Compile Include="Datastore\Migration\002_remove_tvrage_imdb_unique_constraint.cs" />
|
||||||
<Compile Include="Datastore\Migration\003_remove_clean_title_from_scene_mapping.cs" />
|
<Compile Include="Datastore\Migration\003_remove_clean_title_from_scene_mapping.cs" />
|
||||||
<Compile Include="Datastore\Migration\004_updated_history.cs" />
|
<Compile Include="Datastore\Migration\004_updated_history.cs" />
|
||||||
|
<Compile Include="Datastore\Migration\122_add_movieid_to_blacklist.cs" />
|
||||||
<Compile Include="Datastore\Migration\121_update_filedate_config.cs" />
|
<Compile Include="Datastore\Migration\121_update_filedate_config.cs" />
|
||||||
<Compile Include="Datastore\Migration\120_add_studio_to_table.cs" />
|
<Compile Include="Datastore\Migration\120_add_studio_to_table.cs" />
|
||||||
<Compile Include="Datastore\Migration\119_add_youtube_trailer_id_table .cs" />
|
<Compile Include="Datastore\Migration\119_add_youtube_trailer_id_table .cs" />
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ namespace NzbDrone.Core.Organizer
|
|||||||
public static readonly Regex SeriesTitleRegex = new Regex(@"(?<token>\{(?:Series)(?<separator>[- ._])(Clean)?Title\})",
|
public static readonly Regex SeriesTitleRegex = new Regex(@"(?<token>\{(?:Series)(?<separator>[- ._])(Clean)?Title\})",
|
||||||
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
public static readonly Regex MovieTitleRegex = new Regex(@"(?<token>\{((?:(Movie|Original))(?<separator>[- ._])(Clean)?Title)\})",
|
public static readonly Regex MovieTitleRegex = new Regex(@"(?<token>\{((?:(Movie|Original))(?<separator>[- ._])(Clean)?Title(The)?)\})",
|
||||||
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
private static readonly Regex FileNameCleanupRegex = new Regex(@"([- ._])(\1)+", RegexOptions.Compiled);
|
private static readonly Regex FileNameCleanupRegex = new Regex(@"([- ._])(\1)+", RegexOptions.Compiled);
|
||||||
@@ -316,6 +316,22 @@ namespace NzbDrone.Core.Organizer
|
|||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string TitleThe(string title)
|
||||||
|
{
|
||||||
|
string[] prefixes = { "The ", "An ", "A " };
|
||||||
|
foreach (string prefix in prefixes)
|
||||||
|
{
|
||||||
|
int prefix_length = prefix.Length;
|
||||||
|
if (prefix.ToLower() == title.Substring(0, prefix_length).ToLower())
|
||||||
|
{
|
||||||
|
title = title.Substring(prefix_length) + ", " + prefix.Trim();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return title.Trim();
|
||||||
|
}
|
||||||
|
|
||||||
public static string CleanFileName(string name, bool replace = true)
|
public static string CleanFileName(string name, bool replace = true)
|
||||||
{
|
{
|
||||||
string result = name;
|
string result = name;
|
||||||
@@ -472,6 +488,7 @@ namespace NzbDrone.Core.Organizer
|
|||||||
{
|
{
|
||||||
tokenHandlers["{Movie Title}"] = m => movie.Title;
|
tokenHandlers["{Movie Title}"] = m => movie.Title;
|
||||||
tokenHandlers["{Movie CleanTitle}"] = m => CleanTitle(movie.Title);
|
tokenHandlers["{Movie CleanTitle}"] = m => CleanTitle(movie.Title);
|
||||||
|
tokenHandlers["{Movie Title The}"] = m => TitleThe(movie.Title);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddReleaseDateTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, int releaseYear)
|
private void AddReleaseDateTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, int releaseYear)
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ namespace NzbDrone.Core.Organizer
|
|||||||
|
|
||||||
_movie = new Movie
|
_movie = new Movie
|
||||||
{
|
{
|
||||||
Title = "Movie Title",
|
Title = "The Movie Title",
|
||||||
Year = 2010,
|
Year = 2010,
|
||||||
ImdbId = "tt0066921"
|
ImdbId = "tt0066921"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -268,7 +268,7 @@ namespace NzbDrone.Core.Parser
|
|||||||
|
|
||||||
private static readonly Regex ReportImdbId = new Regex(@"(?<imdbid>tt\d{9})", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
private static readonly Regex ReportImdbId = new Regex(@"(?<imdbid>tt\d{9})", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||||
|
|
||||||
private static readonly Regex SimpleTitleRegex = new Regex(@"(?:480[ip]|576[ip]|720[ip]|1080[ip]|[xh][\W_]?26[45]|DD\W?5\W1|[<>?*:|]|848x480|1280x720|1920x1080|(8|10)b(it)?)\s*",
|
private static readonly Regex SimpleTitleRegex = new Regex(@"(?:480[ip]|576[ip]|720[ip]|1080[ip]|2160[ip]|[xh][\W_]?26[45]|DD\W?5\W1|[<>?*:|]|848x480|1280x720|1920x1080|(8|10)b(it)?)\s*",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||||
|
|
||||||
private static readonly Regex WebsitePrefixRegex = new Regex(@"^\[\s*[a-z]+(\.[a-z]+)+\s*\][- ]*",
|
private static readonly Regex WebsitePrefixRegex = new Regex(@"^\[\s*[a-z]+(\.[a-z]+)+\s*\][- ]*",
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ using System.Collections.Generic;
|
|||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
using NzbDrone.Core.Datastore.Extensions;
|
using NzbDrone.Core.Datastore.Extensions;
|
||||||
|
using Marr.Data.QGen;
|
||||||
|
using NzbDrone.Core.MediaFiles;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Tv
|
namespace NzbDrone.Core.Tv
|
||||||
{
|
{
|
||||||
@@ -15,6 +17,7 @@ namespace NzbDrone.Core.Tv
|
|||||||
Movie FindByImdbId(string imdbid);
|
Movie FindByImdbId(string imdbid);
|
||||||
Movie FindByTitleSlug(string slug);
|
Movie FindByTitleSlug(string slug);
|
||||||
List<Movie> MoviesBetweenDates(DateTime start, DateTime end, bool includeUnmonitored);
|
List<Movie> MoviesBetweenDates(DateTime start, DateTime end, bool includeUnmonitored);
|
||||||
|
List<Movie> MoviesWithFiles(int movieId);
|
||||||
PagingSpec<Movie> MoviesWithoutFiles(PagingSpec<Movie> pagingSpec);
|
PagingSpec<Movie> MoviesWithoutFiles(PagingSpec<Movie> pagingSpec);
|
||||||
List<Movie> GetMoviesByFileId(int fileId);
|
List<Movie> GetMoviesByFileId(int fileId);
|
||||||
void SetFileId(int fileId, int movieId);
|
void SetFileId(int fileId, int movieId);
|
||||||
@@ -134,20 +137,29 @@ namespace NzbDrone.Core.Tv
|
|||||||
return query.ToList();
|
return query.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Movie> MoviesWithFiles(int movieId)
|
||||||
|
{
|
||||||
|
return Query.Join<Movie, MovieFile>(JoinType.Inner, m => m.MovieFile, (m, mf) => m.MovieFileId == mf.Id)
|
||||||
|
.Where(m => m.Id == movieId);
|
||||||
|
}
|
||||||
|
|
||||||
public PagingSpec<Movie> MoviesWithoutFiles(PagingSpec<Movie> pagingSpec)
|
public PagingSpec<Movie> MoviesWithoutFiles(PagingSpec<Movie> pagingSpec)
|
||||||
{
|
{
|
||||||
|
|
||||||
var query = Query.Where(pagingSpec.FilterExpression)
|
pagingSpec.TotalRecords = GetMoviesWithoutFilesQuery(pagingSpec).GetRowCount();
|
||||||
|
pagingSpec.Records = GetMoviesWithoutFilesQuery(pagingSpec).ToList();
|
||||||
|
|
||||||
|
return pagingSpec;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SortBuilder<Movie> GetMoviesWithoutFilesQuery(PagingSpec<Movie> pagingSpec)
|
||||||
|
{
|
||||||
|
return Query.Where(pagingSpec.FilterExpression)
|
||||||
.AndWhere(m => m.MovieFileId == 0)
|
.AndWhere(m => m.MovieFileId == 0)
|
||||||
.AndWhere(m => m.Status == MovieStatusType.Released)
|
.AndWhere(m => m.Status == MovieStatusType.Released)
|
||||||
.OrderBy(pagingSpec.OrderByClause(), pagingSpec.ToSortDirection())
|
.OrderBy(pagingSpec.OrderByClause(), pagingSpec.ToSortDirection())
|
||||||
.Skip(pagingSpec.PagingOffset())
|
.Skip(pagingSpec.PagingOffset())
|
||||||
.Take(pagingSpec.PageSize);
|
.Take(pagingSpec.PageSize);
|
||||||
|
|
||||||
pagingSpec.Records = query.ToList();
|
|
||||||
pagingSpec.TotalRecords = pagingSpec.Records.Count;
|
|
||||||
|
|
||||||
return pagingSpec;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -35,6 +35,7 @@ namespace NzbDrone.Core.Tv
|
|||||||
List<Movie> UpdateMovie(List<Movie> movie);
|
List<Movie> UpdateMovie(List<Movie> movie);
|
||||||
bool MoviePathExists(string folder);
|
bool MoviePathExists(string folder);
|
||||||
void RemoveAddOptions(Movie movie);
|
void RemoveAddOptions(Movie movie);
|
||||||
|
List<Movie> MoviesWithFiles(int movieId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MovieService : IMovieService, IHandle<MovieFileAddedEvent>,
|
public class MovieService : IMovieService, IHandle<MovieFileAddedEvent>,
|
||||||
@@ -235,6 +236,11 @@ namespace NzbDrone.Core.Tv
|
|||||||
return episodes;
|
return episodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Movie> MoviesWithFiles(int movieId)
|
||||||
|
{
|
||||||
|
return _movieRepository.MoviesWithFiles(movieId);
|
||||||
|
}
|
||||||
|
|
||||||
public PagingSpec<Movie> MoviesWithoutFiles(PagingSpec<Movie> pagingSpec)
|
public PagingSpec<Movie> MoviesWithoutFiles(PagingSpec<Movie> pagingSpec)
|
||||||
{
|
{
|
||||||
var movieResult = _movieRepository.MoviesWithoutFiles(pagingSpec);
|
var movieResult = _movieRepository.MoviesWithoutFiles(pagingSpec);
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ $.fn.bindSearch = function() {
|
|||||||
minLength : 1
|
minLength : 1
|
||||||
}, {
|
}, {
|
||||||
name : 'series',
|
name : 'series',
|
||||||
displayKey : 'title',
|
displayKey : function(series) {
|
||||||
|
return series.title + ' (' + series.year + ')';
|
||||||
|
},
|
||||||
source : substringMatcher()
|
source : substringMatcher()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
<li><a href="#" data-token="Movie Title">Movie Title</a></li>
|
<li><a href="#" data-token="Movie Title">Movie Title</a></li>
|
||||||
<li><a href="#" data-token="Movie.Title">Movie.Title</a></li>
|
<li><a href="#" data-token="Movie.Title">Movie.Title</a></li>
|
||||||
<li><a href="#" data-token="Movie_Title">Movie_Title</a></li>
|
<li><a href="#" data-token="Movie_Title">Movie_Title</a></li>
|
||||||
|
<li><a href="#" data-token="Movie TitleThe">Movie Title, The</a></li>
|
||||||
<li><a href="#" data-token="Movie CleanTitle">Movie CleanTitle</a></li>
|
<li><a href="#" data-token="Movie CleanTitle">Movie CleanTitle</a></li>
|
||||||
<li><a href="#" data-token="Movie.CleanTitle">Movie.CleanTitle</a></li>
|
<li><a href="#" data-token="Movie.CleanTitle">Movie.CleanTitle</a></li>
|
||||||
<li><a href="#" data-token="Movie_CleanTitle">Movie_CleanTitle</a></li>
|
<li><a href="#" data-token="Movie_CleanTitle">Movie_CleanTitle</a></li>
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Quality Definitions</legend>
|
<legend>Quality Definitions</legend>
|
||||||
<div class="col-md-11">
|
<div class="col-md-11">
|
||||||
<div id="quality-definition-list">
|
<div id="quality-definition-list">
|
||||||
<div class="quality-header x-header hidden-xs">
|
<div class="quality-header x-header hidden-xs">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<span class="col-md-2 col-sm-3">Quality</span>
|
<span class="col-md-2 col-sm-3">Quality</span>
|
||||||
<span class="col-md-2 col-sm-3">Title</span>
|
<span class="col-md-2 col-sm-3">Title</span>
|
||||||
<span class="col-md-4 col-sm-6">Size Limit <i class="icon-sonarr-info" title="Limits are automatically adjusted for the series runtime and number of episodes in the file." /></span>
|
<span class="col-md-4 col-sm-6">Size Limit <i class="icon-sonarr-warning" title="Limits are automatically adjusted for the movie runtime." /></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="rows x-rows">
|
<div class="rows x-rows">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|||||||
@@ -4,92 +4,92 @@ require('jquery-ui');
|
|||||||
var FormatHelpers = require('../../../Shared/FormatHelpers');
|
var FormatHelpers = require('../../../Shared/FormatHelpers');
|
||||||
|
|
||||||
var view = Marionette.ItemView.extend({
|
var view = Marionette.ItemView.extend({
|
||||||
template : 'Settings/Quality/Definition/QualityDefinitionItemViewTemplate',
|
template : 'Settings/Quality/Definition/QualityDefinitionItemViewTemplate',
|
||||||
className : 'row',
|
className : 'row',
|
||||||
|
|
||||||
slider : {
|
|
||||||
min : 0,
|
|
||||||
max : 200,
|
|
||||||
step : 0.1
|
|
||||||
},
|
|
||||||
|
|
||||||
ui : {
|
slider : {
|
||||||
sizeSlider : '.x-slider',
|
min : 0,
|
||||||
thirtyMinuteMinSize : '.x-min-thirty',
|
max : 200,
|
||||||
sixtyMinuteMinSize : '.x-min-sixty',
|
step : 0.1
|
||||||
thirtyMinuteMaxSize : '.x-max-thirty',
|
},
|
||||||
sixtyMinuteMaxSize : '.x-max-sixty'
|
|
||||||
},
|
|
||||||
|
|
||||||
events : {
|
ui : {
|
||||||
'slide .x-slider' : '_updateSize'
|
sizeSlider : '.x-slider',
|
||||||
},
|
thirtyMinuteMinSize : '.x-min-thirty',
|
||||||
|
sixtyMinuteMinSize : '.x-min-sixty',
|
||||||
|
thirtyMinuteMaxSize : '.x-max-thirty',
|
||||||
|
sixtyMinuteMaxSize : '.x-max-sixty'
|
||||||
|
},
|
||||||
|
|
||||||
initialize : function(options) {
|
events : {
|
||||||
this.profileCollection = options.profiles;
|
'slide .x-slider' : '_updateSize'
|
||||||
},
|
},
|
||||||
|
|
||||||
onRender : function() {
|
initialize : function(options) {
|
||||||
if (this.model.get('quality').id === 0) {
|
this.profileCollection = options.profiles;
|
||||||
this.$el.addClass('row advanced-setting');
|
},
|
||||||
}
|
|
||||||
|
|
||||||
this.ui.sizeSlider.slider({
|
onRender : function() {
|
||||||
range : true,
|
if (this.model.get('quality').id === 0) {
|
||||||
min : this.slider.min,
|
this.$el.addClass('row advanced-setting');
|
||||||
max : this.slider.max,
|
}
|
||||||
step : this.slider.step,
|
|
||||||
values : [
|
|
||||||
this.model.get('minSize') || this.slider.min,
|
|
||||||
this.model.get('maxSize') || this.slider.max
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
this._changeSize();
|
this.ui.sizeSlider.slider({
|
||||||
},
|
range : true,
|
||||||
|
min : this.slider.min,
|
||||||
|
max : this.slider.max,
|
||||||
|
step : this.slider.step,
|
||||||
|
values : [
|
||||||
|
this.model.get('minSize') || this.slider.min,
|
||||||
|
this.model.get('maxSize') || this.slider.max
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
_updateSize : function(event, ui) {
|
this._changeSize();
|
||||||
var minSize = ui.values[0];
|
},
|
||||||
var maxSize = ui.values[1];
|
|
||||||
|
|
||||||
if (maxSize === this.slider.max) {
|
|
||||||
maxSize = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.model.set('minSize', minSize);
|
|
||||||
this.model.set('maxSize', maxSize);
|
|
||||||
|
|
||||||
this._changeSize();
|
_updateSize : function(event, ui) {
|
||||||
},
|
var minSize = ui.values[0];
|
||||||
|
var maxSize = ui.values[1];
|
||||||
|
|
||||||
_changeSize : function() {
|
if (maxSize === this.slider.max) {
|
||||||
var minSize = this.model.get('minSize') || this.slider.min;
|
maxSize = null;
|
||||||
var maxSize = this.model.get('maxSize') || null;
|
}
|
||||||
{
|
|
||||||
var minBytes = minSize * 1024 * 1024;
|
|
||||||
var minThirty = FormatHelpers.bytes(minBytes * 30, 2);
|
|
||||||
var minSixty = FormatHelpers.bytes(minBytes * 60, 2);
|
|
||||||
|
|
||||||
this.ui.thirtyMinuteMinSize.html(minThirty);
|
this.model.set('minSize', minSize);
|
||||||
this.ui.sixtyMinuteMinSize.html(minSixty);
|
this.model.set('maxSize', maxSize);
|
||||||
}
|
|
||||||
|
|
||||||
{
|
this._changeSize();
|
||||||
if (maxSize === 0 || maxSize === null) {
|
},
|
||||||
this.ui.thirtyMinuteMaxSize.html('Unlimited');
|
|
||||||
this.ui.sixtyMinuteMaxSize.html('Unlimited');
|
|
||||||
} else {
|
|
||||||
var maxBytes = maxSize * 1024 * 1024;
|
|
||||||
var maxThirty = FormatHelpers.bytes(maxBytes * 30, 2);
|
|
||||||
var maxSixty = FormatHelpers.bytes(maxBytes * 60, 2);
|
|
||||||
|
|
||||||
this.ui.thirtyMinuteMaxSize.html(maxThirty);
|
_changeSize : function() {
|
||||||
this.ui.sixtyMinuteMaxSize.html(maxSixty);
|
var minSize = this.model.get('minSize') || this.slider.min;
|
||||||
}
|
var maxSize = this.model.get('maxSize') || null;
|
||||||
}
|
{
|
||||||
}
|
var minBytes = minSize * 1024 * 1024;
|
||||||
|
var minThirty = FormatHelpers.bytes(minBytes * 90, 2);
|
||||||
|
var minSixty = FormatHelpers.bytes(minBytes * 140, 2);
|
||||||
|
|
||||||
|
this.ui.thirtyMinuteMinSize.html(minThirty);
|
||||||
|
this.ui.sixtyMinuteMinSize.html(minSixty);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
if (maxSize === 0 || maxSize === null) {
|
||||||
|
this.ui.thirtyMinuteMaxSize.html('Unlimited');
|
||||||
|
this.ui.sixtyMinuteMaxSize.html('Unlimited');
|
||||||
|
} else {
|
||||||
|
var maxBytes = maxSize * 1024 * 1024;
|
||||||
|
var maxThirty = FormatHelpers.bytes(maxBytes * 90, 2);
|
||||||
|
var maxSixty = FormatHelpers.bytes(maxBytes * 140, 2);
|
||||||
|
|
||||||
|
this.ui.thirtyMinuteMaxSize.html(maxThirty);
|
||||||
|
this.ui.sixtyMinuteMaxSize.html(maxSixty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
view = AsModelBoundView.call(view);
|
view = AsModelBoundView.call(view);
|
||||||
|
|
||||||
module.exports = view;
|
module.exports = view;
|
||||||
|
|||||||
@@ -1,31 +1,31 @@
|
|||||||
<span class="col-md-2 col-sm-3">
|
<span class="col-md-2 col-sm-3">
|
||||||
{{quality.name}}
|
{{quality.name}}
|
||||||
</span>
|
</span>
|
||||||
<span class="col-md-2 col-sm-3">
|
<span class="col-md-2 col-sm-3">
|
||||||
<input type="text" class="form-control" name="title">
|
<input type="text" class="form-control" name="title">
|
||||||
</span>
|
</span>
|
||||||
<span class="col-md-4 col-sm-6">
|
<span class="col-md-4 col-sm-6">
|
||||||
<div class="x-slider"></div>
|
<div class="x-slider"></div>
|
||||||
<div class="size-label-wrapper">
|
<div class="size-label-wrapper">
|
||||||
<div class="pull-left">
|
<div class="pull-left">
|
||||||
<span class="label label-warning x-min-thirty"
|
<span class="label label-warning x-min-thirty"
|
||||||
name="thirtyMinuteMinSize"
|
name="thirtyMinuteMinSize"
|
||||||
title="Minimum size for a 30 minute episode">
|
title="Minimum size for a 90 minute episode">
|
||||||
</span>
|
</span>
|
||||||
<span class="label label-info x-min-sixty"
|
<span class="label label-info x-min-sixty"
|
||||||
name="sixtyMinuteMinSize"
|
name="sixtyMinuteMinSize"
|
||||||
title="Minimum size for a 60 minute episode">
|
title="Minimum size for a 140 minute episode">
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
<span class="label label-warning x-max-thirty"
|
<span class="label label-warning x-max-thirty"
|
||||||
name="thirtyMinuteMaxSize"
|
name="thirtyMinuteMaxSize"
|
||||||
title="Maximum size for a 30 minute episode">
|
title="Maximum size for a 90 minute movie">
|
||||||
</span>
|
</span>
|
||||||
<span class="label label-info x-max-sixty"
|
<span class="label label-info x-max-sixty"
|
||||||
name="sixtyMinuteMaxSize"
|
name="sixtyMinuteMaxSize"
|
||||||
title="Maximum size for a 60 minute episode">
|
title="Maximum size for a 140 minute movie">
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user