Fixed: Detect Kodi nfo vs. Scene nfo. Other extras fixes

Fixes #240

Co-Authored-By: taloth <taloth@users.noreply.github.com>
This commit is contained in:
Qstick 2018-03-19 21:38:02 -04:00
parent 9d056006cc
commit b03b3d8243
15 changed files with 249 additions and 153 deletions

View File

@ -8,7 +8,7 @@ using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Music; using NzbDrone.Core.Music;
using NzbDrone.Test.Common; using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.Metadata.Consumers.Roksbox namespace NzbDrone.Core.Test.Extras.Metadata.Consumers.Roksbox
{ {
[TestFixture] [TestFixture]
public class FindMetadataFileFixture : CoreTest<RoksboxMetadata> public class FindMetadataFileFixture : CoreTest<RoksboxMetadata>

View File

@ -8,7 +8,7 @@ using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Music; using NzbDrone.Core.Music;
using NzbDrone.Test.Common; using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.Metadata.Consumers.Wdtv namespace NzbDrone.Core.Test.Extras.Metadata.Consumers.Wdtv
{ {
[TestFixture] [TestFixture]
public class FindMetadataFileFixture : CoreTest<WdtvMetadata> public class FindMetadataFileFixture : CoreTest<WdtvMetadata>

View File

@ -0,0 +1,65 @@
using System.IO;
using FizzWare.NBuilder;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Core.Extras.Metadata;
using NzbDrone.Core.Extras.Metadata.Consumers.Xbmc;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Music;
using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test.Extras.Metadata.Consumers.Xbmc
{
[TestFixture]
public class FindMetadataFileFixture : CoreTest<XbmcMetadata>
{
private Artist _artist;
[SetUp]
public void Setup()
{
_artist = Builder<Artist>.CreateNew()
.With(s => s.Path = @"C:\Test\Music\The.Artist".AsOsAgnostic())
.Build();
}
[Test]
public void should_return_null_if_filename_is_not_handled()
{
var path = Path.Combine(_artist.Path, "file.jpg");
Subject.FindMetadataFile(_artist, path).Should().BeNull();
}
[Test]
public void should_return_metadata_for_xbmc_nfo()
{
var path = Path.Combine(_artist.Path, "album.nfo");
Mocker.GetMock<IDetectXbmcNfo>()
.Setup(v => v.IsXbmcNfoFile(path))
.Returns(true);
Subject.FindMetadataFile(_artist, path).Type.Should().Be(MetadataType.AlbumMetadata);
Mocker.GetMock<IDetectXbmcNfo>()
.Verify(v => v.IsXbmcNfoFile(It.IsAny<string>()), Times.Once());
}
[Test]
public void should_return_null_for_scene_nfo()
{
var path = Path.Combine(_artist.Path, "album.nfo");
Mocker.GetMock<IDetectXbmcNfo>()
.Setup(v => v.IsXbmcNfoFile(path))
.Returns(false);
Subject.FindMetadataFile(_artist, path).Should().BeNull();
Mocker.GetMock<IDetectXbmcNfo>()
.Verify(v => v.IsXbmcNfoFile(It.IsAny<string>()), Times.Once());
}
}
}

View File

@ -194,6 +194,7 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<Compile Include="Download\TrackedDownloads\TrackedDownloadServiceFixture.cs" /> <Compile Include="Download\TrackedDownloads\TrackedDownloadServiceFixture.cs" />
<Compile Include="Extras\Metadata\Consumers\Xbmc\FindMetadataFileFixture.cs" />
<Compile Include="FluentTest.cs" /> <Compile Include="FluentTest.cs" />
<Compile Include="Framework\CoreTest.cs" /> <Compile Include="Framework\CoreTest.cs" />
<Compile Include="Framework\DbTest.cs" /> <Compile Include="Framework\DbTest.cs" />
@ -324,8 +325,8 @@
<Compile Include="Messaging\Commands\CommandEqualityComparerFixture.cs" /> <Compile Include="Messaging\Commands\CommandEqualityComparerFixture.cs" />
<Compile Include="Messaging\Commands\CommandExecutorFixture.cs" /> <Compile Include="Messaging\Commands\CommandExecutorFixture.cs" />
<Compile Include="Messaging\Events\EventAggregatorFixture.cs" /> <Compile Include="Messaging\Events\EventAggregatorFixture.cs" />
<Compile Include="Metadata\Consumers\Roksbox\FindMetadataFileFixture.cs" /> <Compile Include="Extras\Metadata\Consumers\Roksbox\FindMetadataFileFixture.cs" />
<Compile Include="Metadata\Consumers\Wdtv\FindMetadataFileFixture.cs" /> <Compile Include="Extras\Metadata\Consumers\Wdtv\FindMetadataFileFixture.cs" />
<Compile Include="NotificationTests\PlexClientServiceTest.cs" /> <Compile Include="NotificationTests\PlexClientServiceTest.cs" />
<Compile Include="NotificationTests\ProwlProviderTest.cs" /> <Compile Include="NotificationTests\ProwlProviderTest.cs" />
<Compile Include="NotificationTests\Xbmc\Http\ActivePlayersFixture.cs" /> <Compile Include="NotificationTests\Xbmc\Http\ActivePlayersFixture.cs" />

View File

@ -18,7 +18,7 @@ namespace NzbDrone.Core.Extras
{ {
public interface IExtraService public interface IExtraService
{ {
void ImportExtraFiles(LocalTrack localEpisode, TrackFile episodeFile, bool isReadOnly); void ImportTrack(LocalTrack localTrack, TrackFile trackFile, bool isReadOnly);
} }
public class ExtraService : IExtraService, public class ExtraService : IExtraService,
@ -51,15 +51,15 @@ namespace NzbDrone.Core.Extras
_logger = logger; _logger = logger;
} }
public void ImportTrack(LocalTrack localTrack, TrackFile trackFile, bool isReadOnly)
{
ImportExtraFiles(localTrack, trackFile, isReadOnly);
CreateAfterImport(localTrack.Artist, trackFile);
}
public void ImportExtraFiles(LocalTrack localTrack, TrackFile trackFile, bool isReadOnly) public void ImportExtraFiles(LocalTrack localTrack, TrackFile trackFile, bool isReadOnly)
{ {
var artist = localTrack.Artist;
foreach (var extraFileManager in _extraFileManagers)
{
extraFileManager.CreateAfterTrackImport(artist, trackFile);
}
if (!_configService.ImportExtraFiles) if (!_configService.ImportExtraFiles)
{ {
return; return;
@ -90,7 +90,7 @@ namespace NzbDrone.Core.Extras
foreach (var extraFileManager in _extraFileManagers) foreach (var extraFileManager in _extraFileManagers)
{ {
var extension = Path.GetExtension(matchingFilename); var extension = Path.GetExtension(matchingFilename);
var extraFile = extraFileManager.Import(artist, trackFile, matchingFilename, extension, isReadOnly); var extraFile = extraFileManager.Import(localTrack.Artist, trackFile, matchingFilename, extension, isReadOnly);
if (extraFile != null) if (extraFile != null)
{ {
@ -105,6 +105,14 @@ namespace NzbDrone.Core.Extras
} }
} }
private void CreateAfterImport(Artist artist, TrackFile trackFile)
{
foreach (var extraFileManager in _extraFileManagers)
{
extraFileManager.CreateAfterTrackImport(artist, trackFile);
}
}
public void Handle(MediaCoversUpdatedEvent message) public void Handle(MediaCoversUpdatedEvent message)
{ {
var artist = message.Artist; var artist = message.Artist;

View File

@ -49,8 +49,6 @@ namespace NzbDrone.Core.Extras.Files
_logger = logger; _logger = logger;
} }
public virtual bool PermanentlyDelete => false;
public List<TExtraFile> GetFilesByArtist(int artistId) public List<TExtraFile> GetFilesByArtist(int artistId)
{ {
return _repository.GetFilesByArtist(artistId); return _repository.GetFilesByArtist(artistId);
@ -122,17 +120,9 @@ namespace NzbDrone.Core.Extras.Files
if (_diskProvider.FileExists(path)) if (_diskProvider.FileExists(path))
{ {
if (PermanentlyDelete) // Send to the recycling bin so they can be recovered if necessary
{ var subfolder = _diskProvider.GetParentFolder(artist.Path).GetRelativePath(_diskProvider.GetParentFolder(path));
_diskProvider.DeleteFile(path); _recycleBinProvider.DeleteFile(path, subfolder);
}
else
{
// Send extra files to the recycling bin so they can be recovered if necessary
var subfolder = _diskProvider.GetParentFolder(artist.Path).GetRelativePath(_diskProvider.GetParentFolder(path));
_recycleBinProvider.DeleteFile(path, subfolder);
}
} }
} }
} }

View File

@ -17,14 +17,17 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
{ {
public class XbmcMetadata : MetadataBase<XbmcMetadataSettings> public class XbmcMetadata : MetadataBase<XbmcMetadataSettings>
{ {
private readonly IMapCoversToLocal _mediaCoverService;
private readonly Logger _logger; private readonly Logger _logger;
private readonly IMapCoversToLocal _mediaCoverService;
private readonly IDetectXbmcNfo _detectNfo;
public XbmcMetadata(IMapCoversToLocal mediaCoverService, public XbmcMetadata(IDetectXbmcNfo detectNfo,
IMapCoversToLocal mediaCoverService,
Logger logger) Logger logger)
{ {
_mediaCoverService = mediaCoverService;
_logger = logger; _logger = logger;
_mediaCoverService = mediaCoverService;
_detectNfo = detectNfo;
} }
private static readonly Regex ArtistImagesRegex = new Regex(@"^(?<type>poster|banner|fanart|logo)\.(?:png|jpg|jpeg)", RegexOptions.Compiled | RegexOptions.IgnoreCase); private static readonly Regex ArtistImagesRegex = new Regex(@"^(?<type>poster|banner|fanart|logo)\.(?:png|jpg|jpeg)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
@ -72,27 +75,22 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
return metadata; return metadata;
} }
if (filename.Equals("artist.nfo", StringComparison.OrdinalIgnoreCase)) var isXbmcNfoFile = _detectNfo.IsXbmcNfoFile(path);
if (filename.Equals("artist.nfo", StringComparison.OrdinalIgnoreCase) &&
isXbmcNfoFile)
{ {
metadata.Type = MetadataType.ArtistMetadata; metadata.Type = MetadataType.ArtistMetadata;
return metadata; return metadata;
} }
if (filename.Equals("album.nfo", StringComparison.OrdinalIgnoreCase)) if (filename.Equals("album.nfo", StringComparison.OrdinalIgnoreCase) &&
isXbmcNfoFile)
{ {
metadata.Type = MetadataType.AlbumMetadata; metadata.Type = MetadataType.AlbumMetadata;
return metadata; return metadata;
} }
var parseResult = Parser.Parser.ParseMusicTitle(filename);
if (parseResult != null &&
Path.GetExtension(filename).Equals(".nfo", StringComparison.OrdinalIgnoreCase))
{
metadata.Type = MetadataType.TrackMetadata;
return metadata;
}
return null; return null;
} }
@ -196,93 +194,7 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
public override MetadataFileResult TrackMetadata(Artist artist, TrackFile trackFile) public override MetadataFileResult TrackMetadata(Artist artist, TrackFile trackFile)
{ {
if (!Settings.TrackMetadata) return null;
{
return null;
}
_logger.Debug("Generating Track Metadata for: {0}", Path.Combine(artist.Path, trackFile.RelativePath));
var xmlResult = string.Empty;
foreach (var episode in trackFile.Tracks.Value)
{
var sb = new StringBuilder();
var xws = new XmlWriterSettings();
xws.OmitXmlDeclaration = true;
xws.Indent = false;
using (var xw = XmlWriter.Create(sb, xws))
{
var doc = new XDocument();
var details = new XElement("episodedetails");
details.Add(new XElement("title", episode.Title));
details.Add(new XElement("episode", episode.TrackNumber));
//If trakt ever gets airs before information for specials we should add set it
details.Add(new XElement("displayseason"));
details.Add(new XElement("displayepisode"));
details.Add(new XElement("watched", "false"));
if (episode.Ratings != null && episode.Ratings.Votes > 0)
{
details.Add(new XElement("rating", episode.Ratings.Value));
}
if (trackFile.MediaInfo != null)
{
var fileInfo = new XElement("fileinfo");
var streamDetails = new XElement("streamdetails");
var video = new XElement("video");
video.Add(new XElement("aspect", (float)trackFile.MediaInfo.Width / (float)trackFile.MediaInfo.Height));
video.Add(new XElement("bitrate", trackFile.MediaInfo.VideoBitrate));
video.Add(new XElement("codec", trackFile.MediaInfo.VideoCodec));
video.Add(new XElement("framerate", trackFile.MediaInfo.VideoFps));
video.Add(new XElement("height", trackFile.MediaInfo.Height));
video.Add(new XElement("scantype", trackFile.MediaInfo.ScanType));
video.Add(new XElement("width", trackFile.MediaInfo.Width));
if (trackFile.MediaInfo.RunTime != null)
{
video.Add(new XElement("duration", trackFile.MediaInfo.RunTime.TotalMinutes));
video.Add(new XElement("durationinseconds", trackFile.MediaInfo.RunTime.TotalSeconds));
}
streamDetails.Add(video);
var audio = new XElement("audio");
audio.Add(new XElement("bitrate", trackFile.MediaInfo.AudioBitrate));
audio.Add(new XElement("channels", trackFile.MediaInfo.AudioChannels));
audio.Add(new XElement("codec", GetAudioCodec(trackFile.MediaInfo.AudioFormat)));
audio.Add(new XElement("language", trackFile.MediaInfo.AudioLanguages));
streamDetails.Add(audio);
if (trackFile.MediaInfo.Subtitles != null && trackFile.MediaInfo.Subtitles.Length > 0)
{
var subtitle = new XElement("subtitle");
subtitle.Add(new XElement("language", trackFile.MediaInfo.Subtitles));
streamDetails.Add(subtitle);
}
fileInfo.Add(streamDetails);
details.Add(fileInfo);
}
//Todo: get guest stars, writer and director
//details.Add(new XElement("credits", tvdbEpisode.Writer.FirstOrDefault()));
//details.Add(new XElement("director", tvdbEpisode.Directors.FirstOrDefault()));
doc.Add(details);
doc.Save(xw);
xmlResult += doc.ToString();
xmlResult += Environment.NewLine;
}
}
return new MetadataFileResult(GetTrackMetadataFilename(trackFile.RelativePath), xmlResult.Trim(Environment.NewLine.ToCharArray()));
} }
public override List<ImageFileResult> ArtistImages(Artist artist) public override List<ImageFileResult> ArtistImages(Artist artist)
@ -339,14 +251,5 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
return Path.ChangeExtension(trackFilePath, "nfo"); return Path.ChangeExtension(trackFilePath, "nfo");
} }
private string GetAudioCodec(string audioCodec)
{
if (audioCodec == "AC-3")
{
return "AC3";
}
return audioCodec;
}
} }
} }

View File

@ -17,20 +17,16 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
{ {
ArtistMetadata = true; ArtistMetadata = true;
AlbumMetadata = true; AlbumMetadata = true;
TrackMetadata = true;
ArtistImages = true; ArtistImages = true;
AlbumImages = true; AlbumImages = true;
} }
[FieldDefinition(0, Label = "Artist Metadata", Type = FieldType.Checkbox)] [FieldDefinition(0, Label = "Artist Metadata", Type = FieldType.Checkbox, HelpText = "artist.nfo")]
public bool ArtistMetadata { get; set; } public bool ArtistMetadata { get; set; }
[FieldDefinition(1, Label = "Album Metadata", Type = FieldType.Checkbox)] [FieldDefinition(1, Label = "Album Metadata", Type = FieldType.Checkbox, HelpText = "album.nfo")]
public bool AlbumMetadata { get; set; } public bool AlbumMetadata { get; set; }
[FieldDefinition(2, Label = "Track Metadata", Type = FieldType.Checkbox)]
public bool TrackMetadata { get; set; }
[FieldDefinition(3, Label = "Artist Images", Type = FieldType.Checkbox)] [FieldDefinition(3, Label = "Artist Images", Type = FieldType.Checkbox)]
public bool ArtistImages { get; set; } public bool ArtistImages { get; set; }

View File

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using NzbDrone.Common.Disk;
namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
{
public interface IDetectXbmcNfo
{
bool IsXbmcNfoFile(string path);
}
public class XbmcNfoDetector : IDetectXbmcNfo
{
private readonly IDiskProvider _diskProvider;
private readonly Regex _regex = new Regex("<(movie|tvshow|episodedetails|artist|album|musicvideo)>", RegexOptions.Compiled);
public XbmcNfoDetector(IDiskProvider diskProvider)
{
_diskProvider = diskProvider;
}
public bool IsXbmcNfoFile(string path)
{
// Lets make sure we're not reading huge files.
if (_diskProvider.GetFileSize(path) > 10.Megabytes())
{
return false;
}
// Check if it contains some of the kodi/xbmc xml tags
var content = _diskProvider.ReadAllText(path);
return _regex.IsMatch(content);
}
}
}

View File

@ -16,7 +16,5 @@ namespace NzbDrone.Core.Extras.Metadata.Files
: base(repository, artistService, diskProvider, recycleBinProvider, logger) : base(repository, artistService, diskProvider, recycleBinProvider, logger)
{ {
} }
public override bool PermanentlyDelete => true;
} }
} }

