mirror of
https://github.com/Readarr/Readarr.git
synced 2026-04-17 21:25:39 -04:00
New: Allow keeping calibre in sync with goodreads
This commit is contained in:
@@ -15,14 +15,17 @@ namespace NzbDrone.Core.Books
|
||||
{
|
||||
private readonly IEditionService _editionService;
|
||||
private readonly IAudioTagService _audioTagService;
|
||||
private readonly IEBookTagService _eBookTagService;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public RefreshEditionService(IEditionService editionService,
|
||||
IAudioTagService audioTagService,
|
||||
IEBookTagService eBookTagService,
|
||||
Logger logger)
|
||||
{
|
||||
_editionService = editionService;
|
||||
_audioTagService = audioTagService;
|
||||
_eBookTagService = eBookTagService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
@@ -52,6 +55,7 @@ namespace NzbDrone.Core.Books
|
||||
}
|
||||
|
||||
_audioTagService.SyncTags(tagsToUpdate);
|
||||
_eBookTagService.SyncTags(tagsToUpdate);
|
||||
|
||||
return add.Any() || delete.Any() || updateList.Any() || merge.Any();
|
||||
}
|
||||
|
||||
@@ -290,6 +290,27 @@ namespace NzbDrone.Core.Configuration
|
||||
set { SetValue("ScrubAudioTags", value); }
|
||||
}
|
||||
|
||||
public WriteBookTagsType WriteBookTags
|
||||
{
|
||||
get { return GetValueEnum("WriteBookTags", WriteBookTagsType.NewFiles); }
|
||||
|
||||
set { SetValue("WriteBookTags", value); }
|
||||
}
|
||||
|
||||
public bool UpdateCovers
|
||||
{
|
||||
get { return GetValueBoolean("UpdateCovers", true); }
|
||||
|
||||
set { SetValue("UpdateCovers", value); }
|
||||
}
|
||||
|
||||
public bool EmbedMetadata
|
||||
{
|
||||
get { return GetValueBoolean("EmbedMetadata", false); }
|
||||
|
||||
set { SetValue("EmbedMetadata", value); }
|
||||
}
|
||||
|
||||
public int FirstDayOfWeek
|
||||
{
|
||||
get { return GetValueInt("FirstDayOfWeek", (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek); }
|
||||
|
||||
@@ -70,6 +70,9 @@ namespace NzbDrone.Core.Configuration
|
||||
string MetadataSource { get; set; }
|
||||
WriteAudioTagsType WriteAudioTags { get; set; }
|
||||
bool ScrubAudioTags { get; set; }
|
||||
WriteBookTagsType WriteBookTags { get; set; }
|
||||
bool UpdateCovers { get; set; }
|
||||
bool EmbedMetadata { get; set; }
|
||||
|
||||
//Forms Auth
|
||||
string RijndaelPassphrase { get; }
|
||||
|
||||
9
src/NzbDrone.Core/Configuration/WriteBookTagsType.cs
Normal file
9
src/NzbDrone.Core/Configuration/WriteBookTagsType.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace NzbDrone.Core.Configuration
|
||||
{
|
||||
public enum WriteBookTagsType
|
||||
{
|
||||
NewFiles,
|
||||
AllFiles,
|
||||
Sync
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,6 @@ using NzbDrone.Core.Extras;
|
||||
using NzbDrone.Core.MediaFiles.Events;
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.RootFolders;
|
||||
@@ -31,9 +30,9 @@ namespace NzbDrone.Core.MediaFiles.BookImport
|
||||
private readonly IUpgradeMediaFiles _bookFileUpgrader;
|
||||
private readonly IMediaFileService _mediaFileService;
|
||||
private readonly IAudioTagService _audioTagService;
|
||||
private readonly IEBookTagService _eBookTagService;
|
||||
private readonly IAuthorService _authorService;
|
||||
private readonly IAddAuthorService _addAuthorService;
|
||||
private readonly IRefreshAuthorService _refreshAuthorService;
|
||||
private readonly IBookService _bookService;
|
||||
private readonly IEditionService _editionService;
|
||||
private readonly IRootFolderService _rootFolderService;
|
||||
@@ -47,9 +46,9 @@ namespace NzbDrone.Core.MediaFiles.BookImport
|
||||
public ImportApprovedBooks(IUpgradeMediaFiles bookFileUpgrader,
|
||||
IMediaFileService mediaFileService,
|
||||
IAudioTagService audioTagService,
|
||||
IEBookTagService eBookTagService,
|
||||
IAuthorService authorService,
|
||||
IAddAuthorService addAuthorService,
|
||||
IRefreshAuthorService refreshAuthorService,
|
||||
IBookService bookService,
|
||||
IEditionService editionService,
|
||||
IRootFolderService rootFolderService,
|
||||
@@ -63,9 +62,9 @@ namespace NzbDrone.Core.MediaFiles.BookImport
|
||||
_bookFileUpgrader = bookFileUpgrader;
|
||||
_mediaFileService = mediaFileService;
|
||||
_audioTagService = audioTagService;
|
||||
_eBookTagService = eBookTagService;
|
||||
_authorService = authorService;
|
||||
_addAuthorService = addAuthorService;
|
||||
_refreshAuthorService = refreshAuthorService;
|
||||
_bookService = bookService;
|
||||
_editionService = editionService;
|
||||
_rootFolderService = rootFolderService;
|
||||
@@ -207,6 +206,7 @@ namespace NzbDrone.Core.MediaFiles.BookImport
|
||||
}
|
||||
|
||||
_audioTagService.WriteTags(bookFile, false);
|
||||
_eBookTagService.WriteTags(bookFile, false);
|
||||
}
|
||||
|
||||
filesToAdd.Add(bookFile);
|
||||
|
||||
@@ -10,6 +10,7 @@ using NzbDrone.Common.Instrumentation.Extensions;
|
||||
using NzbDrone.Common.Serializer;
|
||||
using NzbDrone.Core.Books;
|
||||
using NzbDrone.Core.Books.Calibre;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.MediaFiles.Azw;
|
||||
using NzbDrone.Core.MediaFiles.Commands;
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
@@ -25,6 +26,8 @@ namespace NzbDrone.Core.MediaFiles
|
||||
public interface IEBookTagService
|
||||
{
|
||||
ParsedTrackInfo ReadTags(IFileInfo file);
|
||||
void WriteTags(BookFile trackfile, bool newDownload, bool force = false);
|
||||
void SyncTags(List<Edition> books);
|
||||
List<RetagBookFilePreview> GetRetagPreviewsByAuthor(int authorId);
|
||||
List<RetagBookFilePreview> GetRetagPreviewsByBook(int authorId);
|
||||
}
|
||||
@@ -36,18 +39,21 @@ namespace NzbDrone.Core.MediaFiles
|
||||
private readonly IAuthorService _authorService;
|
||||
private readonly IMediaFileService _mediaFileService;
|
||||
private readonly IRootFolderService _rootFolderService;
|
||||
private readonly IConfigService _configService;
|
||||
private readonly ICalibreProxy _calibre;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public EBookTagService(IAuthorService authorService,
|
||||
IMediaFileService mediaFileService,
|
||||
IRootFolderService rootFolderService,
|
||||
IConfigService configService,
|
||||
ICalibreProxy calibre,
|
||||
Logger logger)
|
||||
{
|
||||
_authorService = authorService;
|
||||
_mediaFileService = mediaFileService;
|
||||
_rootFolderService = rootFolderService;
|
||||
_configService = configService;
|
||||
_calibre = calibre;
|
||||
|
||||
_logger = logger;
|
||||
@@ -72,6 +78,48 @@ namespace NzbDrone.Core.MediaFiles
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteTags(BookFile bookFile, bool newDownload, bool force = false)
|
||||
{
|
||||
if (!force)
|
||||
{
|
||||
if (_configService.WriteBookTags == WriteBookTagsType.NewFiles && !newDownload)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_logger.Debug($"Writing tags for {bookFile}");
|
||||
|
||||
var rootFolder = _rootFolderService.GetBestRootFolder(bookFile.Path);
|
||||
_calibre.SetFields(bookFile, rootFolder.CalibreSettings, _configService.UpdateCovers, _configService.EmbedMetadata);
|
||||
}
|
||||
|
||||
public void SyncTags(List<Edition> editions)
|
||||
{
|
||||
if (_configService.WriteBookTags != WriteBookTagsType.Sync)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// get the tracks to update
|
||||
foreach (var edition in editions)
|
||||
{
|
||||
var bookFiles = edition.BookFiles.Value;
|
||||
|
||||
_logger.Debug($"Syncing ebook tags for {edition}");
|
||||
|
||||
foreach (var file in bookFiles)
|
||||
{
|
||||
// populate tracks (which should also have release/book/author set) because
|
||||
// not all of the updates will have been committed to the database yet
|
||||
file.Edition = edition;
|
||||
|
||||
var rootFolder = _rootFolderService.GetBestRootFolder(file.Path);
|
||||
_calibre.SetFields(file, rootFolder.CalibreSettings, _configService.UpdateCovers, _configService.EmbedMetadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<RetagBookFilePreview> GetRetagPreviewsByAuthor(int authorId)
|
||||
{
|
||||
var files = _mediaFileService.GetFilesByAuthor(authorId);
|
||||
|
||||
@@ -5,6 +5,7 @@ using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Books.Calibre;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.MediaFiles.BookImport;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.RootFolders;
|
||||
@@ -18,6 +19,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||
|
||||
public class UpgradeMediaFileService : IUpgradeMediaFiles
|
||||
{
|
||||
private readonly IConfigService _configService;
|
||||
private readonly IRecycleBinProvider _recycleBinProvider;
|
||||
private readonly IMediaFileService _mediaFileService;
|
||||
private readonly IAudioTagService _audioTagService;
|
||||
@@ -28,7 +30,8 @@ namespace NzbDrone.Core.MediaFiles
|
||||
private readonly ICalibreProxy _calibre;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public UpgradeMediaFileService(IRecycleBinProvider recycleBinProvider,
|
||||
public UpgradeMediaFileService(IConfigService configService,
|
||||
IRecycleBinProvider recycleBinProvider,
|
||||
IMediaFileService mediaFileService,
|
||||
IAudioTagService audioTagService,
|
||||
IMoveBookFiles bookFileMover,
|
||||
@@ -38,6 +41,7 @@ namespace NzbDrone.Core.MediaFiles
|
||||
ICalibreProxy calibre,
|
||||
Logger logger)
|
||||
{
|
||||
_configService = configService;
|
||||
_recycleBinProvider = recycleBinProvider;
|
||||
_mediaFileService = mediaFileService;
|
||||
_audioTagService = audioTagService;
|
||||
@@ -136,15 +140,15 @@ namespace NzbDrone.Core.MediaFiles
|
||||
_calibre.AddFormat(file, settings);
|
||||
}
|
||||
|
||||
_calibre.SetFields(file, settings);
|
||||
_rootFolderWatchingService.ReportFileSystemChangeBeginning(file.Path);
|
||||
|
||||
_calibre.SetFields(file, settings, true, _configService.EmbedMetadata);
|
||||
|
||||
var updated = _calibre.GetBook(file.CalibreId, settings);
|
||||
var path = updated.Formats.Values.OrderByDescending(x => x.LastModified).First().Path;
|
||||
|
||||
file.Path = path;
|
||||
|
||||
_rootFolderWatchingService.ReportFileSystemChangeBeginning(file.Path);
|
||||
|
||||
if (settings.OutputFormat.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
_logger.Trace($"Getting book data for {file.CalibreId}");
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using FluentValidation;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Validation;
|
||||
using NzbDrone.Http.REST.Attributes;
|
||||
using Readarr.Http;
|
||||
using Readarr.Http.REST;
|
||||
@@ -19,6 +22,8 @@ namespace Prowlarr.Api.V1.Config
|
||||
{
|
||||
_configFileProvider = configFileProvider;
|
||||
_configService = configService;
|
||||
|
||||
SharedValidator.RuleFor(c => c.MetadataSource).IsValidUrl().When(c => !c.MetadataSource.IsNullOrWhiteSpace());
|
||||
}
|
||||
|
||||
public override DevelopmentConfigResource GetResourceById(int id)
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Prowlarr.Api.V1.Config
|
||||
{
|
||||
public class DevelopmentConfigResource : RestResource
|
||||
{
|
||||
public string MetadataSource { get; set; }
|
||||
public string ConsoleLogLevel { get; set; }
|
||||
public bool LogSql { get; set; }
|
||||
public int LogRotate { get; set; }
|
||||
@@ -17,6 +18,7 @@ namespace Prowlarr.Api.V1.Config
|
||||
{
|
||||
return new DevelopmentConfigResource
|
||||
{
|
||||
MetadataSource = configService.MetadataSource,
|
||||
ConsoleLogLevel = model.ConsoleLogLevel,
|
||||
LogSql = model.LogSql,
|
||||
LogRotate = model.LogRotate,
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using FluentValidation;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Validation;
|
||||
using Readarr.Http;
|
||||
|
||||
namespace Readarr.Api.V1.Config
|
||||
@@ -12,7 +9,6 @@ namespace Readarr.Api.V1.Config
|
||||
public MetadataProviderConfigController(IConfigService configService)
|
||||
: base(configService)
|
||||
{
|
||||
SharedValidator.RuleFor(c => c.MetadataSource).IsValidUrl().When(c => !c.MetadataSource.IsNullOrWhiteSpace());
|
||||
}
|
||||
|
||||
protected override MetadataProviderConfigResource ToResource(IConfigService model)
|
||||
|
||||
@@ -5,9 +5,9 @@ namespace Readarr.Api.V1.Config
|
||||
{
|
||||
public class MetadataProviderConfigResource : RestResource
|
||||
{
|
||||
public string MetadataSource { get; set; }
|
||||
public WriteAudioTagsType WriteAudioTags { get; set; }
|
||||
public bool ScrubAudioTags { get; set; }
|
||||
public WriteBookTagsType WriteBookTags { get; set; }
|
||||
public bool UpdateCovers { get; set; }
|
||||
public bool EmbedMetadata { get; set; }
|
||||
}
|
||||
|
||||
public static class MetadataProviderConfigResourceMapper
|
||||
@@ -16,9 +16,9 @@ namespace Readarr.Api.V1.Config
|
||||
{
|
||||
return new MetadataProviderConfigResource
|
||||
{
|
||||
MetadataSource = model.MetadataSource,
|
||||
WriteAudioTags = model.WriteAudioTags,
|
||||
ScrubAudioTags = model.ScrubAudioTags,
|
||||
WriteBookTags = model.WriteBookTags,
|
||||
UpdateCovers = model.UpdateCovers,
|
||||
EmbedMetadata = model.EmbedMetadata
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user