2017-10-29 18:19:30 +00:00
|
|
|
using System;
|
2017-01-03 19:24:55 +00:00
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.IO;
|
|
|
|
using System.Linq;
|
|
|
|
using NLog;
|
|
|
|
using NzbDrone.Common.Disk;
|
|
|
|
using NzbDrone.Common.Extensions;
|
|
|
|
using NzbDrone.Core.MediaFiles.Events;
|
|
|
|
using NzbDrone.Core.Messaging.Events;
|
|
|
|
using NzbDrone.Core.Parser;
|
|
|
|
using NzbDrone.Core.Parser.Model;
|
|
|
|
using NzbDrone.Core.Qualities;
|
|
|
|
using NzbDrone.Core.Download;
|
|
|
|
using NzbDrone.Core.Extras;
|
|
|
|
|
|
|
|
|
|
|
|
namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
|
|
|
{
|
|
|
|
public interface IImportApprovedMovie
|
|
|
|
{
|
|
|
|
List<ImportResult> Import(List<ImportDecision> decisions, bool newDownload, DownloadClientItem downloadClientItem = null, ImportMode importMode = ImportMode.Auto);
|
|
|
|
}
|
|
|
|
|
|
|
|
public class ImportApprovedMovie : IImportApprovedMovie
|
|
|
|
{
|
|
|
|
private readonly IUpgradeMediaFiles _episodeFileUpgrader;
|
|
|
|
private readonly IMediaFileService _mediaFileService;
|
|
|
|
private readonly IExtraService _extraService;
|
|
|
|
private readonly IDiskProvider _diskProvider;
|
|
|
|
private readonly IEventAggregator _eventAggregator;
|
|
|
|
private readonly Logger _logger;
|
|
|
|
|
|
|
|
public ImportApprovedMovie(IUpgradeMediaFiles episodeFileUpgrader,
|
|
|
|
IMediaFileService mediaFileService,
|
|
|
|
IExtraService extraService,
|
|
|
|
IDiskProvider diskProvider,
|
|
|
|
IEventAggregator eventAggregator,
|
|
|
|
Logger logger)
|
|
|
|
{
|
|
|
|
_episodeFileUpgrader = episodeFileUpgrader;
|
|
|
|
_mediaFileService = mediaFileService;
|
|
|
|
_extraService = extraService;
|
|
|
|
_diskProvider = diskProvider;
|
|
|
|
_eventAggregator = eventAggregator;
|
|
|
|
_logger = logger;
|
|
|
|
}
|
|
|
|
|
|
|
|
public List<ImportResult> Import(List<ImportDecision> decisions, bool newDownload, DownloadClientItem downloadClientItem = null, ImportMode importMode = ImportMode.Auto)
|
|
|
|
{
|
2017-01-09 03:16:14 +00:00
|
|
|
_logger.Debug("Decisions: {0}", decisions.Count);
|
|
|
|
|
2018-02-02 14:01:02 +00:00
|
|
|
//I added a null op for the rare case that the quality is null. TODO: find out why that would even happen in the first place.
|
2017-01-03 19:24:55 +00:00
|
|
|
var qualifiedImports = decisions.Where(c => c.Approved)
|
|
|
|
.GroupBy(c => c.LocalMovie.Movie.Id, (i, s) => s
|
2018-02-02 14:01:02 +00:00
|
|
|
.OrderByDescending(c => c.LocalMovie.Quality ?? new QualityModel{Quality = Quality.Unknown}, new QualityModelComparer(s.First().LocalMovie.Movie.Profile))
|
2017-01-03 19:24:55 +00:00
|
|
|
.ThenByDescending(c => c.LocalMovie.Size))
|
|
|
|
.SelectMany(c => c)
|
|
|
|
.ToList();
|
|
|
|
|
2018-02-02 14:01:02 +00:00
|
|
|
|
|
|
|
|
2017-01-03 19:24:55 +00:00
|
|
|
var importResults = new List<ImportResult>();
|
|
|
|
|
|
|
|
foreach (var importDecision in qualifiedImports.OrderBy(e => e.LocalMovie.Size)
|
|
|
|
.ThenByDescending(e => e.LocalMovie.Size))
|
|
|
|
{
|
|
|
|
var localMovie = importDecision.LocalMovie;
|
|
|
|
var oldFiles = new List<MovieFile>();
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
//check if already imported
|
|
|
|
if (importResults.Select(r => r.ImportDecision.LocalMovie.Movie)
|
2017-01-20 00:58:57 +00:00
|
|
|
.Select(m => m.Id).Contains(localMovie.Movie.Id))
|
2017-01-03 19:24:55 +00:00
|
|
|
{
|
|
|
|
importResults.Add(new ImportResult(importDecision, "Movie has already been imported"));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-01-20 00:58:57 +00:00
|
|
|
var movieFile = new MovieFile();
|
|
|
|
movieFile.DateAdded = DateTime.UtcNow;
|
|
|
|
movieFile.MovieId = localMovie.Movie.Id;
|
|
|
|
movieFile.Path = localMovie.Path.CleanFilePath();
|
|
|
|
movieFile.Size = _diskProvider.GetFileSize(localMovie.Path);
|
|
|
|
movieFile.Quality = localMovie.Quality;
|
|
|
|
movieFile.MediaInfo = localMovie.MediaInfo;
|
|
|
|
movieFile.Movie = localMovie.Movie;
|
|
|
|
movieFile.ReleaseGroup = localMovie.ParsedMovieInfo.ReleaseGroup;
|
|
|
|
movieFile.Edition = localMovie.ParsedMovieInfo.Edition;
|
2017-01-03 19:24:55 +00:00
|
|
|
|
|
|
|
bool copyOnly;
|
|
|
|
switch (importMode)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
case ImportMode.Auto:
|
|
|
|
copyOnly = downloadClientItem != null && downloadClientItem.IsReadOnly;
|
|
|
|
break;
|
|
|
|
case ImportMode.Move:
|
|
|
|
copyOnly = false;
|
|
|
|
break;
|
|
|
|
case ImportMode.Copy:
|
|
|
|
copyOnly = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (newDownload)
|
|
|
|
{
|
2017-01-20 00:58:57 +00:00
|
|
|
movieFile.SceneName = GetSceneName(downloadClientItem, localMovie);
|
2017-01-03 19:24:55 +00:00
|
|
|
|
2017-01-20 00:58:57 +00:00
|
|
|
var moveResult = _episodeFileUpgrader.UpgradeMovieFile(movieFile, localMovie, copyOnly); //TODO: Check if this works
|
2017-01-03 19:24:55 +00:00
|
|
|
oldFiles = moveResult.OldFiles;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-01-20 00:58:57 +00:00
|
|
|
movieFile.RelativePath = localMovie.Movie.Path.GetRelativePath(movieFile.Path);
|
2017-01-03 19:24:55 +00:00
|
|
|
}
|
|
|
|
|
2017-01-20 00:58:57 +00:00
|
|
|
_mediaFileService.Add(movieFile);
|
2017-01-03 19:24:55 +00:00
|
|
|
importResults.Add(new ImportResult(importDecision));
|
|
|
|
|
|
|
|
if (newDownload)
|
|
|
|
{
|
|
|
|
//_extraService.ImportExtraFiles(localMovie, episodeFile, copyOnly); TODO update for movie
|
|
|
|
}
|
|
|
|
|
|
|
|
if (downloadClientItem != null)
|
|
|
|
{
|
2017-01-20 00:58:57 +00:00
|
|
|
_eventAggregator.PublishEvent(new MovieImportedEvent(localMovie, movieFile, newDownload, downloadClientItem.DownloadClient, downloadClientItem.DownloadId, downloadClientItem.IsReadOnly));
|
2017-01-03 19:24:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-01-20 00:58:57 +00:00
|
|
|
_eventAggregator.PublishEvent(new MovieImportedEvent(localMovie, movieFile, newDownload));
|
2017-01-03 19:24:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (newDownload)
|
|
|
|
{
|
2017-10-29 18:19:30 +00:00
|
|
|
_eventAggregator.PublishEvent(new MovieDownloadedEvent(localMovie, movieFile, oldFiles, downloadClientItem));
|
2017-01-03 19:24:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2017-01-20 00:58:57 +00:00
|
|
|
_logger.Warn(e, "Couldn't import movie " + localMovie);
|
|
|
|
importResults.Add(new ImportResult(importDecision, "Failed to import movie"));
|
2017-01-03 19:24:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//Adding all the rejected decisions
|
|
|
|
importResults.AddRange(decisions.Where(c => !c.Approved)
|
|
|
|
.Select(d => new ImportResult(d, d.Rejections.Select(r => r.Reason).ToArray())));
|
|
|
|
|
|
|
|
return importResults;
|
|
|
|
}
|
|
|
|
|
|
|
|
private string GetSceneName(DownloadClientItem downloadClientItem, LocalMovie localMovie)
|
|
|
|
{
|
|
|
|
if (downloadClientItem != null)
|
|
|
|
{
|
|
|
|
var title = Parser.Parser.RemoveFileExtension(downloadClientItem.Title);
|
|
|
|
|
2017-06-17 13:02:58 +00:00
|
|
|
var parsedTitle = Parser.Parser.ParseMovieTitle(title, false);
|
2017-01-03 19:24:55 +00:00
|
|
|
|
2017-03-01 00:30:23 +00:00
|
|
|
if (parsedTitle != null)
|
2017-01-03 19:24:55 +00:00
|
|
|
{
|
|
|
|
return title;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var fileName = Path.GetFileNameWithoutExtension(localMovie.Path.CleanFilePath());
|
|
|
|
|
|
|
|
if (SceneChecker.IsSceneTitle(fileName))
|
|
|
|
{
|
|
|
|
return fileName;
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|