View File

@ -10,6 +10,7 @@ using NzbDrone.Common.Http;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.Extras.Files; using NzbDrone.Core.Extras.Files;
using NzbDrone.Core.Extras.Metadata.Files; using NzbDrone.Core.Extras.Metadata.Files;
using NzbDrone.Core.Extras.Others;
using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Music; using NzbDrone.Core.Music;
using NzbDrone.Core.Organizer; using NzbDrone.Core.Organizer;
@ -20,6 +21,8 @@ namespace NzbDrone.Core.Extras.Metadata
{ {
private readonly IMetadataFactory _metadataFactory; private readonly IMetadataFactory _metadataFactory;
private readonly ICleanMetadataService _cleanMetadataService; private readonly ICleanMetadataService _cleanMetadataService;
private readonly IRecycleBinProvider _recycleBinProvider;
private readonly IOtherExtraFileRenamer _otherExtraFileRenamer;
private readonly IDiskTransferService _diskTransferService; private readonly IDiskTransferService _diskTransferService;
private readonly IDiskProvider _diskProvider; private readonly IDiskProvider _diskProvider;
private readonly IHttpClient _httpClient; private readonly IHttpClient _httpClient;
@ -31,6 +34,8 @@ namespace NzbDrone.Core.Extras.Metadata
public MetadataService(IConfigService configService, public MetadataService(IConfigService configService,
IDiskProvider diskProvider, IDiskProvider diskProvider,
IDiskTransferService diskTransferService, IDiskTransferService diskTransferService,
IRecycleBinProvider recycleBinProvider,
IOtherExtraFileRenamer otherExtraFileRenamer,
IMetadataFactory metadataFactory, IMetadataFactory metadataFactory,
ICleanMetadataService cleanMetadataService, ICleanMetadataService cleanMetadataService,
IHttpClient httpClient, IHttpClient httpClient,
@ -42,6 +47,8 @@ namespace NzbDrone.Core.Extras.Metadata
{ {
_metadataFactory = metadataFactory; _metadataFactory = metadataFactory;
_cleanMetadataService = cleanMetadataService; _cleanMetadataService = cleanMetadataService;
_otherExtraFileRenamer = otherExtraFileRenamer;
_recycleBinProvider = recycleBinProvider;
_diskTransferService = diskTransferService; _diskTransferService = diskTransferService;
_diskProvider = diskProvider; _diskProvider = diskProvider;
_httpClient = httpClient; _httpClient = httpClient;
@ -249,6 +256,8 @@ namespace NzbDrone.Core.Extras.Metadata
var fullPath = Path.Combine(artist.Path, artistMetadata.RelativePath); var fullPath = Path.Combine(artist.Path, artistMetadata.RelativePath);
_otherExtraFileRenamer.RenameOtherExtraFile(artist, fullPath);
_logger.Debug("Writing Artist Metadata to: {0}", fullPath); _logger.Debug("Writing Artist Metadata to: {0}", fullPath);
SaveMetadataFile(fullPath, artistMetadata.Contents); SaveMetadataFile(fullPath, artistMetadata.Contents);
@ -293,6 +302,8 @@ namespace NzbDrone.Core.Extras.Metadata
var fullPath = Path.Combine(artist.Path, albumMetadata.RelativePath); var fullPath = Path.Combine(artist.Path, albumMetadata.RelativePath);
_otherExtraFileRenamer.RenameOtherExtraFile(artist, fullPath);
_logger.Debug("Writing Album Metadata to: {0}", fullPath); _logger.Debug("Writing Album Metadata to: {0}", fullPath);
SaveMetadataFile(fullPath, albumMetadata.Contents); SaveMetadataFile(fullPath, albumMetadata.Contents);
@ -314,6 +325,8 @@ namespace NzbDrone.Core.Extras.Metadata
var fullPath = Path.Combine(artist.Path, trackMetadata.RelativePath); var fullPath = Path.Combine(artist.Path, trackMetadata.RelativePath);
_otherExtraFileRenamer.RenameOtherExtraFile(artist, fullPath);
var existingMetadata = GetMetadataFile(artist, existingMetadataFiles, c => c.Type == MetadataType.TrackMetadata && var existingMetadata = GetMetadataFile(artist, existingMetadataFiles, c => c.Type == MetadataType.TrackMetadata &&
c.TrackFileId == trackFile.Id); c.TrackFileId == trackFile.Id);
@ -368,6 +381,8 @@ namespace NzbDrone.Core.Extras.Metadata
continue; continue;
} }
_otherExtraFileRenamer.RenameOtherExtraFile(artist, fullPath);
var metadata = GetMetadataFile(artist, existingMetadataFiles, c => c.Type == MetadataType.ArtistImage && var metadata = GetMetadataFile(artist, existingMetadataFiles, c => c.Type == MetadataType.ArtistImage &&
c.RelativePath == image.RelativePath) ?? c.RelativePath == image.RelativePath) ??
new MetadataFile new MetadataFile
@ -401,6 +416,8 @@ namespace NzbDrone.Core.Extras.Metadata
continue; continue;
} }
_otherExtraFileRenamer.RenameOtherExtraFile(artist, fullPath);
var metadata = GetMetadataFile(artist, existingMetadataFiles, c => c.Type == MetadataType.AlbumImage && var metadata = GetMetadataFile(artist, existingMetadataFiles, c => c.Type == MetadataType.AlbumImage &&
c.AlbumId == album.Id && c.AlbumId == album.Id &&
c.RelativePath == image.RelativePath) ?? c.RelativePath == image.RelativePath) ??
@ -471,10 +488,10 @@ namespace NzbDrone.Core.Extras.Metadata
_logger.Debug("Removing duplicate Metadata file: {0}", path); _logger.Debug("Removing duplicate Metadata file: {0}", path);
_diskProvider.DeleteFile(path); var subfolder = _diskProvider.GetParentFolder(artist.Path).GetRelativePath(_diskProvider.GetParentFolder(path));
_recycleBinProvider.DeleteFile(path, subfolder);
_metadataFileService.Delete(file.Id); _metadataFileService.Delete(file.Id);
} }
return matchingMetadataFiles.First(); return matchingMetadataFiles.First();
} }

View File

@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using NLog;
using NzbDrone.Common.Disk;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Music;
namespace NzbDrone.Core.Extras.Others
{
public interface IOtherExtraFileRenamer
{
void RenameOtherExtraFile(Artist artist, string path);
}
public class OtherExtraFileRenamer : IOtherExtraFileRenamer
{
private readonly Logger _logger;
private readonly IDiskProvider _diskProvider;
private readonly IRecycleBinProvider _recycleBinProvider;
private readonly IArtistService _artistService;
private readonly IOtherExtraFileService _otherExtraFileService;
public OtherExtraFileRenamer(IOtherExtraFileService otherExtraFileService,
IArtistService artistService,
IRecycleBinProvider recycleBinProvider,
IDiskProvider diskProvider,
Logger logger)
{
_logger = logger;
_diskProvider = diskProvider;
_recycleBinProvider = recycleBinProvider;
_artistService = artistService;
_otherExtraFileService = otherExtraFileService;
}
public void RenameOtherExtraFile(Artist artist, string path)
{
if (!_diskProvider.FileExists(path))
{
return;
}
var relativePath = artist.Path.GetRelativePath(path);
var otherExtraFile = _otherExtraFileService.FindByPath(relativePath);
if (otherExtraFile != null)
{
var newPath = path + "-orig";
// Recycle an existing -orig file.
RemoveOtherExtraFile(artist, newPath);
// Rename the file to .*-orig
_diskProvider.MoveFile(path, newPath);
otherExtraFile.RelativePath = relativePath + "-orig";
otherExtraFile.Extension += "-orig";
_otherExtraFileService.Upsert(otherExtraFile);
}
}
private void RemoveOtherExtraFile(Artist artist, string path)
{
if (!_diskProvider.FileExists(path))
{
return;
}
var relativePath = artist.Path.GetRelativePath(path);
var otherExtraFile = _otherExtraFileService.FindByPath(relativePath);
if (otherExtraFile != null)
{
var subfolder = Path.GetDirectoryName(relativePath);
_recycleBinProvider.DeleteFile(path, subfolder);
}
}
}
}

View File

@ -65,12 +65,6 @@ namespace NzbDrone.Core.Extras.Others
public override ExtraFile Import(Artist artist, TrackFile trackFile, string path, string extension, bool readOnly) public override ExtraFile Import(Artist artist, TrackFile trackFile, string path, string extension, bool readOnly)
{ {
// If the extension is .nfo we need to change it to .nfo-orig
if (Path.GetExtension(path).Equals(".nfo", StringComparison.OrdinalIgnoreCase))
{
extension += "-orig";
}
var extraFile = ImportFile(artist, trackFile, path, readOnly, extension, null); var extraFile = ImportFile(artist, trackFile, path, readOnly, extension, null);
_otherExtraFileService.Upsert(extraFile); _otherExtraFileService.Upsert(extraFile);

View File

@ -127,7 +127,7 @@ namespace NzbDrone.Core.MediaFiles.TrackImport
if (newDownload) if (newDownload)
{ {
_extraService.ImportExtraFiles(localTrack, trackFile, copyOnly); _extraService.ImportTrack(localTrack, trackFile, copyOnly);
} }
_eventAggregator.PublishEvent(new TrackImportedEvent(localTrack, trackFile, oldFiles, newDownload, downloadClientItem)); _eventAggregator.PublishEvent(new TrackImportedEvent(localTrack, trackFile, oldFiles, newDownload, downloadClientItem));

View File

@ -440,10 +440,12 @@
<Compile Include="Extras\IImportExistingExtraFiles.cs" /> <Compile Include="Extras\IImportExistingExtraFiles.cs" />
<Compile Include="Extras\ImportExistingExtraFileFilterResult.cs" /> <Compile Include="Extras\ImportExistingExtraFileFilterResult.cs" />
<Compile Include="Extras\ImportExistingExtraFilesBase.cs" /> <Compile Include="Extras\ImportExistingExtraFilesBase.cs" />
<Compile Include="Extras\Metadata\Consumers\Xbmc\XbmcNfoDetector.cs" />
<Compile Include="Extras\Metadata\Files\MetadataFile.cs" /> <Compile Include="Extras\Metadata\Files\MetadataFile.cs" />
<Compile Include="Extras\Metadata\Files\MetadataFileRepository.cs" /> <Compile Include="Extras\Metadata\Files\MetadataFileRepository.cs" />
<Compile Include="Extras\Metadata\Files\MetadataFileService.cs" /> <Compile Include="Extras\Metadata\Files\MetadataFileService.cs" />
<Compile Include="Extras\Others\ExistingOtherExtraImporter.cs" /> <Compile Include="Extras\Others\ExistingOtherExtraImporter.cs" />
<Compile Include="Extras\Others\OtherExtraFileRenamer.cs" />
<Compile Include="Extras\Others\OtherExtraFileRepository.cs" /> <Compile Include="Extras\Others\OtherExtraFileRepository.cs" />
<Compile Include="Extras\Others\OtherExtraFileService.cs" /> <Compile Include="Extras\Others\OtherExtraFileService.cs" />
<Compile Include="Extras\Others\OtherExtraFile.cs" /> <Compile Include="Extras\Others\OtherExtraFile.cs" />